diff --git a/src/main/java/cat/udl/eps/softarch/demo/handler/ProcessAdoptionEventHandler.java b/src/main/java/cat/udl/eps/softarch/demo/handler/ProcessAdoptionEventHandler.java new file mode 100644 index 0000000..1aa8006 --- /dev/null +++ b/src/main/java/cat/udl/eps/softarch/demo/handler/ProcessAdoptionEventHandler.java @@ -0,0 +1,66 @@ +package cat.udl.eps.softarch.demo.handler; + +import cat.udl.eps.softarch.demo.domain.Adoption; +import cat.udl.eps.softarch.demo.exceptions.InvalidPostRequest; +import org.springframework.data.rest.core.annotation.HandleBeforeCreate; +import org.springframework.data.rest.core.annotation.RepositoryEventHandler; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; +import cat.udl.eps.softarch.demo.exceptions.UnauthorizedAccessException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +import java.util.Arrays; +import java.util.List; + + +@Component +@RepositoryEventHandler() +public class ProcessAdoptionEventHandler { + + private static final Logger logger = LoggerFactory.getLogger(ProcessAdoptionEventHandler.class); + + // These are the roles that are allowed to create an adoption + private static final String ROLE_USER = "ROLE_USER"; + private static final String ROLE_SHELTER_VOLUNTEER = "ROLE_SHELTER_VOLUNTEER"; + private static final String ROLE_ADMIN = "ROLE_ADMIN"; + + // This function is called before creating an adoption + @HandleBeforeCreate + public void handleAdoptionBeforeCreate(Adoption adoption) throws UnauthorizedAccessException, InvalidPostRequest { + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + + // If the user is not authorized, an exception is thrown + if(!isAuthorized(authentication) ) { + String userName = authentication != null ? authentication.getName() : "anonymous"; + String errorMessage = String.format("Unauthorized attempt to create an adoption by user: %s", userName); + logger.error(errorMessage); + throw new UnauthorizedAccessException(); + } + // If the pet is already adopted or the pet is null, an exception is thrown + else if (adoption.getPet() == null || adoption.getPet().isAdopted() || adoption.getConfirmed()) { + logger.error("Pet is already adopted or bad request"); + throw new InvalidPostRequest(); + } + // If the adoption is successful, the adoption is in process + + logger.info("Adoption for pet {} created successfully by user {}", adoption.getPet().getName(), authentication.getName()); + } + + + // This function allows to check if the user is authorized to perform the action + private boolean isAuthorized(Authentication authentication) { + if (authentication == null || !authentication.isAuthenticated()) { + return false; + } + + List requiredAuthorities = Arrays.asList(ROLE_USER, ROLE_SHELTER_VOLUNTEER, ROLE_ADMIN); + + return authentication.getAuthorities().stream() + .anyMatch(grantedAuthority -> requiredAuthorities.contains(grantedAuthority.getAuthority())); + } + + + +} diff --git a/src/test/java/cat/udl/eps/softarch/demo/steps/ProcessAdoptionStepDefs.java b/src/test/java/cat/udl/eps/softarch/demo/steps/ProcessAdoptionStepDefs.java index 8183374..3268ed0 100644 --- a/src/test/java/cat/udl/eps/softarch/demo/steps/ProcessAdoptionStepDefs.java +++ b/src/test/java/cat/udl/eps/softarch/demo/steps/ProcessAdoptionStepDefs.java @@ -1,6 +1,5 @@ package cat.udl.eps.softarch.demo.steps; - import cat.udl.eps.softarch.demo.domain.Adoption; import cat.udl.eps.softarch.demo.domain.Pet; import cat.udl.eps.softarch.demo.repository.AdoptionRepository; @@ -25,7 +24,6 @@ @SuppressWarnings("ALL") public class ProcessAdoptionStepDefs { - @Autowired StepDefs stepDefs; @@ -40,12 +38,10 @@ public class ProcessAdoptionStepDefs { protected ResultActions result; - @And("I receive a confirmation message for adopting the pet") public void iReceiveAConfirmationMessageForAdoptingThePet() throws Throwable { result.andExpect(status().isOk()) .andExpect(jsonPath("$.message", is("Adoption successful"))); - } @Given("There is an available pet with name {string} i want to adopt") @@ -61,12 +57,10 @@ public void thereIsAnAvailablePetWithName(String arg0) { pet.setDescription("description"); pet.setBreed("breed"); petRepository.save(pet); - } @When("I request to adopt the pet with name {string}") public void iRequestToAdoptThePetWithName(String arg0) throws Throwable { - Adoption adoption = new Adoption(); adoption.setPet(petRepository.findByName(arg0).get(0)); adoption.setUser(userRepository.findAll().iterator().next()); @@ -82,11 +76,8 @@ public void iRequestToAdoptThePetWithName(String arg0) throws Throwable { .characterEncoding(StandardCharsets.UTF_8) .with(AuthenticationStepDefs.authenticate())) .andDo(print()); - } - - @When("I request to adopt without a pet") public void iRequestToAdoptWithoutAPet() throws Throwable{ // Proceed with adoption logic @@ -97,7 +88,6 @@ public void iRequestToAdoptWithoutAPet() throws Throwable{ adoption.setType("Adoption"); adoption.setEndDate(null); - stepDefs.result = stepDefs.mockMvc.perform( post("/adoptions") .contentType(MediaType.APPLICATION_JSON) @@ -105,12 +95,10 @@ public void iRequestToAdoptWithoutAPet() throws Throwable{ .characterEncoding(StandardCharsets.UTF_8) .with(AuthenticationStepDefs.authenticate())) .andDo(print()); - } @And("The pet with name {string} is already adopted") public void thePetWithNameIsAlreadyAdopted(String arg0) { - Pet pet = new Pet(); pet.setName(arg0); pet.setAdopted(true); @@ -121,7 +109,5 @@ public void thePetWithNameIsAlreadyAdopted(String arg0) { pet.setDescription("description"); pet.setBreed("breed"); petRepository.save(pet); - - } }