From f8c7c3268b5d95e60e83fdea247c6ede7691b9f7 Mon Sep 17 00:00:00 2001 From: Loup Theron Date: Thu, 8 Aug 2024 14:32:30 +0200 Subject: [PATCH 1/8] Add keycloak and securize super user api paths --- Makefile | 2 +- .../api/bff/FleetSegmentController.kt | 8 +-- docker-compose.yml | 14 ++++++ frontend/.env.example | 1 + frontend/.env.local.defaults | 7 +-- frontend/src/auth/getOIDCConfig.ts | 3 +- frontend/src/env.d.ts | 1 + frontend/src/features/FleetSegment/apis.ts | 10 ++-- .../useCases/computeFleetSegments.ts} | 2 +- .../useCases/updateActionSegments.ts | 4 +- .../configurations/application-dev.properties | 2 +- .../application-local.properties | 6 +-- .../application-prod.properties | 2 +- infra/dev/keycloak/realm-monitor-dev.json | 50 +++++++++++++++++++ infra/docker/docker-compose.cypress.yml | 1 + infra/docker/docker-compose.puppeteer.yml | 1 + infra/remote/docker-compose.yml | 1 + 17 files changed, 93 insertions(+), 22 deletions(-) rename frontend/src/{domain/use_cases/vessel/getFleetSegments.ts => features/FleetSegment/useCases/computeFleetSegments.ts} (96%) create mode 100644 infra/dev/keycloak/realm-monitor-dev.json diff --git a/Makefile b/Makefile index e7c04517ee..806c4863df 100644 --- a/Makefile +++ b/Makefile @@ -20,7 +20,7 @@ init-local-sig: ./infra/local/postgis_insert_layers.sh && ./infra/init/geoserver_init_layers.sh run-back: run-stubbed-apis - docker compose up -d --quiet-pull --wait db + docker compose up -d --quiet-pull --wait db keycloak cd backend && ./gradlew bootRun --args='--spring.profiles.active=local --spring.config.additional-location=$(INFRA_FOLDER)' run-back-with-monitorenv: run-monitorenv diff --git a/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/api/bff/FleetSegmentController.kt b/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/api/bff/FleetSegmentController.kt index 395600cda4..49c227efdc 100644 --- a/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/api/bff/FleetSegmentController.kt +++ b/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/api/bff/FleetSegmentController.kt @@ -35,7 +35,7 @@ class FleetSegmentController( } } - @PutMapping(value = [""], consumes = ["application/json"]) + @PutMapping(value = ["/backoffice"], consumes = ["application/json"]) @Operation(summary = "Update a fleet segment") fun updateFleetSegment( @Parameter(description = "Year") @@ -56,7 +56,7 @@ class FleetSegmentController( return FleetSegmentDataOutput.fromFleetSegment(updatedFleetSegment) } - @DeleteMapping(value = [""]) + @DeleteMapping(value = ["/backoffice"]) @Operation(summary = "Delete a fleet segment") fun deleteFleetSegment( @Parameter(description = "Year") @@ -72,7 +72,7 @@ class FleetSegmentController( } @ResponseStatus(HttpStatus.CREATED) - @PostMapping(value = [""]) + @PostMapping(value = ["/backoffice"]) @Operation(summary = "Create a fleet segment") fun createFleetSegment( @RequestBody @@ -83,7 +83,7 @@ class FleetSegmentController( return FleetSegmentDataOutput.fromFleetSegment(createdFleetSegment) } - @GetMapping("/years") + @GetMapping("/backoffice/years") @Operation(summary = "Get fleet segment year entries") fun getFleetSegmentYearEntries(): List { return getFleetSegmentYearEntries.execute() diff --git a/docker-compose.yml b/docker-compose.yml index ca24b1d49a..a26f6d68eb 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -46,6 +46,20 @@ services: volumes: - ./frontend/cypress/mappings:/home/wiremock/mappings + keycloak: + container_name: monitorfish_keycloak + image: quay.io/keycloak/keycloak:latest + environment: + - KEYCLOAK_ADMIN=admin + - KEYCLOAK_ADMIN_PASSWORD=admin + ports: + - "8085:8080" + volumes: + - ./infra/dev/keycloak:/opt/keycloak/data/import + command: + - start-dev + - --import-realm + volumes: geoserver-data: driver: local diff --git a/frontend/.env.example b/frontend/.env.example index 9172098f3a..204b72a38b 100644 --- a/frontend/.env.example +++ b/frontend/.env.example @@ -28,6 +28,7 @@ FRONTEND_OIDC_AUTHORITY= FRONTEND_OIDC_CLIENT_ID= FRONTEND_OIDC_ENABLED= FRONTEND_OIDC_REDIRECT_URI= +FRONTEND_OIDC_LOGOUT_REDIRECT_URI= ################################################################################ # Sentry diff --git a/frontend/.env.local.defaults b/frontend/.env.local.defaults index a62b5819b8..63091e28f6 100644 --- a/frontend/.env.local.defaults +++ b/frontend/.env.local.defaults @@ -24,10 +24,11 @@ FRONTEND_MONITORENV_URL=//localhost:8081 ################################################################################ # OICD -FRONTEND_OIDC_AUTHORITY=https://authentification.recette.din.developpement-durable.gouv.fr/authSAML/oidc/monitorfish +FRONTEND_OIDC_AUTHORITY=http://localhost:8085/realms/monitor FRONTEND_OIDC_CLIENT_ID=monitorfish -FRONTEND_OIDC_ENABLED=false -FRONTEND_OIDC_REDIRECT_URI=https://monitorfish.din.developpement-durable.gouv.fr +FRONTEND_OIDC_ENABLED=true +FRONTEND_OIDC_REDIRECT_URI=http://localhost:3000 +FRONTEND_OIDC_LOGOUT_REDIRECT_URI=http://localhost:3000 ################################################################################ # Sentry diff --git a/frontend/src/auth/getOIDCConfig.ts b/frontend/src/auth/getOIDCConfig.ts index 1130a26f22..45ad7859f2 100644 --- a/frontend/src/auth/getOIDCConfig.ts +++ b/frontend/src/auth/getOIDCConfig.ts @@ -6,6 +6,7 @@ const IS_CYPRESS = isCypress() export function getOIDCConfig() { const IS_OIDC_ENABLED = import.meta.env.FRONTEND_OIDC_ENABLED === 'true' const OIDC_REDIRECT_URI = import.meta.env.FRONTEND_OIDC_REDIRECT_URI + const OIDC_LOGOUT_REDIRECT_URI = import.meta.env.FRONTEND_OIDC_LOGOUT_REDIRECT_URI const OIDC_AUTHORITY = import.meta.env.FRONTEND_OIDC_AUTHORITY const OIDC_CLIENT_ID = import.meta.env.FRONTEND_OIDC_CLIENT_ID @@ -21,7 +22,7 @@ export function getOIDCConfig() { authority: String(OIDC_AUTHORITY), client_id: String(OIDC_CLIENT_ID), onSigninCallback, - post_logout_redirect_uri: 'https://www.mer.gouv.fr', + post_logout_redirect_uri: String(OIDC_LOGOUT_REDIRECT_URI), redirect_uri: String(OIDC_REDIRECT_URI), scope: 'openid email', userStore: new WebStorageStateStore({ store: window.localStorage }) diff --git a/frontend/src/env.d.ts b/frontend/src/env.d.ts index fdc0c42f1a..848c3c4cd6 100644 --- a/frontend/src/env.d.ts +++ b/frontend/src/env.d.ts @@ -13,6 +13,7 @@ interface ImportMetaEnv { readonly FRONTEND_OIDC_CLIENT_ID: string readonly FRONTEND_OIDC_ENABLED: string readonly FRONTEND_OIDC_REDIRECT_URI: string + readonly FRONTEND_OIDC_LOGOUT_REDIRECT_URI: string readonly FRONTEND_PRIOR_NOTIFICATION_LIST_ENABLED: string readonly FRONTEND_SENTRY_DSN?: string readonly FRONTEND_SENTRY_ENV?: string diff --git a/frontend/src/features/FleetSegment/apis.ts b/frontend/src/features/FleetSegment/apis.ts index 1ef36182c5..dfcc3ad8ec 100644 --- a/frontend/src/features/FleetSegment/apis.ts +++ b/frontend/src/features/FleetSegment/apis.ts @@ -53,7 +53,7 @@ async function updateFleetSegmentFromAPI( ): Promise { try { return await monitorfishApiKy - .put(`/bff/v1/fleet_segments?year=${year}&segment=${segment}`, { + .put(`/bff/v1/fleet_segments/backoffice?year=${year}&segment=${segment}`, { json: updatedFields }) .json() @@ -70,7 +70,7 @@ async function updateFleetSegmentFromAPI( async function deleteFleetSegmentFromAPI(segment: string, year: number): Promise { try { return await monitorfishApiKy - .delete(`/bff/v1/fleet_segments?year=${year}&segment=${segment}`) + .delete(`/bff/v1/fleet_segments/backoffice?year=${year}&segment=${segment}`) .json() } catch (err) { throw new ApiError(DELETE_FLEET_SEGMENT_ERROR_MESSAGE, err) @@ -85,7 +85,7 @@ async function deleteFleetSegmentFromAPI(segment: string, year: number): Promise async function createFleetSegmentFromAPI(segmentFields: UpdateFleetSegment): Promise { try { return await monitorfishApiKy - .post('/bff/v1/fleet_segments', { + .post('/bff/v1/fleet_segments/backoffice', { json: segmentFields }) .json() @@ -101,7 +101,7 @@ async function createFleetSegmentFromAPI(segmentFields: UpdateFleetSegment): Pro */ async function addFleetSegmentYearFromAPI(nextYear: number) { try { - return await monitorfishApiKy.post(`/bff/v1/fleet_segments/${nextYear}`) + return await monitorfishApiKy.post(`/bff/v1/fleet_segments/${nextYear}/backoffice`) } catch (err) { throw new ApiError(ADD_FLEET_SEGMENT_YEAR_ERROR_MESSAGE, err) } @@ -114,7 +114,7 @@ async function addFleetSegmentYearFromAPI(nextYear: number) { */ async function getFleetSegmentYearEntriesFromAPI(): Promise { try { - return await monitorfishApiKy.get('/bff/v1/fleet_segments/years').json() + return await monitorfishApiKy.get('/bff/v1/fleet_segments/backoffice/years').json() } catch (err) { throw new ApiError(GET_FLEET_SEGMENT_YEAR_ENTRIES_ERROR_MESSAGE, err) } diff --git a/frontend/src/domain/use_cases/vessel/getFleetSegments.ts b/frontend/src/features/FleetSegment/useCases/computeFleetSegments.ts similarity index 96% rename from frontend/src/domain/use_cases/vessel/getFleetSegments.ts rename to frontend/src/features/FleetSegment/useCases/computeFleetSegments.ts index 713a263966..b2ff9acc78 100644 --- a/frontend/src/domain/use_cases/vessel/getFleetSegments.ts +++ b/frontend/src/features/FleetSegment/useCases/computeFleetSegments.ts @@ -3,7 +3,7 @@ import { fleetSegmentApi } from '@features/FleetSegment/apis' import type { FleetSegment } from '@features/FleetSegment/types' import type { MissionActionFormValues } from '@features/Mission/components/MissionForm/types' -export const getFleetSegments = +export const computeFleetSegments = ( faoAreas: string[] | undefined, gearOnBoard: MissionActionFormValues['gearOnboard'], diff --git a/frontend/src/features/Mission/components/MissionForm/useCases/updateActionSegments.ts b/frontend/src/features/Mission/components/MissionForm/useCases/updateActionSegments.ts index fa1ed64c27..6f392da98f 100644 --- a/frontend/src/features/Mission/components/MissionForm/useCases/updateActionSegments.ts +++ b/frontend/src/features/Mission/components/MissionForm/useCases/updateActionSegments.ts @@ -1,6 +1,6 @@ import { MissionAction } from '@features/Mission/missionAction.types' -import { getFleetSegments } from '../../../../../domain/use_cases/vessel/getFleetSegments' +import { computeFleetSegments } from '../../../../FleetSegment/useCases/computeFleetSegments' import type { MissionActionFormValues } from '@features/Mission/components/MissionForm/types' import type { Option } from '@mtes-mct/monitor-ui' @@ -17,7 +17,7 @@ export const updateActionSegments = } const computedFleetSegments = await dispatch( - getFleetSegments(missionAction.faoAreas, missionAction.gearOnboard, missionAction.speciesOnboard) + computeFleetSegments(missionAction.faoAreas, missionAction.gearOnboard, missionAction.speciesOnboard) ) const nextFleetSegments = fleetSegmentsAsOptions diff --git a/infra/configurations/application-dev.properties b/infra/configurations/application-dev.properties index 6ea7919e6c..b95b9ff3e1 100644 --- a/infra/configurations/application-dev.properties +++ b/infra/configurations/application-dev.properties @@ -16,7 +16,7 @@ monitorfish.oidc.userinfo-endpoint=/api/user monitorfish.api.protected.paths=/bff/*,/light/v1/vessels/* # Super-user paths of type /** are not supported -monitorfish.api.protected.super-user-paths=/bff/v1/beacon_malfunctions,/bff/v1/missions,/bff/v1/operational_alerts,/bff/v1/reportings,/bff/v1/vessels/risk_factors +monitorfish.api.protected.super-user-paths=/bff/v1/beacon_malfunctions,/bff/v1/missions,/bff/v1/operational_alerts,/bff/v1/reportings,/bff/v1/vessels/risk_factors,/bff/v1/control_objectives,/bff/v1/fleet_segments/backoffice,/bff/v1/fleet_segments/compute monitorfish.api.protected.public-paths=/api/v1/authorization/management/*,/api/v1/beacon_malfunctions/*,/api/v1/mission_actions/* ################### diff --git a/infra/configurations/application-local.properties b/infra/configurations/application-local.properties index 0616d35857..945466dbb7 100644 --- a/infra/configurations/application-local.properties +++ b/infra/configurations/application-local.properties @@ -15,12 +15,12 @@ monitorfish.sentry.enabled=false sentry.dsn= monitorfish.oidc.enabled=false -monitorfish.oidc.issuer-uri=https://authentification.recette.din.developpement-durable.gouv.fr/authSAML/oidc/monitorfish -monitorfish.oidc.userinfo-endpoint=/api/user +monitorfish.oidc.issuer-uri=http://localhost:8085/realms/monitor +monitorfish.oidc.userinfo-endpoint=/protocol/openid-connect/userinfo monitorfish.api.protected.paths=/bff/*,/light/v1/vessels/* # Super-user paths of type /** are not supported -monitorfish.api.protected.super-user-paths=/bff/v1/beacon_malfunctions,/bff/v1/missions,/bff/v1/operational_alerts,/bff/v1/reportings,/bff/v1/vessels/risk_factors +monitorfish.api.protected.super-user-paths=/bff/v1/beacon_malfunctions,/bff/v1/missions,/bff/v1/operational_alerts,/bff/v1/reportings,/bff/v1/vessels/risk_factors,/bff/v1/control_objectives,/bff/v1/fleet_segments/backoffice,/bff/v1/fleet_segments/compute monitorfish.api.protected.public-paths=/api/v1/authorization/management/*,/api/v1/beacon_malfunctions/*,/api/v1/mission_actions/* monitorfish.api.protected.api-key=DUMMY-API-KEY diff --git a/infra/configurations/application-prod.properties b/infra/configurations/application-prod.properties index a59049e5e6..d3e3884c21 100644 --- a/infra/configurations/application-prod.properties +++ b/infra/configurations/application-prod.properties @@ -16,7 +16,7 @@ monitorfish.oidc.userinfo-endpoint=/api/user monitorfish.api.protected.paths=/bff/*,/light/v1/vessels/* # Super-user paths of type /** are not supported -monitorfish.api.protected.super-user-paths=/bff/v1/beacon_malfunctions,/bff/v1/missions,/bff/v1/operational_alerts,/bff/v1/reportings,/bff/v1/vessels/risk_factors +monitorfish.api.protected.super-user-paths=/bff/v1/beacon_malfunctions,/bff/v1/missions,/bff/v1/operational_alerts,/bff/v1/reportings,/bff/v1/vessels/risk_factors,/bff/v1/control_objectives,/bff/v1/fleet_segments/backoffice,/bff/v1/fleet_segments/compute monitorfish.api.protected.public-paths=/api/v1/authorization/management/*,/api/v1/beacon_malfunctions/*,/api/v1/mission_actions/* ################### diff --git a/infra/dev/keycloak/realm-monitor-dev.json b/infra/dev/keycloak/realm-monitor-dev.json new file mode 100644 index 0000000000..54ddd82e10 --- /dev/null +++ b/infra/dev/keycloak/realm-monitor-dev.json @@ -0,0 +1,50 @@ +{ + "realm": "monitor", + "enabled": true, + "clients": [ + { + "clientId": "monitorfish", + "enabled": true, + "protocol": "openid-connect", + "redirectUris": [ + "http://localhost:3000/*" + ], + "webOrigins": [ + "http://localhost:3000" + ], + "publicClient": true + } + ], + "users": [ + { + "username": "user", + "email": "another@email.com", + "firstName": "User", + "lastName": "Fish", + "enabled": true, + "emailVerified": true, + "credentials": [ + { + "type": "password", + "value": "fish", + "temporary": false + } + ] + }, + { + "username": "superuser", + "email": "dummy@email.gouv.fr", + "firstName": "SuperUser", + "lastName": "Fish", + "enabled": true, + "emailVerified": true, + "credentials": [ + { + "type": "password", + "value": "fish", + "temporary": false + } + ] + } + ] +} diff --git a/infra/docker/docker-compose.cypress.yml b/infra/docker/docker-compose.cypress.yml index 4f31019693..c6203beda3 100644 --- a/infra/docker/docker-compose.cypress.yml +++ b/infra/docker/docker-compose.cypress.yml @@ -42,6 +42,7 @@ services: - FRONTEND_OIDC_CLIENT_ID=monitorfish - FRONTEND_OIDC_ENABLED=false - FRONTEND_OIDC_REDIRECT_URI=https://monitorfish.din.developpement-durable.gouv.fr + - FRONTEND_OIDC_LOGOUT_REDIRECT_URI=https://monitorfish.din.developpement-durable.gouv.fr - FRONTEND_MONITORFISH_VERSION= - FRONTEND_SENTRY_DSN=https://a5f3272efa794bb9ada2ffea90f2fec5@sentry.incubateur.net/8 - FRONTEND_SENTRY_TRACING_ORIGINS= diff --git a/infra/docker/docker-compose.puppeteer.yml b/infra/docker/docker-compose.puppeteer.yml index 64b73f18a3..283316c489 100644 --- a/infra/docker/docker-compose.puppeteer.yml +++ b/infra/docker/docker-compose.puppeteer.yml @@ -58,6 +58,7 @@ services: - FRONTEND_OIDC_CLIENT_ID=monitorfish - FRONTEND_OIDC_ENABLED=false - FRONTEND_OIDC_REDIRECT_URI=https://monitorfish.din.developpement-durable.gouv.fr + - FRONTEND_OIDC_LOGOUT_REDIRECT_URI=https://monitorfish.din.developpement-durable.gouv.fr - FRONTEND_MONITORFISH_VERSION= - FRONTEND_SENTRY_DSN=https://a5f3272efa794bb9ada2ffea90f2fec5@sentry.incubateur.net/8 - FRONTEND_SENTRY_TRACING_ORIGINS= diff --git a/infra/remote/docker-compose.yml b/infra/remote/docker-compose.yml index 4fda5f08fe..7a43bb1dbb 100644 --- a/infra/remote/docker-compose.yml +++ b/infra/remote/docker-compose.yml @@ -35,6 +35,7 @@ services: - MONITORFISH_OIDC_ENABLED=$MONITORFISH_OIDC_ENABLED - MONITORFISH_OIDC_ISSUER_URI=$MONITORFISH_OIDC_AUTHORITY - FRONTEND_OIDC_REDIRECT_URI=$MONITORFISH_OIDC_REDIRECT_URI + - FRONTEND_OIDC_LOGOUT_REDIRECT_URI=$MONITORFISH_OIDC_LOGOUT_REDIRECT_URI - FRONTEND_OIDC_AUTHORITY=$MONITORFISH_OIDC_AUTHORITY - FRONTEND_OIDC_CLIENT_ID=$MONITORFISH_OIDC_CLIENT - MONITORFISH_API_PROTECTED_API_KEY=$MONITORFISH_API_PROTECTED_API_KEY From 2c8f0c255ae5efeec78eff572629d2eae88cdccc Mon Sep 17 00:00:00 2001 From: Loup Theron Date: Fri, 9 Aug 2024 11:14:58 +0200 Subject: [PATCH 2/8] Fix few tests --- .../infrastructure/api/bff/FleetSegmentController.kt | 2 +- .../api/bff/FleetSegmentControllerITests.kt | 10 +++++----- frontend/cypress/e2e/backoffice/fleet_segments.spec.ts | 10 ++++++---- frontend/src/env.d.ts | 2 +- 4 files changed, 13 insertions(+), 11 deletions(-) diff --git a/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/api/bff/FleetSegmentController.kt b/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/api/bff/FleetSegmentController.kt index 49c227efdc..d0a35b6245 100644 --- a/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/api/bff/FleetSegmentController.kt +++ b/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/api/bff/FleetSegmentController.kt @@ -90,7 +90,7 @@ class FleetSegmentController( } @ResponseStatus(HttpStatus.CREATED) - @PostMapping("/{year}") + @PostMapping("/backoffice/{year}") @Operation(summary = "Add a fleet segment year") fun addFleetSegmentYear( @PathParam("Year") diff --git a/backend/src/test/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/api/bff/FleetSegmentControllerITests.kt b/backend/src/test/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/api/bff/FleetSegmentControllerITests.kt index 83159d3a04..0aaeaf2e6f 100644 --- a/backend/src/test/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/api/bff/FleetSegmentControllerITests.kt +++ b/backend/src/test/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/api/bff/FleetSegmentControllerITests.kt @@ -92,7 +92,7 @@ class FleetSegmentControllerITests { // When api.perform( - put("/bff/v1/fleet_segments?year=2021&segment=A_SEGMENT/WITH/SLASH") + put("/bff/v1/fleet_segments/backoffice?year=2021&segment=A_SEGMENT/WITH/SLASH") .content( objectMapper.writeValueAsString(CreateOrUpdateFleetSegmentDataInput(gears = listOf("OTB", "OTC"))), ) @@ -113,7 +113,7 @@ class FleetSegmentControllerITests { @Test fun `Should return Ok When a delete of a fleet segment is done`() { // When - api.perform(delete("/bff/v1/fleet_segments?year=2021&segment=A_SEGMENT/WITH/SLASH")) + api.perform(delete("/bff/v1/fleet_segments/backoffice?year=2021&segment=A_SEGMENT/WITH/SLASH")) // Then .andExpect(status().isOk) } @@ -121,7 +121,7 @@ class FleetSegmentControllerITests { @Test fun `Should return Ok When a new year is created`() { // When - api.perform(post("/bff/v1/fleet_segments/2023")) + api.perform(post("/bff/v1/fleet_segments/backoffice/2023")) // Then .andExpect(status().isCreated) } @@ -136,7 +136,7 @@ class FleetSegmentControllerITests { // When api.perform( - post("/bff/v1/fleet_segments") + post("/bff/v1/fleet_segments/backoffice") .content( objectMapper.writeValueAsString( CreateOrUpdateFleetSegmentDataInput( @@ -164,7 +164,7 @@ class FleetSegmentControllerITests { // When api.perform( - post("/bff/v1/fleet_segments") + post("/bff/v1/fleet_segments/backoffice") .content( objectMapper.writeValueAsString( CreateOrUpdateFleetSegmentDataInput(segment = "SEGMENT", gears = listOf("OTB", "OTC")), diff --git a/frontend/cypress/e2e/backoffice/fleet_segments.spec.ts b/frontend/cypress/e2e/backoffice/fleet_segments.spec.ts index aaadabbea6..aa396bf092 100644 --- a/frontend/cypress/e2e/backoffice/fleet_segments.spec.ts +++ b/frontend/cypress/e2e/backoffice/fleet_segments.spec.ts @@ -8,7 +8,7 @@ dayjs.extend(utc) const currentYear = dayjs().utc().year() context('Fleet segments', () => { beforeEach(() => { - cy.intercept('GET', `/bff/v1/fleet_segments/${currentYear}`).as('fleetSegments') + cy.intercept('GET', `/bff/v1/fleet_segments/backoffice/${currentYear}`).as('fleetSegments') cy.visit('/backoffice/fleet_segments') cy.wait('@fleetSegments') cy.wait(1000) @@ -35,7 +35,7 @@ context('Fleet segments', () => { cy.log('Should update the segment') // When - cy.intercept('PUT', `/bff/v1/fleet_segments?year=${currentYear}&segment=ATL01`).as('updateFleetSegment') + cy.intercept('PUT', `/bff/v1/fleet_segments/backoffice?year=${currentYear}&segment=ATL01`).as('updateFleetSegment') cy.get('[aria-rowindex="2"]').find('[title="Editer la ligne"]').click() cy.fill('Nom', 'ATL036') @@ -92,7 +92,7 @@ context('Fleet segments', () => { it('Should create a new fleet segment and delete it', () => { // Given - cy.intercept('POST', '/bff/v1/fleet_segments').as('createFleetSegment') + cy.intercept('POST', '/bff/v1/fleet_segments/backoffice').as('createFleetSegment') // When cy.clickButton('Ajouter un segment') @@ -137,7 +137,9 @@ context('Fleet segments', () => { // ------------------------------------------------------------------------- cy.log('Should delete a fleet segment') - cy.intercept('DELETE', `/bff/v1/fleet_segments?year=${currentYear}&segment=ABC123`).as('deleteFleetSegment') + cy.intercept('DELETE', `/bff/v1/fleet_segments/backoffice?year=${currentYear}&segment=ABC123`).as( + 'deleteFleetSegment' + ) cy.get('[aria-rowindex="2"]').find('[title="Supprimer la ligne"]').click() cy.wait('@deleteFleetSegment') diff --git a/frontend/src/env.d.ts b/frontend/src/env.d.ts index 848c3c4cd6..e0033d32d4 100644 --- a/frontend/src/env.d.ts +++ b/frontend/src/env.d.ts @@ -12,8 +12,8 @@ interface ImportMetaEnv { readonly FRONTEND_OIDC_AUTHORITY: string readonly FRONTEND_OIDC_CLIENT_ID: string readonly FRONTEND_OIDC_ENABLED: string - readonly FRONTEND_OIDC_REDIRECT_URI: string readonly FRONTEND_OIDC_LOGOUT_REDIRECT_URI: string + readonly FRONTEND_OIDC_REDIRECT_URI: string readonly FRONTEND_PRIOR_NOTIFICATION_LIST_ENABLED: string readonly FRONTEND_SENTRY_DSN?: string readonly FRONTEND_SENTRY_ENV?: string From 65f99aedbf3eb5984e34bc86be1d16bc2a79c91d Mon Sep 17 00:00:00 2001 From: Loup Theron Date: Fri, 9 Aug 2024 11:39:19 +0200 Subject: [PATCH 3/8] Enable oidc in dev --- datascience/docs/source/contributing.rst | 8 ++++++++ frontend/cypress/e2e/backoffice/fleet_segments.spec.ts | 2 +- infra/configurations/application-local.properties | 2 +- 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/datascience/docs/source/contributing.rst b/datascience/docs/source/contributing.rst index 1c4dc886a2..3efd77ba86 100644 --- a/datascience/docs/source/contributing.rst +++ b/datascience/docs/source/contributing.rst @@ -65,6 +65,14 @@ To run the backend for development purpose (with hot-reload), open another termi * During the first run, dependencies will be downloaded * You'll need to install `psql` to interact with the Postgres database +The users for login are: + - User with non super-user access: + - username: "user" + - password: "fish" + - User with super-user access: + - username: "superuser" + - password: "fish" + Then, insert the GIS layers to the postgres database by executing (make sure you have `psql` installed): .. code-block:: shell diff --git a/frontend/cypress/e2e/backoffice/fleet_segments.spec.ts b/frontend/cypress/e2e/backoffice/fleet_segments.spec.ts index aa396bf092..3c5f31b5aa 100644 --- a/frontend/cypress/e2e/backoffice/fleet_segments.spec.ts +++ b/frontend/cypress/e2e/backoffice/fleet_segments.spec.ts @@ -8,7 +8,7 @@ dayjs.extend(utc) const currentYear = dayjs().utc().year() context('Fleet segments', () => { beforeEach(() => { - cy.intercept('GET', `/bff/v1/fleet_segments/backoffice/${currentYear}`).as('fleetSegments') + cy.intercept('GET', `/bff/v1/fleet_segments/${currentYear}`).as('fleetSegments') cy.visit('/backoffice/fleet_segments') cy.wait('@fleetSegments') cy.wait(1000) diff --git a/infra/configurations/application-local.properties b/infra/configurations/application-local.properties index 945466dbb7..c32dba21c7 100644 --- a/infra/configurations/application-local.properties +++ b/infra/configurations/application-local.properties @@ -14,7 +14,7 @@ spring.main.lazy-initialization=true monitorfish.sentry.enabled=false sentry.dsn= -monitorfish.oidc.enabled=false +monitorfish.oidc.enabled=true monitorfish.oidc.issuer-uri=http://localhost:8085/realms/monitor monitorfish.oidc.userinfo-endpoint=/protocol/openid-connect/userinfo From e521eefcc8499962939232ca45b4fa9cb9924fc6 Mon Sep 17 00:00:00 2001 From: Loup Theron Date: Mon, 12 Aug 2024 09:52:44 +0200 Subject: [PATCH 4/8] Fix healthcheck api path and disable oidc authent in e2e tests --- Makefile | 6 +++--- infra/docker/docker-compose.cypress.yml | 3 ++- infra/docker/docker-compose.puppeteer.yml | 1 + 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index 806c4863df..79666b35e3 100644 --- a/Makefile +++ b/Makefile @@ -154,15 +154,15 @@ docker-compose-up: docker compose -f ./infra/docker/docker-compose.cypress.yml up --quiet-pull flyway docker compose -f ./infra/docker/docker-compose.cypress.yml up -d --quiet-pull app @printf 'Waiting for backend app to be ready' - @until curl --output /dev/null --silent --fail "http://localhost:8880/bff/v1/healthcheck"; do printf '.' && sleep 1; done + @until curl --output /dev/null --silent --fail "http://localhost:8880/api/v1/healthcheck"; do printf '.' && sleep 1; done docker-compose-puppeteer-up: docker-env docker compose -f ./infra/docker/docker-compose.puppeteer.yml up -d monitorenv-app docker compose -f ./infra/docker/docker-compose.puppeteer.yml up -d monitorfish-app @printf 'Waiting for MonitorEnv app to be ready' - @until curl --output /dev/null --silent --fail "http://localhost:9880/bff/v1/healthcheck"; do printf '.' && sleep 1; done + @until curl --output /dev/null --silent --fail "http://localhost:9880/api/v1/healthcheck"; do printf '.' && sleep 1; done @printf 'Waiting for MonitorFish app to be ready' - @until curl --output /dev/null --silent --fail "http://localhost:8880/bff/v1/healthcheck"; do printf '.' && sleep 1; done + @until curl --output /dev/null --silent --fail "http://localhost:8880/api/v1/healthcheck"; do printf '.' && sleep 1; done # ---------------------------------------------------------- # CI: Pipeline Commands diff --git a/infra/docker/docker-compose.cypress.yml b/infra/docker/docker-compose.cypress.yml index c6203beda3..4872bebc8c 100644 --- a/infra/docker/docker-compose.cypress.yml +++ b/infra/docker/docker-compose.cypress.yml @@ -25,7 +25,7 @@ services: condition: service_healthy app: - image: monitorfish-app:$MONITORFISH_VERSION + image: monitorfish-app:v1.59.4_snapshot container_name: monitorfish_backend environment: - ENV_DB_URL=jdbc:postgresql://db:5432/monitorfishdb?user=postgres&password=postgres @@ -40,6 +40,7 @@ services: - FRONTEND_MONITORENV_URL=http://0.0.0.0:8081 - FRONTEND_OIDC_AUTHORITY=https://authentification.recette.din.developpement-durable.gouv.fr/authSAML/oidc/monitorfish - FRONTEND_OIDC_CLIENT_ID=monitorfish + - MONITORFISH_OIDC_ENABLED=false - FRONTEND_OIDC_ENABLED=false - FRONTEND_OIDC_REDIRECT_URI=https://monitorfish.din.developpement-durable.gouv.fr - FRONTEND_OIDC_LOGOUT_REDIRECT_URI=https://monitorfish.din.developpement-durable.gouv.fr diff --git a/infra/docker/docker-compose.puppeteer.yml b/infra/docker/docker-compose.puppeteer.yml index 283316c489..13414f13ea 100644 --- a/infra/docker/docker-compose.puppeteer.yml +++ b/infra/docker/docker-compose.puppeteer.yml @@ -56,6 +56,7 @@ services: - FRONTEND_MONITORENV_URL=http://0.0.0.0:9880 - FRONTEND_OIDC_AUTHORITY=https://authentification.recette.din.developpement-durable.gouv.fr/authSAML/oidc/monitorfish - FRONTEND_OIDC_CLIENT_ID=monitorfish + - MONITORFISH_OIDC_ENABLED=false - FRONTEND_OIDC_ENABLED=false - FRONTEND_OIDC_REDIRECT_URI=https://monitorfish.din.developpement-durable.gouv.fr - FRONTEND_OIDC_LOGOUT_REDIRECT_URI=https://monitorfish.din.developpement-durable.gouv.fr From c3a084f6f3ba1b2100ca527f6ce205dffa3b4230 Mon Sep 17 00:00:00 2001 From: Loup Theron Date: Mon, 12 Aug 2024 10:14:57 +0200 Subject: [PATCH 5/8] Fix docker image version --- infra/docker/docker-compose.cypress.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/infra/docker/docker-compose.cypress.yml b/infra/docker/docker-compose.cypress.yml index 4872bebc8c..b0c84d27fb 100644 --- a/infra/docker/docker-compose.cypress.yml +++ b/infra/docker/docker-compose.cypress.yml @@ -25,7 +25,7 @@ services: condition: service_healthy app: - image: monitorfish-app:v1.59.4_snapshot + image: monitorfish-app:$MONITORFISH_VERSION container_name: monitorfish_backend environment: - ENV_DB_URL=jdbc:postgresql://db:5432/monitorfishdb?user=postgres&password=postgres From c0c23fefed541d55f4b0855743745b0e7c21a4aa Mon Sep 17 00:00:00 2001 From: Loup Theron Date: Tue, 13 Aug 2024 11:48:00 +0200 Subject: [PATCH 6/8] Fix fleet segment api --- frontend/src/features/FleetSegment/apis.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/features/FleetSegment/apis.ts b/frontend/src/features/FleetSegment/apis.ts index dfcc3ad8ec..70082b5b52 100644 --- a/frontend/src/features/FleetSegment/apis.ts +++ b/frontend/src/features/FleetSegment/apis.ts @@ -101,7 +101,7 @@ async function createFleetSegmentFromAPI(segmentFields: UpdateFleetSegment): Pro */ async function addFleetSegmentYearFromAPI(nextYear: number) { try { - return await monitorfishApiKy.post(`/bff/v1/fleet_segments/${nextYear}/backoffice`) + return await monitorfishApiKy.post(`/bff/v1/fleet_segments/backoffice/${nextYear}`) } catch (err) { throw new ApiError(ADD_FLEET_SEGMENT_YEAR_ERROR_MESSAGE, err) } From df44b46f8a0a77a5b4ab628e8e38b49502de2a4e Mon Sep 17 00:00:00 2001 From: Loup Theron Date: Wed, 14 Aug 2024 09:10:04 +0200 Subject: [PATCH 7/8] Rename admin apis --- ....kt => ControlObjectiveAdminController.kt} | 4 +- .../api/bff/FleetSegmentAdminController.kt | 88 ++++++++++ .../api/bff/FleetSegmentController.kt | 75 +------- ... ControlObjectiveAdminControllerITests.kt} | 16 +- .../bff/FleetSegmentAdminControllerITests.kt | 162 ++++++++++++++++++ .../api/bff/FleetSegmentControllerITests.kt | 132 +------------- .../e2e/backoffice/control_objectives.spec.ts | 26 +-- .../e2e/backoffice/fleet_segments.spec.ts | 8 +- .../src/features/ControlObjective/apis.ts | 12 +- frontend/src/features/FleetSegment/apis.ts | 10 +- .../configurations/application-dev.properties | 2 +- .../application-local.properties | 2 +- .../application-prod.properties | 2 +- 13 files changed, 295 insertions(+), 244 deletions(-) rename backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/api/bff/{ControlObjectiveController.kt => ControlObjectiveAdminController.kt} (97%) create mode 100644 backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/api/bff/FleetSegmentAdminController.kt rename backend/src/test/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/api/bff/{ControlObjectiveControllerITests.kt => ControlObjectiveAdminControllerITests.kt} (91%) create mode 100644 backend/src/test/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/api/bff/FleetSegmentAdminControllerITests.kt diff --git a/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/api/bff/ControlObjectiveController.kt b/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/api/bff/ControlObjectiveAdminController.kt similarity index 97% rename from backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/api/bff/ControlObjectiveController.kt rename to backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/api/bff/ControlObjectiveAdminController.kt index f4dff6d0e5..f184eb93b3 100644 --- a/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/api/bff/ControlObjectiveController.kt +++ b/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/api/bff/ControlObjectiveAdminController.kt @@ -11,9 +11,9 @@ import org.springframework.http.HttpStatus import org.springframework.web.bind.annotation.* @RestController -@RequestMapping("/bff/v1/control_objectives") +@RequestMapping("/bff/v1/admin/control_objectives") @Tag(name = "APIs for Control objectives") -class ControlObjectiveController( +class ControlObjectiveAdminController( private val getControlObjectivesOfYear: GetControlObjectivesOfYear, private val getControlObjectiveYearEntries: GetControlObjectiveYearEntries, private val addControlObjectiveYear: AddControlObjectiveYear, diff --git a/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/api/bff/FleetSegmentAdminController.kt b/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/api/bff/FleetSegmentAdminController.kt new file mode 100644 index 0000000000..bfb19da1f1 --- /dev/null +++ b/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/api/bff/FleetSegmentAdminController.kt @@ -0,0 +1,88 @@ +package fr.gouv.cnsp.monitorfish.infrastructure.api.bff + +import fr.gouv.cnsp.monitorfish.domain.use_cases.fleet_segment.* +import fr.gouv.cnsp.monitorfish.infrastructure.api.input.CreateOrUpdateFleetSegmentDataInput +import fr.gouv.cnsp.monitorfish.infrastructure.api.outputs.FleetSegmentDataOutput +import io.swagger.v3.oas.annotations.Operation +import io.swagger.v3.oas.annotations.Parameter +import io.swagger.v3.oas.annotations.tags.Tag +import jakarta.websocket.server.PathParam +import org.springframework.http.HttpStatus +import org.springframework.web.bind.annotation.* + +@RestController +@RequestMapping("/bff/v1/admin/fleet_segments") +@Tag(name = "APIs for administration of Fleet segments") +class FleetSegmentAdminController( + private val updateFleetSegment: UpdateFleetSegment, + private val deleteFleetSegment: DeleteFleetSegment, + private val createFleetSegment: CreateFleetSegment, + private val getFleetSegmentYearEntries: GetFleetSegmentYearEntries, + private val addFleetSegmentYear: AddFleetSegmentYear, +) { + + @PutMapping(value = [""], consumes = ["application/json"]) + @Operation(summary = "Update a fleet segment") + fun updateFleetSegment( + @Parameter(description = "Year") + @RequestParam(name = "year") + year: Int, + @Parameter(description = "Segment") + @RequestParam(name = "segment") + segment: String, + @RequestBody + createOrUpdateFleetSegmentData: CreateOrUpdateFleetSegmentDataInput, + ): FleetSegmentDataOutput { + val updatedFleetSegment = updateFleetSegment.execute( + segment = segment, + fields = createOrUpdateFleetSegmentData.toCreateOrUpdateFleetSegmentFields(), + year = year, + ) + + return FleetSegmentDataOutput.fromFleetSegment(updatedFleetSegment) + } + + @DeleteMapping(value = [""]) + @Operation(summary = "Delete a fleet segment") + fun deleteFleetSegment( + @Parameter(description = "Year") + @RequestParam(name = "year") + year: Int, + @Parameter(description = "Segment") + @RequestParam(name = "segment") + segment: String, + ): List { + return deleteFleetSegment.execute(segment, year).map { + FleetSegmentDataOutput.fromFleetSegment(it) + } + } + + @ResponseStatus(HttpStatus.CREATED) + @PostMapping(value = [""]) + @Operation(summary = "Create a fleet segment") + fun createFleetSegment( + @RequestBody + newFleetSegmentData: CreateOrUpdateFleetSegmentDataInput, + ): FleetSegmentDataOutput { + val createdFleetSegment = createFleetSegment.execute(newFleetSegmentData.toCreateOrUpdateFleetSegmentFields()) + + return FleetSegmentDataOutput.fromFleetSegment(createdFleetSegment) + } + + @GetMapping("/years") + @Operation(summary = "Get fleet segment year entries") + fun getFleetSegmentYearEntries(): List { + return getFleetSegmentYearEntries.execute() + } + + @ResponseStatus(HttpStatus.CREATED) + @PostMapping("/{year}") + @Operation(summary = "Add a fleet segment year") + fun addFleetSegmentYear( + @PathParam("Year") + @PathVariable(name = "year") + year: Int, + ) { + return addFleetSegmentYear.execute(year) + } +} diff --git a/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/api/bff/FleetSegmentController.kt b/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/api/bff/FleetSegmentController.kt index d0a35b6245..3a5d37b2f8 100644 --- a/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/api/bff/FleetSegmentController.kt +++ b/backend/src/main/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/api/bff/FleetSegmentController.kt @@ -1,13 +1,12 @@ package fr.gouv.cnsp.monitorfish.infrastructure.api.bff -import fr.gouv.cnsp.monitorfish.domain.use_cases.fleet_segment.* -import fr.gouv.cnsp.monitorfish.infrastructure.api.input.CreateOrUpdateFleetSegmentDataInput +import fr.gouv.cnsp.monitorfish.domain.use_cases.fleet_segment.ComputeFleetSegments +import fr.gouv.cnsp.monitorfish.domain.use_cases.fleet_segment.GetAllFleetSegmentsByYear import fr.gouv.cnsp.monitorfish.infrastructure.api.outputs.FleetSegmentDataOutput import io.swagger.v3.oas.annotations.Operation import io.swagger.v3.oas.annotations.Parameter import io.swagger.v3.oas.annotations.tags.Tag import jakarta.websocket.server.PathParam -import org.springframework.http.HttpStatus import org.springframework.web.bind.annotation.* @RestController @@ -15,11 +14,6 @@ import org.springframework.web.bind.annotation.* @Tag(name = "APIs for Fleet segments") class FleetSegmentController( private val getAllFleetSegmentsByYearByYear: GetAllFleetSegmentsByYear, - private val updateFleetSegment: UpdateFleetSegment, - private val deleteFleetSegment: DeleteFleetSegment, - private val createFleetSegment: CreateFleetSegment, - private val getFleetSegmentYearEntries: GetFleetSegmentYearEntries, - private val addFleetSegmentYear: AddFleetSegmentYear, private val computeFleetSegments: ComputeFleetSegments, ) { @@ -35,71 +29,6 @@ class FleetSegmentController( } } - @PutMapping(value = ["/backoffice"], consumes = ["application/json"]) - @Operation(summary = "Update a fleet segment") - fun updateFleetSegment( - @Parameter(description = "Year") - @RequestParam(name = "year") - year: Int, - @Parameter(description = "Segment") - @RequestParam(name = "segment") - segment: String, - @RequestBody - createOrUpdateFleetSegmentData: CreateOrUpdateFleetSegmentDataInput, - ): FleetSegmentDataOutput { - val updatedFleetSegment = updateFleetSegment.execute( - segment = segment, - fields = createOrUpdateFleetSegmentData.toCreateOrUpdateFleetSegmentFields(), - year = year, - ) - - return FleetSegmentDataOutput.fromFleetSegment(updatedFleetSegment) - } - - @DeleteMapping(value = ["/backoffice"]) - @Operation(summary = "Delete a fleet segment") - fun deleteFleetSegment( - @Parameter(description = "Year") - @RequestParam(name = "year") - year: Int, - @Parameter(description = "Segment") - @RequestParam(name = "segment") - segment: String, - ): List { - return deleteFleetSegment.execute(segment, year).map { - FleetSegmentDataOutput.fromFleetSegment(it) - } - } - - @ResponseStatus(HttpStatus.CREATED) - @PostMapping(value = ["/backoffice"]) - @Operation(summary = "Create a fleet segment") - fun createFleetSegment( - @RequestBody - newFleetSegmentData: CreateOrUpdateFleetSegmentDataInput, - ): FleetSegmentDataOutput { - val createdFleetSegment = createFleetSegment.execute(newFleetSegmentData.toCreateOrUpdateFleetSegmentFields()) - - return FleetSegmentDataOutput.fromFleetSegment(createdFleetSegment) - } - - @GetMapping("/backoffice/years") - @Operation(summary = "Get fleet segment year entries") - fun getFleetSegmentYearEntries(): List { - return getFleetSegmentYearEntries.execute() - } - - @ResponseStatus(HttpStatus.CREATED) - @PostMapping("/backoffice/{year}") - @Operation(summary = "Add a fleet segment year") - fun addFleetSegmentYear( - @PathParam("Year") - @PathVariable(name = "year") - year: Int, - ) { - return addFleetSegmentYear.execute(year) - } - @GetMapping("/compute") @Operation(summary = "compute fleet segments for the current year") fun computeFleetSegments( diff --git a/backend/src/test/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/api/bff/ControlObjectiveControllerITests.kt b/backend/src/test/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/api/bff/ControlObjectiveAdminControllerITests.kt similarity index 91% rename from backend/src/test/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/api/bff/ControlObjectiveControllerITests.kt rename to backend/src/test/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/api/bff/ControlObjectiveAdminControllerITests.kt index 18721de420..1f5a2f3487 100644 --- a/backend/src/test/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/api/bff/ControlObjectiveControllerITests.kt +++ b/backend/src/test/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/api/bff/ControlObjectiveAdminControllerITests.kt @@ -22,8 +22,8 @@ import org.springframework.test.web.servlet.result.MockMvcResultMatchers.status @Import(SentryConfig::class) @AutoConfigureMockMvc(addFilters = false) -@WebMvcTest(value = [(ControlObjectiveController::class)]) -class ControlObjectiveControllerITests { +@WebMvcTest(value = [(ControlObjectiveAdminController::class)]) +class ControlObjectiveAdminControllerITests { @Autowired private lateinit var api: MockMvc @@ -53,7 +53,7 @@ class ControlObjectiveControllerITests { fun `Should return Created When an update of a control objective is done`() { // When api.perform( - put("/bff/v1/control_objectives/123") + put("/bff/v1/admin/control_objectives/123") .content( objectMapper.writeValueAsString(UpdateControlObjectiveDataInput(targetNumberOfControlsAtSea = 123)), ) @@ -66,7 +66,7 @@ class ControlObjectiveControllerITests { @Test fun `Should return Ok When a delete of a control objective is done`() { // When - api.perform(delete("/bff/v1/control_objectives/123")) + api.perform(delete("/bff/v1/admin/control_objectives/123")) // Then .andExpect(status().isOk) } @@ -75,7 +75,7 @@ class ControlObjectiveControllerITests { fun `Should return the id When a adding a control objective`() { // When api.perform( - post("/bff/v1/control_objectives") + post("/bff/v1/admin/control_objectives") .content( objectMapper.writeValueAsString( AddControlObjectiveDataInput(segment = "SEGMENT", facade = "FACADE", year = 2021), @@ -123,7 +123,7 @@ class ControlObjectiveControllerITests { ) // When - api.perform(get("/bff/v1/control_objectives/2021")) + api.perform(get("/bff/v1/admin/control_objectives/2021")) // Then .andExpect(status().isOk) .andExpect(jsonPath("$.length()", equalTo(3))) @@ -135,7 +135,7 @@ class ControlObjectiveControllerITests { given(this.getControlObjectiveYearEntries.execute()).willReturn(listOf(2021, 2022)) // When - api.perform(get("/bff/v1/control_objectives/years")) + api.perform(get("/bff/v1/admin/control_objectives/years")) // Then .andExpect(status().isOk) .andExpect(jsonPath("$.length()", equalTo(2))) @@ -145,7 +145,7 @@ class ControlObjectiveControllerITests { @Test fun `Should add a new control objective year`() { // When - api.perform(post("/bff/v1/control_objectives/years")) + api.perform(post("/bff/v1/admin/control_objectives/years")) // Then .andExpect(status().isCreated) } diff --git a/backend/src/test/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/api/bff/FleetSegmentAdminControllerITests.kt b/backend/src/test/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/api/bff/FleetSegmentAdminControllerITests.kt new file mode 100644 index 0000000000..dd60e34c36 --- /dev/null +++ b/backend/src/test/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/api/bff/FleetSegmentAdminControllerITests.kt @@ -0,0 +1,162 @@ +package fr.gouv.cnsp.monitorfish.infrastructure.api.bff + +import com.fasterxml.jackson.databind.ObjectMapper +import com.nhaarman.mockitokotlin2.any +import com.nhaarman.mockitokotlin2.eq +import fr.gouv.cnsp.monitorfish.config.SentryConfig +import fr.gouv.cnsp.monitorfish.domain.entities.fleet_segment.FleetSegment +import fr.gouv.cnsp.monitorfish.domain.use_cases.dtos.CreateOrUpdateFleetSegmentFields +import fr.gouv.cnsp.monitorfish.domain.use_cases.fleet_segment.* +import fr.gouv.cnsp.monitorfish.infrastructure.api.input.CreateOrUpdateFleetSegmentDataInput +import org.hamcrest.Matchers.equalTo +import org.junit.jupiter.api.Test +import org.mockito.BDDMockito.given +import org.mockito.Mockito +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest +import org.springframework.boot.test.mock.mockito.MockBean +import org.springframework.context.annotation.Import +import org.springframework.http.MediaType +import org.springframework.test.web.servlet.MockMvc +import org.springframework.test.web.servlet.request.MockMvcRequestBuilders.* +import org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath +import org.springframework.test.web.servlet.result.MockMvcResultMatchers.status + +@Import(SentryConfig::class) +@AutoConfigureMockMvc(addFilters = false) +@WebMvcTest(value = [(FleetSegmentAdminController::class)]) +class FleetSegmentAdminControllerITests { + + @Autowired + private lateinit var api: MockMvc + + @MockBean + private lateinit var updateFleetSegment: UpdateFleetSegment + + @MockBean + private lateinit var deleteFleetSegment: DeleteFleetSegment + + @MockBean + private lateinit var createFleetSegment: CreateFleetSegment + + @MockBean + private lateinit var getFleetSegmentYearEntries: GetFleetSegmentYearEntries + + @MockBean + private lateinit var addFleetSegmentYear: AddFleetSegmentYear + + @MockBean + private lateinit var computeFleetSegments: ComputeFleetSegments + + @Autowired + private lateinit var objectMapper: ObjectMapper + + @Test + fun `Should update a fleet segment`() { + // Given + given(this.updateFleetSegment.execute(any(), any(), eq(2021))) + .willReturn( + FleetSegment( + "A_SEGMENT/WITH/SLASH", + "", + listOf("NAMO", "SA"), + listOf("OTB", "OTC"), + listOf(), + listOf(), + listOf(), + 1.2, + 2021, + ), + ) + + // When + api.perform( + put("/bff/v1/admin/fleet_segments?year=2021&segment=A_SEGMENT/WITH/SLASH") + .content( + objectMapper.writeValueAsString(CreateOrUpdateFleetSegmentDataInput(gears = listOf("OTB", "OTC"))), + ) + .contentType(MediaType.APPLICATION_JSON), + ) + // Then + .andExpect(status().isOk) + .andExpect(jsonPath("$.segment", equalTo("A_SEGMENT/WITH/SLASH"))) + .andExpect(jsonPath("$.gears[0]", equalTo("OTB"))) + + Mockito.verify(updateFleetSegment).execute( + "A_SEGMENT/WITH/SLASH", + CreateOrUpdateFleetSegmentFields(gears = listOf("OTB", "OTC")), + 2021, + ) + } + + @Test + fun `Should return Ok When a delete of a fleet segment is done`() { + // When + api.perform(delete("/bff/v1/admin/fleet_segments?year=2021&segment=A_SEGMENT/WITH/SLASH")) + // Then + .andExpect(status().isOk) + } + + @Test + fun `Should return Ok When a new year is created`() { + // When + api.perform(post("/bff/v1/admin/fleet_segments/2023")) + // Then + .andExpect(status().isCreated) + } + + @Test + fun `Should create a fleet segment`() { + // Given + given(createFleetSegment.execute(any())) + .willReturn( + FleetSegment("SW1", "", listOf("NAMO", "SA"), listOf(), listOf(), listOf(), listOf(), 1.2, 2022), + ) + + // When + api.perform( + post("/bff/v1/admin/fleet_segments") + .content( + objectMapper.writeValueAsString( + CreateOrUpdateFleetSegmentDataInput( + segment = "SEGMENT", + gears = listOf("OTB", "OTC"), + year = 2022, + ), + ), + ) + .contentType(MediaType.APPLICATION_JSON), + ) + // Then + .andExpect(status().isCreated) + + Mockito.verify(createFleetSegment).execute( + CreateOrUpdateFleetSegmentFields(segment = "SEGMENT", gears = listOf("OTB", "OTC"), year = 2022), + ) + } + + @Test + fun `Should throw an exception When no year given to create a fleet segment`() { + // Given + given(createFleetSegment.execute(any())) + .willThrow(IllegalArgumentException("Year must be provided")) + + // When + api.perform( + post("/bff/v1/admin/fleet_segments") + .content( + objectMapper.writeValueAsString( + CreateOrUpdateFleetSegmentDataInput(segment = "SEGMENT", gears = listOf("OTB", "OTC")), + ), + ) + .contentType(MediaType.APPLICATION_JSON), + ) + // Then + .andExpect(status().isBadRequest) + + Mockito.verify(createFleetSegment).execute( + CreateOrUpdateFleetSegmentFields(segment = "SEGMENT", gears = listOf("OTB", "OTC")), + ) + } +} diff --git a/backend/src/test/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/api/bff/FleetSegmentControllerITests.kt b/backend/src/test/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/api/bff/FleetSegmentControllerITests.kt index 0aaeaf2e6f..12d63f7a3e 100644 --- a/backend/src/test/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/api/bff/FleetSegmentControllerITests.kt +++ b/backend/src/test/kotlin/fr/gouv/cnsp/monitorfish/infrastructure/api/bff/FleetSegmentControllerITests.kt @@ -2,12 +2,10 @@ package fr.gouv.cnsp.monitorfish.infrastructure.api.bff import com.fasterxml.jackson.databind.ObjectMapper import com.nhaarman.mockitokotlin2.any -import com.nhaarman.mockitokotlin2.eq import fr.gouv.cnsp.monitorfish.config.SentryConfig import fr.gouv.cnsp.monitorfish.domain.entities.fleet_segment.FleetSegment -import fr.gouv.cnsp.monitorfish.domain.use_cases.dtos.CreateOrUpdateFleetSegmentFields -import fr.gouv.cnsp.monitorfish.domain.use_cases.fleet_segment.* -import fr.gouv.cnsp.monitorfish.infrastructure.api.input.CreateOrUpdateFleetSegmentDataInput +import fr.gouv.cnsp.monitorfish.domain.use_cases.fleet_segment.ComputeFleetSegments +import fr.gouv.cnsp.monitorfish.domain.use_cases.fleet_segment.GetAllFleetSegmentsByYear import org.hamcrest.Matchers.equalTo import org.junit.jupiter.api.Test import org.mockito.BDDMockito.given @@ -17,9 +15,8 @@ import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMock import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest import org.springframework.boot.test.mock.mockito.MockBean import org.springframework.context.annotation.Import -import org.springframework.http.MediaType import org.springframework.test.web.servlet.MockMvc -import org.springframework.test.web.servlet.request.MockMvcRequestBuilders.* +import org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get import org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath import org.springframework.test.web.servlet.result.MockMvcResultMatchers.status @@ -34,21 +31,6 @@ class FleetSegmentControllerITests { @MockBean private lateinit var getAllFleetSegmentsByYear: GetAllFleetSegmentsByYear - @MockBean - private lateinit var updateFleetSegment: UpdateFleetSegment - - @MockBean - private lateinit var deleteFleetSegment: DeleteFleetSegment - - @MockBean - private lateinit var createFleetSegment: CreateFleetSegment - - @MockBean - private lateinit var getFleetSegmentYearEntries: GetFleetSegmentYearEntries - - @MockBean - private lateinit var addFleetSegmentYear: AddFleetSegmentYear - @MockBean private lateinit var computeFleetSegments: ComputeFleetSegments @@ -72,114 +54,6 @@ class FleetSegmentControllerITests { .andExpect(jsonPath("$[0].dirm[0]", equalTo("NAMO"))) } - @Test - fun `Should update a fleet segment`() { - // Given - given(this.updateFleetSegment.execute(any(), any(), eq(2021))) - .willReturn( - FleetSegment( - "A_SEGMENT/WITH/SLASH", - "", - listOf("NAMO", "SA"), - listOf("OTB", "OTC"), - listOf(), - listOf(), - listOf(), - 1.2, - 2021, - ), - ) - - // When - api.perform( - put("/bff/v1/fleet_segments/backoffice?year=2021&segment=A_SEGMENT/WITH/SLASH") - .content( - objectMapper.writeValueAsString(CreateOrUpdateFleetSegmentDataInput(gears = listOf("OTB", "OTC"))), - ) - .contentType(MediaType.APPLICATION_JSON), - ) - // Then - .andExpect(status().isOk) - .andExpect(jsonPath("$.segment", equalTo("A_SEGMENT/WITH/SLASH"))) - .andExpect(jsonPath("$.gears[0]", equalTo("OTB"))) - - Mockito.verify(updateFleetSegment).execute( - "A_SEGMENT/WITH/SLASH", - CreateOrUpdateFleetSegmentFields(gears = listOf("OTB", "OTC")), - 2021, - ) - } - - @Test - fun `Should return Ok When a delete of a fleet segment is done`() { - // When - api.perform(delete("/bff/v1/fleet_segments/backoffice?year=2021&segment=A_SEGMENT/WITH/SLASH")) - // Then - .andExpect(status().isOk) - } - - @Test - fun `Should return Ok When a new year is created`() { - // When - api.perform(post("/bff/v1/fleet_segments/backoffice/2023")) - // Then - .andExpect(status().isCreated) - } - - @Test - fun `Should create a fleet segment`() { - // Given - given(createFleetSegment.execute(any())) - .willReturn( - FleetSegment("SW1", "", listOf("NAMO", "SA"), listOf(), listOf(), listOf(), listOf(), 1.2, 2022), - ) - - // When - api.perform( - post("/bff/v1/fleet_segments/backoffice") - .content( - objectMapper.writeValueAsString( - CreateOrUpdateFleetSegmentDataInput( - segment = "SEGMENT", - gears = listOf("OTB", "OTC"), - year = 2022, - ), - ), - ) - .contentType(MediaType.APPLICATION_JSON), - ) - // Then - .andExpect(status().isCreated) - - Mockito.verify(createFleetSegment).execute( - CreateOrUpdateFleetSegmentFields(segment = "SEGMENT", gears = listOf("OTB", "OTC"), year = 2022), - ) - } - - @Test - fun `Should throw an exception When no year given to create a fleet segment`() { - // Given - given(createFleetSegment.execute(any())) - .willThrow(IllegalArgumentException("Year must be provided")) - - // When - api.perform( - post("/bff/v1/fleet_segments/backoffice") - .content( - objectMapper.writeValueAsString( - CreateOrUpdateFleetSegmentDataInput(segment = "SEGMENT", gears = listOf("OTB", "OTC")), - ), - ) - .contentType(MediaType.APPLICATION_JSON), - ) - // Then - .andExpect(status().isBadRequest) - - Mockito.verify(createFleetSegment).execute( - CreateOrUpdateFleetSegmentFields(segment = "SEGMENT", gears = listOf("OTB", "OTC")), - ) - } - @Test fun `Should compute fleet segments`() { // Given diff --git a/frontend/cypress/e2e/backoffice/control_objectives.spec.ts b/frontend/cypress/e2e/backoffice/control_objectives.spec.ts index b26514a917..6d363c4099 100644 --- a/frontend/cypress/e2e/backoffice/control_objectives.spec.ts +++ b/frontend/cypress/e2e/backoffice/control_objectives.spec.ts @@ -4,7 +4,7 @@ context('Control objectives', () => { beforeEach(() => { const currentYear = new Date().getFullYear() cy.intercept('GET', `/bff/v1/fleet_segments/${currentYear}`).as('fleetSegments') - cy.intercept('GET', `/bff/v1/control_objectives/${currentYear}`).as('controlObjectives') + cy.intercept('GET', `/bff/v1/admin/control_objectives/${currentYear}`).as('controlObjectives') cy.visit('/backoffice/control_objectives') cy.wait('@fleetSegments') cy.wait('@controlObjectives') @@ -45,7 +45,7 @@ context('Control objectives', () => { it('Should update the targetNumberOfControlsAtPort field on an objective', () => { // When - cy.intercept('PUT', '/bff/v1/control_objectives/78').as('updateObjective') + cy.intercept('PUT', '/bff/v1/admin/control_objectives/78').as('updateObjective') cy.wait(50) cy.get('*[data-cy="row-78-targetNumberOfControlsAtPort"]') .type('{backspace}{backspace}{backspace}{backspace}{backspace}') @@ -58,7 +58,7 @@ context('Control objectives', () => { cy.get('*[data-cy="row-78-targetNumberOfControlsAtPort"]').should('have.value', '23') // The value is saved in database when I refresh the page - cy.intercept('GET', '/bff/v1/control_objectives').as('controlObjectives') + cy.intercept('GET', '/bff/v1/admin/control_objectives').as('controlObjectives') cy.visit('/backoffice/control_objectives') cy.wait('@controlObjectives') cy.wait(50) @@ -67,7 +67,7 @@ context('Control objectives', () => { it('Should update the targetNumberOfControlsAtSea field on an objective', () => { // When - cy.intercept('PUT', '/bff/v1/control_objectives/78').as('updateObjective') + cy.intercept('PUT', '/bff/v1/admin/control_objectives/78').as('updateObjective') cy.wait(50) cy.get('*[data-cy="row-78-targetNumberOfControlsAtSea"]') .type('{backspace}{backspace}{backspace}{backspace}{backspace}') @@ -80,7 +80,7 @@ context('Control objectives', () => { cy.get('*[data-cy="row-78-targetNumberOfControlsAtSea"]').should('have.value', '23') // The value is saved in database when I refresh the page - cy.intercept('GET', '/bff/v1/control_objectives').as('controlObjectives') + cy.intercept('GET', '/bff/v1/admin/control_objectives').as('controlObjectives') cy.visit('/backoffice/control_objectives') cy.wait('@controlObjectives') cy.wait(50) @@ -89,7 +89,7 @@ context('Control objectives', () => { it('Should update the controlPriorityLevel field on an objective', () => { // When - cy.intercept('PUT', '/bff/v1/control_objectives/78').as('updateObjective') + cy.intercept('PUT', '/bff/v1/admin/control_objectives/78').as('updateObjective') cy.wait(50) cy.get('[data-cy="row-78-controlPriorityLevel"]').parent().click() cy.get('.rs-picker-select-menu-item').eq(2).click() @@ -100,7 +100,7 @@ context('Control objectives', () => { cy.get('[data-cy="row-78-controlPriorityLevel"]').should('exist') // The value is saved in database when I refresh the page - cy.intercept('GET', '/bff/v1/control_objectives').as('controlObjectives') + cy.intercept('GET', '/bff/v1/admin/control_objectives').as('controlObjectives') cy.visit('/backoffice/control_objectives') cy.wait('@controlObjectives') cy.wait(50) @@ -110,7 +110,7 @@ context('Control objectives', () => { it('Should delete an objective', () => { // Given cy.get('.rs-table-row').should('have.length', 67) - cy.intercept('DELETE', '/bff/v1/control_objectives/78').as('deleteObjective') + cy.intercept('DELETE', '/bff/v1/admin/control_objectives/78').as('deleteObjective') // When cy.get('*[data-cy="delete-row-78"]').click() @@ -121,7 +121,7 @@ context('Control objectives', () => { cy.get('.rs-table-row').should('have.length', 66) // The value is saved in database when I refresh the page - cy.intercept('GET', '/bff/v1/control_objectives').as('controlObjectives') + cy.intercept('GET', '/bff/v1/admin/control_objectives').as('controlObjectives') cy.visit('/backoffice/control_objectives') cy.wait('@controlObjectives') cy.wait(50) @@ -132,7 +132,7 @@ context('Control objectives', () => { it('Should add an objective', () => { // Given cy.get('.rs-table-row').should('have.length', 66) - cy.intercept('POST', '/bff/v1/control_objectives').as('addObjective') + cy.intercept('POST', '/bff/v1/admin/control_objectives').as('addObjective') cy.wait(200) // When @@ -145,7 +145,7 @@ context('Control objectives', () => { cy.get('.rs-table-row').should('have.length', 67) // Update the row when the value is updated in local memory - cy.intercept('PUT', '/bff/v1/control_objectives/125').as('updateObjective') + cy.intercept('PUT', '/bff/v1/admin/control_objectives/125').as('updateObjective') cy.get('[data-cy="row-125-targetNumberOfControlsAtPort"]').type( '{backspace}{backspace}{backspace}{backspace}{backspace}' ) @@ -155,7 +155,7 @@ context('Control objectives', () => { cy.get('[data-cy="row-125-targetNumberOfControlsAtPort"]').should('exist') // The value is saved in database when I refresh the page - cy.intercept('GET', '/bff/v1/control_objectives').as('controlObjectives') + cy.intercept('GET', '/bff/v1/admin/control_objectives').as('controlObjectives') cy.visit('/backoffice/control_objectives') cy.wait('@controlObjectives') cy.wait(50) @@ -183,7 +183,7 @@ context('Control objectives', () => { cy.get('.rs-table-row').should('have.length', 67) cy.get('*[data-cy^="control-objectives-year"]').click() cy.get('.rs-picker-select-menu-item').should('have.length', 2) - cy.intercept('POST', '/bff/v1/control_objectives/years').as('addObjectiveYear') + cy.intercept('POST', '/bff/v1/admin/control_objectives/years').as('addObjectiveYear') // When cy.get('*[data-cy="control-objectives-add-year"]').click() diff --git a/frontend/cypress/e2e/backoffice/fleet_segments.spec.ts b/frontend/cypress/e2e/backoffice/fleet_segments.spec.ts index 3c5f31b5aa..2f42267763 100644 --- a/frontend/cypress/e2e/backoffice/fleet_segments.spec.ts +++ b/frontend/cypress/e2e/backoffice/fleet_segments.spec.ts @@ -35,7 +35,7 @@ context('Fleet segments', () => { cy.log('Should update the segment') // When - cy.intercept('PUT', `/bff/v1/fleet_segments/backoffice?year=${currentYear}&segment=ATL01`).as('updateFleetSegment') + cy.intercept('PUT', `/bff/v1/admin/fleet_segments/?year=${currentYear}&segment=ATL01`).as('updateFleetSegment') cy.get('[aria-rowindex="2"]').find('[title="Editer la ligne"]').click() cy.fill('Nom', 'ATL036') @@ -92,7 +92,7 @@ context('Fleet segments', () => { it('Should create a new fleet segment and delete it', () => { // Given - cy.intercept('POST', '/bff/v1/fleet_segments/backoffice').as('createFleetSegment') + cy.intercept('POST', '/bff/v1/admin/fleet_segments').as('createFleetSegment') // When cy.clickButton('Ajouter un segment') @@ -137,9 +137,7 @@ context('Fleet segments', () => { // ------------------------------------------------------------------------- cy.log('Should delete a fleet segment') - cy.intercept('DELETE', `/bff/v1/fleet_segments/backoffice?year=${currentYear}&segment=ABC123`).as( - 'deleteFleetSegment' - ) + cy.intercept('DELETE', `/bff/v1/admin/fleet_segments/?year=${currentYear}&segment=ABC123`).as('deleteFleetSegment') cy.get('[aria-rowindex="2"]').find('[title="Supprimer la ligne"]').click() cy.wait('@deleteFleetSegment') diff --git a/frontend/src/features/ControlObjective/apis.ts b/frontend/src/features/ControlObjective/apis.ts index e82b52f27c..854b23149c 100644 --- a/frontend/src/features/ControlObjective/apis.ts +++ b/frontend/src/features/ControlObjective/apis.ts @@ -17,7 +17,7 @@ export const controlObjectiveApi = monitorfishApi.injectEndpoints({ query: createdFields => ({ body: createdFields, method: 'POST', - url: '/control_objectives' + url: '/admin/control_objectives' }), transformErrorResponse: response => new ApiError(ADD_CONTROL_OBJECTIVES_ERROR_MESSAGE, response) }), @@ -25,7 +25,7 @@ export const controlObjectiveApi = monitorfishApi.injectEndpoints({ invalidatesTags: [{ type: 'ControlObjectivesYears' }], query: () => ({ method: 'POST', - url: '/control_objectives/years' + url: '/admin/control_objectives/years' }), transformErrorResponse: response => new ApiError(ADD_CONTROL_OBJECTIVES_YEAR_ERROR_MESSAGE, response) }), @@ -33,17 +33,17 @@ export const controlObjectiveApi = monitorfishApi.injectEndpoints({ invalidatesTags: [{ type: 'ControlObjectives' }], query: id => ({ method: 'DELETE', - url: `/control_objectives/${id}` + url: `/admin/control_objectives/${id}` }), transformErrorResponse: response => new ApiError(DELETE_CONTROL_OBJECTIVES_ERROR_MESSAGE, response) }), getControlObjectives: builder.query({ providesTags: () => [{ type: 'ControlObjectives' }], - query: year => `/control_objectives/${year}` + query: year => `/admin/control_objectives/${year}` }), getControlObjectiveYears: builder.query({ providesTags: () => [{ type: 'ControlObjectivesYears' }], - query: () => '/control_objectives/years', + query: () => '/admin/control_objectives/years', transformResponse: (baseQueryReturnValue: number[]) => baseQueryReturnValue.sort(ascend(identity)) }), updateControlObjective: builder.mutation({ @@ -51,7 +51,7 @@ export const controlObjectiveApi = monitorfishApi.injectEndpoints({ query: ({ id, updatedFields }) => ({ body: updatedFields, method: 'PUT', - url: `/control_objectives/${id}` + url: `/admin/control_objectives/${id}` }), transformErrorResponse: response => new ApiError(UPDATE_CONTROL_OBJECTIVES_ERROR_MESSAGE, response) }) diff --git a/frontend/src/features/FleetSegment/apis.ts b/frontend/src/features/FleetSegment/apis.ts index 70082b5b52..5e93215dd5 100644 --- a/frontend/src/features/FleetSegment/apis.ts +++ b/frontend/src/features/FleetSegment/apis.ts @@ -53,7 +53,7 @@ async function updateFleetSegmentFromAPI( ): Promise { try { return await monitorfishApiKy - .put(`/bff/v1/fleet_segments/backoffice?year=${year}&segment=${segment}`, { + .put(`/bff/v1/admin/fleet_segments?year=${year}&segment=${segment}`, { json: updatedFields }) .json() @@ -70,7 +70,7 @@ async function updateFleetSegmentFromAPI( async function deleteFleetSegmentFromAPI(segment: string, year: number): Promise { try { return await monitorfishApiKy - .delete(`/bff/v1/fleet_segments/backoffice?year=${year}&segment=${segment}`) + .delete(`/bff/v1/admin/fleet_segments?year=${year}&segment=${segment}`) .json() } catch (err) { throw new ApiError(DELETE_FLEET_SEGMENT_ERROR_MESSAGE, err) @@ -85,7 +85,7 @@ async function deleteFleetSegmentFromAPI(segment: string, year: number): Promise async function createFleetSegmentFromAPI(segmentFields: UpdateFleetSegment): Promise { try { return await monitorfishApiKy - .post('/bff/v1/fleet_segments/backoffice', { + .post('/bff/v1/admin/fleet_segments', { json: segmentFields }) .json() @@ -101,7 +101,7 @@ async function createFleetSegmentFromAPI(segmentFields: UpdateFleetSegment): Pro */ async function addFleetSegmentYearFromAPI(nextYear: number) { try { - return await monitorfishApiKy.post(`/bff/v1/fleet_segments/backoffice/${nextYear}`) + return await monitorfishApiKy.post(`/bff/v1/admin/fleet_segments/${nextYear}`) } catch (err) { throw new ApiError(ADD_FLEET_SEGMENT_YEAR_ERROR_MESSAGE, err) } @@ -114,7 +114,7 @@ async function addFleetSegmentYearFromAPI(nextYear: number) { */ async function getFleetSegmentYearEntriesFromAPI(): Promise { try { - return await monitorfishApiKy.get('/bff/v1/fleet_segments/backoffice/years').json() + return await monitorfishApiKy.get('/bff/v1/admin/fleet_segments/years').json() } catch (err) { throw new ApiError(GET_FLEET_SEGMENT_YEAR_ENTRIES_ERROR_MESSAGE, err) } diff --git a/infra/configurations/application-dev.properties b/infra/configurations/application-dev.properties index b95b9ff3e1..8bb2b8eb24 100644 --- a/infra/configurations/application-dev.properties +++ b/infra/configurations/application-dev.properties @@ -16,7 +16,7 @@ monitorfish.oidc.userinfo-endpoint=/api/user monitorfish.api.protected.paths=/bff/*,/light/v1/vessels/* # Super-user paths of type /** are not supported -monitorfish.api.protected.super-user-paths=/bff/v1/beacon_malfunctions,/bff/v1/missions,/bff/v1/operational_alerts,/bff/v1/reportings,/bff/v1/vessels/risk_factors,/bff/v1/control_objectives,/bff/v1/fleet_segments/backoffice,/bff/v1/fleet_segments/compute +monitorfish.api.protected.super-user-paths=/bff/v1/beacon_malfunctions,/bff/v1/missions,/bff/v1/operational_alerts,/bff/v1/reportings,/bff/v1/vessels/risk_factors,/bff/v1/admin/control_objectives,/bff/v1/admin/fleet_segments,/bff/v1/fleet_segments/compute monitorfish.api.protected.public-paths=/api/v1/authorization/management/*,/api/v1/beacon_malfunctions/*,/api/v1/mission_actions/* ################### diff --git a/infra/configurations/application-local.properties b/infra/configurations/application-local.properties index c32dba21c7..72d74c0001 100644 --- a/infra/configurations/application-local.properties +++ b/infra/configurations/application-local.properties @@ -20,7 +20,7 @@ monitorfish.oidc.userinfo-endpoint=/protocol/openid-connect/userinfo monitorfish.api.protected.paths=/bff/*,/light/v1/vessels/* # Super-user paths of type /** are not supported -monitorfish.api.protected.super-user-paths=/bff/v1/beacon_malfunctions,/bff/v1/missions,/bff/v1/operational_alerts,/bff/v1/reportings,/bff/v1/vessels/risk_factors,/bff/v1/control_objectives,/bff/v1/fleet_segments/backoffice,/bff/v1/fleet_segments/compute +monitorfish.api.protected.super-user-paths=/bff/v1/beacon_malfunctions,/bff/v1/missions,/bff/v1/operational_alerts,/bff/v1/reportings,/bff/v1/vessels/risk_factors,/bff/v1/admin/control_objectives,/bff/v1/admin/fleet_segments,/bff/v1/fleet_segments/compute monitorfish.api.protected.public-paths=/api/v1/authorization/management/*,/api/v1/beacon_malfunctions/*,/api/v1/mission_actions/* monitorfish.api.protected.api-key=DUMMY-API-KEY diff --git a/infra/configurations/application-prod.properties b/infra/configurations/application-prod.properties index d3e3884c21..098d39ac34 100644 --- a/infra/configurations/application-prod.properties +++ b/infra/configurations/application-prod.properties @@ -16,7 +16,7 @@ monitorfish.oidc.userinfo-endpoint=/api/user monitorfish.api.protected.paths=/bff/*,/light/v1/vessels/* # Super-user paths of type /** are not supported -monitorfish.api.protected.super-user-paths=/bff/v1/beacon_malfunctions,/bff/v1/missions,/bff/v1/operational_alerts,/bff/v1/reportings,/bff/v1/vessels/risk_factors,/bff/v1/control_objectives,/bff/v1/fleet_segments/backoffice,/bff/v1/fleet_segments/compute +monitorfish.api.protected.super-user-paths=/bff/v1/beacon_malfunctions,/bff/v1/missions,/bff/v1/operational_alerts,/bff/v1/reportings,/bff/v1/vessels/risk_factors,/bff/v1/admin/control_objectives,/bff/v1/admin/fleet_segments,/bff/v1/fleet_segments/compute monitorfish.api.protected.public-paths=/api/v1/authorization/management/*,/api/v1/beacon_malfunctions/*,/api/v1/mission_actions/* ################### From 20fe8c81fa55a30c85a01ed573221a48c925b102 Mon Sep 17 00:00:00 2001 From: Loup Theron Date: Wed, 14 Aug 2024 09:25:42 +0200 Subject: [PATCH 8/8] Fix typo --- frontend/cypress/e2e/backoffice/fleet_segments.spec.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frontend/cypress/e2e/backoffice/fleet_segments.spec.ts b/frontend/cypress/e2e/backoffice/fleet_segments.spec.ts index 2f42267763..3ad29fb520 100644 --- a/frontend/cypress/e2e/backoffice/fleet_segments.spec.ts +++ b/frontend/cypress/e2e/backoffice/fleet_segments.spec.ts @@ -35,7 +35,7 @@ context('Fleet segments', () => { cy.log('Should update the segment') // When - cy.intercept('PUT', `/bff/v1/admin/fleet_segments/?year=${currentYear}&segment=ATL01`).as('updateFleetSegment') + cy.intercept('PUT', `/bff/v1/admin/fleet_segments?year=${currentYear}&segment=ATL01`).as('updateFleetSegment') cy.get('[aria-rowindex="2"]').find('[title="Editer la ligne"]').click() cy.fill('Nom', 'ATL036') @@ -137,7 +137,7 @@ context('Fleet segments', () => { // ------------------------------------------------------------------------- cy.log('Should delete a fleet segment') - cy.intercept('DELETE', `/bff/v1/admin/fleet_segments/?year=${currentYear}&segment=ABC123`).as('deleteFleetSegment') + cy.intercept('DELETE', `/bff/v1/admin/fleet_segments?year=${currentYear}&segment=ABC123`).as('deleteFleetSegment') cy.get('[aria-rowindex="2"]').find('[title="Supprimer la ligne"]').click() cy.wait('@deleteFleetSegment')