Skip to content

Commit

Permalink
remove the paypal token from the session #657 (#674)
Browse files Browse the repository at this point in the history
* initial work for removing the paypal token from the session #657

* cleanup paypal manager: remove unused code #657

* remove use of session for paypal token #657

* handle payment token removal #657
  • Loading branch information
syjer authored and cbellone committed Jul 3, 2019
1 parent a44dac9 commit 0b186a1
Show file tree
Hide file tree
Showing 21 changed files with 186 additions and 165 deletions.
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,4 @@ junitVersion=5.1.0
systemProp.jdk.tls.client.protocols="TLSv1,TLSv1.1,TLSv1.2"

# https://jitpack.io/#alfio-event/alf.io-public-frontend -> go to commit tab, set the version
alfioPublicFrontendVersion=328724c45d
alfioPublicFrontendVersion=14ce3870c3
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
import alfio.controller.form.ReservationForm;
import alfio.controller.form.WaitingQueueSubscriptionForm;
import alfio.controller.support.Formatters;
import alfio.controller.support.SessionUtil;
import alfio.manager.*;
import alfio.manager.i18n.I18nManager;
import alfio.manager.system.ConfigurationManager;
Expand Down Expand Up @@ -486,7 +485,7 @@ private Optional<String> createTicketReservation(ReservationForm reservation,
bindingResult.reject(ErrorsCode.STEP_1_ACCESS_RESTRICTED);
} catch (TicketReservationManager.InvalidSpecialPriceTokenException invalid) {
bindingResult.reject(ErrorsCode.STEP_1_CODE_NOT_FOUND);
SessionUtil.cleanupSession(request.getRequest());
//SessionUtil.cleanupSession(request.getRequest());
} catch (TicketReservationManager.TooManyTicketsForDiscountCodeException tooMany) {
bindingResult.reject(ErrorsCode.STEP_2_DISCOUNT_CODE_USAGE_EXCEEDED);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
import alfio.controller.api.v2.model.ValidatedResponse;
import alfio.controller.form.ContactAndTicketsForm;
import alfio.controller.form.PaymentForm;
import alfio.controller.support.SessionUtil;
import alfio.controller.support.TemplateProcessor;
import alfio.manager.*;
import alfio.manager.payment.PaymentSpecification;
Expand Down Expand Up @@ -60,7 +59,6 @@

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
Expand Down Expand Up @@ -105,8 +103,7 @@ public class ReservationApiV2Controller {
*/
@GetMapping("/event/{eventName}/reservation/{reservationId}")
public ResponseEntity<ReservationInfo> getReservationInfo(@PathVariable("eventName") String eventName,
@PathVariable("reservationId") String reservationId,
HttpSession session) {
@PathVariable("reservationId") String reservationId) {

Optional<ReservationInfo> res = eventRepository.findOptionalByShortName(eventName).flatMap(event -> ticketReservationManager.findById(reservationId).flatMap(reservation -> {

Expand Down Expand Up @@ -164,11 +161,9 @@ public ResponseEntity<ReservationInfo> getReservationInfo(@PathVariable("eventNa

var formattedExpirationDate = reservation.getValidity() != null ? formatDateForLocales(event, ZonedDateTime.ofInstant(reservation.getValidity().toInstant(), event.getZoneId()), "datetime.pattern") : null;

boolean tokenAcquired = session.getAttribute(PaymentManager.PAYMENT_TOKEN) != null;
PaymentProxy selectedPaymentProxy = null;
if (tokenAcquired) {
selectedPaymentProxy = ((PaymentToken)session.getAttribute(PaymentManager.PAYMENT_TOKEN)).getPaymentProvider();
}
var paymentToken = paymentManager.getPaymentToken(reservationId);
boolean tokenAcquired = paymentToken.isPresent();
PaymentProxy selectedPaymentProxy = paymentToken.map(PaymentToken::getPaymentProvider).orElse(null);

//
var containsCategoriesLinkedToGroups = ticketReservationManager.containsCategoriesLinkedToGroups(reservationId, event.getId());
Expand Down Expand Up @@ -235,12 +230,10 @@ public ResponseEntity<ReservationStatusInfo> getReservationStatus(@PathVariable(

@DeleteMapping("/event/{eventName}/reservation/{reservationId}")
public ResponseEntity<Boolean> cancelPendingReservation(@PathVariable("eventName") String eventName,
@PathVariable("reservationId") String reservationId,
HttpServletRequest request) {
@PathVariable("reservationId") String reservationId) {

getReservationWithPendingStatus(eventName, reservationId)
.ifPresent(er -> ticketReservationManager.cancelPendingReservation(reservationId, false, null));
SessionUtil.cleanupSession(request);
return ResponseEntity.ok(true);
}

Expand All @@ -261,8 +254,7 @@ public ResponseEntity<ValidatedResponse<ReservationPaymentResult>> confirmOvervi
@RequestParam("lang") String lang,
@RequestBody PaymentForm paymentForm,
BindingResult bindingResult,
HttpServletRequest request,
HttpSession session) {
HttpServletRequest request) {

return getReservation(eventName, reservationId).map(er -> {

Expand Down Expand Up @@ -299,7 +291,7 @@ public ResponseEntity<ValidatedResponse<ReservationPaymentResult>> confirmOvervi

OrderSummary orderSummary = ticketReservationManager.orderSummaryForReservationId(reservationId, event);

PaymentToken paymentToken = (PaymentToken) session.getAttribute(PaymentManager.PAYMENT_TOKEN);
PaymentToken paymentToken = paymentManager.getPaymentToken(reservationId).orElse(null);
if(paymentToken == null && StringUtils.isNotEmpty(paymentForm.getGatewayToken())) {
paymentToken = paymentManager.buildPaymentToken(paymentForm.getGatewayToken(), paymentForm.getPaymentMethod(), new PaymentContext(event, reservationId));
}
Expand All @@ -323,7 +315,7 @@ public ResponseEntity<ValidatedResponse<ReservationPaymentResult>> confirmOvervi
MessageSourceResolvable message = new DefaultMessageSourceResolvable(new String[]{errorMessageCode, StripeCreditCardManager.STRIPE_UNEXPECTED});
bindingResult.reject(ErrorsCode.STEP_2_PAYMENT_PROCESSING_ERROR, new Object[]{messageSource.getMessage(message, locale)}, null);
//SessionUtil.addToFlash(bindingResult, redirectAttributes);
SessionUtil.removePaymentToken(request);
//SessionUtil.removePaymentToken(request);
return buildReservationPaymentStatus(bindingResult);
}

Expand Down Expand Up @@ -592,6 +584,14 @@ public ResponseEntity<TransactionInitializationToken> initTransaction(@PathVaria
return responseEntity.orElseGet(() -> ResponseEntity.badRequest().build());
}

@DeleteMapping("/event/{eventName}/reservation/{reservationId}/payment/token")
public ResponseEntity<Boolean> removeToken(@PathVariable("eventName") String eventName,
@PathVariable("reservationId") String reservationId) {

var res = getEventReservationPair(eventName, reservationId).map(et -> paymentManager.removePaymentTokenReservation(et.getRight().getId())).orElse(false);
return ResponseEntity.ok(res);
}

private Optional<Pair<Event, TicketReservation>> getEventReservationPair(@PathVariable("eventName") String eventName, @PathVariable("reservationId") String reservationId) {
return eventRepository.findOptionalByShortName(eventName)
.map(event -> Pair.of(event, ticketReservationManager.findById(reservationId)))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@
*/
package alfio.controller.payment;

import alfio.manager.PaymentManager;
import alfio.manager.TicketReservationManager;
import alfio.manager.payment.PayPalManager;
import alfio.model.Event;
import alfio.model.TicketReservation;
import alfio.model.transaction.token.PayPalToken;
Expand All @@ -28,9 +28,7 @@
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import javax.servlet.http.HttpSession;
import java.util.Optional;

import static org.apache.commons.lang3.StringUtils.isNotBlank;
Expand All @@ -42,15 +40,14 @@ public class PayPalCallbackController {

private final EventRepository eventRepository;
private final TicketReservationManager ticketReservationManager;
private final PayPalManager payPalManager;

@GetMapping("/confirm")
public String payPalSuccess(@PathVariable("eventName") String eventName,
@PathVariable("reservationId") String reservationId,
@RequestParam(value = "paymentId", required = false) String payPalPaymentId,
@RequestParam(value = "PayerID", required = false) String payPalPayerID,
@RequestParam(value = "hmac") String hmac,
RedirectAttributes redirectAttributes,
HttpSession session) {
@RequestParam(value = "hmac") String hmac) {

Optional<Event> optionalEvent = eventRepository.findOptionalByShortName(eventName);
if(optionalEvent.isEmpty()) {
Expand All @@ -60,30 +57,26 @@ public String payPalSuccess(@PathVariable("eventName") String eventName,
Optional<TicketReservation> optionalReservation = ticketReservationManager.findById(reservationId);

if(optionalReservation.isEmpty()) {
return "redirect:/event/"+eventName;
return "redirect:/event/" + eventName;
}

var res = optionalReservation.get();
var ev = optionalEvent.get();

if (isNotBlank(payPalPayerID) && isNotBlank(payPalPaymentId)) {
redirectAttributes.addFlashAttribute("paypalCheckoutConfirmation", true)
.addFlashAttribute("tokenAcquired", true);
session.setAttribute(PaymentManager.PAYMENT_TOKEN, new PayPalToken(payPalPayerID, payPalPaymentId, hmac));
var token = new PayPalToken(payPalPayerID, payPalPaymentId, hmac);
payPalManager.saveToken(res.getId(), ev, token);
return "redirect:/event/" + ev.getShortName() + "/reservation/" +res.getId() + "/overview";
} else {
return payPalCancel(eventName, reservationId, redirectAttributes, session);
return payPalCancel(ev.getShortName(), res.getId());
}

return "redirect:/event/"+eventName+"/reservation/"+reservationId+"/overview";
}

@GetMapping("/cancel")
public String payPalCancel(@PathVariable("eventName") String eventName,
@PathVariable("reservationId") String reservationId,
RedirectAttributes redirectAttributes,
HttpSession session) {

session.removeAttribute(PaymentManager.PAYMENT_TOKEN);
@PathVariable("reservationId") String reservationId) {

redirectAttributes.addFlashAttribute("tokenAcquired", false)
.addFlashAttribute("payPalCancelled", true);
payPalManager.removeToken(reservationId);
return "redirect:/event/"+eventName+"/reservation/"+reservationId+"/overview";
}
}
33 changes: 33 additions & 0 deletions src/main/java/alfio/manager/PaymentManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import alfio.model.system.ConfigurationKeys;
import alfio.model.transaction.*;
import alfio.model.transaction.capabilities.ClientServerTokenRequest;
import alfio.model.transaction.capabilities.ExtractPaymentTokenFromTransaction;
import alfio.model.transaction.capabilities.PaymentInfo;
import alfio.model.transaction.capabilities.RefundRequest;
import alfio.repository.AuditingRepository;
Expand Down Expand Up @@ -61,6 +62,14 @@ Optional<PaymentProvider> lookupProviderByMethodAndCapabilities(PaymentMethod pa
return doLookupProvidersByMethodAndCapabilities(paymentMethod, context, capabilities).findFirst();
}

Optional<PaymentProvider> lookupByTransaction(Transaction transaction) {
return paymentProviders.stream().filter(p -> p.accept(transaction)).findFirst();
}

Optional<PaymentProvider> lookupByTransactionAndCapabilities(Transaction transaction, List<Class<? extends Capability>> capabilities) {
return paymentProviders.stream().filter(p -> p.accept(transaction)).filter(p -> capabilities.stream().allMatch(c -> c.isInstance(p))).findFirst();
}

List<PaymentProvider> lookupProvidersByMethodAndCapabilities(PaymentMethod paymentMethod,
PaymentContext context,
List<Class<? extends Capability>> capabilities) {
Expand Down Expand Up @@ -201,6 +210,30 @@ public Optional<PaymentResult> getTransactionStatus(TicketReservation reservatio
});
}

public Optional<PaymentToken> getPaymentToken(String reservationId) {
return transactionRepository.loadOptionalByReservationId(reservationId)
.filter(t->t.getStatus() == Transaction.Status.PENDING)
.flatMap(t -> {
if(t.getMetadata().containsKey(PAYMENT_TOKEN)) {
return lookupByTransactionAndCapabilities(t, List.of(ExtractPaymentTokenFromTransaction.class))
.map(ExtractPaymentTokenFromTransaction.class::cast)
.flatMap(paymentProvider -> paymentProvider.extractToken(t));
}
return Optional.empty();
});
}

public boolean removePaymentTokenReservation(String reservationId) {
return transactionRepository.loadOptionalByReservationId(reservationId).filter(t->t.getStatus() == Transaction.Status.PENDING)
.map(t -> {
if (t.getMetadata().containsKey(PAYMENT_TOKEN)) {
return transactionRepository.invalidateById(t.getId()) == 1;
} else {
return false;
}
}).orElse(false);
}

@Data
public static final class PaymentMethodDTO {

Expand Down
5 changes: 5 additions & 0 deletions src/main/java/alfio/manager/payment/BankTransferManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -116,4 +116,9 @@ public static OptionalInt getOfflinePaymentWaitingPeriod(PaymentContext paymentC
int waitingPeriod = configurationManager.getFor(paymentContext.getEvent(), OFFLINE_PAYMENT_DAYS).getValueAsIntOrDefault(5);
return OptionalInt.of( Math.min(daysToBegin, waitingPeriod) );
}

@Override
public boolean accept(Transaction transaction) {
return PaymentProxy.OFFLINE == transaction.getPaymentProxy();
}
}
1 change: 1 addition & 0 deletions src/main/java/alfio/manager/payment/BaseStripeManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@
@AllArgsConstructor
class BaseStripeManager {

static final String STRIPE_MANAGER_TYPE_KEY = "stripeManagerType";
static final String SUCCEEDED = "succeeded";
private final ConfigurationManager configurationManager;
private final ConfigurationRepository configurationRepository;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,7 @@
import alfio.model.TicketReservation;
import alfio.model.system.Configuration;
import alfio.model.system.ConfigurationKeys;
import alfio.model.transaction.PaymentContext;
import alfio.model.transaction.PaymentMethod;
import alfio.model.transaction.PaymentProvider;
import alfio.model.transaction.*;
import alfio.repository.EventRepository;
import alfio.repository.TicketReservationRepository;
import alfio.util.ErrorsCode;
Expand Down Expand Up @@ -145,4 +143,9 @@ public PaymentResult doPayment( PaymentSpecification spec ) {
return PaymentResult.failed( ErrorsCode.STEP_2_PAYMENT_REQUEST_CREATION );
}
}

@Override
public boolean accept(Transaction transaction) {
return PaymentProxy.MOLLIE == transaction.getPaymentProxy();
}
}
9 changes: 6 additions & 3 deletions src/main/java/alfio/manager/payment/OnSiteManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,7 @@

import alfio.manager.support.PaymentResult;
import alfio.manager.system.ConfigurationManager;
import alfio.model.transaction.PaymentContext;
import alfio.model.transaction.PaymentMethod;
import alfio.model.transaction.PaymentProvider;
import alfio.model.transaction.*;
import alfio.repository.TransactionRepository;
import lombok.AllArgsConstructor;
import lombok.extern.log4j.Log4j2;
Expand All @@ -44,6 +42,11 @@ public boolean accept(PaymentMethod paymentMethod, PaymentContext context) {
return paymentMethod == PaymentMethod.ON_SITE && configurationManager.getBooleanConfigValue(context.narrow(ON_SITE_ENABLED), false);
}

@Override
public boolean accept(Transaction transaction) {
return PaymentProxy.ON_SITE == transaction.getPaymentProxy();
}

@Override
public PaymentResult doPayment(PaymentSpecification spec) {
PaymentManagerUtils.invalidateExistingTransactions(spec.getReservationId(), transactionRepository);
Expand Down
Loading

0 comments on commit 0b186a1

Please sign in to comment.