Skip to content

Commit

Permalink
#742 add ticket validity check for badge scan
Browse files Browse the repository at this point in the history
  • Loading branch information
cbellone committed Sep 6, 2019
1 parent e54d49e commit d539ae7
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 9 deletions.
31 changes: 24 additions & 7 deletions src/main/java/alfio/manager/CheckInManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.GeneralSecurityException;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
Expand Down Expand Up @@ -213,9 +214,19 @@ private TicketAndCheckInResult extractStatus(Optional<Event> maybeEvent, Optiona
}

Ticket ticket = maybeTicket.get();
if(ticket.getCategoryId() == null) {
return new TicketAndCheckInResult(new TicketWithCategory(ticket, null), new DefaultCheckInResult(INVALID_TICKET_STATE, "Invalid ticket state"));
}

TicketCategory tc = ticketCategoryRepository.getById(ticket.getCategoryId());

Event event = maybeEvent.get();
if(ticketCode.filter(StringUtils::isNotBlank).isEmpty()) {
if(ticket.isCheckedIn() && ticketCategoryRepository.getCheckInStrategy(ticket.getCategoryId()) == TicketCategory.TicketCheckInStrategy.ONCE_PER_DAY) {
if(ticket.isCheckedIn() && tc.getTicketCheckInStrategy() == TicketCategory.TicketCheckInStrategy.ONCE_PER_DAY) {
if(!isBadgeValidNow(tc, event)) {
// if the badge is not currently valid, we give an error
return new TicketAndCheckInResult(new TicketWithCategory(ticket, null), new DefaultCheckInResult(INVALID_TICKET_CATEGORY_CHECK_IN_DATE, "Not allowed to check in at this time."));
}
var ticketsReservationId = ticket.getTicketsReservationId();
int previousScan = auditingRepository.countAuditsOfTypesInTheSameDay(ticketsReservationId, Set.of(CHECK_IN.name(), MANUAL_CHECK_IN.name(), BADGE_SCAN.name()), ZonedDateTime.now(event.getZoneId()));
if(previousScan > 0) {
Expand All @@ -228,12 +239,6 @@ private TicketAndCheckInResult extractStatus(Optional<Event> maybeEvent, Optiona

String code = ticketCode.get();

if(ticket.getCategoryId() == null) {
return new TicketAndCheckInResult(new TicketWithCategory(ticket, null), new DefaultCheckInResult(INVALID_TICKET_STATE, "Invalid ticket state"));
}

TicketCategory tc = ticketCategoryRepository.getById(ticket.getCategoryId());

ZonedDateTime now = ZonedDateTime.now(event.getZoneId());
if(!tc.hasValidCheckIn(now, event.getZoneId())) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy - hh:mm");
Expand Down Expand Up @@ -266,6 +271,18 @@ private TicketAndCheckInResult extractStatus(Optional<Event> maybeEvent, Optiona
return new TicketAndCheckInResult(new TicketWithCategory(ticket, tc), new DefaultCheckInResult(OK_READY_TO_BE_CHECKED_IN, "Ready to be checked in"));
}

private static boolean isBadgeValidNow(TicketCategory tc, Event event) {
var zoneId = event.getZoneId();
var now = ZonedDateTime.now(zoneId);
return now.isAfter(toZoneIdIfNotNull(tc.getValidCheckInFrom(), zoneId).orElse(event.getBegin()))
&& now.isAfter(toZoneIdIfNotNull(tc.getTicketValidityStart(), zoneId).orElse(event.getBegin()))
&& now.isBefore(toZoneIdIfNotNull(tc.getTicketValidityEnd(), zoneId).orElse(event.getEnd()));
}

private static Optional<ZonedDateTime> toZoneIdIfNotNull(ZonedDateTime in, ZoneId zoneId) {
return Optional.ofNullable(in).map(d -> d.withZoneSameInstant(zoneId));
}

private static Pair<Cipher, SecretKeySpec> getCypher(String key) {
try {
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
Expand Down
2 changes: 0 additions & 2 deletions src/main/java/alfio/repository/TicketCategoryRepository.java
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,4 @@ default Map<Integer, TicketCategoryStatisticView> findStatisticsForEventIdByCate
@Query("select access_restricted from ticket_category where id = :id")
Boolean isAccessRestricted(@Bind("id") Integer hiddenCategoryId);

@Query("select ticket_checkin_strategy from ticket_category where id = :id")
TicketCategory.TicketCheckInStrategy getCheckInStrategy(@Bind("id") int categoryId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -527,6 +527,14 @@ updateTicketOwnerForm, new BeanPropertyBindingResult(updateTicketOwnerForm, "upd
MonetaryUtil.unitToCents(category.getPrice()), category.getCode(), category.getValidCheckInFrom(), category.getValidCheckInTo(), category.getTicketValidityStart(), category.getTicketValidityEnd(),
TicketCategory.TicketCheckInStrategy.ONCE_PER_DAY
);
ticketAndcheckInResult = checkInApiController.checkIn(event.getId(), ticketIdentifier, badgeScan, new TestingAuthenticationToken("ciccio", "ciccio"));
// the event start date is in one week, so we expect an error here
assertEquals(CheckInStatus.INVALID_TICKET_CATEGORY_CHECK_IN_DATE, ticketAndcheckInResult.getResult().getStatus());

eventRepository.updateHeader(event.getId(), event.getDisplayName(), event.getWebsiteUrl(), event.getExternalUrl(), event.getTermsAndConditionsUrl(), event.getPrivacyPolicyUrl(), event.getImageUrl(),
event.getFileBlobId(), event.getLocation(), event.getLatitude(), event.getLongitude(), ZonedDateTime.now(event.getZoneId()).minusSeconds(1), event.getEnd(), event.getTimeZone(),
event.getOrganizationId(), event.getLocales());

ticketAndcheckInResult = checkInApiController.checkIn(event.getId(), ticketIdentifier, badgeScan, new TestingAuthenticationToken("ciccio", "ciccio"));
// we have already scanned the ticket today, so we expect to receive a warning
assertEquals(CheckInStatus.BADGE_SCAN_ALREADY_DONE, ticketAndcheckInResult.getResult().getStatus());
Expand Down

0 comments on commit d539ae7

Please sign in to comment.