From 3bb2d44439eed48caad73392c0c8a2a276fae7c1 Mon Sep 17 00:00:00 2001 From: Markus Herhoffer Date: Fri, 27 Dec 2024 16:19:30 +0100 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20(#220):=20Add=20endpoint=20to=20get?= =?UTF-8?q?=20my=20org?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../hopps/org/rest/OrganizationResource.java | 47 +++++++++++++---- .../OrganizationResourceAuthorizedTests.java | 51 +++++++++++++++++++ 2 files changed, 89 insertions(+), 9 deletions(-) create mode 100644 backend/app.hopps.org/src/test/java/app/hopps/org/rest/OrganizationResourceAuthorizedTests.java diff --git a/backend/app.hopps.org/src/main/java/app/hopps/org/rest/OrganizationResource.java b/backend/app.hopps.org/src/main/java/app/hopps/org/rest/OrganizationResource.java index 09f9977f..f482fcd1 100644 --- a/backend/app.hopps.org/src/main/java/app/hopps/org/rest/OrganizationResource.java +++ b/backend/app.hopps.org/src/main/java/app/hopps/org/rest/OrganizationResource.java @@ -1,6 +1,7 @@ package app.hopps.org.rest; import app.hopps.org.jpa.Member; +import app.hopps.org.jpa.MemberRepository; import app.hopps.org.jpa.Organization; import app.hopps.org.jpa.OrganizationRepository; import app.hopps.org.rest.RestValidator.ValidationResult; @@ -12,12 +13,15 @@ import jakarta.ws.rs.BadRequestException; import jakarta.ws.rs.Consumes; import jakarta.ws.rs.GET; +import jakarta.ws.rs.NotFoundException; import jakarta.ws.rs.POST; import jakarta.ws.rs.Path; import jakarta.ws.rs.PathParam; import jakarta.ws.rs.Produces; +import jakarta.ws.rs.core.Context; import jakarta.ws.rs.core.MediaType; import jakarta.ws.rs.core.Response; +import jakarta.ws.rs.core.SecurityContext; import org.eclipse.microprofile.openapi.annotations.Operation; import org.eclipse.microprofile.openapi.annotations.media.Content; import org.eclipse.microprofile.openapi.annotations.media.Schema; @@ -28,6 +32,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.util.Collection; import java.util.Map; @Path("/organization") @@ -36,17 +41,18 @@ public class OrganizationResource { private static final Logger LOG = LoggerFactory.getLogger(OrganizationResource.class); - private final Validator validator; - private final Process process; - private final OrganizationRepository organizationRepository; + @Inject + Validator validator; @Inject - public OrganizationResource(Validator validator, @Named("NewOrganization") Process process, - OrganizationRepository organizationRepository) { - this.validator = validator; - this.process = process; - this.organizationRepository = organizationRepository; - } + @Named("NewOrganization") + Process process; + + @Inject + OrganizationRepository organizationRepository; + + @Inject + MemberRepository memberRepository; @GET @Path("{slug}") @@ -63,6 +69,29 @@ public Response getOrganizationBySlug(@PathParam("slug") String slug) { return Response.ok(organization).build(); } + @GET + @Path("/my") + @Produces(MediaType.APPLICATION_JSON) + @Operation(summary = "Get my organization", description = "Retrieves the details of an organization the current user is assigned to.") + @APIResponse(responseCode = "200", description = "Own organization retrieved successfully", content = @Content(mediaType = MediaType.APPLICATION_JSON, schema = @Schema(implementation = Organization.class))) + @APIResponse(responseCode = "404", description = "Organization not found for user") + public Organization getMyOrganization(@Context SecurityContext securityContext) { + + String userName = securityContext.getUserPrincipal().getName(); + Member me = memberRepository.findByEmail(userName); + if (me == null) { + throw new NotFoundException("Organization of User not found"); + } + + Collection orgs = me.getOrganizations(); + if (orgs.size() > 1) { + throw new IllegalStateException( + "More than one organization is currently not implemented. User: " + userName); + } + + return orgs.stream().findFirst().orElseThrow(); + } + @GET @Path("{slug}/members") @Produces(MediaType.APPLICATION_JSON) diff --git a/backend/app.hopps.org/src/test/java/app/hopps/org/rest/OrganizationResourceAuthorizedTests.java b/backend/app.hopps.org/src/test/java/app/hopps/org/rest/OrganizationResourceAuthorizedTests.java new file mode 100644 index 00000000..9d64fc6a --- /dev/null +++ b/backend/app.hopps.org/src/test/java/app/hopps/org/rest/OrganizationResourceAuthorizedTests.java @@ -0,0 +1,51 @@ +package app.hopps.org.rest; + +import app.hopps.org.jpa.Organization; +import app.hopps.org.jpa.OrganizationRepository; +import io.quarkus.test.common.http.TestHTTPEndpoint; +import io.quarkus.test.junit.QuarkusTest; +import io.quarkus.test.security.TestSecurity; +import jakarta.inject.Inject; +import jakarta.ws.rs.core.MediaType; +import org.flywaydb.core.Flyway; +import org.instancio.Instancio; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.slf4j.Logger; + +import java.nio.file.Files; +import java.nio.file.Paths; +import java.sql.SQLException; + +import static io.restassured.RestAssured.given; +import static org.hamcrest.Matchers.is; +import static org.slf4j.LoggerFactory.getLogger; + +@QuarkusTest +@TestHTTPEndpoint(OrganizationResource.class) +class OrganizationResourceAuthorizedTests { + + @Inject + Flyway flyway; + + @BeforeEach + public void cleanDatabase() throws Exception { + flyway.clean(); + flyway.migrate(); + } + + @Test + @DisplayName("should return Organization of current user") + @TestSecurity(user = "emanuel_urban@domain.none") + void shouldReturnMyOrg() { + + given() + .contentType(MediaType.APPLICATION_JSON) + .when() + .get("my") + .then() + .statusCode(200) + .body("name", is("GrĂ¼nes Herz e.V.")); + } +}