Ejemplo n.º 1
0
        private void SetAuthorInfo(ApplicationCore.Models.Ticket entity)
        {
            if (User.IsPerson())
            {
                Guid currentUserId = User.GetUserId();
                entity.EditorId = currentUserId;
                if (entity.Id == Guid.Empty)
                {
                    entity.CreatorId = currentUserId;
                }
            }
            else
            {
                // API Client (S2S) without user.
                // TODO: Save client id as author information.
                entity.EditorId = null;
            }
            var timestamp = DateTime.UtcNow;

            entity.EditedAt = timestamp;
            if (entity.Id == Guid.Empty)
            {
                entity.CreatedAt = timestamp;
            }
        }
Ejemplo n.º 2
0
        private async Task <IActionResult> ValidateTicketAsync(ApplicationCore.Models.Ticket ticket,
                                                               string ticketNumber = null,
                                                               string ticketSecret = null)
        {
            if (ticket == null)
            {
                string lookupValueType = ticketNumber == null ? "secret" : "number";
                string lookupValue     = ticketNumber ?? ticketSecret;
                _logger.LogInformation(
                    $"Ticket with {lookupValueType} {lookupValue} was not found in the database.", lookupValue);
                return(TicketNotFound());
            }

            ClaimsPrincipal currentUser = await TryGetAuthenticatedUser();

            UserContext context = currentUser.GetContext();

            // If the user is logged in for a single event only,
            // check if the ticket and the event are the same.
            if (context.EventId != null &&
                context.EventId != ticket.EventId)
            {
                return(WrongEvent());
            }

            if (!currentUser.Identity.IsAuthenticated)
            {
                _logger.LogInformation("Unauthorized. Redirect to event homepage.");

                string validationUri = GetTicketValidationUri(ticket.TicketSecret);
                string redirectUrl   = await _ticketRedirectService.GetRedirectUrlAsync(ticket.Id, validationUri);

                return(Redirect(redirectUrl));
            }

            var currentEvent = ticket.Event;

            if (currentEvent == null)
            {
                // try to get the event for which the master qr code was issued.
                UserContext userContext = User.GetContext();
                if (userContext?.EventId != null)
                {
                    currentEvent = _context.Events.Find(userContext.EventId);
                }
            }
            if (currentEvent != null && currentEvent.IsConference)
            {
                return(ConferenceCheckInDialog(ticket));
            }

            if (ticket.Validated)
            {
                _logger.LogInformation("The ticket has already been used before.");
                return(View("TicketUsed", ticket));
            }
            ticket.Validated = true;
            _context.SaveChanges();
            return(View("TicketValid", ticket));
        }
Ejemplo n.º 3
0
        public async Task <IActionResult> ValidateTicketByQrCodeValueAsync(string secret)
        {
            if (secret == null)
            {
                return(NotFound());
            }

            ApplicationCore.Models.Ticket ticket =
                await FindTicketAsync(e => e.TicketSecret == secret);

            return(await ValidateTicketAsync(ticket, ticketSecret : secret));
        }
Ejemplo n.º 4
0
        public async Task <IActionResult> ValidateTicketByNumberAsync(string number)
        {
            if (number == null)
            {
                return(NotFound());
            }

            ApplicationCore.Models.Ticket ticket =
                await FindTicketAsync(e => e.TicketNumber == number);

            return(await ValidateTicketAsync(ticket, ticketNumber : number));
        }
Ejemplo n.º 5
0
        public async Task <ActionResult <Ticket> > CreateTicketAsync(Ticket model)
        {
            if (model.Id != Guid.Empty)
            {
                return(BadRequest(
                           new ProblemDetails {
                    Detail = "This method can't be used to update tickets."
                }));
            }
            if (await _context.Tickets.AnyAsync(t => t.TicketNumber == model.TicketNumber))
            {
                return(BadRequest(
                           new ProblemDetails {
                    Detail = $"The ticket number \"{model.TicketNumber}\" is already in use."
                }));
            }
            var evt = await _context.Events.FindAsync(model.EventId);

            if (evt == null)
            {
                return(BadRequest(
                           new ProblemDetails {
                    Detail = $"There's no event with id {model.EventId}."
                }));
            }
            var entity = new ApplicationCore.Models.Ticket();

            _mapper.Map(model, entity);
            entity.TicketSecret = Guid.NewGuid().ToString("N");
            entity.TicketNumber = entity.TicketNumber
                                  ?? _ticketNumberService.GenerateTicketNumber(evt);
            SetAuthorInfo(entity);
            _context.Add(entity);
            _context.SaveChanges();
            _context.Entry(entity).Reference(e => e.TicketType).Load();

            if (entity.BookingDate != null)
            {
                await _auditEventLog.AddAsync(new ApplicationCore.Models.AuditEvent
                {
                    Time     = entity.BookingDate.Value,
                    TicketId = entity.Id,
                    Action   = EventManagementConstants.Auditing.Actions.TicketOrder,
                    Detail   = $"Ticket der Kategorie \"{entity.TicketType.Name}\" wurde für {entity.TicketType.Price:c} bestellt."
                });
            }

            model = _mapper.Map <Ticket>(entity);
            return(CreatedAtAction(nameof(GetById), new { id = model.Id }, model));
        }
Ejemplo n.º 6
0
        private async Task SendMailAsync(ApplicationCore.Models.Ticket ticket,
                                         int secondsDelay = BatchMailSentIntervalSeconds)
        {
            var deliveryType = TicketDeliveryType.Email;
            await _ticketDeliveryService.ValidateAsync(ticket.Id, deliveryType);

            string validationUriFormat = GetTicketValidationUriFormatString();
            string validationUri       = GetTicketValidationUri(ticket.TicketSecret);
            string homepageUrl         = await _ticketRedirectService.GetRedirectUrlAsync(ticket.Id, validationUri);

            Expression <Action> methodCall =
                () => _ticketDeliveryService.SendTicketAsync(
                    ticket.Id, deliveryType, validationUriFormat, homepageUrl);

            _backgroundJobs.Schedule(
                methodCall,
                TimeSpan.FromSeconds(secondsDelay));
        }
Ejemplo n.º 7
0
        /// <summary>Update ticket data and return the right <see cref="IActionResult"/>.</summary>
        /// <param name="id">Id of the ticket to update.</param>
        /// <param name="modelResolver">Function that returns the new model with updated values.</param>
        private async Task <IActionResult> UpdateTicketResultAsync(Guid id,
                                                                   Func <ApplicationCore.Models.Ticket, Ticket> modelResolver)
        {
            ApplicationCore.Models.Ticket entity = await _context.Tickets.FindAsync(id);

            if (entity == null)
            {
                return(NotFound());
            }

            Ticket model = modelResolver(entity);

            if (model.TicketNumber != entity.TicketNumber)
            {
                return(BadRequest(
                           new ProblemDetails {
                    Detail = "The TicketNumber can't be changed."
                }));
            }
            if (model.EventId != entity.EventId)
            {
                return(BadRequest(
                           new ProblemDetails {
                    Detail = "The ticket is only valid for a single event."
                }));
            }

            if (model.TermsAccepted != entity.TermsAccepted)
            {
                await _auditEventLog.AddAsync(new ApplicationCore.Models.AuditEvent(model.TermsAccepted)
                {
                    Time     = DateTime.UtcNow,
                    TicketId = entity.Id,
                    Action   = EventManagementConstants.Auditing.Actions.TermsAccepted,
                    Detail   = model.TermsAccepted
                        ? "Die Einverständniserklärung der Eltern wurde abgegeben."
                        : "Status der Einverständniserklärung wurde in \"nicht abgegeben\" geändert."
                });
            }
            if (model.Validated != entity.Validated)
            {
                var checkInStatus = model.Validated ? "erfolgreich" : "ausstehend";
                await _auditEventLog.AddAsync(new ApplicationCore.Models.AuditEvent(model.Validated)
                {
                    Time     = DateTime.UtcNow,
                    TicketId = entity.Id,
                    Action   = EventManagementConstants.Auditing.Actions.TicketStatusChanged,
                    Detail   = $"Check-in-Status wurde von einem Administrator auf \"{checkInStatus}\" geändert."
                });
            }

            _mapper.Map(model, entity);
            SetAuthorInfo(entity);

            bool ticketTypeModified    = _context.Entry(entity).Property(e => e.TicketTypeId).IsModified;
            bool paymentStatusModified = _context.Entry(entity).Property(e => e.PaymentStatus).IsModified;

            if (ticketTypeModified)
            {
                _context.Entry(entity).Reference(e => e.TicketType).Load();
                await _auditEventLog.AddAsync(new ApplicationCore.Models.AuditEvent
                {
                    Time     = DateTime.UtcNow,
                    TicketId = entity.Id,
                    Action   = EventManagementConstants.Auditing.Actions.TicketTypeChanged,
                    Detail   = $"Der Ticket-Typ wurde auf \"{entity.TicketType.Name}\" geändert."
                });
            }

            if (paymentStatusModified)
            {
                string description = entity.PaymentStatus.GetDescription();
                float  amountPaid  = entity.AmountPaid.GetValueOrDefault();
                _context.Entry(entity).Reference(e => e.TicketType).Load();
                await _auditEventLog.AddAsync(new ApplicationCore.Models.AuditEvent
                {
                    Time     = DateTime.UtcNow,
                    TicketId = entity.Id,
                    Action   = EventManagementConstants.Auditing.Actions.PaymentStatusUpdated,
                    Detail   = $"Der Zahlungstatus wurde auf \"{description}\" geändert. " +
                               $"Bereits bezahlter Betrag: {amountPaid:c} von {entity.TicketType.Price:c}. " +
                               $"Ticket-Typ: {entity.TicketType.Name}.",
                    Level = _levels[entity.PaymentStatus]
                });
            }
            await _context.SaveChangesAsync();

            return(NoContent());
        }
Ejemplo n.º 8
0
        private IActionResult ConferenceCheckInDialog(ApplicationCore.Models.Ticket ticket)
        {
            var model = _mapper.Map <Models.ConferenceDialogModel>(ticket);

            return(View("ConferenceDialog", model));
        }