diff --git a/src/main/java/org/dependencytrack/auth/Permissions.java b/src/main/java/org/dependencytrack/auth/Permissions.java index 62419d962..72612c8c3 100644 --- a/src/main/java/org/dependencytrack/auth/Permissions.java +++ b/src/main/java/org/dependencytrack/auth/Permissions.java @@ -29,15 +29,38 @@ public enum Permissions { BOM_UPLOAD("Allows the ability to upload CycloneDX Software Bill of Materials (SBOM)"), VIEW_PORTFOLIO("Provides the ability to view the portfolio of projects, components, and licenses"), PORTFOLIO_MANAGEMENT("Allows the creation, modification, and deletion of data in the portfolio"), + PORTFOLIO_MANAGEMENT_CREATE("Allows the creation of data in the portfolio"), + PORTFOLIO_MANAGEMENT_READ("Allows the reading of data in the portfolio"), + PORTFOLIO_MANAGEMENT_UPDATE("Allows the updating of data in the portfolio"), + PORTFOLIO_MANAGEMENT_DELETE("Allows the deletion of data in the portfolio"), VIEW_VULNERABILITY("Provides the ability to view the vulnerabilities projects are affected by"), - VULNERABILITY_ANALYSIS("Provides the ability to make analysis decisions on vulnerabilities"), + VULNERABILITY_ANALYSIS("Provides all abilities to make analysis decisions on vulnerabilities"), + VULNERABILITY_ANALYSIS_CREATE("Provides the ability to upload supported VEX documents to a project"), + VULNERABILITY_ANALYSIS_READ("Provides the ability read the VEX document for a project"), + VULNERABILITY_ANALYSIS_UPDATE("Provides the ability to make analysis decisions on vulnerabilities and upload supported VEX documents for a project"), VIEW_POLICY_VIOLATION("Provides the ability to view policy violations"), - VULNERABILITY_MANAGEMENT("Allows management of internally-defined vulnerabilities"), + VULNERABILITY_MANAGEMENT("Allows all management permissions of internally-defined vulnerabilities"), + VULNERABILITY_MANAGEMENT_CREATE("Allows creation of internally-defined vulnerabilities"), + VULNERABILITY_MANAGEMENT_READ("Allows reading internally-defined vulnerabilities"), + VULNERABILITY_MANAGEMENT_UPDATE("Allows updating internally-defined vulnerabilities and vulnerability tags"), + VULNERABILITY_MANAGEMENT_DELETE("Allows management of internally-defined vulnerabilities"), POLICY_VIOLATION_ANALYSIS("Provides the ability to make analysis decisions on policy violations"), ACCESS_MANAGEMENT("Allows the management of users, teams, and API keys"), - SYSTEM_CONFIGURATION("Allows the configuration of the system including notifications, repositories, and email settings"), + ACCESS_MANAGEMENT_CREATE("Allows create permissions of users, teams, and API keys"), + ACCESS_MANAGEMENT_READ("Allows read permissions of users, teams, and API keys"), + ACCESS_MANAGEMENT_UPDATE("Allows update permissions of users, teams, and API keys"), + ACCESS_MANAGEMENT_DELETE("Allows delete permissions of users, teams, and API keys"), + SYSTEM_CONFIGURATION("Allows all access to configuration of the system including notifications, repositories, and email settings"), + SYSTEM_CONFIGURATION_CREATE("Allows creating configuration of the system including notifications, repositories, and email settings"), + SYSTEM_CONFIGURATION_READ("Allows reading the configuration of the system including notifications, repositories, and email settings"), + SYSTEM_CONFIGURATION_UPDATE("Allows updating the configuration of the system including notifications, repositories, and email settings"), + SYSTEM_CONFIGURATION_DELETE("Allows deleting the configuration of the system including notifications, repositories, and email settings"), PROJECT_CREATION_UPLOAD("Provides the ability to optionally create project (if non-existent) on BOM or scan upload"), - POLICY_MANAGEMENT("Allows the creation, modification, and deletion of policy"); + POLICY_MANAGEMENT("Allows the creation, modification, and deletion of policy"), + POLICY_MANAGEMENT_CREATE("Allows the creation of a policy"), + POLICY_MANAGEMENT_READ("Allows reading of policies"), + POLICY_MANAGEMENT_UPDATE("Allows the modification of a policy"), + POLICY_MANAGEMENT_DELETE("Allows the deletion of a policy"); private final String description; @@ -53,15 +76,38 @@ public static class Constants { public static final String BOM_UPLOAD = "BOM_UPLOAD"; public static final String VIEW_PORTFOLIO = "VIEW_PORTFOLIO"; public static final String PORTFOLIO_MANAGEMENT = "PORTFOLIO_MANAGEMENT"; + public static final String PORTFOLIO_MANAGEMENT_CREATE = "PORTFOLIO_MANAGEMENT_CREATE"; + public static final String PORTFOLIO_MANAGEMENT_READ = "PORTFOLIO_MANAGEMENT_READ"; + public static final String PORTFOLIO_MANAGEMENT_UPDATE = "PORTFOLIO_MANAGEMENT_UPDATE"; + public static final String PORTFOLIO_MANAGEMENT_DELETE = "PORTFOLIO_MANAGEMENT_DELETE"; public static final String VIEW_VULNERABILITY = "VIEW_VULNERABILITY"; public static final String VULNERABILITY_ANALYSIS = "VULNERABILITY_ANALYSIS"; + public static final String VULNERABILITY_ANALYSIS_CREATE = "VULNERABILITY_ANALYSIS_CREATE"; + public static final String VULNERABILITY_ANALYSIS_READ = "VULNERABILITY_ANALYSIS_READ"; + public static final String VULNERABILITY_ANALYSIS_UPDATE = "VULNERABILITY_ANALYSIS_UPDATE"; public static final String VIEW_POLICY_VIOLATION = "VIEW_POLICY_VIOLATION"; public static final String VULNERABILITY_MANAGEMENT = "VULNERABILITY_MANAGEMENT"; + public static final String VULNERABILITY_MANAGEMENT_CREATE = "VULNERABILITY_MANAGEMENT_CREATE"; + public static final String VULNERABILITY_MANAGEMENT_READ = "VULNERABILITY_MANAGEMENT_READ"; + public static final String VULNERABILITY_MANAGEMENT_UPDATE = "VULNERABILITY_MANAGEMENT_UPDATE"; + public static final String VULNERABILITY_MANAGEMENT_DELETE = "VULNERABILITY_MANAGEMENT_DELETE"; public static final String POLICY_VIOLATION_ANALYSIS = "POLICY_VIOLATION_ANALYSIS"; public static final String ACCESS_MANAGEMENT = "ACCESS_MANAGEMENT"; + public static final String ACCESS_MANAGEMENT_CREATE = "ACCESS_MANAGEMENT_CREATE"; + public static final String ACCESS_MANAGEMENT_READ = "ACCESS_MANAGEMENT_READ"; + public static final String ACCESS_MANAGEMENT_UPDATE = "ACCESS_MANAGEMENT_UPDATE"; + public static final String ACCESS_MANAGEMENT_DELETE = "ACCESS_MANAGEMENT_DELETE"; public static final String SYSTEM_CONFIGURATION = "SYSTEM_CONFIGURATION"; + public static final String SYSTEM_CONFIGURATION_CREATE = "SYSTEM_CONFIGURATION_CREATE"; + public static final String SYSTEM_CONFIGURATION_READ = "SYSTEM_CONFIGURATION_READ"; + public static final String SYSTEM_CONFIGURATION_UPDATE = "SYSTEM_CONFIGURATION_UPDATE"; + public static final String SYSTEM_CONFIGURATION_DELETE = "SYSTEM_CONFIGURATION_DELETE"; public static final String PROJECT_CREATION_UPLOAD = "PROJECT_CREATION_UPLOAD"; public static final String POLICY_MANAGEMENT = "POLICY_MANAGEMENT"; + public static final String POLICY_MANAGEMENT_CREATE = "POLICY_MANAGEMENT_CREATE"; + public static final String POLICY_MANAGEMENT_READ = "POLICY_MANAGEMENT_READ"; + public static final String POLICY_MANAGEMENT_UPDATE = "POLICY_MANAGEMENT_UPDATE"; + public static final String POLICY_MANAGEMENT_DELETE = "POLICY_MANAGEMENT_DELETE"; } } diff --git a/src/main/java/org/dependencytrack/persistence/DefaultObjectGenerator.java b/src/main/java/org/dependencytrack/persistence/DefaultObjectGenerator.java index 2ecf9ea4c..afb386700 100644 --- a/src/main/java/org/dependencytrack/persistence/DefaultObjectGenerator.java +++ b/src/main/java/org/dependencytrack/persistence/DefaultObjectGenerator.java @@ -170,7 +170,11 @@ private List getPortfolioManagersPermissions(final List final List permissions = new ArrayList<>(); for (final Permission permission: fullList) { if (permission.getName().equals(Permissions.Constants.VIEW_PORTFOLIO) || - permission.getName().equals(Permissions.Constants.PORTFOLIO_MANAGEMENT)) { + permission.getName().equals(Permissions.Constants.PORTFOLIO_MANAGEMENT) || + permission.getName().equals(Permissions.Constants.PORTFOLIO_MANAGEMENT_CREATE) || + permission.getName().equals(Permissions.Constants.PORTFOLIO_MANAGEMENT_READ) || + permission.getName().equals(Permissions.Constants.PORTFOLIO_MANAGEMENT_UPDATE) || + permission.getName().equals(Permissions.Constants.PORTFOLIO_MANAGEMENT_DELETE)) { permissions.add(permission); } } diff --git a/src/main/java/org/dependencytrack/resources/v1/AccessControlResource.java b/src/main/java/org/dependencytrack/resources/v1/AccessControlResource.java index 3dd78c77c..653e70a9a 100644 --- a/src/main/java/org/dependencytrack/resources/v1/AccessControlResource.java +++ b/src/main/java/org/dependencytrack/resources/v1/AccessControlResource.java @@ -75,7 +75,7 @@ public class AccessControlResource extends AlpineResource { @Produces(MediaType.APPLICATION_JSON) @Operation( summary = "Returns the projects assigned to the specified team", - description = "

Requires permission ACCESS_MANAGEMENT

" + description = "

Requires permission ACCESS_MANAGEMENT or ACCESS_MANAGEMENT_READ

" ) @PaginatedApi @ApiResponses(value = { @@ -87,7 +87,7 @@ public class AccessControlResource extends AlpineResource { @ApiResponse(responseCode = "401", description = "Unauthorized"), @ApiResponse(responseCode = "404", description = "The UUID of the team could not be found"), }) - @PermissionRequired(Permissions.Constants.ACCESS_MANAGEMENT) + @PermissionRequired({ Permissions.Constants.ACCESS_MANAGEMENT, Permissions.Constants.ACCESS_MANAGEMENT_READ }) public Response retrieveProjects(@Parameter(description = "The UUID of the team to retrieve mappings for", schema = @Schema(type = "string", format = "uuid"), required = true) @PathParam("uuid") @ValidUuid String uuid, @Parameter(description = "Optionally excludes inactive projects from being returned", required = false) @@ -118,7 +118,7 @@ public Response retrieveProjects(@Parameter(description = "The UUID of the team @ApiResponse(responseCode = "404", description = "The UUID of the team or project could not be found"), @ApiResponse(responseCode = "409", description = "A mapping with the same team and project already exists") }) - @PermissionRequired(Permissions.Constants.ACCESS_MANAGEMENT) + @PermissionRequired({Permissions.Constants.ACCESS_MANAGEMENT, Permissions.Constants.ACCESS_MANAGEMENT_CREATE}) public Response addMapping(AclMappingRequest request) { final Validator validator = super.getValidator(); failOnValidationError( @@ -148,13 +148,13 @@ public Response addMapping(AclMappingRequest request) { @Produces(MediaType.APPLICATION_JSON) @Operation( summary = "Removes an ACL mapping", - description = "

Requires permission ACCESS_MANAGEMENT

" + description = "

Requires permission ACCESS_MANAGEMENT or ACCESS_MANAGEMENT_DELETE

" ) @ApiResponses(value = { @ApiResponse(responseCode = "401", description = "Unauthorized"), @ApiResponse(responseCode = "404", description = "The UUID of the team or project could not be found"), }) - @PermissionRequired(Permissions.Constants.ACCESS_MANAGEMENT) + @PermissionRequired({Permissions.Constants.ACCESS_MANAGEMENT, Permissions.Constants.ACCESS_MANAGEMENT_DELETE}) public Response deleteMapping( @Parameter(description = "The UUID of the team to delete the mapping for", schema = @Schema(type = "string", format = "uuid"), required = true) @PathParam("teamUuid") @ValidUuid String teamUuid, diff --git a/src/main/java/org/dependencytrack/resources/v1/AnalysisResource.java b/src/main/java/org/dependencytrack/resources/v1/AnalysisResource.java index 6758b1d53..12b7e5a48 100644 --- a/src/main/java/org/dependencytrack/resources/v1/AnalysisResource.java +++ b/src/main/java/org/dependencytrack/resources/v1/AnalysisResource.java @@ -125,14 +125,14 @@ public Response retrieveAnalysis(@Parameter(description = "The UUID of the proje @Produces(MediaType.APPLICATION_JSON) @Operation( summary = "Records an analysis decision", - description = "

Requires permission VULNERABILITY_ANALYSIS

" + description = "

Requires permission VULNERABILITY_ANALYSIS or VULNERABILITY_ANALYSIS_UPDATE

" ) @ApiResponses(value = { @ApiResponse(responseCode = "200", content = @Content(schema = @Schema(implementation = Analysis.class))), @ApiResponse(responseCode = "401", description = "Unauthorized"), @ApiResponse(responseCode = "404", description = "The project, component, or vulnerability could not be found") }) - @PermissionRequired(Permissions.Constants.VULNERABILITY_ANALYSIS) + @PermissionRequired({Permissions.Constants.VULNERABILITY_ANALYSIS, Permissions.Constants.VULNERABILITY_ANALYSIS_UPDATE}) public Response updateAnalysis(AnalysisRequest request) { final Validator validator = getValidator(); failOnValidationError( diff --git a/src/main/java/org/dependencytrack/resources/v1/BomResource.java b/src/main/java/org/dependencytrack/resources/v1/BomResource.java index 8f7cea0e5..0638de75e 100644 --- a/src/main/java/org/dependencytrack/resources/v1/BomResource.java +++ b/src/main/java/org/dependencytrack/resources/v1/BomResource.java @@ -228,8 +228,8 @@ public Response exportComponentAsCycloneDx( then the projectName and projectVersion must be specified. Optionally, if autoCreate is specified and true and the project does not exist, the project will be created. In this scenario, the principal making the request will - additionally need the PORTFOLIO_MANAGEMENT or - PROJECT_CREATION_UPLOAD permission. + additionally need the PORTFOLIO_MANAGEMENT, PORTFOLIO_MANAGEMENT_CREATE, + or PROJECT_CREATION_UPLOAD permission.

The BOM will be validated against the CycloneDX schema. If schema validation fails, @@ -274,7 +274,7 @@ public Response uploadBom(@Parameter(required = true) BomSubmitRequest request) try (QueryManager qm = new QueryManager()) { Project project = qm.getProject(request.getProjectName(), request.getProjectVersion()); if (project == null && request.isAutoCreate()) { - if (hasPermission(Permissions.Constants.PORTFOLIO_MANAGEMENT) || hasPermission(Permissions.Constants.PROJECT_CREATION_UPLOAD)) { + if (hasPermission(Permissions.Constants.PORTFOLIO_MANAGEMENT) || hasPermission(Permissions.Constants.PORTFOLIO_MANAGEMENT_CREATE) || hasPermission(Permissions.Constants.PROJECT_CREATION_UPLOAD)) { Project parent = null; if (request.getParentUUID() != null || request.getParentName() != null) { if (request.getParentUUID() != null) { @@ -320,8 +320,8 @@ public Response uploadBom(@Parameter(required = true) BomSubmitRequest request) then the projectName and projectVersion must be specified. Optionally, if autoCreate is specified and true and the project does not exist, the project will be created. In this scenario, the principal making the request will - additionally need the PORTFOLIO_MANAGEMENT or - PROJECT_CREATION_UPLOAD permission. + additionally need the PORTFOLIO_MANAGEMENT, PORTFOLIO_MANAGEMENT_CREATE, + or PROJECT_CREATION_UPLOAD permission.

The BOM will be validated against the CycloneDX schema. If schema validation fails, @@ -366,7 +366,7 @@ public Response uploadBom( final String trimmedProjectVersion = StringUtils.trimToNull(projectVersion); Project project = qm.getProject(trimmedProjectName, trimmedProjectVersion); if (project == null && autoCreate) { - if (hasPermission(Permissions.Constants.PORTFOLIO_MANAGEMENT) || hasPermission(Permissions.Constants.PROJECT_CREATION_UPLOAD)) { + if (hasPermission(Permissions.Constants.PORTFOLIO_MANAGEMENT) || hasPermission(Permissions.Constants.PORTFOLIO_MANAGEMENT_CREATE) || hasPermission(Permissions.Constants.PROJECT_CREATION_UPLOAD)) { Project parent = null; if (parentUUID != null || parentName != null) { if (parentUUID != null) { diff --git a/src/main/java/org/dependencytrack/resources/v1/ComponentPropertyResource.java b/src/main/java/org/dependencytrack/resources/v1/ComponentPropertyResource.java index eef110a76..698fcf752 100644 --- a/src/main/java/org/dependencytrack/resources/v1/ComponentPropertyResource.java +++ b/src/main/java/org/dependencytrack/resources/v1/ComponentPropertyResource.java @@ -106,7 +106,7 @@ public Response getProperties( @Produces(MediaType.APPLICATION_JSON) @Operation( summary = "Creates a new component property", - description = "

Requires permission PORTFOLIO_MANAGEMENT

" + description = "

Requires permission PORTFOLIO_MANAGEMENT or PORTFOLIO_MANAGEMENT_CREATE

" ) @ApiResponses(value = { @ApiResponse(responseCode = "201", content = @Content(schema = @Schema(implementation = ComponentProperty.class))), @@ -115,7 +115,7 @@ public Response getProperties( @ApiResponse(responseCode = "404", description = "The component could not be found"), @ApiResponse(responseCode = "409", description = "A property with the specified component/group/name combination already exists") }) - @PermissionRequired(Permissions.Constants.PORTFOLIO_MANAGEMENT) + @PermissionRequired({Permissions.Constants.PORTFOLIO_MANAGEMENT, Permissions.Constants.PORTFOLIO_MANAGEMENT_CREATE}) public Response createProperty( @Parameter(description = "The UUID of the component to create a property for", schema = @Schema(type = "string", format = "uuid"), required = true) @PathParam("uuid") @ValidUuid String uuid, @@ -164,7 +164,7 @@ public Response createProperty( @Produces(MediaType.APPLICATION_JSON) @Operation( summary = "Deletes a config property", - description = "

Requires permission PORTFOLIO_MANAGEMENT

" + description = "

Requires permission PORTFOLIO_MANAGEMENT or PORTFOLIO_MANAGEMENT_DELETE

" ) @ApiResponses(value = { @ApiResponse(responseCode = "204"), @@ -172,7 +172,7 @@ public Response createProperty( @ApiResponse(responseCode = "403", description = "Access to the specified component is forbidden"), @ApiResponse(responseCode = "404", description = "The component or component property could not be found"), }) - @PermissionRequired(Permissions.Constants.PORTFOLIO_MANAGEMENT) + @PermissionRequired({Permissions.Constants.PORTFOLIO_MANAGEMENT, Permissions.Constants.PORTFOLIO_MANAGEMENT_DELETE}) public Response deleteProperty( @Parameter(description = "The UUID of the component to delete a property from", schema = @Schema(type = "string", format = "uuid"), required = true) @PathParam("uuid") @ValidUuid final String componentUuid, diff --git a/src/main/java/org/dependencytrack/resources/v1/ComponentResource.java b/src/main/java/org/dependencytrack/resources/v1/ComponentResource.java index a116e508f..3c71c445d 100644 --- a/src/main/java/org/dependencytrack/resources/v1/ComponentResource.java +++ b/src/main/java/org/dependencytrack/resources/v1/ComponentResource.java @@ -346,7 +346,7 @@ public Response getComponentByHash( @Produces(MediaType.APPLICATION_JSON) @Operation( summary = "Creates a new component", - description = "

Requires permission PORTFOLIO_MANAGEMENT

" + description = "

Requires permission PORTFOLIO_MANAGEMENT or PORTFOLIO_MANAGEMENT_UPDATE

" ) @ApiResponses(value = { @ApiResponse(content = @Content(schema = @Schema(implementation = Component.class)), @@ -355,7 +355,8 @@ public Response getComponentByHash( @ApiResponse(responseCode = "403", description = "Access to the specified project is forbidden"), @ApiResponse(responseCode = "404", description = "The project could not be found") }) - @PermissionRequired(Permissions.Constants.PORTFOLIO_MANAGEMENT) + @PermissionRequired({ Permissions.Constants.PORTFOLIO_MANAGEMENT, + Permissions.Constants.PORTFOLIO_MANAGEMENT_UPDATE }) public Response createComponent(@Parameter(description = "The UUID of the project to create a component for", schema = @Schema(format = "uuid"), required = true) @PathParam("uuid") @ValidUuid String uuid, Component jsonComponent) { final Validator validator = super.getValidator(); @@ -466,7 +467,7 @@ public Response createComponent(@Parameter(description = "The UUID of the projec @Produces(MediaType.APPLICATION_JSON) @Operation( summary = "Updates a component", - description = "

Requires permission PORTFOLIO_MANAGEMENT

" + description = "

Requires permission PORTFOLIO_MANAGEMENT or PORTFOLIO_MANAGEMENT_UPDATE

" ) @ApiResponses(value = { @ApiResponse(responseCode = "201", content = @Content(schema = @Schema(implementation = Component.class))), @@ -474,7 +475,7 @@ public Response createComponent(@Parameter(description = "The UUID of the projec @ApiResponse(responseCode = "403", description = "Access to the specified component is forbidden"), @ApiResponse(responseCode = "404", description = "The UUID of the component could not be found"), }) - @PermissionRequired(Permissions.Constants.PORTFOLIO_MANAGEMENT) + @PermissionRequired({Permissions.Constants.PORTFOLIO_MANAGEMENT, Permissions.Constants.PORTFOLIO_MANAGEMENT_UPDATE}) public Response updateComponent(Component jsonComponent) { final Validator validator = super.getValidator(); failOnValidationError( @@ -594,7 +595,7 @@ public Response updateComponent(Component jsonComponent) { @ApiResponse(responseCode = "403", description = "Access to the specified component is forbidden"), @ApiResponse(responseCode = "404", description = "The UUID of the component could not be found") }) - @PermissionRequired(Permissions.Constants.PORTFOLIO_MANAGEMENT) + @PermissionRequired({Permissions.Constants.PORTFOLIO_MANAGEMENT, Permissions.Constants.PORTFOLIO_MANAGEMENT_DELETE}) public Response deleteComponent( @Parameter(description = "The UUID of the component to delete", schema = @Schema(format = "uuid"), required = true) @PathParam("uuid") @ValidUuid String uuid) { @@ -617,13 +618,13 @@ public Response deleteComponent( @Produces(MediaType.APPLICATION_JSON) @Operation( summary = "Requests the identification of internal components in the portfolio", - description = "

Requires permission SYSTEM_CONFIGURATION

" + description = "

Requires permission SYSTEM_CONFIGURATION or SYSTEM_CONFIGURATION_READ

" ) @ApiResponses(value = { @ApiResponse(responseCode = "204"), @ApiResponse(responseCode = "401", description = "Unauthorized") }) - @PermissionRequired(Permissions.Constants.SYSTEM_CONFIGURATION) + @PermissionRequired({Permissions.Constants.SYSTEM_CONFIGURATION, Permissions.Constants.SYSTEM_CONFIGURATION_READ}) public Response identifyInternalComponents() { Event.dispatch(new InternalComponentIdentificationEvent()); return Response.status(Response.Status.NO_CONTENT).build(); diff --git a/src/main/java/org/dependencytrack/resources/v1/ConfigPropertyResource.java b/src/main/java/org/dependencytrack/resources/v1/ConfigPropertyResource.java index 3b893e72e..74969c369 100644 --- a/src/main/java/org/dependencytrack/resources/v1/ConfigPropertyResource.java +++ b/src/main/java/org/dependencytrack/resources/v1/ConfigPropertyResource.java @@ -61,13 +61,13 @@ public class ConfigPropertyResource extends AbstractConfigPropertyResource { @Produces(MediaType.APPLICATION_JSON) @Operation( summary = "Returns a list of all ConfigProperties for the specified groupName", - description = "

Requires permission SYSTEM_CONFIGURATION

" + description = "

Requires permission SYSTEM_CONFIGURATION or SYSTEM_CONFIGURATION_READ

" ) @ApiResponses(value = { @ApiResponse(responseCode = "200", content = @Content(array = @ArraySchema(schema = @Schema(implementation = ConfigProperty.class)))), @ApiResponse(responseCode = "401", description = "Unauthorized") }) - @PermissionRequired(Permissions.Constants.SYSTEM_CONFIGURATION) + @PermissionRequired({Permissions.Constants.SYSTEM_CONFIGURATION, Permissions.Constants.SYSTEM_CONFIGURATION_READ}) public Response getConfigProperties() { try (QueryManager qm = new QueryManager(getAlpineRequest())) { final List configProperties = qm.getConfigProperties(); @@ -89,14 +89,14 @@ public Response getConfigProperties() { @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) @Operation(summary = "Updates a config property", - description = "

Requires permission SYSTEM_CONFIGURATION

" + description = "

Requires permission SYSTEM_CONFIGURATION or SYSTEM_CONFIGURATION_UPDATE

" ) @ApiResponses(value = { @ApiResponse(responseCode = "200", content = @Content(schema = @Schema(implementation = ConfigProperty.class))), @ApiResponse(responseCode = "401", description = "Unauthorized"), @ApiResponse(responseCode = "404", description = "The config property could not be found"), }) - @PermissionRequired(Permissions.Constants.SYSTEM_CONFIGURATION) + @PermissionRequired({Permissions.Constants.SYSTEM_CONFIGURATION, Permissions.Constants.SYSTEM_CONFIGURATION_UPDATE}) public Response updateConfigProperty(ConfigProperty json) { final Validator validator = super.getValidator(); failOnValidationError( @@ -115,14 +115,14 @@ public Response updateConfigProperty(ConfigProperty json) { @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) @Operation(summary = "Updates an array of config properties", - description = "

Requires permission SYSTEM_CONFIGURATION

" + description = "

Requires permission SYSTEM_CONFIGURATION or SYSTEM_CONFIGURATION_UPDATE

" ) @ApiResponses(value = { @ApiResponse(responseCode = "200", content = @Content(array = @ArraySchema(schema = @Schema(implementation = ConfigProperty.class)))), @ApiResponse(responseCode = "401", description = "Unauthorized"), @ApiResponse(responseCode = "404", description = "One or more config properties could not be found"), }) - @PermissionRequired(Permissions.Constants.SYSTEM_CONFIGURATION) + @PermissionRequired({Permissions.Constants.SYSTEM_CONFIGURATION, Permissions.Constants.SYSTEM_CONFIGURATION_UPDATE}) public Response updateConfigProperty(List list) { final Validator validator = super.getValidator(); for (ConfigProperty item : list) { diff --git a/src/main/java/org/dependencytrack/resources/v1/FindingResource.java b/src/main/java/org/dependencytrack/resources/v1/FindingResource.java index bb8b713c0..2de146f60 100644 --- a/src/main/java/org/dependencytrack/resources/v1/FindingResource.java +++ b/src/main/java/org/dependencytrack/resources/v1/FindingResource.java @@ -180,13 +180,13 @@ public Response exportFindingsByProject(@Parameter(description = "The UUID of th @Path("/portfolio/analyze") @Operation( summary = "Triggers Vulnerability Analysis for the entire portfolio", - description = "

Requires permission SYSTEM_CONFIGURATION

" + description = "

Requires permission SYSTEM_CONFIGURATION or SYSTEM_CONFIGURATION_CREATE

" ) @ApiResponses(value = { @ApiResponse(responseCode = "304", description = "Analysis is already in progress"), @ApiResponse(responseCode = "401", description = "Unauthorized") }) - @PermissionRequired(Permissions.Constants.SYSTEM_CONFIGURATION) // Require admin privileges due to system impact + @PermissionRequired({Permissions.Constants.SYSTEM_CONFIGURATION, Permissions.Constants.SYSTEM_CONFIGURATION_CREATE}) // Require admin privileges due to system impact public Response analyzePortfolio() { LOGGER.info("Portfolio analysis requested by " + super.getPrincipal().getName()); if (Event.isEventBeingProcessed(PortfolioRepositoryMetaAnalysisEvent.CHAIN_IDENTIFIER)) { diff --git a/src/main/java/org/dependencytrack/resources/v1/IntegrationResource.java b/src/main/java/org/dependencytrack/resources/v1/IntegrationResource.java index 9a1ecf9e6..d85ac6666 100644 --- a/src/main/java/org/dependencytrack/resources/v1/IntegrationResource.java +++ b/src/main/java/org/dependencytrack/resources/v1/IntegrationResource.java @@ -53,7 +53,7 @@ public class IntegrationResource extends AlpineResource { @Produces(MediaType.APPLICATION_JSON) @Operation( summary = "Returns a list of all ecosystems in OSV", - description = "

Requires permission SYSTEM_CONFIGURATION

" + description = "

Requires permission SYSTEM_CONFIGURATION or SYSTEM_CONFIGURATION_READ

" ) @ApiResponses(value = { @ApiResponse( @@ -62,7 +62,7 @@ public class IntegrationResource extends AlpineResource { ), @ApiResponse(responseCode = "401", description = "Unauthorized") }) - @PermissionRequired(Permissions.Constants.SYSTEM_CONFIGURATION) + @PermissionRequired({Permissions.Constants.SYSTEM_CONFIGURATION, Permissions.Constants.SYSTEM_CONFIGURATION_READ}) public Response getAllEcosystems() { OsvDownloadTask osvDownloadTask = new OsvDownloadTask(); final List ecosystems = osvDownloadTask.getEcosystems(); @@ -74,7 +74,7 @@ public Response getAllEcosystems() { @Produces(MediaType.APPLICATION_JSON) @Operation( summary = "Returns a list of available inactive ecosystems in OSV to be selected by user", - description = "

Requires permission SYSTEM_CONFIGURATION

" + description = "

Requires permission SYSTEM_CONFIGURATION or SYSTEM_CONFIGURATION_READ

" ) @ApiResponses(value = { @ApiResponse( @@ -83,7 +83,7 @@ public Response getAllEcosystems() { ), @ApiResponse(responseCode = "401", description = "Unauthorized") }) - @PermissionRequired(Permissions.Constants.SYSTEM_CONFIGURATION) + @PermissionRequired({Permissions.Constants.SYSTEM_CONFIGURATION, Permissions.Constants.SYSTEM_CONFIGURATION_READ}) public Response getInactiveEcosystems() { OsvDownloadTask osvDownloadTask = new OsvDownloadTask(); var selectedEcosystems = osvDownloadTask.getEnabledEcosystems(); diff --git a/src/main/java/org/dependencytrack/resources/v1/LdapResource.java b/src/main/java/org/dependencytrack/resources/v1/LdapResource.java index 2aa82838f..94a023b07 100644 --- a/src/main/java/org/dependencytrack/resources/v1/LdapResource.java +++ b/src/main/java/org/dependencytrack/resources/v1/LdapResource.java @@ -83,7 +83,7 @@ public class LdapResource extends AlpineResource { This API performs a pass-through query to the configured LDAP server. Search criteria results are cached using default Alpine CacheManager policy.

-

Requires permission ACCESS_MANAGEMENT

""" +

Requires permission ACCESS_MANAGEMENT or ACCESS_MANAGEMENT_READ

""" ) @ApiResponses(value = { @ApiResponse( @@ -93,7 +93,7 @@ public class LdapResource extends AlpineResource { ), @ApiResponse(responseCode = "401", description = "Unauthorized") }) - @PermissionRequired(Permissions.Constants.ACCESS_MANAGEMENT) + @PermissionRequired({Permissions.Constants.ACCESS_MANAGEMENT, Permissions.Constants.ACCESS_MANAGEMENT_READ}) public Response retrieveLdapGroups() { if (!LdapConnectionWrapper.LDAP_CONFIGURED) { return Response.ok().build(); @@ -131,14 +131,14 @@ public Response retrieveLdapGroups() { @Produces(MediaType.APPLICATION_JSON) @Operation( summary = "Returns the DNs of all groups mapped to the specified team", - description = "

Requires permission ACCESS_MANAGEMENT

" + description = "

Requires permission ACCESS_MANAGEMENT or ACCESS_MANAGEMENT_READ

" ) @ApiResponses(value = { @ApiResponse(responseCode = "200", content = @Content(array = @ArraySchema(schema = @Schema(implementation = MappedLdapGroup.class)))), @ApiResponse(responseCode = "401", description = "Unauthorized"), @ApiResponse(responseCode = "404", description = "The UUID of the team could not be found"), }) - @PermissionRequired(Permissions.Constants.ACCESS_MANAGEMENT) + @PermissionRequired({Permissions.Constants.ACCESS_MANAGEMENT, Permissions.Constants.ACCESS_MANAGEMENT_READ }) public Response retrieveLdapGroups(@Parameter(description = "The UUID of the team to retrieve mappings for", schema = @Schema(type = "string", format = "uuid"), required = true) @PathParam("uuid") @ValidUuid String uuid) { try (QueryManager qm = new QueryManager()) { @@ -157,7 +157,7 @@ public Response retrieveLdapGroups(@Parameter(description = "The UUID of the tea @Produces(MediaType.APPLICATION_JSON) @Operation( summary = "Adds a mapping", - description = "

Requires permission ACCESS_MANAGEMENT

" + description = "

Requires permission ACCESS_MANAGEMENT or ACCESS_MANAGEMENT_CREATE

" ) @ApiResponses(value = { @ApiResponse(responseCode = "200", content = @Content(schema = @Schema(implementation = MappedLdapGroup.class))), @@ -165,7 +165,7 @@ public Response retrieveLdapGroups(@Parameter(description = "The UUID of the tea @ApiResponse(responseCode = "404", description = "The UUID of the team could not be found"), @ApiResponse(responseCode = "409", description = "A mapping with the same team and dn already exists") }) - @PermissionRequired(Permissions.Constants.ACCESS_MANAGEMENT) + @PermissionRequired({Permissions.Constants.ACCESS_MANAGEMENT, Permissions.Constants.ACCESS_MANAGEMENT_CREATE}) public Response addMapping(MappedLdapGroupRequest request) { final Validator validator = super.getValidator(); failOnValidationError( @@ -192,14 +192,14 @@ public Response addMapping(MappedLdapGroupRequest request) { @Produces(MediaType.APPLICATION_JSON) @Operation( summary = "Removes a mapping", - description = "

Requires permission ACCESS_MANAGEMENT

" + description = "

Requires permission ACCESS_MANAGEMENT or ACCESS_MANAGEMENT_DELETE

" ) @ApiResponses(value = { @ApiResponse(responseCode = "204"), @ApiResponse(responseCode = "401", description = "Unauthorized"), @ApiResponse(responseCode = "404", description = "The UUID of the mapping could not be found"), }) - @PermissionRequired(Permissions.Constants.ACCESS_MANAGEMENT) + @PermissionRequired({Permissions.Constants.ACCESS_MANAGEMENT, Permissions.Constants.ACCESS_MANAGEMENT_DELETE}) public Response deleteMapping( @Parameter(description = "The UUID of the mapping to delete", schema = @Schema(type = "string", format = "uuid"), required = true) @PathParam("uuid") @ValidUuid String uuid) { diff --git a/src/main/java/org/dependencytrack/resources/v1/LicenseGroupResource.java b/src/main/java/org/dependencytrack/resources/v1/LicenseGroupResource.java index fd451b4c8..f3d64559f 100644 --- a/src/main/java/org/dependencytrack/resources/v1/LicenseGroupResource.java +++ b/src/main/java/org/dependencytrack/resources/v1/LicenseGroupResource.java @@ -71,7 +71,7 @@ public class LicenseGroupResource extends AlpineResource { @Produces(MediaType.APPLICATION_JSON) @Operation( summary = "Returns a list of all license groups", - description = "

Requires permission POLICY_MANAGEMENT

" + description = "

Requires permission POLICY_MANAGEMENT or POLICY_MANAGEMENT_READ

" ) @PaginatedApi @ApiResponses(value = { @@ -82,7 +82,7 @@ public class LicenseGroupResource extends AlpineResource { ), @ApiResponse(responseCode = "401", description = "Unauthorized") }) - @PermissionRequired(Permissions.Constants.POLICY_MANAGEMENT) + @PermissionRequired({Permissions.Constants.POLICY_MANAGEMENT, Permissions.Constants.POLICY_MANAGEMENT_READ}) public Response getLicenseGroups() { try (QueryManager qm = new QueryManager(getAlpineRequest())) { final PaginatedResult result = qm.getLicenseGroups(); @@ -95,13 +95,13 @@ public Response getLicenseGroups() { @Produces(MediaType.APPLICATION_JSON) @Operation( summary = "Returns a specific license group", - description = "

Requires permission POLICY_MANAGEMENT

" + description = "

Requires permission POLICY_MANAGEMENT or POLICY_MANAGEMENT_READ

" ) @ApiResponses(value = { @ApiResponse(responseCode = "401", description = "Unauthorized"), @ApiResponse(responseCode = "404", description = "The license group could not be found") }) - @PermissionRequired(Permissions.Constants.POLICY_MANAGEMENT) + @PermissionRequired({Permissions.Constants.POLICY_MANAGEMENT, Permissions.Constants.POLICY_MANAGEMENT_READ}) public Response getLicenseGroup( @Parameter(description = "The UUID of the license group to retrieve", schema = @Schema(type = "string", format = "uuid"), required = true) @PathParam("uuid") @ValidUuid String uuid) { @@ -120,14 +120,14 @@ public Response getLicenseGroup( @Produces(MediaType.APPLICATION_JSON) @Operation( summary = "Creates a new license group", - description = "

Requires permission POLICY_MANAGEMENT

" + description = "

Requires permission POLICY_MANAGEMENT or POLICY_MANAGEMENT_CREATE

" ) @ApiResponses(value = { @ApiResponse(responseCode = "201", content = @Content(schema = @Schema(implementation = LicenseGroup.class))), @ApiResponse(responseCode = "401", description = "Unauthorized"), @ApiResponse(responseCode = "409", description = "A license group with the specified name already exists") }) - @PermissionRequired(Permissions.Constants.POLICY_MANAGEMENT) + @PermissionRequired({Permissions.Constants.POLICY_MANAGEMENT, Permissions.Constants.POLICY_MANAGEMENT_CREATE}) public Response createLicenseGroup(LicenseGroup jsonLicenseGroup) { final Validator validator = super.getValidator(); failOnValidationError( @@ -150,14 +150,14 @@ public Response createLicenseGroup(LicenseGroup jsonLicenseGroup) { @Produces(MediaType.APPLICATION_JSON) @Operation( summary = "Updates a license group", - description = "

Requires permission POLICY_MANAGEMENT

" + description = "

Requires permission POLICY_MANAGEMENT or POLICY_MANAGEMENT_UPDATE

" ) @ApiResponses(value = { @ApiResponse(responseCode = "200", content = @Content(schema = @Schema(implementation = LicenseGroup.class))), @ApiResponse(responseCode = "401", description = "Unauthorized"), @ApiResponse(responseCode = "404", description = "The license group could not be found") }) - @PermissionRequired(Permissions.Constants.POLICY_MANAGEMENT) + @PermissionRequired({Permissions.Constants.POLICY_MANAGEMENT, Permissions.Constants.POLICY_MANAGEMENT_UPDATE}) public Response updateLicenseGroup(LicenseGroup jsonLicenseGroup) { final Validator validator = super.getValidator(); failOnValidationError( @@ -181,14 +181,14 @@ public Response updateLicenseGroup(LicenseGroup jsonLicenseGroup) { @Produces(MediaType.APPLICATION_JSON) @Operation( summary = "Deletes a license group", - description = "

Requires permission POLICY_MANAGEMENT

" + description = "

Requires permission POLICY_MANAGEMENT or POLICY_MANAGEMENT_DELETE

" ) @ApiResponses(value = { @ApiResponse(responseCode = "204"), @ApiResponse(responseCode = "401", description = "Unauthorized"), @ApiResponse(responseCode = "404", description = "The UUID of the license group could not be found") }) - @PermissionRequired(Permissions.Constants.POLICY_MANAGEMENT) + @PermissionRequired({Permissions.Constants.POLICY_MANAGEMENT, Permissions.Constants.POLICY_MANAGEMENT_DELETE}) public Response deleteLicenseGroup( @Parameter(description = "The UUID of the license group to delete", schema = @Schema(type = "string", format = "uuid"), required = true) @PathParam("uuid") @ValidUuid String uuid) { @@ -209,7 +209,7 @@ public Response deleteLicenseGroup( @Produces(MediaType.APPLICATION_JSON) @Operation( summary = "Adds the license to the specified license group.", - description = "

Requires permission POLICY_MANAGEMENT

" + description = "

Requires permission POLICY_MANAGEMENT or POLICY_MANAGEMENT_UPDATE

" ) @ApiResponses(value = { @ApiResponse(responseCode = "200", content = @Content(schema = @Schema(implementation = LicenseGroup.class))), @@ -217,7 +217,7 @@ public Response deleteLicenseGroup( @ApiResponse(responseCode = "401", description = "Unauthorized"), @ApiResponse(responseCode = "404", description = "The license group or license could not be found") }) - @PermissionRequired(Permissions.Constants.POLICY_MANAGEMENT) + @PermissionRequired({Permissions.Constants.POLICY_MANAGEMENT, Permissions.Constants.POLICY_MANAGEMENT_UPDATE}) public Response addLicenseToLicenseGroup( @Parameter(description = "A valid license group", schema = @Schema(type = "string", format = "uuid"), required = true) @PathParam("uuid") @ValidUuid String uuid, @@ -249,7 +249,7 @@ public Response addLicenseToLicenseGroup( @Produces(MediaType.APPLICATION_JSON) @Operation( summary = "Removes the license from the license group.", - description = "

Requires permission POLICY_MANAGEMENT

" + description = "

Requires permission POLICY_MANAGEMENT or POLICY_MANAGEMENT_UPDATE

" ) @ApiResponses(value = { @ApiResponse(responseCode = "200", content = @Content(schema = @Schema(implementation = LicenseGroup.class))), @@ -257,7 +257,7 @@ public Response addLicenseToLicenseGroup( @ApiResponse(responseCode = "401", description = "Unauthorized"), @ApiResponse(responseCode = "404", description = "The license group or license could not be found") }) - @PermissionRequired(Permissions.Constants.POLICY_MANAGEMENT) + @PermissionRequired({Permissions.Constants.POLICY_MANAGEMENT, Permissions.Constants.POLICY_MANAGEMENT_UPDATE}) public Response removeLicenseFromLicenseGroup( @Parameter(description = "A valid license group", schema = @Schema(type = "string", format = "uuid"), required = true) @PathParam("uuid") @ValidUuid String uuid, diff --git a/src/main/java/org/dependencytrack/resources/v1/LicenseResource.java b/src/main/java/org/dependencytrack/resources/v1/LicenseResource.java index f00cda358..0b1bf42e1 100644 --- a/src/main/java/org/dependencytrack/resources/v1/LicenseResource.java +++ b/src/main/java/org/dependencytrack/resources/v1/LicenseResource.java @@ -132,14 +132,14 @@ public Response getLicense( @Produces(MediaType.APPLICATION_JSON) @Operation( summary = "Creates a new custom license", - description = "

Requires permission SYSTEM_CONFIGURATION

" + description = "

Requires permission SYSTEM_CONFIGURATION or SYSTEM_CONFIGURATION_CREATE

" ) @ApiResponses(value = { @ApiResponse(responseCode = "201", content = @Content(schema = @Schema(implementation = License.class))), @ApiResponse(responseCode = "401", description = "Unauthorized"), @ApiResponse(responseCode = "409", description = "A license with the specified ID already exists.") }) - @PermissionRequired(Permissions.Constants.SYSTEM_CONFIGURATION) + @PermissionRequired({Permissions.Constants.SYSTEM_CONFIGURATION, Permissions.Constants.SYSTEM_CONFIGURATION_CREATE}) public Response createLicense(License jsonLicense) { final Validator validator = super.getValidator(); failOnValidationError( @@ -163,7 +163,7 @@ public Response createLicense(License jsonLicense) { @Produces(MediaType.APPLICATION_JSON) @Operation( summary = "Deletes a custom license", - description = "

Requires permission SYSTEM_CONFIGURATION

" + description = "

Requires permission SYSTEM_CONFIGURATION or SYSTEM_CONFIGURATION_DELETE

" ) @ApiResponses(value = { @ApiResponse(responseCode = "204"), @@ -171,7 +171,7 @@ public Response createLicense(License jsonLicense) { @ApiResponse(responseCode = "404", description = "The license could not be found"), @ApiResponse(responseCode = "409", description = "Only custom licenses can be deleted.") }) - @PermissionRequired(Permissions.Constants.SYSTEM_CONFIGURATION) + @PermissionRequired({Permissions.Constants.SYSTEM_CONFIGURATION, Permissions.Constants.SYSTEM_CONFIGURATION_DELETE}) public Response deleteLicense( @Parameter(description = "The SPDX License ID of the license to delete", required = true) @PathParam("licenseId") String licenseId) { diff --git a/src/main/java/org/dependencytrack/resources/v1/MetricsResource.java b/src/main/java/org/dependencytrack/resources/v1/MetricsResource.java index 2003a9552..073ccc325 100644 --- a/src/main/java/org/dependencytrack/resources/v1/MetricsResource.java +++ b/src/main/java/org/dependencytrack/resources/v1/MetricsResource.java @@ -162,13 +162,13 @@ public Response getPortfolioMetricsXDays( @Produces(MediaType.APPLICATION_JSON) @Operation( summary = "Requests a refresh of the portfolio metrics", - description = "

Requires permission PORTFOLIO_MANAGEMENT

" + description = "

Requires permission PORTFOLIO_MANAGEMENT or PORTFOLIO_MANAGEMENT_READ

" ) @ApiResponses(value = { @ApiResponse(responseCode = "200", content = @Content(schema = @Schema(implementation = PortfolioMetrics.class))), @ApiResponse(responseCode = "401", description = "Unauthorized") }) - @PermissionRequired(Permissions.Constants.PORTFOLIO_MANAGEMENT) + @PermissionRequired({Permissions.Constants.PORTFOLIO_MANAGEMENT, Permissions.Constants.PORTFOLIO_MANAGEMENT_READ}) public Response RefreshPortfolioMetrics() { Event.dispatch(new PortfolioMetricsUpdateEvent()); return Response.ok().build(); @@ -261,14 +261,14 @@ public Response getProjectMetricsXDays( @Produces(MediaType.APPLICATION_JSON) @Operation( summary = "Requests a refresh of a specific projects metrics", - description = "

Requires permission PORTFOLIO_MANAGEMENT

" + description = "

Requires permission PORTFOLIO_MANAGEMENT or PORTFOLIO_MANAGEMENT_READ

" ) @ApiResponses(value = { @ApiResponse(responseCode = "401", description = "Unauthorized"), @ApiResponse(responseCode = "403", description = "Access to the specified project is forbidden"), @ApiResponse(responseCode = "404", description = "The project could not be found") }) - @PermissionRequired(Permissions.Constants.PORTFOLIO_MANAGEMENT) + @PermissionRequired({Permissions.Constants.PORTFOLIO_MANAGEMENT, Permissions.Constants.PORTFOLIO_MANAGEMENT_READ}) public Response RefreshProjectMetrics( @Parameter(description = "The UUID of the project to refresh metrics on", schema = @Schema(type = "string", format = "uuid"), required = true) @PathParam("uuid") @ValidUuid String uuid) { @@ -377,14 +377,14 @@ public Response getComponentMetricsXDays( @Produces(MediaType.APPLICATION_JSON) @Operation( summary = "Requests a refresh of a specific components metrics", - description = "

Requires permission PORTFOLIO_MANAGEMENT

" + description = "

Requires permission PORTFOLIO_MANAGEMENT or PORTFOLIO_MANAGEMENT_READ

" ) @ApiResponses(value = { @ApiResponse(responseCode = "401", description = "Unauthorized"), @ApiResponse(responseCode = "403", description = "Access to the specified component is forbidden"), @ApiResponse(responseCode = "404", description = "The component could not be found") }) - @PermissionRequired(Permissions.Constants.PORTFOLIO_MANAGEMENT) + @PermissionRequired({Permissions.Constants.PORTFOLIO_MANAGEMENT, Permissions.Constants.PORTFOLIO_MANAGEMENT_READ}) public Response RefreshComponentMetrics( @Parameter(description = "The UUID of the component to refresh metrics on", schema = @Schema(type = "string", format = "uuid"), required = true) @PathParam("uuid") @ValidUuid String uuid) { diff --git a/src/main/java/org/dependencytrack/resources/v1/NotificationPublisherResource.java b/src/main/java/org/dependencytrack/resources/v1/NotificationPublisherResource.java index 93aa0df0f..3d41d6c1f 100644 --- a/src/main/java/org/dependencytrack/resources/v1/NotificationPublisherResource.java +++ b/src/main/java/org/dependencytrack/resources/v1/NotificationPublisherResource.java @@ -74,13 +74,13 @@ public class NotificationPublisherResource extends AlpineResource { @GET @Produces(MediaType.APPLICATION_JSON) @Operation(summary = "Returns a list of all notification publishers", - description = "

Requires permission SYSTEM_CONFIGURATION

" + description = "

Requires permission SYSTEM_CONFIGURATION or SYSTEM_CONFIGURATION_READ

" ) @ApiResponses(value = { @ApiResponse(responseCode = "200", content = @Content(array = @ArraySchema(schema = @Schema(implementation = NotificationPublisher.class)))), @ApiResponse(responseCode = "401", description = "Unauthorized") }) - @PermissionRequired(Permissions.Constants.SYSTEM_CONFIGURATION) + @PermissionRequired({Permissions.Constants.SYSTEM_CONFIGURATION, Permissions.Constants.SYSTEM_CONFIGURATION_READ}) public Response getAllNotificationPublishers() { try (QueryManager qm = new QueryManager()) { final List publishers = qm.getAllNotificationPublishers(); @@ -93,7 +93,7 @@ public Response getAllNotificationPublishers() { @Produces(MediaType.APPLICATION_JSON) @Operation( summary = "Creates a new notification publisher", - description = "

Requires permission SYSTEM_CONFIGURATION

" + description = "

Requires permission SYSTEM_CONFIGURATION or SYSTEM_CONFIGURATION_CREATE

" ) @ApiResponses(value = { @ApiResponse(responseCode = "201", content = @Content(schema = @Schema(implementation = NotificationPublisher.class))), @@ -101,7 +101,7 @@ public Response getAllNotificationPublishers() { @ApiResponse(responseCode = "401", description = "Unauthorized"), @ApiResponse(responseCode = "409", description = "Conflict with an existing publisher's name") }) - @PermissionRequired(Permissions.Constants.SYSTEM_CONFIGURATION) + @PermissionRequired({Permissions.Constants.SYSTEM_CONFIGURATION, Permissions.Constants.SYSTEM_CONFIGURATION_CREATE}) public Response createNotificationPublisher(NotificationPublisher jsonNotificationPublisher) { final Validator validator = super.getValidator(); failOnValidationError( @@ -140,7 +140,7 @@ public Response createNotificationPublisher(NotificationPublisher jsonNotificati @Produces(MediaType.APPLICATION_JSON) @Operation( summary = "Updates a notification publisher", - description = "

Requires permission SYSTEM_CONFIGURATION

" + description = "

Requires permission SYSTEM_CONFIGURATION or SYSTEM_CONFIGURATION_UPDATE

" ) @ApiResponses(value = { @ApiResponse(responseCode = "200", content = @Content(schema = @Schema(implementation = NotificationPublisher.class))), @@ -149,7 +149,7 @@ public Response createNotificationPublisher(NotificationPublisher jsonNotificati @ApiResponse(responseCode = "404", description = "The notification publisher could not be found"), @ApiResponse(responseCode = "409", description = "Conflict with an existing publisher's name") }) - @PermissionRequired(Permissions.Constants.SYSTEM_CONFIGURATION) + @PermissionRequired({Permissions.Constants.SYSTEM_CONFIGURATION, Permissions.Constants.SYSTEM_CONFIGURATION_UPDATE}) public Response updateNotificationPublisher(NotificationPublisher jsonNotificationPublisher) { final Validator validator = super.getValidator(); failOnValidationError( @@ -200,7 +200,7 @@ public Response updateNotificationPublisher(NotificationPublisher jsonNotificati @Produces(MediaType.APPLICATION_JSON) @Operation( summary = "Deletes a notification publisher and all related notification rules", - description = "

Requires permission SYSTEM_CONFIGURATION

" + description = "

Requires permission SYSTEM_CONFIGURATION or SYSTEM_CONFIGURATION_DELETE

" ) @ApiResponses(value = { @ApiResponse(responseCode = "204"), @@ -208,7 +208,8 @@ public Response updateNotificationPublisher(NotificationPublisher jsonNotificati @ApiResponse(responseCode = "401", description = "Unauthorized"), @ApiResponse(responseCode = "404", description = "The UUID of the notification publisher could not be found") }) - @PermissionRequired(Permissions.Constants.SYSTEM_CONFIGURATION) + @PermissionRequired({ Permissions.Constants.SYSTEM_CONFIGURATION, + Permissions.Constants.SYSTEM_CONFIGURATION_DELETE }) public Response deleteNotificationPublisher(@Parameter(description = "The UUID of the notification publisher to delete", schema = @Schema(type = "string", format = "uuid"), required = true) @PathParam("notificationPublisherUuid") @ValidUuid String notificationPublisherUuid) { try (QueryManager qm = new QueryManager()) { @@ -232,13 +233,13 @@ public Response deleteNotificationPublisher(@Parameter(description = "The UUID o @Produces(MediaType.APPLICATION_JSON) @Operation( summary = "Restore the default notification publisher templates using the ones in the solution classpath", - description = "

Requires permission SYSTEM_CONFIGURATION

" + description = "

Requires permission SYSTEM_CONFIGURATION or SYSTEM_CONFIGURATION_CREATE

" ) @ApiResponses(value = { @ApiResponse(responseCode = "200"), @ApiResponse(responseCode = "401", description = "Unauthorized") }) - @PermissionRequired(Permissions.Constants.SYSTEM_CONFIGURATION) + @PermissionRequired({Permissions.Constants.SYSTEM_CONFIGURATION, Permissions.Constants.SYSTEM_CONFIGURATION_CREATE}) public Response restoreDefaultTemplates() { try (QueryManager qm = new QueryManager()) { final ConfigProperty property = qm.getConfigProperty( diff --git a/src/main/java/org/dependencytrack/resources/v1/NotificationRuleResource.java b/src/main/java/org/dependencytrack/resources/v1/NotificationRuleResource.java index b26cd486a..fc3df4430 100644 --- a/src/main/java/org/dependencytrack/resources/v1/NotificationRuleResource.java +++ b/src/main/java/org/dependencytrack/resources/v1/NotificationRuleResource.java @@ -75,7 +75,7 @@ public class NotificationRuleResource extends AlpineResource { @GET @Produces(MediaType.APPLICATION_JSON) @Operation(summary = "Returns a list of all notification rules", - description = "

Requires permission SYSTEM_CONFIGURATION

" + description = "

Requires permission SYSTEM_CONFIGURATION or SYSTEM_CONFIGURATION_READ

" ) @PaginatedApi @ApiResponses(value = { @@ -86,7 +86,7 @@ public class NotificationRuleResource extends AlpineResource { ), @ApiResponse(responseCode = "401", description = "Unauthorized") }) - @PermissionRequired(Permissions.Constants.SYSTEM_CONFIGURATION) + @PermissionRequired({Permissions.Constants.SYSTEM_CONFIGURATION, Permissions.Constants.SYSTEM_CONFIGURATION_READ}) public Response getAllNotificationRules() { try (QueryManager qm = new QueryManager(getAlpineRequest())) { final PaginatedResult result = qm.getNotificationRules(); @@ -98,14 +98,14 @@ public Response getAllNotificationRules() { @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) @Operation(summary = "Creates a new notification rule", - description = "

Requires permission SYSTEM_CONFIGURATION

" + description = "

Requires permission SYSTEM_CONFIGURATION or SYSTEM_CONFIGURATION_CREATE

" ) @ApiResponses(value = { @ApiResponse(responseCode = "201", content = @Content(schema = @Schema(implementation = NotificationRule.class))), @ApiResponse(responseCode = "401", description = "Unauthorized"), @ApiResponse(responseCode = "404", description = "The UUID of the notification publisher could not be found") }) - @PermissionRequired(Permissions.Constants.SYSTEM_CONFIGURATION) + @PermissionRequired({Permissions.Constants.SYSTEM_CONFIGURATION, Permissions.Constants.SYSTEM_CONFIGURATION_CREATE}) public Response createNotificationRule(NotificationRule jsonRule) { final Validator validator = super.getValidator(); failOnValidationError( @@ -134,14 +134,14 @@ public Response createNotificationRule(NotificationRule jsonRule) { @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) @Operation(summary = "Updates a notification rule", - description = "

Requires permission SYSTEM_CONFIGURATION

" + description = "

Requires permission SYSTEM_CONFIGURATION or SYSTEM_CONFIGURATION_UPDATE

" ) @ApiResponses(value = { @ApiResponse(responseCode = "200", content = @Content(schema = @Schema(implementation = NotificationRule.class))), @ApiResponse(responseCode = "401", description = "Unauthorized"), @ApiResponse(responseCode = "404", description = "The UUID of the notification rule could not be found") }) - @PermissionRequired(Permissions.Constants.SYSTEM_CONFIGURATION) + @PermissionRequired({Permissions.Constants.SYSTEM_CONFIGURATION, Permissions.Constants.SYSTEM_CONFIGURATION_UPDATE}) public Response updateNotificationRule(NotificationRule jsonRule) { final Validator validator = super.getValidator(); failOnValidationError( @@ -165,14 +165,14 @@ public Response updateNotificationRule(NotificationRule jsonRule) { @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) @Operation(summary = "Deletes a notification rule", - description = "

Requires permission SYSTEM_CONFIGURATION

" + description = "

Requires permission SYSTEM_CONFIGURATION or SYSTEM_CONFIGURATION_DELETE

" ) @ApiResponses(value = { @ApiResponse(responseCode = "204"), @ApiResponse(responseCode = "401", description = "Unauthorized"), @ApiResponse(responseCode = "404", description = "The UUID of the notification rule could not be found") }) - @PermissionRequired(Permissions.Constants.SYSTEM_CONFIGURATION) + @PermissionRequired({Permissions.Constants.SYSTEM_CONFIGURATION, Permissions.Constants.SYSTEM_CONFIGURATION_DELETE}) public Response deleteNotificationRule(NotificationRule jsonRule) { try (QueryManager qm = new QueryManager()) { final NotificationRule rule = qm.getObjectByUuid(NotificationRule.class, jsonRule.getUuid()); @@ -190,7 +190,7 @@ public Response deleteNotificationRule(NotificationRule jsonRule) { @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) @Operation(summary = "Adds a project to a notification rule", - description = "

Requires permission SYSTEM_CONFIGURATION

" + description = "

Requires permission SYSTEM_CONFIGURATION or SYSTEM_CONFIGURATION_UPDATE

" ) @ApiResponses(value = { @ApiResponse(responseCode = "200", content = @Content(schema = @Schema(implementation = NotificationRule.class))), @@ -198,7 +198,7 @@ public Response deleteNotificationRule(NotificationRule jsonRule) { @ApiResponse(responseCode = "401", description = "Unauthorized"), @ApiResponse(responseCode = "404", description = "The notification rule or project could not be found") }) - @PermissionRequired(Permissions.Constants.SYSTEM_CONFIGURATION) + @PermissionRequired({Permissions.Constants.SYSTEM_CONFIGURATION, Permissions.Constants.SYSTEM_CONFIGURATION_UPDATE}) public Response addProjectToRule( @Parameter(description = "The UUID of the rule to add a project to", schema = @Schema(type = "string", format = "uuid"), required = true) @PathParam("ruleUuid") @ValidUuid String ruleUuid, @@ -231,7 +231,7 @@ public Response addProjectToRule( @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) @Operation(summary = "Removes a project from a notification rule", - description = "

Requires permission SYSTEM_CONFIGURATION

" + description = "

Requires permission SYSTEM_CONFIGURATION or SYSTEM_CONFIGURATION_DELETE

" ) @ApiResponses(value = { @ApiResponse(responseCode = "200", content = @Content(schema = @Schema(implementation = NotificationRule.class))), @@ -239,7 +239,7 @@ public Response addProjectToRule( @ApiResponse(responseCode = "401", description = "Unauthorized"), @ApiResponse(responseCode = "404", description = "The notification rule or project could not be found") }) - @PermissionRequired(Permissions.Constants.SYSTEM_CONFIGURATION) + @PermissionRequired({Permissions.Constants.SYSTEM_CONFIGURATION, Permissions.Constants.SYSTEM_CONFIGURATION_DELETE}) public Response removeProjectFromRule( @Parameter(description = "The UUID of the rule to remove the project from", schema = @Schema(type = "string", format = "uuid"), required = true) @PathParam("ruleUuid") @ValidUuid String ruleUuid, @@ -272,7 +272,7 @@ public Response removeProjectFromRule( @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) @Operation(summary = "Adds a team to a notification rule", - description = "

Requires permission SYSTEM_CONFIGURATION

" + description = "

Requires permission SYSTEM_CONFIGURATION or SYSTEM_CONFIGURATION_UPDATE

" ) @ApiResponses(value = { @ApiResponse(responseCode = "200", content = @Content(schema = @Schema(implementation = NotificationRule.class))), @@ -280,7 +280,7 @@ public Response removeProjectFromRule( @ApiResponse(responseCode = "401", description = "Unauthorized"), @ApiResponse(responseCode = "404", description = "The notification rule or team could not be found") }) - @PermissionRequired(Permissions.Constants.SYSTEM_CONFIGURATION) + @PermissionRequired({Permissions.Constants.SYSTEM_CONFIGURATION, Permissions.Constants.SYSTEM_CONFIGURATION_UPDATE}) public Response addTeamToRule( @Parameter(description = "The UUID of the rule to add a team to", schema = @Schema(type = "string", format = "uuid"), required = true) @PathParam("ruleUuid") @ValidUuid String ruleUuid, @@ -313,7 +313,7 @@ public Response addTeamToRule( @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) @Operation(summary = "Removes a team from a notification rule", - description = "

Requires permission SYSTEM_CONFIGURATION

" + description = "

Requires permission SYSTEM_CONFIGURATION or SYSTEM_CONFIGURATION_DELETE

" ) @ApiResponses(value = { @ApiResponse(responseCode = "200", content = @Content(schema = @Schema(implementation = NotificationRule.class))), @@ -321,7 +321,7 @@ public Response addTeamToRule( @ApiResponse(responseCode = "401", description = "Unauthorized"), @ApiResponse(responseCode = "404", description = "The notification rule or team could not be found") }) - @PermissionRequired(Permissions.Constants.SYSTEM_CONFIGURATION) + @PermissionRequired({Permissions.Constants.SYSTEM_CONFIGURATION, Permissions.Constants.SYSTEM_CONFIGURATION_DELETE}) public Response removeTeamFromRule( @Parameter(description = "The UUID of the rule to remove the project from", schema = @Schema(type = "string", format = "uuid"), required = true) @PathParam("ruleUuid") @ValidUuid String ruleUuid, diff --git a/src/main/java/org/dependencytrack/resources/v1/OidcResource.java b/src/main/java/org/dependencytrack/resources/v1/OidcResource.java index 91733001e..2ecc4ff80 100644 --- a/src/main/java/org/dependencytrack/resources/v1/OidcResource.java +++ b/src/main/java/org/dependencytrack/resources/v1/OidcResource.java @@ -87,13 +87,13 @@ public Response isAvailable() { @Produces(MediaType.APPLICATION_JSON) @Operation( summary = "Returns a list of all groups", - description = "

Requires permission ACCESS_MANAGEMENT

" + description = "

Requires permission ACCESS_MANAGEMENT or ACCESS_MANAGEMENT_READ

" ) @ApiResponses(value = { @ApiResponse(responseCode = "200", content = @Content(array = @ArraySchema(schema = @Schema(implementation = OidcGroup.class)))), @ApiResponse(responseCode = "401", description = "Unauthorized") }) - @PermissionRequired(Permissions.Constants.ACCESS_MANAGEMENT) + @PermissionRequired({Permissions.Constants.ACCESS_MANAGEMENT, Permissions.Constants.ACCESS_MANAGEMENT_READ}) public Response retrieveGroups() { try (QueryManager qm = new QueryManager()) { final List oidcGroups = qm.getOidcGroups(); @@ -107,13 +107,13 @@ public Response retrieveGroups() { @Consumes(MediaType.APPLICATION_JSON) @Operation( summary = "Creates group", - description = "

Requires permission ACCESS_MANAGEMENT

" + description = "

Requires permission ACCESS_MANAGEMENT or ACCESS_MANAGEMENT_CREATE

" ) @ApiResponses(value = { @ApiResponse(responseCode = "201", content = @Content(schema = @Schema(implementation = OidcGroup.class))), @ApiResponse(responseCode = "401", description = "Unauthorized") }) - @PermissionRequired(Permissions.Constants.ACCESS_MANAGEMENT) + @PermissionRequired({Permissions.Constants.ACCESS_MANAGEMENT, Permissions.Constants.ACCESS_MANAGEMENT_CREATE}) public Response createGroup(final OidcGroup jsonGroup) { final Validator validator = super.getValidator(); failOnValidationError( @@ -137,13 +137,13 @@ public Response createGroup(final OidcGroup jsonGroup) { @Consumes(MediaType.APPLICATION_JSON) @Operation( summary = "Updates group", - description = "

Requires permission ACCESS_MANAGEMENT

" + description = "

Requires permission ACCESS_MANAGEMENT or ACCESS_MANAGEMENT_UPDATE

" ) @ApiResponses(value = { @ApiResponse(responseCode = "200", content = @Content(schema = @Schema(implementation = OidcGroup.class))), @ApiResponse(responseCode = "401", description = "Unauthorized") }) - @PermissionRequired(Permissions.Constants.ACCESS_MANAGEMENT) + @PermissionRequired({Permissions.Constants.ACCESS_MANAGEMENT, Permissions.Constants.ACCESS_MANAGEMENT_UPDATE}) public Response updateGroup(final OidcGroup jsonGroup) { final Validator validator = super.getValidator(); failOnValidationError( @@ -169,14 +169,14 @@ public Response updateGroup(final OidcGroup jsonGroup) { @Consumes(MediaType.APPLICATION_JSON) @Operation( summary = "Deletes a group", - description = "

Requires permission ACCESS_MANAGEMENT

" + description = "

Requires permission ACCESS_MANAGEMENT or ACCESS_MANAGEMENT_DELETE

" ) @ApiResponses(value = { @ApiResponse(responseCode = "204"), @ApiResponse(responseCode = "401", description = "Unauthorized"), @ApiResponse(responseCode = "404", description = "The group could not be found") }) - @PermissionRequired(Permissions.Constants.ACCESS_MANAGEMENT) + @PermissionRequired({ Permissions.Constants.ACCESS_MANAGEMENT, Permissions.Constants.ACCESS_MANAGEMENT_DELETE }) public Response deleteGroup(@Parameter(description = "The UUID of the group to delete", schema = @Schema(type = "string", format = "uuid"), required = true) @PathParam("uuid") @ValidUuid final String uuid) { try (QueryManager qm = new QueryManager()) { @@ -197,14 +197,14 @@ public Response deleteGroup(@Parameter(description = "The UUID of the group to d @Produces(MediaType.APPLICATION_JSON) @Operation( summary = "Returns a list of teams associated with the specified group", - description = "

Requires permission ACCESS_MANAGEMENT

" + description = "

Requires permission ACCESS_MANAGEMENT or ACCESS_MANAGEMENT_READ

" ) @ApiResponses(value = { @ApiResponse(responseCode = "200", content = @Content(array = @ArraySchema(schema = @Schema(implementation = Team.class)))), @ApiResponse(responseCode = "401", description = "Unauthorized"), @ApiResponse(responseCode = "404", description = "The UUID of the mapping could not be found"), }) - @PermissionRequired(Permissions.Constants.ACCESS_MANAGEMENT) + @PermissionRequired({ Permissions.Constants.ACCESS_MANAGEMENT, Permissions.Constants.ACCESS_MANAGEMENT_READ }) public Response retrieveTeamsMappedToGroup(@Parameter(description = "The UUID of the mapping to retrieve the team for", schema = @Schema(type = "string", format = "uuid"), required = true) @PathParam("uuid") @ValidUuid final String uuid) { try (final QueryManager qm = new QueryManager()) { @@ -226,7 +226,7 @@ public Response retrieveTeamsMappedToGroup(@Parameter(description = "The UUID of @Produces(MediaType.APPLICATION_JSON) @Operation( summary = "Adds a mapping", - description = "

Requires permission ACCESS_MANAGEMENT

" + description = "

Requires permission ACCESS_MANAGEMENT or ACCESS_MANAGEMENT_CREATE

" ) @ApiResponses(value = { @ApiResponse(responseCode = "200", content = @Content(schema = @Schema(implementation = MappedOidcGroup.class))), @@ -234,7 +234,7 @@ public Response retrieveTeamsMappedToGroup(@Parameter(description = "The UUID of @ApiResponse(responseCode = "404", description = "The UUID of the team or group could not be found"), @ApiResponse(responseCode = "409", description = "A mapping with the same team and group name already exists") }) - @PermissionRequired(Permissions.Constants.ACCESS_MANAGEMENT) + @PermissionRequired({Permissions.Constants.ACCESS_MANAGEMENT, Permissions.Constants.ACCESS_MANAGEMENT_CREATE}) public Response addMapping(final MappedOidcGroupRequest request) { final Validator validator = super.getValidator(); failOnValidationError( @@ -268,14 +268,14 @@ public Response addMapping(final MappedOidcGroupRequest request) { @Produces(MediaType.APPLICATION_JSON) @Operation( summary = "Deletes a mapping", - description = "

Requires permission ACCESS_MANAGEMENT

" + description = "

Requires permission ACCESS_MANAGEMENT or ACCESS_MANAGEMENT_DELETE

" ) @ApiResponses(value = { @ApiResponse(responseCode = "204"), @ApiResponse(responseCode = "401", description = "Unauthorized"), @ApiResponse(responseCode = "404", description = "The UUID of the mapping could not be found"), }) - @PermissionRequired(Permissions.Constants.ACCESS_MANAGEMENT) + @PermissionRequired({ Permissions.Constants.ACCESS_MANAGEMENT, Permissions.Constants.ACCESS_MANAGEMENT_DELETE }) public Response deleteMappingByUuid(@Parameter(description = "The UUID of the mapping to delete", schema = @Schema(type = "string", format = "uuid"), required = true) @PathParam("uuid") @ValidUuid final String uuid) { try (QueryManager qm = new QueryManager()) { @@ -295,14 +295,14 @@ public Response deleteMappingByUuid(@Parameter(description = "The UUID of the ma @Produces(MediaType.APPLICATION_JSON) @Operation( summary = "Deletes a mapping", - description = "

Requires permission ACCESS_MANAGEMENT

" + description = "

Requires permission ACCESS_MANAGEMENT or ACCESS_MANAGEMENT_DELETE

" ) @ApiResponses(value = { @ApiResponse(responseCode = "204"), @ApiResponse(responseCode = "401", description = "Unauthorized"), @ApiResponse(responseCode = "404", description = "The UUID of the mapping could not be found"), }) - @PermissionRequired(Permissions.Constants.ACCESS_MANAGEMENT) + @PermissionRequired({ Permissions.Constants.ACCESS_MANAGEMENT, Permissions.Constants.ACCESS_MANAGEMENT_DELETE }) public Response deleteMapping(@Parameter(description = "The UUID of the group to delete a mapping for", schema = @Schema(type = "string", format = "uuid"), required = true) @PathParam("groupUuid") @ValidUuid final String groupUuid, @Parameter(description = "The UUID of the team to delete a mapping for", schema = @Schema(type = "string", format = "uuid"), required = true) diff --git a/src/main/java/org/dependencytrack/resources/v1/PermissionResource.java b/src/main/java/org/dependencytrack/resources/v1/PermissionResource.java index 41f6243a2..fc4875b9d 100644 --- a/src/main/java/org/dependencytrack/resources/v1/PermissionResource.java +++ b/src/main/java/org/dependencytrack/resources/v1/PermissionResource.java @@ -69,13 +69,13 @@ public class PermissionResource extends AlpineResource { @Produces(MediaType.APPLICATION_JSON) @Operation( summary = "Returns a list of all permissions", - description = "

Requires permission ACCESS_MANAGEMENT

" + description = "

Requires permission ACCESS_MANAGEMENT or ACCESS_MANAGEMENT_READ

" ) @ApiResponses(value = { @ApiResponse(responseCode = "200", content = @Content(schema = @Schema(implementation = Permissions.class))), @ApiResponse(responseCode = "401", description = "Unauthorized") }) - @PermissionRequired(Permissions.Constants.ACCESS_MANAGEMENT) + @PermissionRequired({Permissions.Constants.ACCESS_MANAGEMENT, Permissions.Constants.ACCESS_MANAGEMENT_READ}) public Response getAllPermissions() { try (QueryManager qm = new QueryManager()) { final List permissions = qm.getPermissions(); @@ -89,7 +89,7 @@ public Response getAllPermissions() { @Produces(MediaType.APPLICATION_JSON) @Operation( summary = "Adds the permission to the specified username.", - description = "

Requires permission ACCESS_MANAGEMENT

" + description = "

Requires permission ACCESS_MANAGEMENT or ACCESS_MANAGEMENT_UPDATE

" ) @ApiResponses(value = { @ApiResponse(responseCode = "200", content = @Content(schema = @Schema(implementation = UserPrincipal.class))), @@ -97,7 +97,7 @@ public Response getAllPermissions() { @ApiResponse(responseCode = "401", description = "Unauthorized"), @ApiResponse(responseCode = "404", description = "The user could not be found") }) - @PermissionRequired(Permissions.Constants.ACCESS_MANAGEMENT) + @PermissionRequired({Permissions.Constants.ACCESS_MANAGEMENT, Permissions.Constants.ACCESS_MANAGEMENT_UPDATE}) public Response addPermissionToUser( @Parameter(description = "A valid username", required = true) @PathParam("username") String username, @@ -130,7 +130,7 @@ public Response addPermissionToUser( @Produces(MediaType.APPLICATION_JSON) @Operation( summary = "Removes the permission from the user.", - description = "

Requires permission ACCESS_MANAGEMENT

" + description = "

Requires permission ACCESS_MANAGEMENT or ACCESS_MANAGEMENT_DELETE

" ) @ApiResponses(value = { @ApiResponse(responseCode = "200", content = @Content(schema = @Schema(implementation = UserPrincipal.class))), @@ -138,7 +138,7 @@ public Response addPermissionToUser( @ApiResponse(responseCode = "401", description = "Unauthorized"), @ApiResponse(responseCode = "404", description = "The user could not be found") }) - @PermissionRequired(Permissions.Constants.ACCESS_MANAGEMENT) + @PermissionRequired({Permissions.Constants.ACCESS_MANAGEMENT, Permissions.Constants.ACCESS_MANAGEMENT_DELETE}) public Response removePermissionFromUser( @Parameter(description = "A valid username", required = true) @PathParam("username") String username, @@ -170,7 +170,7 @@ public Response removePermissionFromUser( @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) @Operation( - description = "

Requires permission ACCESS_MANAGEMENT

" + description = "

Requires permission ACCESS_MANAGEMENT or ACCESS_MANAGEMENT_UPDATE

" ) @ApiResponses(value = { @ApiResponse(responseCode = "200", content = @Content(schema = @Schema(implementation = Team.class))), @@ -178,7 +178,7 @@ public Response removePermissionFromUser( @ApiResponse(responseCode = "401", description = "Unauthorized"), @ApiResponse(responseCode = "404", description = "The team could not be found") }) - @PermissionRequired(Permissions.Constants.ACCESS_MANAGEMENT) + @PermissionRequired({Permissions.Constants.ACCESS_MANAGEMENT, Permissions.Constants.ACCESS_MANAGEMENT_UPDATE}) public Response addPermissionToTeam( @Parameter(description = "A valid team uuid", schema = @Schema(type = "string", format = "uuid"), required = true) @PathParam("uuid") @ValidUuid String uuid, @@ -210,7 +210,7 @@ public Response addPermissionToTeam( @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) @Operation( - description = "

Requires permission ACCESS_MANAGEMENT

" + description = "

Requires permission ACCESS_MANAGEMENT or ACCESS_MANAGEMENT_DELETE

" ) @ApiResponses(value = { @ApiResponse(responseCode = "204", content = @Content(schema = @Schema(implementation = Team.class))), @@ -218,7 +218,7 @@ public Response addPermissionToTeam( @ApiResponse(responseCode = "401", description = "Unauthorized"), @ApiResponse(responseCode = "404", description = "The team could not be found") }) - @PermissionRequired(Permissions.Constants.ACCESS_MANAGEMENT) + @PermissionRequired({Permissions.Constants.ACCESS_MANAGEMENT, Permissions.Constants.ACCESS_MANAGEMENT_DELETE}) public Response removePermissionFromTeam( @Parameter(description = "A valid team uuid", schema = @Schema(type = "string", format = "uuid"), required = true) @PathParam("uuid") @ValidUuid String uuid, diff --git a/src/main/java/org/dependencytrack/resources/v1/PolicyConditionResource.java b/src/main/java/org/dependencytrack/resources/v1/PolicyConditionResource.java index a6004128a..20f9b644e 100644 --- a/src/main/java/org/dependencytrack/resources/v1/PolicyConditionResource.java +++ b/src/main/java/org/dependencytrack/resources/v1/PolicyConditionResource.java @@ -77,15 +77,15 @@ public class PolicyConditionResource extends AlpineResource { @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) @Operation( - summary = "Creates a new policy condition", - description = "

Requires permission POLICY_MANAGEMENT

" + summary = "Creates a new policy condition for an existing policy", + description = "

Requires permission POLICY_MANAGEMENT or POLICY_MANAGEMENT_UPDATE

" ) @ApiResponses(value = { @ApiResponse(responseCode = "201", content = @Content(schema = @Schema(implementation = PolicyCondition.class))), @ApiResponse(responseCode = "401", description = "Unauthorized"), @ApiResponse(responseCode = "404", description = "The UUID of the policy could not be found") }) - @PermissionRequired(Permissions.Constants.POLICY_MANAGEMENT) + @PermissionRequired({Permissions.Constants.POLICY_MANAGEMENT, Permissions.Constants.POLICY_MANAGEMENT_UPDATE}) public Response createPolicyCondition( @Parameter(description = "The UUID of the policy", schema = @Schema(type = "string", format = "uuid"), required = true) @PathParam("uuid") @ValidUuid String uuid, @@ -114,7 +114,7 @@ public Response createPolicyCondition( @Produces(MediaType.APPLICATION_JSON) @Operation( summary = "Updates a policy condition", - description = "

Requires permission POLICY_MANAGEMENT

" + description = "

Requires permission POLICY_MANAGEMENT or POLICY_MANAGEMENT_UPDATE

" ) @ApiResponses(value = { @ApiResponse(responseCode = "200", content = @Content(schema = @Schema(implementation = PolicyCondition.class))), @@ -122,7 +122,7 @@ public Response createPolicyCondition( @ApiResponse(responseCode = "401", description = "Unauthorized"), @ApiResponse(responseCode = "404", description = "The UUID of the policy condition could not be found") }) - @PermissionRequired(Permissions.Constants.POLICY_MANAGEMENT) + @PermissionRequired({Permissions.Constants.POLICY_MANAGEMENT, Permissions.Constants.POLICY_MANAGEMENT_UPDATE}) public Response updatePolicyCondition(PolicyCondition jsonPolicyCondition) { final Validator validator = super.getValidator(); failOnValidationError( @@ -145,15 +145,15 @@ public Response updatePolicyCondition(PolicyCondition jsonPolicyCondition) { @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) @Operation( - summary = "Deletes a policy condition", - description = "

Requires permission POLICY_MANAGEMENT

" + summary = "Deletes a policy condition from an existing policy", + description = "

Requires permission POLICY_MANAGEMENT or POLICY_MANAGEMENT_UPDATE

" ) @ApiResponses(value = { @ApiResponse(responseCode = "204"), @ApiResponse(responseCode = "401", description = "Unauthorized"), @ApiResponse(responseCode = "404", description = "The UUID of the policy condition could not be found") }) - @PermissionRequired(Permissions.Constants.POLICY_MANAGEMENT) + @PermissionRequired({Permissions.Constants.POLICY_MANAGEMENT, Permissions.Constants.POLICY_MANAGEMENT_UPDATE}) public Response deletePolicyCondition( @Parameter(description = "The UUID of the policy condition to delete", schema = @Schema(type = "string", format = "uuid"), required = true) @PathParam("uuid") @ValidUuid String uuid) { diff --git a/src/main/java/org/dependencytrack/resources/v1/PolicyResource.java b/src/main/java/org/dependencytrack/resources/v1/PolicyResource.java index fc967c1db..9a4aef9f0 100644 --- a/src/main/java/org/dependencytrack/resources/v1/PolicyResource.java +++ b/src/main/java/org/dependencytrack/resources/v1/PolicyResource.java @@ -71,7 +71,7 @@ public class PolicyResource extends AlpineResource { @Produces(MediaType.APPLICATION_JSON) @Operation( summary = "Returns a list of all policies", - description = "

Requires permission POLICY_MANAGEMENT

" + description = "

Requires permission POLICY_MANAGEMENT or POLICY_MANAGEMENT_READ

" ) @PaginatedApi @ApiResponses(value = { @@ -82,7 +82,7 @@ public class PolicyResource extends AlpineResource { ), @ApiResponse(responseCode = "401", description = "Unauthorized") }) - @PermissionRequired(Permissions.Constants.POLICY_MANAGEMENT) + @PermissionRequired({Permissions.Constants.POLICY_MANAGEMENT, Permissions.Constants.POLICY_MANAGEMENT_READ}) public Response getPolicies() { try (QueryManager qm = new QueryManager(getAlpineRequest())) { final PaginatedResult result = qm.getPolicies(); @@ -95,14 +95,14 @@ public Response getPolicies() { @Produces(MediaType.APPLICATION_JSON) @Operation( summary = "Returns a specific policy" - , description = "

Requires permission POLICY_MANAGEMENT

" + , description = "

Requires permission POLICY_MANAGEMENT or POLICY_MANAGEMENT_READ

" ) @ApiResponses(value = { @ApiResponse(responseCode = "200", content = @Content(schema = @Schema(implementation = Policy.class))), @ApiResponse(responseCode = "401", description = "Unauthorized"), @ApiResponse(responseCode = "404", description = "The policy could not be found") }) - @PermissionRequired(Permissions.Constants.POLICY_MANAGEMENT) + @PermissionRequired({Permissions.Constants.POLICY_MANAGEMENT, Permissions.Constants.POLICY_MANAGEMENT_READ}) public Response getPolicy( @Parameter(description = "The UUID of the policy to retrieve", schema = @Schema(type = "string", format = "uuid"), required = true) @PathParam("uuid") @ValidUuid String uuid) { @@ -121,14 +121,14 @@ public Response getPolicy( @Produces(MediaType.APPLICATION_JSON) @Operation( summary = "Creates a new policy", - description = "

Requires permission POLICY_MANAGEMENT

" + description = "

Requires permission POLICY_MANAGEMENT or POLICY_MANAGEMENT_CREATE

" ) @ApiResponses(value = { @ApiResponse(responseCode = "201", content = @Content(schema = @Schema(implementation = Policy.class))), @ApiResponse(responseCode = "401", description = "Unauthorized"), @ApiResponse(responseCode = "409", description = "A policy with the specified name already exists") }) - @PermissionRequired(Permissions.Constants.POLICY_MANAGEMENT) + @PermissionRequired({Permissions.Constants.POLICY_MANAGEMENT, Permissions.Constants.POLICY_MANAGEMENT_CREATE}) public Response createPolicy(Policy jsonPolicy) { final Validator validator = super.getValidator(); failOnValidationError( @@ -161,14 +161,14 @@ public Response createPolicy(Policy jsonPolicy) { @Produces(MediaType.APPLICATION_JSON) @Operation( summary = "Updates a policy", - description = "

Requires permission POLICY_MANAGEMENT

" + description = "

Requires permission POLICY_MANAGEMENT or POLICY_MANAGEMENT_UPDATE

" ) @ApiResponses(value = { @ApiResponse(responseCode = "200", content = @Content(schema = @Schema(implementation = Policy.class))), @ApiResponse(responseCode = "401", description = "Unauthorized"), @ApiResponse(responseCode = "404", description = "The policy could not be found") }) - @PermissionRequired(Permissions.Constants.POLICY_MANAGEMENT) + @PermissionRequired({Permissions.Constants.POLICY_MANAGEMENT, Permissions.Constants.POLICY_MANAGEMENT_UPDATE}) public Response updatePolicy(Policy jsonPolicy) { final Validator validator = super.getValidator(); failOnValidationError( @@ -195,14 +195,14 @@ public Response updatePolicy(Policy jsonPolicy) { @Produces(MediaType.APPLICATION_JSON) @Operation( summary = "Deletes a policy" - , description = "

Requires permission POLICY_MANAGEMENT

" + , description = "

Requires permission POLICY_MANAGEMENT or POLICY_MANAGEMENT_DELETE

" ) @ApiResponses(value = { @ApiResponse(responseCode = "204"), @ApiResponse(responseCode = "401", description = "Unauthorized"), @ApiResponse(responseCode = "404", description = "The UUID of the policy could not be found") }) - @PermissionRequired(Permissions.Constants.POLICY_MANAGEMENT) + @PermissionRequired({Permissions.Constants.POLICY_MANAGEMENT, Permissions.Constants.POLICY_MANAGEMENT_DELETE}) public Response deletePolicy( @Parameter(description = "The UUID of the policy to delete", schema = @Schema(type = "string", format = "uuid"), required = true) @PathParam("uuid") @ValidUuid String uuid) { @@ -223,7 +223,7 @@ public Response deletePolicy( @Produces(MediaType.APPLICATION_JSON) @Operation( summary = "Adds a project to a policy", - description = "

Requires permission POLICY_MANAGEMENT

" + description = "

Requires permission POLICY_MANAGEMENT or POLICY_MANAGEMENT_UPDATE

" ) @ApiResponses(value = { @ApiResponse(responseCode = "200", content = @Content(schema = @Schema(implementation = Policy.class))), @@ -231,7 +231,7 @@ public Response deletePolicy( @ApiResponse(responseCode = "401", description = "Unauthorized"), @ApiResponse(responseCode = "404", description = "The policy or project could not be found") }) - @PermissionRequired(Permissions.Constants.POLICY_MANAGEMENT) + @PermissionRequired({Permissions.Constants.POLICY_MANAGEMENT, Permissions.Constants.POLICY_MANAGEMENT_UPDATE}) public Response addProjectToPolicy( @Parameter(description = "The UUID of the policy to add a project to", schema = @Schema(type = "string", format = "uuid"), required = true) @PathParam("policyUuid") @ValidUuid String policyUuid, @@ -262,7 +262,7 @@ public Response addProjectToPolicy( @Produces(MediaType.APPLICATION_JSON) @Operation( summary = "Removes a project from a policy", - description = "

Requires permission POLICY_MANAGEMENT

" + description = "

Requires permission POLICY_MANAGEMENT or POLICY_MANAGEMENT_DELETE

" ) @ApiResponses(value = { @ApiResponse(responseCode = "204", content = @Content(schema = @Schema(implementation = Policy.class))), @@ -270,7 +270,7 @@ public Response addProjectToPolicy( @ApiResponse(responseCode = "401", description = "Unauthorized"), @ApiResponse(responseCode = "404", description = "The policy or project could not be found") }) - @PermissionRequired(Permissions.Constants.POLICY_MANAGEMENT) + @PermissionRequired({Permissions.Constants.POLICY_MANAGEMENT, Permissions.Constants.POLICY_MANAGEMENT_DELETE}) public Response removeProjectFromPolicy( @Parameter(description = "The UUID of the policy to remove the project from", schema = @Schema(type = "string", format = "uuid"), required = true) @PathParam("policyUuid") @ValidUuid String policyUuid, @@ -301,7 +301,7 @@ public Response removeProjectFromPolicy( @Produces(MediaType.APPLICATION_JSON) @Operation( summary = "Adds a tag to a policy", - description = "

Requires permission POLICY_MANAGEMENT

" + description = "

Requires permission POLICY_MANAGEMENT or POLICY_MANAGEMENT_UPDATE

" ) @ApiResponses(value = { @ApiResponse(responseCode = "200", content = @Content(schema = @Schema(implementation = Policy.class))), @@ -309,7 +309,7 @@ public Response removeProjectFromPolicy( @ApiResponse(responseCode = "401", description = "Unauthorized"), @ApiResponse(responseCode = "404", description = "The policy or tag could not be found") }) - @PermissionRequired(Permissions.Constants.POLICY_MANAGEMENT) + @PermissionRequired({Permissions.Constants.POLICY_MANAGEMENT, Permissions.Constants.POLICY_MANAGEMENT_UPDATE}) public Response addTagToPolicy( @Parameter(description = "The UUID of the policy to add a project to", schema = @Schema(type = "string", format = "uuid"), required = true) @PathParam("policyUuid") @ValidUuid String policyUuid, @@ -341,7 +341,7 @@ public Response addTagToPolicy( @Produces(MediaType.APPLICATION_JSON) @Operation( summary = "Removes a tag from a policy", - description = "

Requires permission POLICY_MANAGEMENT

" + description = "

Requires permission POLICY_MANAGEMENT or POLICY_MANAGEMENT_DELETE

" ) @ApiResponses(value = { @ApiResponse(responseCode = "204", content = @Content(schema = @Schema(implementation = Policy.class))), @@ -349,7 +349,7 @@ public Response addTagToPolicy( @ApiResponse(responseCode = "401", description = "Unauthorized"), @ApiResponse(responseCode = "404", description = "The policy or tag could not be found") }) - @PermissionRequired(Permissions.Constants.POLICY_MANAGEMENT) + @PermissionRequired({Permissions.Constants.POLICY_MANAGEMENT, Permissions.Constants.POLICY_MANAGEMENT_DELETE}) public Response removeTagFromPolicy( @Parameter(description = "The UUID of the policy to remove the tag from", schema = @Schema(type = "string", format = "uuid"), required = true) @PathParam("policyUuid") @ValidUuid String policyUuid, diff --git a/src/main/java/org/dependencytrack/resources/v1/ProjectPropertyResource.java b/src/main/java/org/dependencytrack/resources/v1/ProjectPropertyResource.java index b0633422d..487d07ec2 100644 --- a/src/main/java/org/dependencytrack/resources/v1/ProjectPropertyResource.java +++ b/src/main/java/org/dependencytrack/resources/v1/ProjectPropertyResource.java @@ -67,7 +67,7 @@ public class ProjectPropertyResource extends AbstractConfigPropertyResource { @Produces(MediaType.APPLICATION_JSON) @Operation( summary = "Returns a list of all ProjectProperties for the specified project", - description = "

Requires permission PORTFOLIO_MANAGEMENT

" + description = "

Requires permission PORTFOLIO_MANAGEMENT or PORTFOLIO_MANAGEMENT_READ

" ) @ApiResponses(value = { @ApiResponse(responseCode = "200", content = @Content(array = @ArraySchema(schema = @Schema(implementation = ProjectProperty.class)))), @@ -75,7 +75,7 @@ public class ProjectPropertyResource extends AbstractConfigPropertyResource { @ApiResponse(responseCode = "403", description = "Access to the specified project is forbidden"), @ApiResponse(responseCode = "404", description = "The project could not be found") }) - @PermissionRequired(Permissions.Constants.PORTFOLIO_MANAGEMENT) + @PermissionRequired({Permissions.Constants.PORTFOLIO_MANAGEMENT, Permissions.Constants.PORTFOLIO_MANAGEMENT_READ}) public Response getProperties( @Parameter(description = "The UUID of the project to retrieve properties for", schema = @Schema(type = "string", format = "uuid"), required = true) @PathParam("uuid") @ValidUuid String uuid) { @@ -109,7 +109,7 @@ public Response getProperties( @Produces(MediaType.APPLICATION_JSON) @Operation( summary = "Creates a new project property", - description = "

Requires permission PORTFOLIO_MANAGEMENT

" + description = "

Requires permission PORTFOLIO_MANAGEMENT or PORTFOLIO_MANAGEMENT_UPDATE

" ) @ApiResponses(value = { @ApiResponse(responseCode = "201", content = @Content(schema = @Schema(implementation = ProjectProperty.class))), @@ -118,7 +118,7 @@ public Response getProperties( @ApiResponse(responseCode = "404", description = "The project could not be found"), @ApiResponse(responseCode = "409", description = "A property with the specified project/group/name combination already exists") }) - @PermissionRequired(Permissions.Constants.PORTFOLIO_MANAGEMENT) + @PermissionRequired({Permissions.Constants.PORTFOLIO_MANAGEMENT, Permissions.Constants.PORTFOLIO_MANAGEMENT_UPDATE}) public Response createProperty( @Parameter(description = "The UUID of the project to create a property for", schema = @Schema(type = "string", format = "uuid"), required = true) @PathParam("uuid") @ValidUuid String uuid, @@ -165,7 +165,7 @@ public Response createProperty( @Produces(MediaType.APPLICATION_JSON) @Operation( summary = "Updates a project property", - description = "

Requires permission PORTFOLIO_MANAGEMENT

" + description = "

Requires permission PORTFOLIO_MANAGEMENT or PORTFOLIO_MANAGEMENT_UPDATE

" ) @ApiResponses(value = { @ApiResponse(responseCode = "200", content = @Content(schema = @Schema(implementation = ProjectProperty.class))), @@ -173,7 +173,7 @@ public Response createProperty( @ApiResponse(responseCode = "403", description = "Access to the specified project is forbidden"), @ApiResponse(responseCode = "404", description = "The project could not be found"), }) - @PermissionRequired(Permissions.Constants.PORTFOLIO_MANAGEMENT) + @PermissionRequired({Permissions.Constants.PORTFOLIO_MANAGEMENT, Permissions.Constants.PORTFOLIO_MANAGEMENT_UPDATE}) public Response updateProperty( @Parameter(description = "The UUID of the project to create a property for", schema = @Schema(type = "string", format = "uuid"), required = true) @PathParam("uuid") @ValidUuid String uuid, @@ -208,7 +208,7 @@ public Response updateProperty( @Produces(MediaType.APPLICATION_JSON) @Operation( summary = "Deletes a config property", - description = "

Requires permission PORTFOLIO_MANAGEMENT

" + description = "

Requires permission PORTFOLIO_MANAGEMENT or PORTFOLIO_MANAGEMENT_DELETE

" ) @ApiResponses(value = { @ApiResponse(responseCode = "204"), @@ -216,7 +216,7 @@ public Response updateProperty( @ApiResponse(responseCode = "403", description = "Access to the specified project is forbidden"), @ApiResponse(responseCode = "404", description = "The project or project property could not be found"), }) - @PermissionRequired(Permissions.Constants.PORTFOLIO_MANAGEMENT) + @PermissionRequired({Permissions.Constants.PORTFOLIO_MANAGEMENT, Permissions.Constants.PORTFOLIO_MANAGEMENT_DELETE}) public Response deleteProperty( @Parameter(description = "The UUID of the project to delete a property from", schema = @Schema(type = "string", format = "uuid"), required = true) @PathParam("uuid") @ValidUuid String uuid, diff --git a/src/main/java/org/dependencytrack/resources/v1/ProjectResource.java b/src/main/java/org/dependencytrack/resources/v1/ProjectResource.java index 8cf412017..b968e8b0a 100644 --- a/src/main/java/org/dependencytrack/resources/v1/ProjectResource.java +++ b/src/main/java/org/dependencytrack/resources/v1/ProjectResource.java @@ -220,6 +220,7 @@ public Response getProjectChildrenConcise( @ApiResponse(responseCode = "403", description = "Access to the specified project is forbidden"), @ApiResponse(responseCode = "404", description = "The project could not be found") }) + @PermissionRequired(Permissions.Constants.VIEW_PORTFOLIO) public Response getProject( @Parameter(description = "The UUID of the project to retrieve", schema = @Schema(type = "string", format = "uuid"), required = true) @@ -343,7 +344,7 @@ public Response getProjectsByClassifier( summary = "Creates a new project", description = """

If a parent project exists, parent.uuid is required

-

Requires permission PORTFOLIO_MANAGEMENT

""" +

Requires permission PORTFOLIO_MANAGEMENT or PORTFOLIO_MANAGEMENT_CREATE

""" ) @ApiResponses(value = { @ApiResponse(responseCode = "201", content = @Content(schema = @Schema(implementation = Project.class))), @@ -354,7 +355,7 @@ public Response getProjectsByClassifier(
  • A project with the specified name already exists
  • """), }) - @PermissionRequired(Permissions.Constants.PORTFOLIO_MANAGEMENT) + @PermissionRequired({Permissions.Constants.PORTFOLIO_MANAGEMENT, Permissions.Constants.PORTFOLIO_MANAGEMENT_CREATE}) public Response createProject(Project jsonProject) { final Validator validator = super.getValidator(); failOnValidationError( @@ -403,7 +404,7 @@ public Response createProject(Project jsonProject) { @Produces(MediaType.APPLICATION_JSON) @Operation( summary = "Updates a project", - description = "

    Requires permission PORTFOLIO_MANAGEMENT

    " + description = "

    Requires permission PORTFOLIO_MANAGEMENT or PORTFOLIO_MANAGEMENT_UPDATE

    " ) @ApiResponses(value = { @ApiResponse(responseCode = "200", content = @Content(schema = @Schema(implementation = Project.class))), @@ -417,7 +418,7 @@ public Response createProject(Project jsonProject) {
  • A project cannot select itself as a parent
  • """) }) - @PermissionRequired(Permissions.Constants.PORTFOLIO_MANAGEMENT) + @PermissionRequired({Permissions.Constants.PORTFOLIO_MANAGEMENT, Permissions.Constants.PORTFOLIO_MANAGEMENT_UPDATE}) public Response updateProject(Project jsonProject) { final Validator validator = super.getValidator(); failOnValidationError( @@ -473,7 +474,7 @@ public Response updateProject(Project jsonProject) { @Produces(MediaType.APPLICATION_JSON) @Operation( summary = "Partially updates a project", - description = "

    Requires permission PORTFOLIO_MANAGEMENT

    " + description = "

    Requires permission PORTFOLIO_MANAGEMENT or PORTFOLIO_MANAGEMENT_UPDATE

    " ) @ApiResponses(value = { @ApiResponse(responseCode = "200", content = @Content(schema = @Schema(implementation = Project.class))), @@ -487,7 +488,7 @@ public Response updateProject(Project jsonProject) {
  • A project cannot select itself as a parent
  • """) }) - @PermissionRequired(Permissions.Constants.PORTFOLIO_MANAGEMENT) + @PermissionRequired({Permissions.Constants.PORTFOLIO_MANAGEMENT, Permissions.Constants.PORTFOLIO_MANAGEMENT_UPDATE}) public Response patchProject( @Parameter(description = "The UUID of the project to modify", schema = @Schema(type = "string", format = "uuid"), required = true) @PathParam("uuid") @ValidUuid String uuid, @@ -609,7 +610,7 @@ private boolean setIfDifferent(final Project source, final Project target, f @Produces(MediaType.APPLICATION_JSON) @Operation( summary = "Deletes a project", - description = "

    Requires permission PORTFOLIO_MANAGEMENT

    " + description = "

    Requires permission PORTFOLIO_MANAGEMENT or PORTFOLIO_MANAGEMENT_DELETE

    " ) @ApiResponses(value = { @ApiResponse(responseCode = "204"), @@ -618,7 +619,7 @@ private boolean setIfDifferent(final Project source, final Project target, f @ApiResponse(responseCode = "404", description = "The UUID of the project could not be found"), @ApiResponse(responseCode = "500", description = "Unable to delete components of the project") }) - @PermissionRequired(Permissions.Constants.PORTFOLIO_MANAGEMENT) + @PermissionRequired({Permissions.Constants.PORTFOLIO_MANAGEMENT, Permissions.Constants.PORTFOLIO_MANAGEMENT_DELETE}) public Response deleteProject( @Parameter(description = "The UUID of the project to delete", schema = @Schema(type = "string", format = "uuid"), required = true) @PathParam("uuid") @ValidUuid String uuid) { @@ -646,14 +647,14 @@ public Response deleteProject( @Produces(MediaType.APPLICATION_JSON) @Operation( summary = "Clones a project", - description = "

    Requires permission PORTFOLIO_MANAGEMENT

    " + description = "

    Requires permission PORTFOLIO_MANAGEMENT or PORTFOLIO_MANAGEMENT_CREATE

    " ) @ApiResponses(value = { @ApiResponse(responseCode = "200", content = @Content(schema = @Schema(implementation = Project.class))), @ApiResponse(responseCode = "401", description = "Unauthorized"), @ApiResponse(responseCode = "404", description = "The UUID of the project could not be found") }) - @PermissionRequired(Permissions.Constants.PORTFOLIO_MANAGEMENT) + @PermissionRequired({Permissions.Constants.PORTFOLIO_MANAGEMENT, Permissions.Constants.PORTFOLIO_MANAGEMENT_CREATE}) public Response cloneProject(CloneProjectRequest jsonRequest) { final Validator validator = super.getValidator(); failOnValidationError( diff --git a/src/main/java/org/dependencytrack/resources/v1/RepositoryResource.java b/src/main/java/org/dependencytrack/resources/v1/RepositoryResource.java index 2c9764dc7..64d2c1d4d 100644 --- a/src/main/java/org/dependencytrack/resources/v1/RepositoryResource.java +++ b/src/main/java/org/dependencytrack/resources/v1/RepositoryResource.java @@ -76,7 +76,7 @@ public class RepositoryResource extends AlpineResource { @Produces(MediaType.APPLICATION_JSON) @Operation( summary = "Returns a list of all repositories", - description = "

    Requires permission SYSTEM_CONFIGURATION

    " + description = "

    Requires permission SYSTEM_CONFIGURATION or SYSTEM_CONFIGURATION_READ

    " ) @PaginatedApi @ApiResponses(value = { @@ -86,7 +86,7 @@ public class RepositoryResource extends AlpineResource { ), @ApiResponse(responseCode = "401", description = "Unauthorized") }) - @PermissionRequired(Permissions.Constants.SYSTEM_CONFIGURATION) + @PermissionRequired({Permissions.Constants.SYSTEM_CONFIGURATION, Permissions.Constants.SYSTEM_CONFIGURATION_READ}) public Response getRepositories() { try (QueryManager qm = new QueryManager(getAlpineRequest())) { final PaginatedResult result = qm.getRepositories(); @@ -99,7 +99,7 @@ public Response getRepositories() { @Produces(MediaType.APPLICATION_JSON) @Operation( summary = "Returns repositories that support the specific type", - description = "

    Requires permission SYSTEM_CONFIGURATION

    " + description = "

    Requires permission SYSTEM_CONFIGURATION or SYSTEM_CONFIGURATION_READ

    " ) @PaginatedApi @ApiResponses(value = { @@ -110,7 +110,7 @@ public Response getRepositories() { ), @ApiResponse(responseCode = "401", description = "Unauthorized") }) - @PermissionRequired(Permissions.Constants.SYSTEM_CONFIGURATION) + @PermissionRequired({Permissions.Constants.SYSTEM_CONFIGURATION, Permissions.Constants.SYSTEM_CONFIGURATION_READ}) public Response getRepositoriesByType( @Parameter(description = "The type of repositories to retrieve", required = true) @PathParam("type") RepositoryType type) { @@ -162,14 +162,14 @@ public Response getRepositoryMetaComponent( @Produces(MediaType.APPLICATION_JSON) @Operation( summary = "Creates a new repository", - description = "

    Requires permission SYSTEM_CONFIGURATION

    " + description = "

    Requires permission SYSTEM_CONFIGURATION or SYSTEM_CONFIGURATION_CREATE

    " ) @ApiResponses(value = { @ApiResponse(responseCode = "201", content = @Content(schema = @Schema(implementation = Repository.class))), @ApiResponse(responseCode = "401", description = "Unauthorized"), @ApiResponse(responseCode = "409", description = "A repository with the specified identifier already exists") }) - @PermissionRequired(Permissions.Constants.SYSTEM_CONFIGURATION) + @PermissionRequired({Permissions.Constants.SYSTEM_CONFIGURATION, Permissions.Constants.SYSTEM_CONFIGURATION_CREATE}) public Response createRepository(Repository jsonRepository) { final Validator validator = super.getValidator(); failOnValidationError( @@ -204,14 +204,14 @@ public Response createRepository(Repository jsonRepository) { @Produces(MediaType.APPLICATION_JSON) @Operation( summary = "Updates a repository", - description = "

    Requires permission SYSTEM_CONFIGURATION

    " + description = "

    Requires permission SYSTEM_CONFIGURATION or SYSTEM_CONFIGURATION_UPDATE

    " ) @ApiResponses(value = { @ApiResponse(responseCode = "200", content = @Content(schema = @Schema(implementation = Repository.class))), @ApiResponse(responseCode = "401", description = "Unauthorized"), @ApiResponse(responseCode = "404", description = "The UUID of the repository could not be found") }) - @PermissionRequired(Permissions.Constants.SYSTEM_CONFIGURATION) + @PermissionRequired({Permissions.Constants.SYSTEM_CONFIGURATION, Permissions.Constants.SYSTEM_CONFIGURATION_UPDATE}) public Response updateRepository(Repository jsonRepository) { final Validator validator = super.getValidator(); failOnValidationError(validator.validateProperty(jsonRepository, "identifier"), @@ -249,14 +249,14 @@ public Response updateRepository(Repository jsonRepository) { @Produces(MediaType.APPLICATION_JSON) @Operation( summary = "Deletes a repository", - description = "

    Requires permission SYSTEM_CONFIGURATION

    " + description = "

    Requires permission SYSTEM_CONFIGURATION or SYSTEM_CONFIGURATION_DELETE

    " ) @ApiResponses(value = { @ApiResponse(responseCode = "204"), @ApiResponse(responseCode = "401", description = "Unauthorized"), @ApiResponse(responseCode = "404", description = "The UUID of the repository could not be found") }) - @PermissionRequired(Permissions.Constants.SYSTEM_CONFIGURATION) + @PermissionRequired({Permissions.Constants.SYSTEM_CONFIGURATION, Permissions.Constants.SYSTEM_CONFIGURATION_DELETE}) public Response deleteRepository( @Parameter(description = "The UUID of the repository to delete", schema = @Schema(type = "string", format = "uuid"), required = true) @PathParam("uuid") @ValidUuid String uuid) { diff --git a/src/main/java/org/dependencytrack/resources/v1/ServiceResource.java b/src/main/java/org/dependencytrack/resources/v1/ServiceResource.java index c1701d4db..32acf2b36 100644 --- a/src/main/java/org/dependencytrack/resources/v1/ServiceResource.java +++ b/src/main/java/org/dependencytrack/resources/v1/ServiceResource.java @@ -141,7 +141,7 @@ public Response getServiceByUuid( @Produces(MediaType.APPLICATION_JSON) @Operation( summary = "Creates a new service", - description = "

    Requires permission PORTFOLIO_MANAGEMENT

    " + description = "

    Requires permission PORTFOLIO_MANAGEMENT or PORTFOLIO_MANAGEMENT_CREATE

    " ) @ApiResponses(value = { @ApiResponse(responseCode = "201", content = @Content(schema = @Schema(implementation = ServiceComponent.class))), @@ -149,7 +149,7 @@ public Response getServiceByUuid( @ApiResponse(responseCode = "403", description = "Access to the specified project is forbidden"), @ApiResponse(responseCode = "404", description = "The project could not be found") }) - @PermissionRequired(Permissions.Constants.PORTFOLIO_MANAGEMENT) + @PermissionRequired({Permissions.Constants.PORTFOLIO_MANAGEMENT, Permissions.Constants.PORTFOLIO_MANAGEMENT_CREATE}) public Response createService(@Parameter(description = "The UUID of the project", schema = @Schema(type = "string", format = "uuid"), required = true) @PathParam("uuid") @ValidUuid String uuid, ServiceComponent jsonService) { final Validator validator = super.getValidator(); @@ -194,7 +194,7 @@ public Response createService(@Parameter(description = "The UUID of the project" @Produces(MediaType.APPLICATION_JSON) @Operation( summary = "Updates a service", - description = "

    Requires permission PORTFOLIO_MANAGEMENT

    " + description = "

    Requires permission PORTFOLIO_MANAGEMENT or PORTFOLIO_MANAGEMENT_UPDATE

    " ) @ApiResponses(value = { @ApiResponse(responseCode = "200", content = @Content(schema = @Schema(implementation = ServiceComponent.class))), @@ -202,7 +202,7 @@ public Response createService(@Parameter(description = "The UUID of the project" @ApiResponse(responseCode = "403", description = "Access to the specified service is forbidden"), @ApiResponse(responseCode = "404", description = "The UUID of the service could not be found"), }) - @PermissionRequired(Permissions.Constants.PORTFOLIO_MANAGEMENT) + @PermissionRequired({Permissions.Constants.PORTFOLIO_MANAGEMENT, Permissions.Constants.PORTFOLIO_MANAGEMENT_UPDATE}) public Response updateService(ServiceComponent jsonService) { final Validator validator = super.getValidator(); failOnValidationError( @@ -245,7 +245,7 @@ public Response updateService(ServiceComponent jsonService) { @Produces(MediaType.APPLICATION_JSON) @Operation( summary = "Deletes a service", - description = "

    Requires permission PORTFOLIO_MANAGEMENT

    " + description = "

    Requires permission PORTFOLIO_MANAGEMENT or PORTFOLIO_MANAGEMENT_DELETE

    " ) @ApiResponses(value = { @ApiResponse(responseCode = "204"), @@ -253,7 +253,7 @@ public Response updateService(ServiceComponent jsonService) { @ApiResponse(responseCode = "403", description = "Access to the specified service is forbidden"), @ApiResponse(responseCode = "404", description = "The UUID of the service could not be found") }) - @PermissionRequired(Permissions.Constants.PORTFOLIO_MANAGEMENT) + @PermissionRequired({Permissions.Constants.PORTFOLIO_MANAGEMENT, Permissions.Constants.PORTFOLIO_MANAGEMENT_DELETE}) public Response deleteService( @Parameter(description = "The UUID of the service to delete", schema = @Schema(type = "string", format = "uuid"), required = true) @PathParam("uuid") @ValidUuid String uuid) { diff --git a/src/main/java/org/dependencytrack/resources/v1/TeamResource.java b/src/main/java/org/dependencytrack/resources/v1/TeamResource.java index 86b732b8e..470b3ef9f 100644 --- a/src/main/java/org/dependencytrack/resources/v1/TeamResource.java +++ b/src/main/java/org/dependencytrack/resources/v1/TeamResource.java @@ -74,12 +74,12 @@ public class TeamResource extends AlpineResource { @Produces(MediaType.APPLICATION_JSON) @Operation( summary = "Returns a list of all teams", - description = "

    Requires permission ACCESS_MANAGEMENT

    " + description = "

    Requires permission ACCESS_MANAGEMENT or ACCESS_MANAGEMENT_READ

    " ) @ApiResponses(value = { @ApiResponse(responseCode = "401", description = "Unauthorized") }) - @PermissionRequired(Permissions.Constants.ACCESS_MANAGEMENT) + @PermissionRequired({Permissions.Constants.ACCESS_MANAGEMENT, Permissions.Constants.ACCESS_MANAGEMENT_READ}) public Response getTeams() { try (QueryManager qm = new QueryManager(getAlpineRequest())) { final long totalCount = qm.getCount(Team.class); @@ -93,14 +93,14 @@ public Response getTeams() { @Produces(MediaType.APPLICATION_JSON) @Operation( summary = "Returns a specific team", - description = "

    Requires permission ACCESS_MANAGEMENT

    " + description = "

    Requires permission ACCESS_MANAGEMENT or ACCESS_MANAGEMENT_READ

    " ) @ApiResponses(value = { @ApiResponse(responseCode = "200", content = @Content(schema = @Schema(implementation = Team.class))), @ApiResponse(responseCode = "401", description = "Unauthorized"), @ApiResponse(responseCode = "404", description = "The team could not be found") }) - @PermissionRequired(Permissions.Constants.ACCESS_MANAGEMENT) + @PermissionRequired({Permissions.Constants.ACCESS_MANAGEMENT, Permissions.Constants.ACCESS_MANAGEMENT_READ}) public Response getTeam( @Parameter(description = "The UUID of the team to retrieve", schema = @Schema(type = "string", format = "uuid"), required = true) @PathParam("uuid") @ValidUuid String uuid) { @@ -119,13 +119,13 @@ public Response getTeam( @Produces(MediaType.APPLICATION_JSON) @Operation( summary = "Creates a new team along with an associated API key", - description = "

    Requires permission ACCESS_MANAGEMENT

    " + description = "

    Requires permission ACCESS_MANAGEMENT or ACCESS_MANAGEMENT_CREATE

    " ) @ApiResponses(value = { @ApiResponse(responseCode = "201", content = @Content(schema = @Schema(implementation = Team.class))), @ApiResponse(responseCode = "401", description = "Unauthorized") }) - @PermissionRequired(Permissions.Constants.ACCESS_MANAGEMENT) + @PermissionRequired({Permissions.Constants.ACCESS_MANAGEMENT, Permissions.Constants.ACCESS_MANAGEMENT_CREATE}) //public Response createTeam(String jsonRequest) { public Response createTeam(Team jsonTeam) { //Team team = MapperUtil.readAsObjectOf(Team.class, jsonRequest); @@ -146,14 +146,14 @@ public Response createTeam(Team jsonTeam) { @Produces(MediaType.APPLICATION_JSON) @Operation( summary = "Updates a team's fields including", - description = "

    Requires permission ACCESS_MANAGEMENT

    " + description = "

    Requires permission ACCESS_MANAGEMENT or ACCESS_MANAGEMENT_UPDATE

    " ) @ApiResponses(value = { @ApiResponse(responseCode = "200", content = @Content(schema = @Schema(implementation = Team.class))), @ApiResponse(responseCode = "401", description = "Unauthorized"), @ApiResponse(responseCode = "404", description = "The team could not be found") }) - @PermissionRequired(Permissions.Constants.ACCESS_MANAGEMENT) + @PermissionRequired({Permissions.Constants.ACCESS_MANAGEMENT, Permissions.Constants.ACCESS_MANAGEMENT_UPDATE}) public Response updateTeam(Team jsonTeam) { final Validator validator = super.getValidator(); failOnValidationError( @@ -178,14 +178,14 @@ public Response updateTeam(Team jsonTeam) { @Produces(MediaType.APPLICATION_JSON) @Operation( summary = "Deletes a team", - description = "

    Requires permission ACCESS_MANAGEMENT

    " + description = "

    Requires permission ACCESS_MANAGEMENT or ACCESS_MANAGEMENT_DELETE

    " ) @ApiResponses(value = { @ApiResponse(responseCode = "204"), @ApiResponse(responseCode = "401", description = "Unauthorized"), @ApiResponse(responseCode = "404", description = "The team could not be found") }) - @PermissionRequired(Permissions.Constants.ACCESS_MANAGEMENT) + @PermissionRequired({Permissions.Constants.ACCESS_MANAGEMENT, Permissions.Constants.ACCESS_MANAGEMENT_DELETE}) public Response deleteTeam(Team jsonTeam) { try (QueryManager qm = new QueryManager()) { final Team team = qm.getObjectByUuid(Team.class, jsonTeam.getUuid(), Team.FetchGroup.ALL.name()); @@ -205,14 +205,14 @@ public Response deleteTeam(Team jsonTeam) { @Produces(MediaType.APPLICATION_JSON) @Operation( summary = "Generates an API key and returns its value", - description = "

    Requires permission ACCESS_MANAGEMENT

    " + description = "

    Requires permission ACCESS_MANAGEMENT or ACCESS_MANAGEMENT_CREATE

    " ) @ApiResponses(value = { @ApiResponse(responseCode = "201", content = @Content(schema = @Schema(implementation = ApiKey.class))), @ApiResponse(responseCode = "401", description = "Unauthorized"), @ApiResponse(responseCode = "404", description = "The team could not be found") }) - @PermissionRequired(Permissions.Constants.ACCESS_MANAGEMENT) + @PermissionRequired({Permissions.Constants.ACCESS_MANAGEMENT, Permissions.Constants.ACCESS_MANAGEMENT_CREATE}) public Response generateApiKey( @Parameter(description = "The UUID of the team to generate a key for", schema = @Schema(type = "string", format = "uuid"), required = true) @PathParam("uuid") @ValidUuid String uuid) { @@ -232,14 +232,14 @@ public Response generateApiKey( @Produces(MediaType.APPLICATION_JSON) @Operation( summary = "Regenerates an API key by removing the specified key, generating a new one and returning its value", - description = "

    Requires permission ACCESS_MANAGEMENT

    " + description = "

    Requires permission ACCESS_MANAGEMENT or ACCESS_MANAGEMENT_CREATE

    " ) @ApiResponses(value = { @ApiResponse(responseCode = "200", content = @Content(schema = @Schema(implementation = ApiKey.class))), @ApiResponse(responseCode = "401", description = "Unauthorized"), @ApiResponse(responseCode = "404", description = "The API key could not be found") }) - @PermissionRequired(Permissions.Constants.ACCESS_MANAGEMENT) + @PermissionRequired({Permissions.Constants.ACCESS_MANAGEMENT, Permissions.Constants.ACCESS_MANAGEMENT_CREATE}) public Response regenerateApiKey( @Parameter(description = "The API key to regenerate", required = true) @PathParam("apikey") String apikey) { @@ -260,14 +260,14 @@ public Response regenerateApiKey( @Produces(MediaType.APPLICATION_JSON) @Operation( summary = "Updates an API key's comment", - description = "

    Requires permission ACCESS_MANAGEMENT

    " + description = "

    Requires permission ACCESS_MANAGEMENT or ACCESS_MANAGEMENT_UPDATE

    " ) @ApiResponses(value = { @ApiResponse(responseCode = "200", content = @Content(schema = @Schema(implementation = ApiKey.class))), @ApiResponse(responseCode = "401", description = "Unauthorized"), @ApiResponse(responseCode = "404", description = "The API key could not be found") }) - @PermissionRequired(Permissions.Constants.ACCESS_MANAGEMENT) + @PermissionRequired({Permissions.Constants.ACCESS_MANAGEMENT, Permissions.Constants.ACCESS_MANAGEMENT_UPDATE}) public Response updateApiKeyComment(@PathParam("apikey") final String apikey, final String comment) { try (final var qm = new QueryManager()) { @@ -291,14 +291,14 @@ public Response updateApiKeyComment(@PathParam("apikey") final String apikey, @Path("/key/{apikey}") @Operation( summary = "Deletes the specified API key", - description = "

    Requires permission ACCESS_MANAGEMENT

    " + description = "

    Requires permission ACCESS_MANAGEMENT or ACCESS_MANAGEMENT_DELETE

    " ) @ApiResponses(value = { @ApiResponse(responseCode = "204"), @ApiResponse(responseCode = "401", description = "Unauthorized"), @ApiResponse(responseCode = "404", description = "The API key could not be found") }) - @PermissionRequired(Permissions.Constants.ACCESS_MANAGEMENT) + @PermissionRequired({Permissions.Constants.ACCESS_MANAGEMENT, Permissions.Constants.ACCESS_MANAGEMENT_DELETE}) public Response deleteApiKey( @Parameter(description = "The API key to delete", required = true) @PathParam("apikey") String apikey) { diff --git a/src/main/java/org/dependencytrack/resources/v1/UserResource.java b/src/main/java/org/dependencytrack/resources/v1/UserResource.java index 3abccab4b..48898714c 100644 --- a/src/main/java/org/dependencytrack/resources/v1/UserResource.java +++ b/src/main/java/org/dependencytrack/resources/v1/UserResource.java @@ -236,7 +236,7 @@ public Response forceChangePassword(@FormParam("username") String username, @For @Produces(MediaType.APPLICATION_JSON) @Operation( summary = "Returns a list of all managed users", - description = "

    Requires permission ACCESS_MANAGEMENT

    " + description = "

    Requires permission ACCESS_MANAGEMENT or ACCESS_MANAGEMENT_READ

    " ) @ApiResponses(value = { @ApiResponse( @@ -246,7 +246,7 @@ public Response forceChangePassword(@FormParam("username") String username, @For ), @ApiResponse(responseCode = "401", description = "Unauthorized") }) - @PermissionRequired(Permissions.Constants.ACCESS_MANAGEMENT) + @PermissionRequired({Permissions.Constants.ACCESS_MANAGEMENT, Permissions.Constants.ACCESS_MANAGEMENT_READ}) public Response getManagedUsers() { try (QueryManager qm = new QueryManager(getAlpineRequest())) { final long totalCount = qm.getCount(ManagedUser.class); @@ -260,7 +260,7 @@ public Response getManagedUsers() { @Produces(MediaType.APPLICATION_JSON) @Operation( summary = "Returns a list of all LDAP users", - description = "

    Requires permission ACCESS_MANAGEMENT

    " + description = "

    Requires permission ACCESS_MANAGEMENT or ACCESS_MANAGEMENT_READ

    " ) @ApiResponses(value = { @ApiResponse( @@ -270,7 +270,7 @@ public Response getManagedUsers() { ), @ApiResponse(responseCode = "401", description = "Unauthorized") }) - @PermissionRequired(Permissions.Constants.ACCESS_MANAGEMENT) + @PermissionRequired({Permissions.Constants.ACCESS_MANAGEMENT, Permissions.Constants.ACCESS_MANAGEMENT_READ}) public Response getLdapUsers() { try (QueryManager qm = new QueryManager(getAlpineRequest())) { final long totalCount = qm.getCount(LdapUser.class); @@ -287,7 +287,7 @@ public Response getLdapUsers() { @Produces(MediaType.APPLICATION_JSON) @Operation( summary = "Returns a list of all OIDC users", - description = "

    Requires permission ACCESS_MANAGEMENT

    " + description = "

    Requires permission ACCESS_MANAGEMENT or ACCESS_MANAGEMENT_READ

    " ) @ApiResponses(value = { @ApiResponse( @@ -295,7 +295,7 @@ public Response getLdapUsers() { headers = @Header(name = TOTAL_COUNT_HEADER, description = "The total number of OIDC users", schema = @Schema(format = "integer"))), @ApiResponse(responseCode = "401", description = "Unauthorized") }) - @PermissionRequired(Permissions.Constants.ACCESS_MANAGEMENT) + @PermissionRequired({Permissions.Constants.ACCESS_MANAGEMENT, Permissions.Constants.ACCESS_MANAGEMENT_READ}) public Response getOidcUsers() { try (QueryManager qm = new QueryManager(getAlpineRequest())) { final long totalCount = qm.getCount(OidcUser.class); @@ -388,7 +388,7 @@ public Response updateSelf(ManagedUser jsonUser) { @Produces(MediaType.APPLICATION_JSON) @Operation( summary = "Creates a new user that references an existing LDAP object.", - description = "

    Requires permission ACCESS_MANAGEMENT

    " + description = "

    Requires permission ACCESS_MANAGEMENT or ACCESS_MANAGEMENT_CREATE

    " ) @ApiResponses(value = { @ApiResponse(responseCode = "201", content = @Content(schema = @Schema(implementation = LdapUser.class))), @@ -396,7 +396,7 @@ public Response updateSelf(ManagedUser jsonUser) { @ApiResponse(responseCode = "401", description = "Unauthorized"), @ApiResponse(responseCode = "409", description = "A user with the same username already exists. Cannot create new user") }) - @PermissionRequired(Permissions.Constants.ACCESS_MANAGEMENT) + @PermissionRequired({Permissions.Constants.ACCESS_MANAGEMENT, Permissions.Constants.ACCESS_MANAGEMENT_CREATE}) public Response createLdapUser(LdapUser jsonUser) { try (QueryManager qm = new QueryManager()) { if (StringUtils.isBlank(jsonUser.getUsername())) { @@ -420,14 +420,14 @@ public Response createLdapUser(LdapUser jsonUser) { @Produces(MediaType.APPLICATION_JSON) @Operation( summary = "Deletes a user.", - description = "

    Requires permission ACCESS_MANAGEMENT

    " + description = "

    Requires permission ACCESS_MANAGEMENT or ACCESS_MANAGEMENT_DELETE

    " ) @ApiResponses(value = { @ApiResponse(responseCode = "204"), @ApiResponse(responseCode = "401", description = "Unauthorized"), @ApiResponse(responseCode = "404", description = "The user could not be found") }) - @PermissionRequired(Permissions.Constants.ACCESS_MANAGEMENT) + @PermissionRequired({Permissions.Constants.ACCESS_MANAGEMENT, Permissions.Constants.ACCESS_MANAGEMENT_DELETE}) public Response deleteLdapUser(LdapUser jsonUser) { try (QueryManager qm = new QueryManager()) { final LdapUser user = qm.getLdapUser(jsonUser.getUsername()); @@ -449,7 +449,7 @@ public Response deleteLdapUser(LdapUser jsonUser) { @Produces(MediaType.APPLICATION_JSON) @Operation( summary = "Creates a new user.", - description = "

    Requires permission ACCESS_MANAGEMENT

    " + description = "

    Requires permission ACCESS_MANAGEMENT or ACCESS_MANAGEMENT_CREATE

    " ) @ApiResponses(value = { @ApiResponse(responseCode = "201", content = @Content(schema = @Schema(implementation = ManagedUser.class))), @@ -457,7 +457,7 @@ public Response deleteLdapUser(LdapUser jsonUser) { @ApiResponse(responseCode = "401", description = "Unauthorized"), @ApiResponse(responseCode = "409", description = "A user with the same username already exists. Cannot create new user") }) - @PermissionRequired(Permissions.Constants.ACCESS_MANAGEMENT) + @PermissionRequired({Permissions.Constants.ACCESS_MANAGEMENT, Permissions.Constants.ACCESS_MANAGEMENT_CREATE}) public Response createManagedUser(ManagedUser jsonUser) { try (QueryManager qm = new QueryManager()) { @@ -497,7 +497,7 @@ public Response createManagedUser(ManagedUser jsonUser) { @Produces(MediaType.APPLICATION_JSON) @Operation( summary = "Updates a managed user.", - description = "

    Requires permission ACCESS_MANAGEMENT

    " + description = "

    Requires permission ACCESS_MANAGEMENT or ACCESS_MANAGEMENT_UPDATE

    " ) @ApiResponses(value = { @ApiResponse(responseCode = "200", content = @Content(schema = @Schema(implementation = ManagedUser.class))), @@ -505,7 +505,7 @@ public Response createManagedUser(ManagedUser jsonUser) { @ApiResponse(responseCode = "401", description = "Unauthorized"), @ApiResponse(responseCode = "404", description = "The user could not be found") }) - @PermissionRequired(Permissions.Constants.ACCESS_MANAGEMENT) + @PermissionRequired({Permissions.Constants.ACCESS_MANAGEMENT, Permissions.Constants.ACCESS_MANAGEMENT_UPDATE}) public Response updateManagedUser(ManagedUser jsonUser) { try (QueryManager qm = new QueryManager()) { ManagedUser user = qm.getManagedUser(jsonUser.getUsername()); @@ -540,14 +540,14 @@ public Response updateManagedUser(ManagedUser jsonUser) { @Produces(MediaType.APPLICATION_JSON) @Operation( summary = "Deletes a user.", - description = "

    Requires permission ACCESS_MANAGEMENT

    " + description = "

    Requires permission ACCESS_MANAGEMENT or ACCESS_MANAGEMENT_DELETE

    " ) @ApiResponses(value = { @ApiResponse(responseCode = "204"), @ApiResponse(responseCode = "401", description = "Unauthorized"), @ApiResponse(responseCode = "404", description = "The user could not be found") }) - @PermissionRequired(Permissions.Constants.ACCESS_MANAGEMENT) + @PermissionRequired({Permissions.Constants.ACCESS_MANAGEMENT, Permissions.Constants.ACCESS_MANAGEMENT_DELETE}) public Response deleteManagedUser(ManagedUser jsonUser) { try (QueryManager qm = new QueryManager()) { final ManagedUser user = qm.getManagedUser(jsonUser.getUsername()); @@ -569,7 +569,7 @@ public Response deleteManagedUser(ManagedUser jsonUser) { @Produces(MediaType.APPLICATION_JSON) @Operation( summary = "Creates a new user that references an existing OpenID Connect user.", - description = "

    Requires permission ACCESS_MANAGEMENT

    " + description = "

    Requires permission ACCESS_MANAGEMENT or ACCESS_MANAGEMENT_CREATE

    " ) @ApiResponses(value = { @ApiResponse(responseCode = "201", content = @Content(schema = @Schema(implementation = OidcUser.class))), @@ -577,7 +577,7 @@ public Response deleteManagedUser(ManagedUser jsonUser) { @ApiResponse(responseCode = "401", description = "Unauthorized"), @ApiResponse(responseCode = "409", description = "A user with the same username already exists. Cannot create new user") }) - @PermissionRequired(Permissions.Constants.ACCESS_MANAGEMENT) + @PermissionRequired({Permissions.Constants.ACCESS_MANAGEMENT, Permissions.Constants.ACCESS_MANAGEMENT_CREATE}) public Response createOidcUser(final OidcUser jsonUser) { try (QueryManager qm = new QueryManager()) { if (StringUtils.isBlank(jsonUser.getUsername())) { @@ -601,14 +601,14 @@ public Response createOidcUser(final OidcUser jsonUser) { @Produces(MediaType.APPLICATION_JSON) @Operation( summary = "Deletes an OpenID Connect user.", - description = "

    Requires permission ACCESS_MANAGEMENT

    " + description = "

    Requires permission ACCESS_MANAGEMENT or ACCESS_MANAGEMENT_DELETE

    " ) @ApiResponses(value = { @ApiResponse(responseCode = "204"), @ApiResponse(responseCode = "401", description = "Unauthorized"), @ApiResponse(responseCode = "404", description = "The user could not be found") }) - @PermissionRequired(Permissions.Constants.ACCESS_MANAGEMENT) + @PermissionRequired({Permissions.Constants.ACCESS_MANAGEMENT, Permissions.Constants.ACCESS_MANAGEMENT_DELETE}) public Response deleteOidcUser(final OidcUser jsonUser) { try (QueryManager qm = new QueryManager()) { final OidcUser user = qm.getOidcUser(jsonUser.getUsername()); @@ -630,7 +630,7 @@ public Response deleteOidcUser(final OidcUser jsonUser) { @Produces(MediaType.APPLICATION_JSON) @Operation( summary = "Adds the username to the specified team.", - description = "

    Requires permission ACCESS_MANAGEMENT

    " + description = "

    Requires permission ACCESS_MANAGEMENT or ACCESS_MANAGEMENT_UPDATE

    " ) @ApiResponses(value = { @ApiResponse(responseCode = "200", content = @Content(schema = @Schema(implementation = UserPrincipal.class))), @@ -638,7 +638,7 @@ public Response deleteOidcUser(final OidcUser jsonUser) { @ApiResponse(responseCode = "401", description = "Unauthorized"), @ApiResponse(responseCode = "404", description = "The user or team could not be found") }) - @PermissionRequired(Permissions.Constants.ACCESS_MANAGEMENT) + @PermissionRequired({Permissions.Constants.ACCESS_MANAGEMENT, Permissions.Constants.ACCESS_MANAGEMENT_UPDATE}) public Response addTeamToUser( @Parameter(description = "A valid username", required = true) @PathParam("username") String username, @@ -670,7 +670,7 @@ public Response addTeamToUser( @Produces(MediaType.APPLICATION_JSON) @Operation( summary = "Removes the username from the specified team.", - description = "

    Requires permission ACCESS_MANAGEMENT

    " + description = "

    Requires permission ACCESS_MANAGEMENT or ACCESS_MANAGEMENT_DELETE

    " ) @ApiResponses(value = { @ApiResponse(responseCode = "200", content = @Content(schema = @Schema(implementation = UserPrincipal.class))), @@ -678,7 +678,7 @@ public Response addTeamToUser( @ApiResponse(responseCode = "401", description = "Unauthorized"), @ApiResponse(responseCode = "404", description = "The user or team could not be found") }) - @PermissionRequired(Permissions.Constants.ACCESS_MANAGEMENT) + @PermissionRequired({Permissions.Constants.ACCESS_MANAGEMENT, Permissions.Constants.ACCESS_MANAGEMENT_DELETE}) public Response removeTeamFromUser( @Parameter(description = "A valid username", required = true) @PathParam("username") String username, diff --git a/src/main/java/org/dependencytrack/resources/v1/VexResource.java b/src/main/java/org/dependencytrack/resources/v1/VexResource.java index f1b0da738..cc9b3158c 100644 --- a/src/main/java/org/dependencytrack/resources/v1/VexResource.java +++ b/src/main/java/org/dependencytrack/resources/v1/VexResource.java @@ -87,7 +87,7 @@ public class VexResource extends AlpineResource { @Produces({CycloneDxMediaType.APPLICATION_CYCLONEDX_JSON, MediaType.APPLICATION_OCTET_STREAM}) @Operation( summary = "Returns a VEX for a project in CycloneDX format", - description = "

    Requires permission VULNERABILITY_ANALYSIS

    " + description = "

    Requires permission VULNERABILITY_ANALYSIS or VULNERABILITY_ANALYSIS_READ

    " ) @ApiResponses(value = { @ApiResponse(responseCode = "200", content = @Content(schema = @Schema(type = "string"))), @@ -95,7 +95,7 @@ public class VexResource extends AlpineResource { @ApiResponse(responseCode = "403", description = "Access to the specified project is forbidden"), @ApiResponse(responseCode = "404", description = "The project could not be found") }) - @PermissionRequired(Permissions.Constants.VULNERABILITY_ANALYSIS) + @PermissionRequired({Permissions.Constants.VULNERABILITY_ANALYSIS, Permissions.Constants.VULNERABILITY_ANALYSIS_READ}) public Response exportProjectAsCycloneDx( @Parameter(description = "The UUID of the project to export", schema = @Schema(type = "string", format = "uuid"), required = true) @PathParam("uuid") @ValidUuid String uuid, @@ -147,7 +147,7 @@ public Response exportProjectAsCycloneDx( When uploading large VEX files, the POST endpoint is preferred, as it does not have this limit.

    -

    Requires permission VULNERABILITY_ANALYSIS

    """ +

    Requires permission VULNERABILITY_ANALYSIS or VULNERABILITY_ANALYSIS_UPDATE

    """ ) @ApiResponses(value = { @ApiResponse( @@ -161,7 +161,7 @@ public Response exportProjectAsCycloneDx( @ApiResponse(responseCode = "403", description = "Access to the specified project is forbidden"), @ApiResponse(responseCode = "404", description = "The project could not be found") }) - @PermissionRequired(Permissions.Constants.VULNERABILITY_ANALYSIS) + @PermissionRequired({Permissions.Constants.VULNERABILITY_ANALYSIS, Permissions.Constants.VULNERABILITY_ANALYSIS_UPDATE}) public Response uploadVex(VexSubmitRequest request) { final Validator validator = getValidator(); if (request.getProject() != null) { @@ -201,7 +201,7 @@ public Response uploadVex(VexSubmitRequest request) { a response with problem details in RFC 9457 format will be returned. In this case, the response's content type will be application/problem+json.

    -

    Requires permission VULNERABILITY_ANALYSIS

    """ +

    Requires permission VULNERABILITY_ANALYSIS or VULNERABILITY_ANALYSIS_UPDATE

    """ ) @ApiResponses(value = { @ApiResponse( @@ -216,7 +216,7 @@ public Response uploadVex(VexSubmitRequest request) { @ApiResponse(responseCode = "403", description = "Access to the specified project is forbidden"), @ApiResponse(responseCode = "404", description = "The project could not be found") }) - @PermissionRequired(Permissions.Constants.VULNERABILITY_ANALYSIS) + @PermissionRequired({Permissions.Constants.VULNERABILITY_ANALYSIS, Permissions.Constants.VULNERABILITY_ANALYSIS_UPDATE}) public Response uploadVex(@FormDataParam("project") String projectUuid, @FormDataParam("projectName") String projectName, @FormDataParam("projectVersion") String projectVersion, diff --git a/src/main/java/org/dependencytrack/resources/v1/ViolationAnalysisResource.java b/src/main/java/org/dependencytrack/resources/v1/ViolationAnalysisResource.java index ad2da2e93..86ad93476 100644 --- a/src/main/java/org/dependencytrack/resources/v1/ViolationAnalysisResource.java +++ b/src/main/java/org/dependencytrack/resources/v1/ViolationAnalysisResource.java @@ -109,7 +109,7 @@ public Response retrieveAnalysis(@Parameter(description = "The UUID of the compo @Produces(MediaType.APPLICATION_JSON) @Operation( summary = "Records a violation analysis decision", - description = "

    Requires permission VIEW_POLICY_VIOLATION

    " + description = "

    Requires permission POLICY_VIOLATION_ANALYSIS

    " ) @ApiResponses(value = { @ApiResponse(responseCode = "401", description = "Unauthorized"), diff --git a/src/main/java/org/dependencytrack/resources/v1/VulnerabilityPolicyBundleResource.java b/src/main/java/org/dependencytrack/resources/v1/VulnerabilityPolicyBundleResource.java index 90d898cac..5bb644372 100644 --- a/src/main/java/org/dependencytrack/resources/v1/VulnerabilityPolicyBundleResource.java +++ b/src/main/java/org/dependencytrack/resources/v1/VulnerabilityPolicyBundleResource.java @@ -49,14 +49,14 @@ public class VulnerabilityPolicyBundleResource extends AlpineResource { @Produces(MediaType.APPLICATION_JSON) @Operation( summary = "Returns vulnerability policy resource bundle", - description = "

    Requires permission POLICY_MANAGEMENT

    " + description = "

    Requires permission POLICY_MANAGEMENT or POLICY_MANAGEMENT_READ

    " ) @ApiResponses(value = { @ApiResponse(responseCode = "200", content = @Content(schema = @Schema(implementation = VulnerabilityPolicyBundle.class ))), @ApiResponse(responseCode = "401", description = "Unauthorized") }) - @PermissionRequired(Permissions.Constants.POLICY_MANAGEMENT) + @PermissionRequired({Permissions.Constants.POLICY_MANAGEMENT, Permissions.Constants.POLICY_MANAGEMENT_READ}) public Response getVulnerabilityPolicyBundle() { try (QueryManager qm = new QueryManager(getAlpineRequest())) { final VulnerabilityPolicyBundle bundle = qm.getVulnerabilityPolicyBundle(); diff --git a/src/main/java/org/dependencytrack/resources/v1/VulnerabilityPolicyResource.java b/src/main/java/org/dependencytrack/resources/v1/VulnerabilityPolicyResource.java index 27ae34199..9edf73d93 100644 --- a/src/main/java/org/dependencytrack/resources/v1/VulnerabilityPolicyResource.java +++ b/src/main/java/org/dependencytrack/resources/v1/VulnerabilityPolicyResource.java @@ -78,7 +78,7 @@ public class VulnerabilityPolicyResource extends AlpineResource { @Produces(MediaType.APPLICATION_JSON) @Operation( summary = "Returns a list of all vulnerability policies", - description = "

    Requires permission POLICY_MANAGEMENT

    " + description = "

    Requires permission POLICY_MANAGEMENT or POLICY_MANAGEMENT_READ

    " ) @PaginatedApi @ApiResponses(value = { @@ -86,7 +86,7 @@ public class VulnerabilityPolicyResource extends AlpineResource { content = @Content(array = @ArraySchema(schema = @Schema(implementation = VulnerabilityPolicy.class)))), @ApiResponse(responseCode = "401", description = "Unauthorized") }) - @PermissionRequired(Permissions.Constants.POLICY_MANAGEMENT) + @PermissionRequired({Permissions.Constants.POLICY_MANAGEMENT, Permissions.Constants.POLICY_MANAGEMENT_READ}) public Response getVulnerabilityPolicies() { VulnerabilityPolicyProviderFactory instance = VulnerabilityPolicyProviderFactory.getInstance(); VulnerabilityPolicyProvider vulnerabilityPolicyProvider = instance.policyProviderImpl(); @@ -100,7 +100,7 @@ public Response getVulnerabilityPolicies() { @Operation( summary = "Triggers policy bundle synchronization. Returns a workflow token if trigger succeeded.", // responseContainer = "Map", - description = "

    Requires permission POLICY_MANAGEMENT

    " + description = "

    Requires permission POLICY_MANAGEMENT or POLICY_MANAGEMENT_UPDATE

    " ) @ApiResponses(value = { @ApiResponse(responseCode = "200", content = @Content( schema = @Schema(type = "string"))), @@ -108,7 +108,7 @@ public Response getVulnerabilityPolicies() { @ApiResponse(responseCode = "401", description = "Unauthorized"), @ApiResponse(responseCode = "409", description = "Conflict") }) - @PermissionRequired(Permissions.Constants.POLICY_MANAGEMENT) + @PermissionRequired({Permissions.Constants.POLICY_MANAGEMENT, Permissions.Constants.POLICY_MANAGEMENT_UPDATE}) public Response triggerVulnerabilityPolicyBundleSync() { if (!Config.getInstance().getPropertyAsBoolean(ConfigKey.VULNERABILITY_POLICY_ANALYSIS_ENABLED)) { return Response diff --git a/src/main/java/org/dependencytrack/resources/v1/VulnerabilityResource.java b/src/main/java/org/dependencytrack/resources/v1/VulnerabilityResource.java index c6ddad249..25b30716c 100644 --- a/src/main/java/org/dependencytrack/resources/v1/VulnerabilityResource.java +++ b/src/main/java/org/dependencytrack/resources/v1/VulnerabilityResource.java @@ -163,14 +163,14 @@ public Response getVulnerabilitiesByProject(@Parameter(description = "The UUID o @Produces(MediaType.APPLICATION_JSON) @Operation( summary = "Returns a specific vulnerability", - description = "

    Requires permission VULNERABILITY_MANAGEMENT

    " + description = "

    Requires permission VULNERABILITY_MANAGEMENT or VULNERABILITY_MANAGEMENT_READ

    " ) @ApiResponses(value = { @ApiResponse(responseCode = "200", content = @Content(schema = @Schema(implementation = Vulnerability.class))), @ApiResponse(responseCode = "401", description = "Unauthorized"), @ApiResponse(responseCode = "404", description = "The vulnerability could not be found") }) - @PermissionRequired(Permissions.Constants.VULNERABILITY_MANAGEMENT) + @PermissionRequired({Permissions.Constants.VULNERABILITY_MANAGEMENT, Permissions.Constants.VULNERABILITY_MANAGEMENT_READ}) public Response getVulnerabilityByUuid(@Parameter(description = "The UUID of the vulnerability", schema = @Schema(type = "string", format = "uuid"), required = true) @PathParam("uuid") @ValidUuid String uuid) { try (QueryManager qm = new QueryManager()) { @@ -282,14 +282,14 @@ public Response getAllVulnerabilities() { @Produces(MediaType.APPLICATION_JSON) @Operation( summary = "Creates a new vulnerability", - description = "

    Requires permission VULNERABILITY_MANAGEMENT

    " + description = "

    Requires permission VULNERABILITY_MANAGEMENT or VULNERABILITY_MANAGEMENT_CREATE

    " ) @ApiResponses(value = { @ApiResponse(responseCode = "201", content = @Content(schema = @Schema(implementation = Vulnerability.class))), @ApiResponse(responseCode = "401", description = "Unauthorized"), @ApiResponse(responseCode = "409", description = "A vulnerability with the specified vulnId already exists") }) - @PermissionRequired(Permissions.Constants.VULNERABILITY_MANAGEMENT) + @PermissionRequired({Permissions.Constants.VULNERABILITY_MANAGEMENT, Permissions.Constants.VULNERABILITY_MANAGEMENT_CREATE}) public Response createVulnerability(Vulnerability jsonVulnerability) { final Validator validator = super.getValidator(); failOnValidationError( @@ -353,7 +353,7 @@ public Response createVulnerability(Vulnerability jsonVulnerability) { @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) @Operation( - description = "

    Requires permission VULNERABILITY_MANAGEMENT

    " + description = "

    Requires permission VULNERABILITY_MANAGEMENT or VULNERABILITY_MANAGEMENT_UPDATE

    " ) @ApiResponses(value = { @ApiResponse(responseCode = "200", content = @Content(schema = @Schema(implementation = Vulnerability.class))), @@ -362,7 +362,7 @@ public Response createVulnerability(Vulnerability jsonVulnerability) { @ApiResponse(responseCode = "404", description = "The vulnerability could not be found"), @ApiResponse(responseCode = "406", description = "The vulnId may not be changed") }) - @PermissionRequired(Permissions.Constants.VULNERABILITY_MANAGEMENT) + @PermissionRequired({Permissions.Constants.VULNERABILITY_MANAGEMENT, Permissions.Constants.VULNERABILITY_MANAGEMENT_UPDATE}) public Response updateVulnerability(Vulnerability jsonVuln) { final Validator validator = super.getValidator(); failOnValidationError( @@ -434,7 +434,7 @@ public Response updateVulnerability(Vulnerability jsonVuln) { @Produces(MediaType.APPLICATION_JSON) @Operation( summary = "Deletes a vulnerability", - description = "

    Requires permission VULNERABILITY_MANAGEMENT

    " + description = "

    Requires permission VULNERABILITY_MANAGEMENT or VULNERABILITY_MANAGEMENT_DELETE

    " ) @ApiResponses(value = { @ApiResponse(responseCode = "204"), @@ -443,7 +443,7 @@ public Response updateVulnerability(Vulnerability jsonVuln) { @ApiResponse(responseCode = "404", description = "The UUID of the vulnerability could not be found"), @ApiResponse(responseCode = "412", description = "Portfolio components or services are affected by this vulnerability. Unable to delete.") }) - @PermissionRequired(Permissions.Constants.VULNERABILITY_MANAGEMENT) + @PermissionRequired({Permissions.Constants.VULNERABILITY_MANAGEMENT, Permissions.Constants.VULNERABILITY_MANAGEMENT_DELETE}) public Response deleteVulnerability( @Parameter(description = "The UUID of the vulnerability to delete", schema = @Schema(type = "string", format = "uuid"), required = true) @PathParam("uuid") @ValidUuid String uuid) { @@ -472,13 +472,13 @@ public Response deleteVulnerability( @Produces(MediaType.APPLICATION_JSON) @Operation( summary = "Generates an internal vulnerability identifier", - description = "

    Requires permission PORTFOLIO_MANAGEMENT

    " + description = "

    Requires permission PORTFOLIO_MANAGEMENT or PORTFOLIO_MANAGEMENT_CREATE

    " ) @ApiResponses(value = { @ApiResponse(responseCode = "200", content = @Content(schema = @Schema(type = "string"))), @ApiResponse(responseCode = "401", description = "Unauthorized") }) - @PermissionRequired(Permissions.Constants.PORTFOLIO_MANAGEMENT) + @PermissionRequired({Permissions.Constants.PORTFOLIO_MANAGEMENT, Permissions.Constants.PORTFOLIO_MANAGEMENT_CREATE}) public Response generateInternalVulnerabilityIdentifier() { final String vulnId = VulnerabilityUtil.randomInternalId(); return Response.ok(vulnId).build(); @@ -530,14 +530,14 @@ public void recalculateScoresAndSeverityFromVectors(Vulnerability vuln) throws M @Produces(MediaType.APPLICATION_JSON) @Operation( summary = "Assigns a vulnerability to a component", - description = "

    Requires permission PORTFOLIO_MANAGEMENT

    " + description = "

    Requires permission PORTFOLIO_MANAGEMENT or PORTFOLIO_MANAGEMENT_UPDATE

    " ) @ApiResponses(value = { @ApiResponse(responseCode = "401", description = "Unauthorized"), @ApiResponse(responseCode = "403", description = "Access to the specified component is forbidden"), @ApiResponse(responseCode = "404", description = "The vulnerability or component could not be found") }) - @PermissionRequired(Permissions.Constants.PORTFOLIO_MANAGEMENT) + @PermissionRequired({Permissions.Constants.PORTFOLIO_MANAGEMENT, Permissions.Constants.PORTFOLIO_MANAGEMENT_UPDATE}) public Response assignVulnerability(@Parameter(description = "The vulnerability source", required = true) @PathParam("source") String source, @Parameter(description = "The vulnId", required = true) @@ -569,14 +569,14 @@ public Response assignVulnerability(@Parameter(description = "The vulnerability @Produces(MediaType.APPLICATION_JSON) @Operation( summary = "Assigns a vulnerability to a component", - description = "

    Requires permission PORTFOLIO_MANAGEMENT

    " + description = "

    Requires permission PORTFOLIO_MANAGEMENT or PORTFOLIO_MANAGEMENT_UPDATE

    " ) @ApiResponses(value = { @ApiResponse(responseCode = "401", description = "Unauthorized"), @ApiResponse(responseCode = "403", description = "Access to the specified component is forbidden"), @ApiResponse(responseCode = "404", description = "The vulnerability or component could not be found") }) - @PermissionRequired(Permissions.Constants.PORTFOLIO_MANAGEMENT) + @PermissionRequired({Permissions.Constants.PORTFOLIO_MANAGEMENT, Permissions.Constants.PORTFOLIO_MANAGEMENT_UPDATE}) public Response assignVulnerability(@Parameter(description = "The UUID of the vulnerability", schema = @Schema(type = "string", format = "uuid"), required = true) @PathParam("uuid") @ValidUuid String uuid, @Parameter(description = "The UUID of the component", schema = @Schema(type = "string", format = "uuid"), required = true) @@ -606,14 +606,14 @@ public Response assignVulnerability(@Parameter(description = "The UUID of the vu @Produces(MediaType.APPLICATION_JSON) @Operation( summary = "Removes assignment of a vulnerability from a component", - description = "

    Requires permission PORTFOLIO_MANAGEMENT

    " + description = "

    Requires permission PORTFOLIO_MANAGEMENT or PORTFOLIO_MANAGEMENT_DELETE

    " ) @ApiResponses(value = { @ApiResponse(responseCode = "401", description = "Unauthorized"), @ApiResponse(responseCode = "403", description = "Access to the specified component is forbidden"), @ApiResponse(responseCode = "404", description = "The vulnerability or component could not be found") }) - @PermissionRequired(Permissions.Constants.PORTFOLIO_MANAGEMENT) + @PermissionRequired({Permissions.Constants.PORTFOLIO_MANAGEMENT, Permissions.Constants.PORTFOLIO_MANAGEMENT_DELETE}) public Response unassignVulnerability(@Parameter(description = "The vulnerability source", required = true) @PathParam("source") String source, @Parameter(description = "The vulnId", required = true) @@ -645,14 +645,14 @@ public Response unassignVulnerability(@Parameter(description = "The vulnerabilit @Produces(MediaType.APPLICATION_JSON) @Operation( summary = "Removes assignment of a vulnerability from a component", - description = "

    Requires permission PORTFOLIO_MANAGEMENT

    " + description = "

    Requires permission PORTFOLIO_MANAGEMENT or PORTFOLIO_MANAGEMENT_DELETE

    " ) @ApiResponses(value = { @ApiResponse(responseCode = "401", description = "Unauthorized"), @ApiResponse(responseCode = "403", description = "Access to the specified component is forbidden"), @ApiResponse(responseCode = "404", description = "The vulnerability or component could not be found") }) - @PermissionRequired(Permissions.Constants.PORTFOLIO_MANAGEMENT) + @PermissionRequired({Permissions.Constants.PORTFOLIO_MANAGEMENT, Permissions.Constants.PORTFOLIO_MANAGEMENT_DELETE}) public Response unassignVulnerability(@Parameter(description = "The UUID of the vulnerability", schema = @Schema(type = "string", format = "uuid"), required = true) @PathParam("uuid") @ValidUuid String uuid, @Parameter(description = "The UUID of the component", schema = @Schema(type = "string", format = "uuid"), required = true) @@ -682,13 +682,13 @@ public Response unassignVulnerability(@Parameter(description = "The UUID of the @Produces(MediaType.APPLICATION_JSON) @Operation( summary = "Updates tags for a vulnerability", - description = "

    Requires permission VULNERABILITY_MANAGEMENT

    " + description = "

    Requires permission VULNERABILITY_MANAGEMENT or VULNERABILITY_MANAGEMENT_UPDATE

    " ) @ApiResponses(value = { @ApiResponse(responseCode = "401", description = "Unauthorized"), @ApiResponse(responseCode = "404", description = "The vulnerability could not be found") }) - @PermissionRequired(Permissions.Constants.VULNERABILITY_MANAGEMENT) + @PermissionRequired({Permissions.Constants.VULNERABILITY_MANAGEMENT, Permissions.Constants.VULNERABILITY_MANAGEMENT_UPDATE}) public Response updateVulnerabilityTags(List tags, @Parameter(description = "UUID of the vulnerability", schema = @Schema(type = "string", format = "uuid"), required = true) @PathParam("uuid") @ValidUuid String uuid) { diff --git a/src/test/java/org/dependencytrack/auth/PermissionsTest.java b/src/test/java/org/dependencytrack/auth/PermissionsTest.java index 5263c0938..83f680339 100644 --- a/src/test/java/org/dependencytrack/auth/PermissionsTest.java +++ b/src/test/java/org/dependencytrack/auth/PermissionsTest.java @@ -21,36 +21,82 @@ import org.junit.Assert; import org.junit.Test; -import static org.dependencytrack.auth.Permissions.Constants.ACCESS_MANAGEMENT; import static org.dependencytrack.auth.Permissions.Constants.BOM_UPLOAD; -import static org.dependencytrack.auth.Permissions.Constants.POLICY_MANAGEMENT; -import static org.dependencytrack.auth.Permissions.Constants.POLICY_VIOLATION_ANALYSIS; -import static org.dependencytrack.auth.Permissions.Constants.PORTFOLIO_MANAGEMENT; -import static org.dependencytrack.auth.Permissions.Constants.PROJECT_CREATION_UPLOAD; -import static org.dependencytrack.auth.Permissions.Constants.SYSTEM_CONFIGURATION; -import static org.dependencytrack.auth.Permissions.Constants.VIEW_POLICY_VIOLATION; import static org.dependencytrack.auth.Permissions.Constants.VIEW_PORTFOLIO; +import static org.dependencytrack.auth.Permissions.Constants.PORTFOLIO_MANAGEMENT; +import static org.dependencytrack.auth.Permissions.Constants.PORTFOLIO_MANAGEMENT_CREATE; +import static org.dependencytrack.auth.Permissions.Constants.PORTFOLIO_MANAGEMENT_READ; +import static org.dependencytrack.auth.Permissions.Constants.PORTFOLIO_MANAGEMENT_UPDATE; +import static org.dependencytrack.auth.Permissions.Constants.PORTFOLIO_MANAGEMENT_DELETE; import static org.dependencytrack.auth.Permissions.Constants.VIEW_VULNERABILITY; import static org.dependencytrack.auth.Permissions.Constants.VULNERABILITY_ANALYSIS; +import static org.dependencytrack.auth.Permissions.Constants.VULNERABILITY_ANALYSIS_CREATE; +import static org.dependencytrack.auth.Permissions.Constants.VULNERABILITY_ANALYSIS_READ; +import static org.dependencytrack.auth.Permissions.Constants.VULNERABILITY_ANALYSIS_UPDATE; +import static org.dependencytrack.auth.Permissions.Constants.VIEW_POLICY_VIOLATION; import static org.dependencytrack.auth.Permissions.Constants.VULNERABILITY_MANAGEMENT; +import static org.dependencytrack.auth.Permissions.Constants.VULNERABILITY_MANAGEMENT_CREATE; +import static org.dependencytrack.auth.Permissions.Constants.VULNERABILITY_MANAGEMENT_READ; +import static org.dependencytrack.auth.Permissions.Constants.VULNERABILITY_MANAGEMENT_UPDATE; +import static org.dependencytrack.auth.Permissions.Constants.VULNERABILITY_MANAGEMENT_DELETE; +import static org.dependencytrack.auth.Permissions.Constants.POLICY_VIOLATION_ANALYSIS; +import static org.dependencytrack.auth.Permissions.Constants.ACCESS_MANAGEMENT; +import static org.dependencytrack.auth.Permissions.Constants.ACCESS_MANAGEMENT_CREATE; +import static org.dependencytrack.auth.Permissions.Constants.ACCESS_MANAGEMENT_READ; +import static org.dependencytrack.auth.Permissions.Constants.ACCESS_MANAGEMENT_UPDATE; +import static org.dependencytrack.auth.Permissions.Constants.ACCESS_MANAGEMENT_DELETE; +import static org.dependencytrack.auth.Permissions.Constants.SYSTEM_CONFIGURATION; +import static org.dependencytrack.auth.Permissions.Constants.SYSTEM_CONFIGURATION_CREATE; +import static org.dependencytrack.auth.Permissions.Constants.SYSTEM_CONFIGURATION_READ; +import static org.dependencytrack.auth.Permissions.Constants.SYSTEM_CONFIGURATION_UPDATE; +import static org.dependencytrack.auth.Permissions.Constants.SYSTEM_CONFIGURATION_DELETE; +import static org.dependencytrack.auth.Permissions.Constants.PROJECT_CREATION_UPLOAD; +import static org.dependencytrack.auth.Permissions.Constants.POLICY_MANAGEMENT; +import static org.dependencytrack.auth.Permissions.Constants.POLICY_MANAGEMENT_CREATE; +import static org.dependencytrack.auth.Permissions.Constants.POLICY_MANAGEMENT_READ; +import static org.dependencytrack.auth.Permissions.Constants.POLICY_MANAGEMENT_UPDATE; +import static org.dependencytrack.auth.Permissions.Constants.POLICY_MANAGEMENT_DELETE; public class PermissionsTest { @Test public void testPermissionEnums() { - Assert.assertEquals(12, Permissions.values().length); + Assert.assertEquals(35, Permissions.values().length); Assert.assertEquals("BOM_UPLOAD", Permissions.BOM_UPLOAD.name()); Assert.assertEquals("VIEW_PORTFOLIO", Permissions.VIEW_PORTFOLIO.name()); Assert.assertEquals("PORTFOLIO_MANAGEMENT", Permissions.PORTFOLIO_MANAGEMENT.name()); + Assert.assertEquals("PORTFOLIO_MANAGEMENT_CREATE", Permissions.PORTFOLIO_MANAGEMENT_CREATE.name()); + Assert.assertEquals("PORTFOLIO_MANAGEMENT_READ", Permissions.PORTFOLIO_MANAGEMENT_READ.name()); + Assert.assertEquals("PORTFOLIO_MANAGEMENT_UPDATE", Permissions.PORTFOLIO_MANAGEMENT_UPDATE.name()); + Assert.assertEquals("PORTFOLIO_MANAGEMENT_DELETE", Permissions.PORTFOLIO_MANAGEMENT_DELETE.name()); Assert.assertEquals("VIEW_VULNERABILITY", Permissions.VIEW_VULNERABILITY.name()); Assert.assertEquals("VULNERABILITY_ANALYSIS", Permissions.VULNERABILITY_ANALYSIS.name()); + Assert.assertEquals("VULNERABILITY_ANALYSIS_CREATE", Permissions.VULNERABILITY_ANALYSIS_CREATE.name()); + Assert.assertEquals("VULNERABILITY_ANALYSIS_READ", Permissions.VULNERABILITY_ANALYSIS_READ.name()); + Assert.assertEquals("VULNERABILITY_ANALYSIS_UPDATE", Permissions.VULNERABILITY_ANALYSIS_UPDATE.name()); Assert.assertEquals("VIEW_POLICY_VIOLATION", Permissions.VIEW_POLICY_VIOLATION.name()); Assert.assertEquals("VULNERABILITY_MANAGEMENT", Permissions.VULNERABILITY_MANAGEMENT.name()); + Assert.assertEquals("VULNERABILITY_MANAGEMENT_CREATE", Permissions.VULNERABILITY_MANAGEMENT_CREATE.name()); + Assert.assertEquals("VULNERABILITY_MANAGEMENT_READ", Permissions.VULNERABILITY_MANAGEMENT_READ.name()); + Assert.assertEquals("VULNERABILITY_MANAGEMENT_UPDATE", Permissions.VULNERABILITY_MANAGEMENT_UPDATE.name()); + Assert.assertEquals("VULNERABILITY_MANAGEMENT_DELETE", Permissions.VULNERABILITY_MANAGEMENT_DELETE.name()); Assert.assertEquals("POLICY_VIOLATION_ANALYSIS", Permissions.POLICY_VIOLATION_ANALYSIS.name()); Assert.assertEquals("ACCESS_MANAGEMENT", Permissions.ACCESS_MANAGEMENT.name()); + Assert.assertEquals("ACCESS_MANAGEMENT_CREATE", Permissions.ACCESS_MANAGEMENT_CREATE.name()); + Assert.assertEquals("ACCESS_MANAGEMENT_READ", Permissions.ACCESS_MANAGEMENT_READ.name()); + Assert.assertEquals("ACCESS_MANAGEMENT_UPDATE", Permissions.ACCESS_MANAGEMENT_UPDATE.name()); + Assert.assertEquals("ACCESS_MANAGEMENT_DELETE", Permissions.ACCESS_MANAGEMENT_DELETE.name()); Assert.assertEquals("SYSTEM_CONFIGURATION", Permissions.SYSTEM_CONFIGURATION.name()); + Assert.assertEquals("SYSTEM_CONFIGURATION_CREATE", Permissions.SYSTEM_CONFIGURATION_CREATE.name()); + Assert.assertEquals("SYSTEM_CONFIGURATION_READ", Permissions.SYSTEM_CONFIGURATION_READ.name()); + Assert.assertEquals("SYSTEM_CONFIGURATION_UPDATE", Permissions.SYSTEM_CONFIGURATION_UPDATE.name()); + Assert.assertEquals("SYSTEM_CONFIGURATION_DELETE", Permissions.SYSTEM_CONFIGURATION_DELETE.name()); Assert.assertEquals("PROJECT_CREATION_UPLOAD", Permissions.PROJECT_CREATION_UPLOAD.name()); Assert.assertEquals("POLICY_MANAGEMENT", Permissions.POLICY_MANAGEMENT.name()); + Assert.assertEquals("POLICY_MANAGEMENT_CREATE", Permissions.POLICY_MANAGEMENT_CREATE.name()); + Assert.assertEquals("POLICY_MANAGEMENT_READ", Permissions.POLICY_MANAGEMENT_READ.name()); + Assert.assertEquals("POLICY_MANAGEMENT_UPDATE", Permissions.POLICY_MANAGEMENT_UPDATE.name()); + Assert.assertEquals("POLICY_MANAGEMENT_DELETE", Permissions.POLICY_MANAGEMENT_DELETE.name()); } @Test @@ -58,14 +104,37 @@ public void testPermissionConstants() { Assert.assertEquals("BOM_UPLOAD", BOM_UPLOAD); Assert.assertEquals("VIEW_PORTFOLIO", VIEW_PORTFOLIO); Assert.assertEquals("PORTFOLIO_MANAGEMENT", PORTFOLIO_MANAGEMENT); + Assert.assertEquals("PORTFOLIO_MANAGEMENT_CREATE", PORTFOLIO_MANAGEMENT_CREATE); + Assert.assertEquals("PORTFOLIO_MANAGEMENT_READ", PORTFOLIO_MANAGEMENT_READ); + Assert.assertEquals("PORTFOLIO_MANAGEMENT_UPDATE", PORTFOLIO_MANAGEMENT_UPDATE); + Assert.assertEquals("PORTFOLIO_MANAGEMENT_DELETE", PORTFOLIO_MANAGEMENT_DELETE); Assert.assertEquals("VIEW_VULNERABILITY", VIEW_VULNERABILITY); Assert.assertEquals("VULNERABILITY_ANALYSIS", VULNERABILITY_ANALYSIS); + Assert.assertEquals("VULNERABILITY_ANALYSIS_CREATE", VULNERABILITY_ANALYSIS_CREATE); + Assert.assertEquals("VULNERABILITY_ANALYSIS_READ", VULNERABILITY_ANALYSIS_READ); + Assert.assertEquals("VULNERABILITY_ANALYSIS_UPDATE", VULNERABILITY_ANALYSIS_UPDATE); Assert.assertEquals("VIEW_POLICY_VIOLATION", VIEW_POLICY_VIOLATION); Assert.assertEquals("VULNERABILITY_MANAGEMENT", VULNERABILITY_MANAGEMENT); + Assert.assertEquals("VULNERABILITY_MANAGEMENT_CREATE", VULNERABILITY_MANAGEMENT_CREATE); + Assert.assertEquals("VULNERABILITY_MANAGEMENT_READ", VULNERABILITY_MANAGEMENT_READ); + Assert.assertEquals("VULNERABILITY_MANAGEMENT_UPDATE", VULNERABILITY_MANAGEMENT_UPDATE); + Assert.assertEquals("VULNERABILITY_MANAGEMENT_DELETE", VULNERABILITY_MANAGEMENT_DELETE); Assert.assertEquals("POLICY_VIOLATION_ANALYSIS", POLICY_VIOLATION_ANALYSIS); Assert.assertEquals("ACCESS_MANAGEMENT", ACCESS_MANAGEMENT); + Assert.assertEquals("ACCESS_MANAGEMENT_CREATE", ACCESS_MANAGEMENT_CREATE); + Assert.assertEquals("ACCESS_MANAGEMENT_READ", ACCESS_MANAGEMENT_READ); + Assert.assertEquals("ACCESS_MANAGEMENT_UPDATE", ACCESS_MANAGEMENT_UPDATE); + Assert.assertEquals("ACCESS_MANAGEMENT_DELETE", ACCESS_MANAGEMENT_DELETE); Assert.assertEquals("SYSTEM_CONFIGURATION", SYSTEM_CONFIGURATION); + Assert.assertEquals("SYSTEM_CONFIGURATION_CREATE", SYSTEM_CONFIGURATION_CREATE); + Assert.assertEquals("SYSTEM_CONFIGURATION_READ", SYSTEM_CONFIGURATION_READ); + Assert.assertEquals("SYSTEM_CONFIGURATION_UPDATE", SYSTEM_CONFIGURATION_UPDATE); + Assert.assertEquals("SYSTEM_CONFIGURATION_DELETE", SYSTEM_CONFIGURATION_DELETE); Assert.assertEquals("PROJECT_CREATION_UPLOAD", PROJECT_CREATION_UPLOAD); Assert.assertEquals("POLICY_MANAGEMENT", POLICY_MANAGEMENT); + Assert.assertEquals("POLICY_MANAGEMENT_CREATE", POLICY_MANAGEMENT_CREATE); + Assert.assertEquals("POLICY_MANAGEMENT_READ", POLICY_MANAGEMENT_READ); + Assert.assertEquals("POLICY_MANAGEMENT_UPDATE", POLICY_MANAGEMENT_UPDATE); + Assert.assertEquals("POLICY_MANAGEMENT_DELETE", POLICY_MANAGEMENT_DELETE); } } diff --git a/src/test/java/org/dependencytrack/resources/v1/PermissionResourceTest.java b/src/test/java/org/dependencytrack/resources/v1/PermissionResourceTest.java index ba737005e..ff7736bb7 100644 --- a/src/test/java/org/dependencytrack/resources/v1/PermissionResourceTest.java +++ b/src/test/java/org/dependencytrack/resources/v1/PermissionResourceTest.java @@ -64,7 +64,7 @@ public void getAllPermissionsTest() { Assert.assertNull(response.getHeaderString(TOTAL_COUNT_HEADER)); JsonArray json = parseJsonArray(response); Assert.assertNotNull(json); - Assert.assertEquals(12, json.size()); + Assert.assertEquals(35, json.size()); Assert.assertEquals("ACCESS_MANAGEMENT", json.getJsonObject(0).getString("name")); Assert.assertEquals("Allows the management of users, teams, and API keys", json.getJsonObject(0).getString("description")); }