Skip to content

Commit

Permalink
fixed spelling error
Browse files Browse the repository at this point in the history
  • Loading branch information
harmlessprince committed Feb 16, 2025
1 parent 720f3ab commit 52042a6
Show file tree
Hide file tree
Showing 25 changed files with 145 additions and 54 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.harmlessprince.ecommerceApi.auth;


import com.harmlessprince.ecommerceApi.contexts.TenantContext;
import com.harmlessprince.ecommerceApi.custom.AppConstants;
import com.harmlessprince.ecommerceApi.events.UserLoginEvent;
import com.harmlessprince.ecommerceApi.exceptions.CustomBadRequestException;
Expand Down Expand Up @@ -82,5 +83,21 @@ public ResponseEntity<LoginResponse> login(@RequestBody @Valid LoginRequest logi
return ResponseEntity.ok(loginResponse);
}

@PostMapping("/login/customer")
public ResponseEntity<LoginResponse> loginAsCustomer(@RequestBody @Valid LoginRequest loginRequest, @RequestHeader(value = "X-Session-Id", required = false) String sessionId) {
User user = authenticationService.loginAsCustomer(loginRequest, TenantContext.getCurrentTenantID());
String token = jwtService.generateToken(user);
LoginResponse loginResponse = new LoginResponse(
userMapper.fromUser(user),
token,
jwtService.getExpirationTime()
);
Tenant tenant = user.getTenant();
if(sessionId != null && tenant != null) {
eventPublisher.publishEvent(new UserLoginEvent(this, user, sessionId , tenant.getId()));
}
return ResponseEntity.ok(loginResponse);
}


}
Original file line number Diff line number Diff line change
@@ -1,15 +1,22 @@
package com.harmlessprince.ecommerceApi.auth;

import com.harmlessprince.ecommerceApi.exceptions.CustomBadRequestException;
import com.harmlessprince.ecommerceApi.role.Role;
import com.harmlessprince.ecommerceApi.user.User;
import com.harmlessprince.ecommerceApi.user.UserRepository;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.Objects;
import java.util.Optional;

@Slf4j
@Service
@AllArgsConstructor
public class AuthenticationService {
Expand All @@ -28,13 +35,43 @@ public User signup(RegisterUserRequest request, Role role) {
}

public User login(LoginRequest request) {
Optional<User> user = userRepository.findFirstByEmail(request.email());

if (user.isEmpty()){
throw new BadCredentialsException("Invalid email or password");
}

User retrievedUser = user.get();
if (Objects.equals(retrievedUser.getRole().getName(), "customer")) {
throw new CustomBadRequestException("Invalid email or password");
}
authenticationManager.authenticate(
new UsernamePasswordAuthenticationToken(
request.email(),
request.password()
)
);
return retrievedUser;
}

public User loginAsCustomer(LoginRequest request, String tenantId) {
Optional<User> user = userRepository.findFirstByEmailAndTenantId(request.email(), tenantId);

if (user.isEmpty()){
throw new BadCredentialsException("Invalid email or password");
}

User retrievedUser = user.get();
if (!Objects.equals(retrievedUser.getRole().getSlug(), "customer")) {
throw new BadCredentialsException("Invalid email or password");
}
authenticationManager.authenticate(
new UsernamePasswordAuthenticationToken(
request.email(),
request.password()
)
);
return userRepository.findFirstByEmail(request.email()).orElseThrow(() -> new UsernameNotFoundException("User not found"));
return retrievedUser;
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ public class AppConstants {
public static final String PENDING_PAYMENT_STATUS = "PENDING";
public static final String REFUNDED_PAYMENT_STATUS = "REFUNDED";
public static final String ABANDONED_PAYMENT_STATUS = "ABANDONED";
public static final String PROCESSING_PAYMENT_STATUS = "PROCESSING";
public static final List<String> PAYMENT_STATUSES = Arrays.asList(SUCCESS_PAYMENT_STATUS, FAILED_PAYMENT_STATUS, PENDING_PAYMENT_STATUS, REFUNDED_PAYMENT_STATUS, ABANDONED_PAYMENT_STATUS);

// PAYSTACK API Constants
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ public ResponseEntity<CustomResponse<CustomerResponse>> deactivateCustomer(@Path
return ResponseEntity.ok(CustomResponse.sendSuccessResponse(null, "Customer deactivated successfully"));
}

@PatchMapping("/{customerId}/activiate")
@PatchMapping("/{customerId}/activate")
@ShopOwnerAccess
public ResponseEntity<CustomResponse<CustomerResponse>> activateCustomer(@PathVariable() String customerId) {
Optional<User> customer = this.customerService.findById(customerId);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import org.springframework.web.servlet.resource.NoResourceFoundException;

import java.util.HashMap;
import java.util.Map;

@RestControllerAdvice
@Slf4j
Expand Down Expand Up @@ -80,14 +81,24 @@ public ResponseEntity<CustomErrorResponse> handleBadRequestExceptions(Exception
}


@ExceptionHandler(BadCredentialsException.class)
public ResponseEntity<Map<String, Object>> handleBadCredentialsException(BadCredentialsException ex) {
Map<String, Object> response = new HashMap<>();
response.put("status", HttpStatus.BAD_REQUEST.value());
response.put("success", false);
response.put("error", "bad credentials");
response.put("message", "Invalid email or password");
return new ResponseEntity<>(response, HttpStatus.BAD_REQUEST);
}

@ExceptionHandler(Exception.class)
public ProblemDetail handle(Exception exception) {
ProblemDetail errorDetail = null;
exception.printStackTrace();

if (exception instanceof BadCredentialsException) {
errorDetail = ProblemDetail.forStatusAndDetail(HttpStatusCode.valueOf(400), exception.getMessage());
errorDetail.setProperty("description", "The username or password is incorrect");
errorDetail.setProperty("description", "The email or password is incorrect");
errorDetail.setStatus(400);
return errorDetail;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ public TenantInterceptor(HttpHeaderTenantResolver tenantResolver, TenantService
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
String requestURI = request.getRequestURI();
log.info("Request URI: {}", requestURI);
if (isPathAllowed(requestURI)) {
return true;
}
Expand Down Expand Up @@ -90,13 +91,13 @@ private List<String> allowedPaths() {
private boolean isPathAllowed(String url) {
// Remove the version part (e.g., "/v1/") from the URL
String path = url.replaceFirst("^/v\\d+/", "");

log.info("Request URI: {}", path);
// Get the list of allowed paths
List<String> allowedPaths = allowedPaths();

// Check if the remaining path is in the allowed paths
for (String allowedPath : allowedPaths) {
if (path.contains(allowedPath)) {
if (path.equals(allowedPath)) {
return true; // Return early when a match is found
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import com.fasterxml.jackson.annotation.JsonManagedReference;
import com.harmlessprince.ecommerceApi.bases.BaseEntity;
import com.harmlessprince.ecommerceApi.custom.AppConstants;
import com.harmlessprince.ecommerceApi.payment.PaymentGateWayEnum;
import com.harmlessprince.ecommerceApi.payment.PaymentStatusEnum;
import com.harmlessprince.ecommerceApi.user.AnonymousUser;
import com.harmlessprince.ecommerceApi.user.User;
import lombok.*;
Expand Down Expand Up @@ -36,12 +38,13 @@ public class Order extends BaseEntity {
private String area;
private String landmark;
private Object meta;
private String status;

private OrderStatusEnum status = OrderStatusEnum.PENDING;

@Builder.Default
private String paymentStatus = AppConstants.PENDING_PAYMENT_STATUS;
private PaymentStatusEnum paymentStatus = PaymentStatusEnum.PENDING;

private String paymentGateway; // PAYSTACK, FLUTTERWAVE, STRIPE
private PaymentGateWayEnum paymentGateway;

private String paymentGatewayTransactionId;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package com.harmlessprince.ecommerceApi.order;

import com.harmlessprince.ecommerceApi.payment.PaymentGateWayEnum;
import com.harmlessprince.ecommerceApi.payment.PaymentStatusEnum;
import com.harmlessprince.ecommerceApi.user.UserSlimResponse;
import lombok.*;

Expand Down Expand Up @@ -28,9 +30,9 @@ public class OrderResponse implements Serializable {
private final String city;
private final String area;
private final String landmark;
private final String status;
private final String paymentStatus;
private final String paymentGateway;
private final OrderStatusEnum status;
private final PaymentStatusEnum paymentStatus;
private final PaymentGateWayEnum paymentGateway;
private final String paymentGatewayTransactionId;
private final String fulfillmentStatus;
private final UserSlimResponse user;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import com.harmlessprince.ecommerceApi.contexts.TenantContext;
import com.harmlessprince.ecommerceApi.custom.AppConstants;
import com.harmlessprince.ecommerceApi.exceptions.CustomBadRequestException;
import com.harmlessprince.ecommerceApi.payment.PaymentStatusEnum;
import com.harmlessprince.ecommerceApi.promotion.Promotion;
import com.harmlessprince.ecommerceApi.promotion.PromotionRepository;
import com.harmlessprince.ecommerceApi.user.User;
Expand Down Expand Up @@ -32,7 +33,7 @@ public Order createOrder(User authenticatedUser, CheckoutRequest request) throws
.totalPrice(0.0)
.shippingAddress(request.getShippingAddress())
.billingAddress(request.getBillingAddress())
.status("pending")
.status(OrderStatusEnum.PENDING)
.city(request.getCity())
.country(request.getCountry())
.state(request.getState())
Expand All @@ -41,7 +42,7 @@ public Order createOrder(User authenticatedUser, CheckoutRequest request) throws
.shippingMethod(request.getShippingMethod())
.meta(request.getMeta())
.tenantId(TenantContext.getCurrentTenantID())
.paymentStatus(AppConstants.PENDING_PAYMENT_STATUS)
.paymentStatus(PaymentStatusEnum.PENDING)
.fulfillmentStatus(AppConstants.UNFULFILLED_ORDER_STATUS)
.build();
if (request.getPromoCode() != null) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package com.harmlessprince.ecommerceApi.order;

public enum OrderStatusEnum {
PENDING, PROCESSING, UNFULFILLED, SHIPPED, DELIVERED, CANCELLED;
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,11 @@ public class InitiatePaymentRequest {
private String paymentMethod;

@NotNull(message = "payment gateway is required")
private String paymentGateway;
private PaymentGateWayEnum paymentGateway;

@NotNull(message = "currency is required")
private String currency;

public String getPaymentGateway() {
return paymentGateway.toUpperCase();
}

public String getPaymentMethod() {
return paymentMethod.toLowerCase();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public class Payment extends BaseEntity {
private String paidAt;


private String gateway; // PAYSTACK, FLUTTERWAVE, STRIPE
private PaymentGateWayEnum gateway; // PAYSTACK, FLUTTERWAVE, STRIPE

private String paymentMethod;

Expand All @@ -45,7 +45,7 @@ public class Payment extends BaseEntity {
private String orderId;

@Builder.Default
private String status = AppConstants.PENDING_PAYMENT_STATUS; // SUCCESS, FAILED, PENDING, REFUNDED
private PaymentStatusEnum status = PaymentStatusEnum.PENDING; // SUCCESS, FAILED, PENDING, REFUNDED

@Indexed(unique = true, sparse = true)
private String paymentGatewayTransactionId;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import com.harmlessprince.ecommerceApi.handler.CustomResponse;
import com.harmlessprince.ecommerceApi.order.Order;
import com.harmlessprince.ecommerceApi.order.OrderRepository;
import com.harmlessprince.ecommerceApi.order.OrderStatusEnum;
import com.harmlessprince.ecommerceApi.paymentGateway.InitializePaymentDto;
import com.harmlessprince.ecommerceApi.paymentGateway.PaymentVerificationDto;
import com.harmlessprince.ecommerceApi.paymentSecret.PaymentSecretService;
Expand Down Expand Up @@ -40,7 +41,7 @@ public class PaymentController {
public ResponseEntity<CustomResponse<?>> initialPayment(@RequestBody @Valid InitiatePaymentRequest request, @AuthenticationPrincipal User user) {

// 3. Validate Payment Gateway & Method
if (!AppConstants.PAYMENT_GATEWAYS.contains(request.getPaymentGateway())) {
if (!AppConstants.PAYMENT_GATEWAYS.contains(request.getPaymentGateway().name())) {
throw new CustomBadRequestException("Payment gateway is not supported, supported gateways are: " + AppConstants.PAYMENT_GATEWAYS);
}
if (!paymentService.getPaymentMethods(request.getPaymentGateway()).contains(request.getPaymentMethod())) {
Expand Down Expand Up @@ -83,10 +84,10 @@ public Object verifyPayment(@RequestBody @Valid ConfirmPaymentRequest request) {
retrievedPayment.setGateway(paymentVerificationDto.getPaymentGateway());
retrievedPayment.setGatewayResponse(paymentVerificationDto.getMessage());
retrievedPayment.setMetadata(paymentVerificationDto.getPaymentGatewayResponse());
log.info("Expected Status <-> Actual Status: " + AppConstants.SUCCESS_PAYMENT_STATUS + "<>" + paymentVerificationDto.getStatus().toUpperCase());
log.info("Expected Status <-> Actual Status: " + AppConstants.SUCCESS_PAYMENT_STATUS + "<>" + paymentVerificationDto.getStatus());
log.info("Expected Amount Paid <-> Actual Amount Paid: " + retrievedPayment.getAmount() + "<>" + paymentVerificationDto.getAmountPaid());
if (!Objects.equals(paymentVerificationDto.getStatus().toUpperCase(), AppConstants.SUCCESS_PAYMENT_STATUS) || paymentVerificationDto.getAmountPaid() < retrievedPayment.getAmount() || !retrievedPayment.getCurrency().equals(paymentVerificationDto.getCurrency())) {
retrievedPayment.setStatus(paymentVerificationDto.getStatus().toUpperCase());
if (!Objects.equals(paymentVerificationDto.getStatus(), AppConstants.SUCCESS_PAYMENT_STATUS) || paymentVerificationDto.getAmountPaid() < retrievedPayment.getAmount() || !retrievedPayment.getCurrency().equals(paymentVerificationDto.getCurrency())) {
retrievedPayment.setStatus(paymentVerificationDto.getStatus());
paymentRepository.save(retrievedPayment);
return ResponseEntity.badRequest().body(CustomResponse.sendErrorResponse(paymentVerificationDto.getMessage()));
}
Expand All @@ -98,7 +99,7 @@ public Object verifyPayment(@RequestBody @Valid ConfirmPaymentRequest request) {
paymentRepository.save(retrievedPayment);

Order order = retrievedPayment.getOrder();
order.setStatus(AppConstants.SUCCESS_PAYMENT_STATUS);
order.setStatus(OrderStatusEnum.PROCESSING);
order.setPaymentStatus(retrievedPayment.getStatus());
order.setFulfillmentStatus(AppConstants.PROCESSING_ORDER_STATUS);
orderRepository.save(order);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package com.harmlessprince.ecommerceApi.payment;

public enum PaymentGateWayEnum {
PAYSTACK, FLUTTERWAVE, STRIPE
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,24 +44,24 @@ public PaymentVerificationDto verifyPayment(Payment payment) {
}


public String getGatewayName(String gateway){
public String getGatewayName(PaymentGateWayEnum gateway){
PaymentGateway paymentGateway = gatewayResolver.getGateway(gateway);
if (paymentGateway == null) {
throw new RuntimeException("Invalid Payment Gateway");
}
return paymentGateway.getGatewayName();
}

public String generateReference(String gateway) {
public String generateReference(PaymentGateWayEnum gateway) {
PaymentGateway paymentGateway = gatewayResolver.getGateway(gateway);
if (gateway == null) {
throw new RuntimeException("Unsupported Payment Gateway");
}
return paymentGateway.generateReference();
}

public List<String> getPaymentMethods(String gateway){
PaymentGateway paymentGateway = gatewayResolver.getGateway(gateway.toUpperCase());
public List<String> getPaymentMethods(PaymentGateWayEnum gateway){
PaymentGateway paymentGateway = gatewayResolver.getGateway(gateway);

if (paymentGateway == null) {
throw new RuntimeException("Invalid Payment Gateway");
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package com.harmlessprince.ecommerceApi.payment;

public enum PaymentStatusEnum {
SUCCESS, FAILED, PENDING, REFUNDED, ABANDONED, PROCESSING;
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.harmlessprince.ecommerceApi.payment.PaymentGateWayEnum;
import jakarta.validation.constraints.NotNull;
import lombok.*;

Expand Down Expand Up @@ -34,7 +35,7 @@ public class InitializePaymentDto {

@NotNull(message = "Payment gateway cannot be null")
@JsonProperty("payment_gateway")
private String paymentGateway;
private PaymentGateWayEnum paymentGateway;

@JsonIgnore
private String tenantId;
Expand Down
Loading

0 comments on commit 52042a6

Please sign in to comment.