Skip to content

feat: add ROLE_HELPDESK_INTEGRATION authority and middleware read/write permissions for req. endpoints - #1246

Open
ondraholis wants to merge 25 commits into
masterfrom
feature/helpdesk-integration-role
Open

feat: add ROLE_HELPDESK_INTEGRATION authority and middleware read/write permissions for req. endpoints#1246
ondraholis wants to merge 25 commits into
masterfrom
feature/helpdesk-integration-role

Conversation

@ondraholis

@ondraholis ondraholis commented Jul 31, 2026

Copy link
Copy Markdown
Collaborator

Description:

Introduces the ROLE_HELPDESK_INTEGRATION Spring Security authority and negotiator_helpdesk OAuth2 scope required by the helpdesk middleware service account. This is Change 1 from the
helpdesk integration plan (helpdesk-integration-plan.md).

Changes to Negotiator authorization:

  • CustomJWTAuthConverter — maps the negotiator_helpdesk scope to ROLE_HELPDESK_INTEGRATION
  • PostServiceImpl.checkAuthorization() — allows ROLE_HELPDESK_INTEGRATION to post messages when the negotiation state permits
  • PostServiceImpl.isNegotiationCreatorOrAdminOrHelpdeskIntegration() — allows ROLE_HELPDESK_INTEGRATION to read also private posts
  • NegotiationController.sendEventForNegotiationResource() — allows ROLE_HELPDESK_INTEGRATION to trigger resource state transitions
  • ResourceLifecycleServiceImpl / ResourceStateMachineConfig — introduces isRepresentativeOrHelpdeskIntegration security attribute on all representative-accessible transitions
  • NegotiationAccessManagerImpl.verifyReadAccessForNegotiation() — allows ROLE_HELPDESK_INTEGRATION to read negotiations and their resources
  • NegotiationServiceImpl.isAuthorizedForNegotiation() — allows ROLE_HELPDESK_INTEGRATION to read attachments (used by DBAttachmentService)

Changes to OIDC server config:

  • api-scopes.yaml — registers the negotiator_helpdesk scope
  • api-resources.yaml — associates negotiator_helpdesk with the https://negotiator.bbmri-eric.eu resource so the aud claim is populated correctly
  • clients.json — adds helpdesk-client for local development and testing

Changes to Swagger:

  • Adds bearerAuth HTTP Bearer scheme so machine tokens can be used in Swagger UI
  • Adds @securityrequirement(name = "bearerAuth") to NegotiationController and AttachmentController

Checklist:

  • I have performed a self-review of my code
  • I have made my code as simple as possible
  • I have removed all commented code
  • I have described the PR and added a meaningful title in the Conventional Commits format
  • I have added relevant tests for my changes and the code coverage has not dropped substantially
  • I have updated the documentation in all relevant places (Javadoc, Swagger, MDs...)

@sonarqubecloud

sonarqubecloud Bot commented Aug 2, 2026

Copy link
Copy Markdown

@sonarqubecloud

sonarqubecloud Bot commented Aug 2, 2026

Copy link
Copy Markdown

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a dedicated helpdesk integration authority/scope and wires it through Negotiator’s security model so a middleware service account can read/write the required negotiation resources and use machine tokens via Swagger.

Changes:

  • Introduces ROLE_HELPDESK_INTEGRATION and maps the negotiator_helpdesk OAuth2 scope to that role.
  • Extends read/write authorization in posts, negotiations, resource lifecycle transitions, and attachments for helpdesk integration.
  • Updates Swagger/OpenAPI to support HTTP Bearer (JWT) auth, and adds test data + unit/integration tests for the new role.

Reviewed changes

Copilot reviewed 21 out of 21 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
oidc-server-config/clients.json Adds a local dev/test client for helpdesk integration scope.
oidc-server-config/api-scopes.yaml Registers the new negotiator_helpdesk scope.
oidc-server-config/api-resources.yaml Associates the new scope with the Negotiator API resource for correct aud.
backend/src/test/java/eu/bbmri_eric/negotiator/unit/service/PostServiceTest.java Adds unit coverage for helpdesk post creation behavior.
backend/src/test/java/eu/bbmri_eric/negotiator/unit/CustomJWTAuthConverterTest.java Adds test asserting scope→role mapping for helpdesk.
backend/src/test/java/eu/bbmri_eric/negotiator/negotiation/NegotiationControllerTests.java Extends controller tests to cover helpdesk access and new fixture negotiation.
backend/src/test/java/eu/bbmri_eric/negotiator/integration/service/NegotiationLifecycleServiceImplTest.java Adds integration tests for helpdesk lifecycle events/permissions.
backend/src/test/java/eu/bbmri_eric/negotiator/integration/api/v3/PostControllerTests.java Adds integration tests for helpdesk reading/creating posts.
backend/src/test/java/eu/bbmri_eric/negotiator/integration/api/v3/AttachmentControllerTests.java Refactors attachment test setup and adds helpdesk download coverage.
backend/src/main/resources/db/test/migration/R__Initial_data.sql Adds helpdesk test user + negotiation/resources/posts fixtures for integration tests.
backend/src/main/java/eu/bbmri_eric/negotiator/post/PostServiceImpl.java Expands post read/write authorization to include helpdesk integration.
backend/src/main/java/eu/bbmri_eric/negotiator/post/PostController.java Declares bearer auth requirement in API docs for machine tokens.
backend/src/main/java/eu/bbmri_eric/negotiator/negotiation/state_machine/resource/ResourceStateMachineConfig.java Updates representative-secured transitions to allow helpdesk integration as well.
backend/src/main/java/eu/bbmri_eric/negotiator/negotiation/state_machine/resource/ResourceLifecycleServiceImpl.java Extends security rule evaluation to allow helpdesk integration on representative transitions.
backend/src/main/java/eu/bbmri_eric/negotiator/negotiation/NegotiationServiceImpl.java Allows helpdesk integration to pass negotiation authorization checks (used for attachments).
backend/src/main/java/eu/bbmri_eric/negotiator/negotiation/NegotiationController.java Allows helpdesk integration to trigger resource lifecycle events.
backend/src/main/java/eu/bbmri_eric/negotiator/negotiation/NegotiationAccessManagerImpl.java Grants helpdesk integration read access to negotiations/resources.
backend/src/main/java/eu/bbmri_eric/negotiator/common/configuration/SwaggerConfig.java Adds bearerAuth scheme and attempts to enable it globally in OpenAPI.
backend/src/main/java/eu/bbmri_eric/negotiator/common/configuration/security/oauth2/CustomJWTAuthConverter.java Maps negotiator_helpdesk scope to ROLE_HELPDESK_INTEGRATION.
backend/src/main/java/eu/bbmri_eric/negotiator/common/AuthenticatedUserContext.java Adds helpdesk role constant + helper to detect helpdesk integration requests.
backend/src/main/java/eu/bbmri_eric/negotiator/attachment/AttachmentController.java Declares bearer auth requirement in API docs for machine tokens.

Comment on lines 83 to +85
.webhooks(webhookPaths)
.components(components);
.components(components)
.addSecurityItem(new SecurityRequirement().addList("security_auth").addList("bearerAuth"));
Comment on lines +383 to +404
@ParameterizedTest
@EnumSource(PostType.class)
@WithMockNegotiatorUser(authorities = "ROLE_HELPDESK_INTEGRATION")
public void test_createPublicAndPrivatePost_asHelpdeskIntegration_Ok(PostType postType) {
negotiation.setPublicPostsEnabled(true);
when(negotiationRepository.findById(any())).thenReturn(Optional.of(negotiation));
when(personRepository.findById(any())).thenReturn(Optional.of(researcher));
when(postRepository.save(any())).thenReturn(publicPost1);
PostCreateDTO postCreateDTO =
PostCreateDTO.builder().text(publicPost1.getText()).type(PostType.PUBLIC).build();
PostDTO postDTO =
PostDTO.builder()
.id("test-id")
.createdBy(new UserResponseModel())
.creationDate(LocalDateTime.now())
.text(publicPost1.getText())
.type(postType)
.build();
when(modelMapper.map(publicPost1, PostDTO.class)).thenReturn(postDTO);
PostDTO returnedPostDTO = postService.create(postCreateDTO, negotiation.getId());
assertEquals(postType, returnedPostDTO.getType());
}
Comment on lines +171 to +175
} else if (securityRule.getAttributes().contains("isRepresentativeOrHelpdeskIntegration")) {
return AuthenticatedUserContext.isHelpdeskIntegration()
|| personService.isRepresentativeOfAnyResource(
AuthenticatedUserContext.getCurrentlyAuthenticatedUserInternalId(),
List.of(resourceId));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants