Skip to content
This repository has been archived by the owner on Dec 4, 2024. It is now read-only.

Commit

Permalink
feat: verify cognito role
Browse files Browse the repository at this point in the history
  • Loading branch information
MuriloKakazu committed Oct 2, 2024
1 parent 272a3db commit ffc5c32
Show file tree
Hide file tree
Showing 6 changed files with 83 additions and 0 deletions.
1 change: 1 addition & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-validation'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'io.jsonwebtoken:jjwt:0.9.1'
implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.5.0'
implementation 'org.apache.httpcomponents:httpclient:4.5'
compileOnly 'org.projectlombok:lombok'
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package br.com.fiap.grupo30.fastfood.infrastructure.auth;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.util.Base64;
import java.util.List;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

@Aspect
@Component
public class AdminAuthorizationAspect {

private final ObjectMapper objectMapper = new ObjectMapper();
private static String ADMIN_ROLE = "admin-group";
private static String BEARER_TYPE = "Bearer";
private static Integer JWT_PARTS = 3;

@Before("@annotation(AdminRequired)")
public void checkAdminRole() throws Exception {
ServletRequestAttributes attrs =
(ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attrs.getRequest();
HttpServletResponse response = attrs.getResponse();

String authorizationHeader = request.getHeader("Authorization");

if (authorizationHeader == null || !authorizationHeader.startsWith(BEARER_TYPE)) {
response.sendError(
HttpServletResponse.SC_UNAUTHORIZED, "Missing or invalid Authorization header");
return;
}

String jwtToken = authorizationHeader.substring(7);

String[] tokenParts = jwtToken.split("\\.");

if (tokenParts.length != JWT_PARTS) {
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Invalid JWT token structure");
return;
}

String payload = new String(Base64.getDecoder().decode(tokenParts[1]));
JsonNode jsonNode = objectMapper.readTree(payload);

JsonNode groupsNode = jsonNode.get("cognito:groups");
if (groupsNode != null && groupsNode.isArray()) {
List<String> groups = objectMapper.convertValue(groupsNode, List.class);
if (!groups.contains(ADMIN_ROLE)) {
response.sendError(
HttpServletResponse.SC_UNAUTHORIZED, "User does not have admin role");
return;
}
} else {
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "No cognito:groups found");
return;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package br.com.fiap.grupo30.fastfood.infrastructure.auth;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface AdminRequired {}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package br.com.fiap.grupo30.fastfood.presentation.controllers;

import br.com.fiap.grupo30.fastfood.domain.usecases.order.*;
import br.com.fiap.grupo30.fastfood.infrastructure.auth.AdminRequired;
import br.com.fiap.grupo30.fastfood.presentation.presenters.dto.AddCustomerCpfRequest;
import br.com.fiap.grupo30.fastfood.presentation.presenters.dto.AddOrderProductRequest;
import br.com.fiap.grupo30.fastfood.presentation.presenters.dto.OrderDTO;
Expand Down Expand Up @@ -147,6 +148,7 @@ public ResponseEntity<OrderDTO> finishPreparingOrder(@PathVariable Long orderId)
return ResponseEntity.ok().body(order);
}

@AdminRequired()
@PostMapping(value = "/{orderId}/deliver")
@Operation(
summary = "Deliver an order",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import br.com.fiap.grupo30.fastfood.domain.usecases.payment.CollectOrderPaymentViaCashUseCase;
import br.com.fiap.grupo30.fastfood.domain.usecases.payment.GeneratePaymentQrCodeUseCase;
import br.com.fiap.grupo30.fastfood.infrastructure.auth.AdminRequired;
import br.com.fiap.grupo30.fastfood.presentation.presenters.dto.CollectPaymentViaCashRequest;
import br.com.fiap.grupo30.fastfood.presentation.presenters.dto.OrderDTO;
import br.com.fiap.grupo30.fastfood.presentation.presenters.dto.PaymentQrCodeDTO;
Expand Down Expand Up @@ -39,6 +40,7 @@ public ResponseEntity<PaymentQrCodeDTO> generateQrCodeForPaymentCollection(
return ResponseEntity.ok().body(qrCode);
}

@AdminRequired()
@PostMapping(value = "/{orderId}/collect")
@Operation(summary = "Collect payment by cash")
public ResponseEntity<OrderDTO> collectPaymentByBash(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package br.com.fiap.grupo30.fastfood.presentation.controllers;

import br.com.fiap.grupo30.fastfood.domain.usecases.product.*;
import br.com.fiap.grupo30.fastfood.infrastructure.auth.AdminRequired;
import br.com.fiap.grupo30.fastfood.presentation.presenters.dto.ProductDTO;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
Expand Down Expand Up @@ -61,6 +62,7 @@ public ResponseEntity<ProductDTO> findProductById(@PathVariable Long id) {
return ResponseEntity.ok().body(dto);
}

@AdminRequired
@PostMapping
@Operation(
summary = "Create a new product",
Expand All @@ -81,6 +83,7 @@ public ResponseEntity<ProductDTO> createProduct(@RequestBody @Valid ProductDTO d
return ResponseEntity.created(uri).body(dtoCreated);
}

@AdminRequired()
@PutMapping(value = PATH_VARIABLE_ID)
@Operation(
summary = "Update a product",
Expand All @@ -98,6 +101,7 @@ public ResponseEntity<ProductDTO> updateProduct(
return ResponseEntity.ok().body(dtoUpdated);
}

@AdminRequired
@DeleteMapping(value = PATH_VARIABLE_ID)
@Operation(
summary = "Delete a product",
Expand Down

0 comments on commit ffc5c32

Please sign in to comment.