From c3fdd9fcc8df834f379a99eedcf825ba1e86f363 Mon Sep 17 00:00:00 2001 From: Avgustin Marinov Date: Fri, 11 Jul 2025 16:50:01 +0300 Subject: [PATCH] Refactor permissions (#2544) Signed-off-by: Avgustin Marinov --- .../resource/MgmtRolloutResourceTest.java | 5 +- .../rest/AbstractRestIntegrationTest.java | 3 +- .../im/authentication/SpPermission.java | 246 +++--------------- .../hawkbit/im/authentication/SpRole.java | 8 +- .../StaticAuthenticationProvider.java | 2 +- .../security/SystemSecurityContext.java | 66 ++--- 6 files changed, 67 insertions(+), 263 deletions(-) diff --git a/hawkbit-mgmt/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtRolloutResourceTest.java b/hawkbit-mgmt/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtRolloutResourceTest.java index a57a793a9..b34be41c3 100644 --- a/hawkbit-mgmt/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtRolloutResourceTest.java +++ b/hawkbit-mgmt/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtRolloutResourceTest.java @@ -78,8 +78,9 @@ import org.springframework.test.web.servlet.ResultMatcher; * Feature: Component Tests - Management API
* Story: Rollout Resource */ -@TestPropertySource(locations = "classpath:/mgmt-test.properties", properties = { - "hawkbit.server.repository.dynamicRolloutsMinInvolvePeriodMS=-1" }) +@TestPropertySource( + locations = "classpath:/mgmt-test.properties", + properties = { "hawkbit.server.repository.dynamicRolloutsMinInvolvePeriodMS=-1" }) class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTest { private static final String HREF_ROLLOUT_PREFIX = "http://localhost/rest/v1/rollouts/"; diff --git a/hawkbit-rest-core/src/test/java/org/eclipse/hawkbit/rest/AbstractRestIntegrationTest.java b/hawkbit-rest-core/src/test/java/org/eclipse/hawkbit/rest/AbstractRestIntegrationTest.java index cbe29dac1..37197e068 100644 --- a/hawkbit-rest-core/src/test/java/org/eclipse/hawkbit/rest/AbstractRestIntegrationTest.java +++ b/hawkbit-rest-core/src/test/java/org/eclipse/hawkbit/rest/AbstractRestIntegrationTest.java @@ -28,8 +28,7 @@ import org.springframework.web.filter.CharacterEncodingFilter; * Abstract Test for Rest tests. */ @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.MOCK) -@ContextConfiguration(classes = { - RestConfiguration.class, JpaRepositoryConfiguration.class, TestConfiguration.class }) +@ContextConfiguration(classes = { RestConfiguration.class, JpaRepositoryConfiguration.class, TestConfiguration.class }) @WebAppConfiguration @AutoConfigureMockMvc public abstract class AbstractRestIntegrationTest extends AbstractIntegrationTest { diff --git a/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/im/authentication/SpPermission.java b/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/im/authentication/SpPermission.java index 2f637b336..68a4d3806 100644 --- a/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/im/authentication/SpPermission.java +++ b/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/im/authentication/SpPermission.java @@ -137,8 +137,7 @@ public final class SpPermission { public static final String APPROVE_ROLLOUT = "APPROVE_ROLLOUT"; /** - * Permission to administrate the system on a global, i.e. tenant - * independent scale. That includes the deletion of tenants. + * Permission to administrate the system on a global, i.e. tenant independent scale. That includes the deletion of tenants. */ public static final String SYSTEM_ADMIN = "SYSTEM_ADMIN"; @@ -167,10 +166,8 @@ public final class SpPermission { *

* Contains all the spring security evaluation expressions for the {@link PreAuthorize} annotation for method security. *

- * *

* Examples: - * * {@code * hasRole([role]) Returns true if the current principal has the specified role. * hasAnyRole([role1,role2]) Returns true if the current principal has any of the supplied roles (given as a comma-separated list of strings) @@ -188,225 +185,58 @@ public final class SpPermission { @NoArgsConstructor(access = AccessLevel.PRIVATE) public static final class SpringEvalExpressions { - /* - * Spring security eval expressions. - */ public static final String BRACKET_OPEN = "("; public static final String BRACKET_CLOSE = ")"; public static final String HAS_AUTH_PREFIX = "hasAuthority" + BRACKET_OPEN + "'"; public static final String HAS_AUTH_SUFFIX = "'" + BRACKET_CLOSE; public static final String HAS_AUTH_AND = " and "; + public static final String HAS_AUTH_OR = " or "; /** - * The role which contains the spring security context in case the - * system is executing code which is necessary to be privileged. + * The role which contains the spring security context in case the system is executing code which is necessary to be privileged. */ public static final String SYSTEM_ROLE = "ROLE_SYSTEM_CODE"; + /** - * Spring security eval hasAnyRole expression to check if the spring - * context contains system code role - * {@link SpringEvalExpressions#SYSTEM_ROLE}. - */ - public static final String IS_SYSTEM_CODE = HAS_AUTH_PREFIX + SYSTEM_ROLE + HAS_AUTH_SUFFIX; - /** - * The spring security eval expression operator {@code or}. - */ - public static final String HAS_AUTH_OR = " or "; - /** - * Spring security eval hasAuthority expression to check if spring - * context contains {@link SpPermission#UPDATE_TARGET} or - * {@link #IS_SYSTEM_CODE}. - */ - public static final String HAS_AUTH_UPDATE_TARGET = HAS_AUTH_PREFIX + UPDATE_TARGET + HAS_AUTH_SUFFIX - + HAS_AUTH_OR + IS_SYSTEM_CODE; - /** - * Spring security eval hasAuthority expression to check if spring - * context contains {@link SpPermission#SYSTEM_ADMIN} or - * {@link #IS_SYSTEM_CODE}. - */ - public static final String HAS_AUTH_SYSTEM_ADMIN = HAS_AUTH_PREFIX + SYSTEM_ADMIN + HAS_AUTH_SUFFIX - + HAS_AUTH_OR + IS_SYSTEM_CODE; - /** - * Spring security eval hasAuthority expression to check if spring - * context contains {@link SpPermission#READ_TARGET} or - * {@link #IS_SYSTEM_CODE}. - */ - public static final String HAS_AUTH_READ_TARGET = HAS_AUTH_PREFIX + READ_TARGET + HAS_AUTH_SUFFIX + HAS_AUTH_OR - + IS_SYSTEM_CODE; - /** - * Spring security eval hasAuthority expression to check if spring - * context contains {@link SpPermission#READ_TARGET_SEC_TOKEN} or - * {@link #IS_SYSTEM_CODE}. - */ - public static final String HAS_AUTH_READ_TARGET_SEC_TOKEN = HAS_AUTH_PREFIX + READ_TARGET_SEC_TOKEN - + HAS_AUTH_SUFFIX + HAS_AUTH_OR + IS_SYSTEM_CODE; - /** - * Spring security eval hasAuthority expression to check if spring - * context contains {@link SpPermission#CREATE_TARGET} or - * {@link #IS_SYSTEM_CODE}. - */ - public static final String HAS_AUTH_CREATE_TARGET = HAS_AUTH_PREFIX + CREATE_TARGET + HAS_AUTH_SUFFIX - + HAS_AUTH_OR + IS_SYSTEM_CODE; - /** - * Spring security eval hasAuthority expression to check if spring - * context contains {@link SpPermission#DELETE_TARGET} or - * {@link #IS_SYSTEM_CODE}. - */ - public static final String HAS_AUTH_DELETE_TARGET = HAS_AUTH_PREFIX + DELETE_TARGET + HAS_AUTH_SUFFIX - + HAS_AUTH_OR + IS_SYSTEM_CODE; - /** - * Spring security eval hasAuthority expression to check if spring - * context contains {@link SpPermission#READ_REPOSITORY} and - * {@link SpPermission#UPDATE_TARGET} or {@link #IS_SYSTEM_CODE}. - */ - public static final String HAS_AUTH_READ_REPOSITORY_AND_UPDATE_TARGET = BRACKET_OPEN + HAS_AUTH_PREFIX - + READ_REPOSITORY + HAS_AUTH_SUFFIX + HAS_AUTH_AND + HAS_AUTH_PREFIX + UPDATE_TARGET + HAS_AUTH_SUFFIX - + BRACKET_CLOSE + HAS_AUTH_OR + IS_SYSTEM_CODE; - /** - * Spring security eval hasAuthority expression to check if spring - * context contains {@link SpPermission#CREATE_REPOSITORY} or - * {@link #IS_SYSTEM_CODE}. - */ - public static final String HAS_AUTH_CREATE_REPOSITORY = HAS_AUTH_PREFIX + CREATE_REPOSITORY + HAS_AUTH_SUFFIX - + HAS_AUTH_OR + IS_SYSTEM_CODE; - /** - * Spring security eval hasAuthority expression to check if spring - * context contains {@link SpPermission#DELETE_REPOSITORY} or - * {@link #IS_SYSTEM_CODE}. - */ - public static final String HAS_AUTH_DELETE_REPOSITORY = HAS_AUTH_PREFIX + DELETE_REPOSITORY + HAS_AUTH_SUFFIX - + HAS_AUTH_OR + IS_SYSTEM_CODE; - /** - * Spring security eval hasAuthority expression to check if spring - * context contains {@link SpPermission#READ_REPOSITORY} or - * {@link #IS_SYSTEM_CODE}. - */ - public static final String HAS_AUTH_READ_REPOSITORY = HAS_AUTH_PREFIX + READ_REPOSITORY + HAS_AUTH_SUFFIX - + HAS_AUTH_OR + IS_SYSTEM_CODE; - /** - * Spring security eval hasAuthority expression to check if spring - * context contains {@link SpPermission#UPDATE_REPOSITORY} or - * {@link #IS_SYSTEM_CODE}. - */ - public static final String HAS_AUTH_UPDATE_REPOSITORY = HAS_AUTH_PREFIX + UPDATE_REPOSITORY + HAS_AUTH_SUFFIX - + HAS_AUTH_OR + IS_SYSTEM_CODE; - /** - * Spring security eval hasAuthority expression to check if spring - * context contains {@link SpPermission#READ_REPOSITORY} and - * {@link SpPermission#UPDATE_REPOSITORY} or {@link #IS_SYSTEM_CODE}. - */ - public static final String HAS_AUTH_READ_REPOSITORY_AND_UPDATE_REPOSITORY = BRACKET_OPEN + HAS_AUTH_PREFIX - + READ_REPOSITORY + HAS_AUTH_SUFFIX + HAS_AUTH_AND + HAS_AUTH_PREFIX + UPDATE_REPOSITORY - + HAS_AUTH_SUFFIX + BRACKET_CLOSE + HAS_AUTH_OR + IS_SYSTEM_CODE; - /** - * Spring security eval hasAuthority expression to check if spring - * context contains {@link SpPermission#READ_REPOSITORY} and - * {@link SpPermission#READ_TARGET} or {@link #IS_SYSTEM_CODE}. - */ - public static final String HAS_AUTH_READ_REPOSITORY_AND_READ_TARGET = BRACKET_OPEN + HAS_AUTH_PREFIX - + READ_REPOSITORY + HAS_AUTH_SUFFIX + HAS_AUTH_AND + HAS_AUTH_PREFIX + READ_TARGET + HAS_AUTH_SUFFIX - + BRACKET_CLOSE + HAS_AUTH_OR + IS_SYSTEM_CODE; - /** - * Spring security eval hasAuthority expression to check if spring - * context contains {@link SpPermission#DOWNLOAD_REPOSITORY_ARTIFACT} or - * {@link #IS_SYSTEM_CODE}. - */ - public static final String HAS_AUTH_DOWNLOAD_ARTIFACT = HAS_AUTH_PREFIX + DOWNLOAD_REPOSITORY_ARTIFACT - + HAS_AUTH_SUFFIX + HAS_AUTH_OR + IS_SYSTEM_CODE; - /** - * Spring security eval hasAuthority expression to check if spring - * context contains {@link SpPermission#CREATE_REPOSITORY} and - * {@link SpPermission#CREATE_TARGET} or {@link #IS_SYSTEM_CODE}. - */ - public static final String HAS_AUTH_CREATE_REPOSITORY_AND_CREATE_TARGET = BRACKET_OPEN + HAS_AUTH_PREFIX - + CREATE_REPOSITORY + HAS_AUTH_SUFFIX + HAS_AUTH_AND + HAS_AUTH_PREFIX + CREATE_TARGET + HAS_AUTH_SUFFIX - + BRACKET_CLOSE + HAS_AUTH_OR + IS_SYSTEM_CODE; - /** - * Spring security eval hasAuthority expression to check if spring - * context contains {@link SpPermission#READ_ROLLOUT} or - * {@link #IS_SYSTEM_CODE}. - */ - public static final String HAS_AUTH_ROLLOUT_MANAGEMENT_READ = HAS_AUTH_PREFIX + READ_ROLLOUT + HAS_AUTH_SUFFIX - + HAS_AUTH_OR + IS_SYSTEM_CODE; - /** - * Spring security eval hasAuthority expression to check if spring - * context contains {@link SpPermission#READ_ROLLOUT} and - * {@link SpPermission#READ_TARGET} or {@link #IS_SYSTEM_CODE}. - */ - public static final String HAS_AUTH_ROLLOUT_MANAGEMENT_READ_AND_TARGET_READ = BRACKET_OPEN + HAS_AUTH_PREFIX - + READ_ROLLOUT + HAS_AUTH_SUFFIX + HAS_AUTH_AND + HAS_AUTH_PREFIX + READ_TARGET + HAS_AUTH_SUFFIX - + BRACKET_CLOSE + HAS_AUTH_OR + IS_SYSTEM_CODE; - /** - * Spring security eval hasAuthority expression to check if spring - * context contains {@link SpPermission#CREATE_ROLLOUT} or - * {@link #IS_SYSTEM_CODE}. - */ - public static final String HAS_AUTH_ROLLOUT_MANAGEMENT_CREATE = HAS_AUTH_PREFIX + CREATE_ROLLOUT - + HAS_AUTH_SUFFIX + HAS_AUTH_OR + IS_SYSTEM_CODE; - /** - * Spring security eval hasAuthority expression to check if spring - * context contains {@link SpPermission#HANDLE_ROLLOUT} or - * {@link #IS_SYSTEM_CODE}. - */ - public static final String HAS_AUTH_ROLLOUT_MANAGEMENT_HANDLE = HAS_AUTH_PREFIX + HANDLE_ROLLOUT - + HAS_AUTH_SUFFIX + HAS_AUTH_OR + IS_SYSTEM_CODE; - /** - * Spring security eval hasAuthority expression to check if spring - * context contains {@link SpPermission#APPROVE_ROLLOUT} or - * {@link #IS_SYSTEM_CODE}. - */ - public static final String HAS_AUTH_ROLLOUT_MANAGEMENT_APPROVE = HAS_AUTH_PREFIX + APPROVE_ROLLOUT - + HAS_AUTH_SUFFIX + HAS_AUTH_OR + IS_SYSTEM_CODE; - /** - * Spring security eval hasAuthority expression to check if spring - * context contains {@link SpPermission#UPDATE_ROLLOUT} or - * {@link #IS_SYSTEM_CODE}. - */ - public static final String HAS_AUTH_ROLLOUT_MANAGEMENT_UPDATE = HAS_AUTH_PREFIX + UPDATE_ROLLOUT - + HAS_AUTH_SUFFIX + HAS_AUTH_OR + IS_SYSTEM_CODE; - /** - * Spring security eval hasAuthority expression to check if spring - * context contains {@link SpPermission#DELETE_ROLLOUT} or - * {@link #IS_SYSTEM_CODE}. - */ - public static final String HAS_AUTH_ROLLOUT_MANAGEMENT_DELETE = HAS_AUTH_PREFIX + DELETE_ROLLOUT - + HAS_AUTH_SUFFIX + HAS_AUTH_OR + IS_SYSTEM_CODE; - /** - * Spring security eval hasAuthority expression to check if spring - * context contains {@link SpPermission#READ_TENANT_CONFIGURATION} or - * {@link #IS_SYSTEM_CODE}. - */ - public static final String HAS_AUTH_TENANT_CONFIGURATION_READ = HAS_AUTH_PREFIX + READ_TENANT_CONFIGURATION - + HAS_AUTH_SUFFIX + HAS_AUTH_OR + IS_SYSTEM_CODE; - /** - * Spring security eval hasAuthority expression to check if spring - * context contains {@link SpPermission#TENANT_CONFIGURATION} or - * {@link #IS_SYSTEM_CODE}. - */ - public static final String HAS_AUTH_TENANT_CONFIGURATION = HAS_AUTH_PREFIX + TENANT_CONFIGURATION - + HAS_AUTH_SUFFIX + HAS_AUTH_OR + IS_SYSTEM_CODE; - /** - * The role which contains in the spring security context in case an - * controller is authenticated. + * The role which contains in the spring security context in case ancontroller is authenticated. */ public static final String CONTROLLER_ROLE = "ROLE_CONTROLLER"; /** - * The role which contained in the spring security context in case that a - * controller is authenticated, but only as 'anonymous'. + * The role which contained in the spring security context in case that a controller is authenticated, but only as 'anonymous'. */ public static final String CONTROLLER_ROLE_ANONYMOUS = "ROLE_CONTROLLER_ANONYMOUS"; - /** - * Spring security eval hasAnyRole expression to check if the spring - * context contains the anonymous role or the controller specific role - * {@link SpringEvalExpressions#CONTROLLER_ROLE}. - */ + + public static final String IS_SYSTEM_CODE = HAS_AUTH_PREFIX + SYSTEM_ROLE + HAS_AUTH_SUFFIX; + + public static final String HAS_AUTH_UPDATE_TARGET = HAS_AUTH_PREFIX + UPDATE_TARGET + HAS_AUTH_SUFFIX; + public static final String HAS_AUTH_SYSTEM_ADMIN = HAS_AUTH_PREFIX + SYSTEM_ADMIN + HAS_AUTH_SUFFIX; + public static final String HAS_AUTH_READ_TARGET = HAS_AUTH_PREFIX + READ_TARGET + HAS_AUTH_SUFFIX; + public static final String HAS_AUTH_CREATE_TARGET = HAS_AUTH_PREFIX + CREATE_TARGET + HAS_AUTH_SUFFIX; + public static final String HAS_AUTH_DELETE_TARGET = HAS_AUTH_PREFIX + DELETE_TARGET + HAS_AUTH_SUFFIX; + public static final String HAS_AUTH_READ_REPOSITORY_AND_UPDATE_TARGET = BRACKET_OPEN + HAS_AUTH_PREFIX + + READ_REPOSITORY + HAS_AUTH_SUFFIX + HAS_AUTH_AND + HAS_AUTH_PREFIX + UPDATE_TARGET + HAS_AUTH_SUFFIX + + BRACKET_CLOSE; + public static final String HAS_AUTH_CREATE_REPOSITORY = HAS_AUTH_PREFIX + CREATE_REPOSITORY + HAS_AUTH_SUFFIX; + public static final String HAS_AUTH_DELETE_REPOSITORY = HAS_AUTH_PREFIX + DELETE_REPOSITORY + HAS_AUTH_SUFFIX; + public static final String HAS_AUTH_READ_REPOSITORY = HAS_AUTH_PREFIX + READ_REPOSITORY + HAS_AUTH_SUFFIX; + public static final String HAS_AUTH_UPDATE_REPOSITORY = HAS_AUTH_PREFIX + UPDATE_REPOSITORY + HAS_AUTH_SUFFIX; + public static final String HAS_AUTH_READ_REPOSITORY_AND_READ_TARGET = BRACKET_OPEN + HAS_AUTH_PREFIX + + READ_REPOSITORY + HAS_AUTH_SUFFIX + HAS_AUTH_AND + HAS_AUTH_PREFIX + READ_TARGET + HAS_AUTH_SUFFIX + + BRACKET_CLOSE; + public static final String HAS_AUTH_DOWNLOAD_ARTIFACT = HAS_AUTH_PREFIX + DOWNLOAD_REPOSITORY_ARTIFACT + HAS_AUTH_SUFFIX; + public static final String HAS_AUTH_ROLLOUT_MANAGEMENT_READ = HAS_AUTH_PREFIX + READ_ROLLOUT + HAS_AUTH_SUFFIX; + public static final String HAS_AUTH_ROLLOUT_MANAGEMENT_READ_AND_TARGET_READ = BRACKET_OPEN + HAS_AUTH_PREFIX + + READ_ROLLOUT + HAS_AUTH_SUFFIX + HAS_AUTH_AND + HAS_AUTH_PREFIX + READ_TARGET + HAS_AUTH_SUFFIX + + BRACKET_CLOSE; + public static final String HAS_AUTH_ROLLOUT_MANAGEMENT_CREATE = HAS_AUTH_PREFIX + CREATE_ROLLOUT + HAS_AUTH_SUFFIX; + public static final String HAS_AUTH_ROLLOUT_MANAGEMENT_HANDLE = HAS_AUTH_PREFIX + HANDLE_ROLLOUT + HAS_AUTH_SUFFIX; + public static final String HAS_AUTH_ROLLOUT_MANAGEMENT_APPROVE = HAS_AUTH_PREFIX + APPROVE_ROLLOUT + HAS_AUTH_SUFFIX; + public static final String HAS_AUTH_ROLLOUT_MANAGEMENT_UPDATE = HAS_AUTH_PREFIX + UPDATE_ROLLOUT + HAS_AUTH_SUFFIX; + public static final String HAS_AUTH_ROLLOUT_MANAGEMENT_DELETE = HAS_AUTH_PREFIX + DELETE_ROLLOUT + HAS_AUTH_SUFFIX; + public static final String HAS_AUTH_TENANT_CONFIGURATION_READ = HAS_AUTH_PREFIX + READ_TENANT_CONFIGURATION + HAS_AUTH_SUFFIX; + public static final String HAS_AUTH_TENANT_CONFIGURATION = HAS_AUTH_PREFIX + TENANT_CONFIGURATION + HAS_AUTH_SUFFIX; + public static final String IS_CONTROLLER = "hasAnyRole('" + CONTROLLER_ROLE_ANONYMOUS + "', '" + CONTROLLER_ROLE + "')"; - /** - * Spring security eval hasAuthority expression to check if spring - * context contains {@link #IS_CONTROLLER} or - * {@link #HAS_AUTH_READ_REPOSITORY_AND_UPDATE_TARGET}. - */ - public static final String IS_CONTROLLER_OR_HAS_AUTH_READ_REPOSITORY_AND_UPDATE_TARGET = - IS_CONTROLLER + HAS_AUTH_OR + HAS_AUTH_READ_REPOSITORY_AND_UPDATE_TARGET; + public static final String IS_CONTROLLER_OR_HAS_AUTH_READ_REPOSITORY_AND_UPDATE_TARGET = IS_CONTROLLER + HAS_AUTH_OR + HAS_AUTH_READ_REPOSITORY_AND_UPDATE_TARGET; } } \ No newline at end of file diff --git a/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/im/authentication/SpRole.java b/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/im/authentication/SpRole.java index ab3a485ea..24100a53d 100644 --- a/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/im/authentication/SpRole.java +++ b/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/im/authentication/SpRole.java @@ -9,6 +9,8 @@ */ package org.eclipse.hawkbit.im.authentication; +import static org.eclipse.hawkbit.im.authentication.SpPermission.SpringEvalExpressions.SYSTEM_ROLE; + import lombok.AccessLevel; import lombok.NoArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -54,11 +56,15 @@ public final class SpRole { TENANT_ADMIN + IMPLIES + REPOSITORY_ADMIN + LINE_BREAK + TENANT_ADMIN + IMPLIES + ROLLOUT_ADMIN + LINE_BREAK + TENANT_ADMIN + IMPLIES + SpPermission.TENANT_CONFIGURATION + LINE_BREAK; + public static final String SYSTEM_ROLE_HIERARCHY = + SYSTEM_ROLE + IMPLIES + TENANT_ADMIN + LINE_BREAK + + SYSTEM_ROLE + IMPLIES + SpPermission.SYSTEM_ADMIN + LINE_BREAK; public static final String DEFAULT_ROLE_HIERARCHY = TARGET_ADMIN_HIERARCHY + REPOSITORY_ADMIN_HIERARCHY + ROLLOUT_ADMIN_HIERARCHY + TENANT_CONFIGURATION_HIERARCHY + - TENANT_ADMIN_HIERARCHY; + TENANT_ADMIN_HIERARCHY + + SYSTEM_ROLE_HIERARCHY; } \ No newline at end of file diff --git a/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/im/authentication/StaticAuthenticationProvider.java b/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/im/authentication/StaticAuthenticationProvider.java index 2cc8a5d70..15aed3ea0 100644 --- a/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/im/authentication/StaticAuthenticationProvider.java +++ b/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/im/authentication/StaticAuthenticationProvider.java @@ -40,7 +40,7 @@ public class StaticAuthenticationProvider extends DaoAuthenticationProvider { public StaticAuthenticationProvider( final TenantAwareUserProperties tenantAwareUserProperties, final SecurityProperties securityProperties) { - setUserDetailsService(userDetailsService(tenantAwareUserProperties, securityProperties)); + super(userDetailsService(tenantAwareUserProperties, securityProperties)); } @Override diff --git a/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/security/SystemSecurityContext.java b/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/security/SystemSecurityContext.java index f32b0b55b..1be9ebe1f 100644 --- a/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/security/SystemSecurityContext.java +++ b/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/security/SystemSecurityContext.java @@ -11,7 +11,6 @@ package org.eclipse.hawkbit.security; import java.io.Serial; import java.util.Collection; -import java.util.Collections; import java.util.List; import java.util.UUID; import java.util.concurrent.Callable; @@ -42,62 +41,35 @@ public class SystemSecurityContext { private final TenantAware tenantAware; private final RoleHierarchy roleHierarchy; - /** - * Autowired constructor. - * - * @param tenantAware the tenant aware bean to retrieve the current tenant - */ public SystemSecurityContext(final TenantAware tenantAware) { this(tenantAware, null); } - /** - * Autowired constructor. - * - * @param tenantAware the tenant aware bean to retrieve the current tenant - * @param roleHierarchy the roleHierarchy that is applied - */ public SystemSecurityContext(final TenantAware tenantAware, final RoleHierarchy roleHierarchy) { this.tenantAware = tenantAware; this.roleHierarchy = roleHierarchy; } /** - * Runs a given {@link Callable} within a system security context, which is - * permitted to call secured system code. Often the system needs to call - * secured methods by its own without relying on the current security - * context e.g. if the current security context does not contain the - * necessary permission it's necessary to execute code as system code to - * execute necessary methods and functionality. - *
- * The security context will be switched to the system code and back after - * the callable is called. - *
- * The system code is executed for a current tenant by using the - * {@link TenantAware#getCurrentTenant()}. + * Runs a given {@link Callable} within a system security context, which is permitted to call secured system code. Often the system needs + * to call secured methods by its own without relying on the current security context e.g. if the current security context does not contain + * the necessary permission it's necessary to execute code as system code to execute necessary methods and functionality.
+ * The security context will be switched to the system code and back after the callable is called.
+ * The system code is executed for a current tenant by using the {@link TenantAware#getCurrentTenant()}. * * @param callable the callable to call within the system security context * @return the return value of the {@link Callable#call()} method. */ - // Exception squid:S2221 - Callable declares Exception - @SuppressWarnings("squid:S2221") public T runAsSystem(final Callable callable) { return runAsSystemAsTenant(callable, tenantAware.getCurrentTenant()); } /** - * Runs a given {@link Callable} within a system security context, which is - * permitted to call secured system code. Often the system needs to call - * secured methods by its own without relying on the current security - * context e.g. if the current security context does not contain the - * necessary permission it's necessary to execute code as system code to - * execute necessary methods and functionality. - * - * The security context will be switched to the system code and back after - * the callable is called. - * - * The system code is executed for a specific given tenant by using the - * {@link TenantAware}. + * Runs a given {@link Callable} within a system security context, which is permitted to call secured system code. Often the system needs + * to call secured methods by its own without relying on the current security context e.g. if the current security context does not contain + * the necessary permission it's necessary to execute code as system code to execute necessary methods and functionality.
+ * The security context will be switched to the system code and back after the callable is called.
+ * The system code is executed for a specific given tenant by using the {@link TenantAware}. * * @param callable the callable to call within the system security context * @param tenant the tenant to act as system code @@ -121,20 +93,16 @@ public class SystemSecurityContext { /** * Runs a given {@link Callable} within a system security context, which has the provided {@link GrantedAuthority}s to successfully - * run the {@link Callable}. - *
+ * run the {@link Callable}.
* The security context will be switched to a new {@link SecurityContext} and back after the callable is called. * * @param tenant under which the {@link Callable#call()} must be executed. * @param callable to call within the security context * @return the return value of the {@link Callable#call()} method. */ - // The callable API throws a Exception and not a specific one - @SuppressWarnings({ "squid:S2221", "squid:S00112" }) public T runAsControllerAsTenant(@NotEmpty final String tenant, @NotNull final Callable callable) { final SecurityContext oldContext = SecurityContextHolder.getContext(); - List authorities = Collections - .singletonList(new SimpleGrantedAuthority(SpringEvalExpressions.CONTROLLER_ROLE_ANONYMOUS)); + final List authorities = List.of(new SimpleGrantedAuthority(SpringEvalExpressions.CONTROLLER_ROLE_ANONYMOUS)); try { return tenantAware.runAsTenant(tenant, () -> { setCustomSecurityContext(tenant, oldContext.getAuthentication().getPrincipal(), authorities); @@ -152,6 +120,7 @@ public class SystemSecurityContext { return SecurityContextHolder.getContext().getAuthentication() instanceof SystemCodeAuthentication; } + @SuppressWarnings("java:S3776") // java:S3776 - better in one place for better readability public boolean hasPermission(final String permission) { final SecurityContext context = SecurityContextHolder.getContext(); if (context != null) { @@ -180,8 +149,8 @@ public class SystemSecurityContext { SecurityContextHolder.setContext(securityContextImpl); } - private void setCustomSecurityContext(final String tenantId, final Object principal, - final Collection authorities) { + private void setCustomSecurityContext( + final String tenantId, final Object principal, final Collection authorities) { final AnonymousAuthenticationToken authenticationToken = new AnonymousAuthenticationToken( UUID.randomUUID().toString(), principal, authorities); authenticationToken.setDetails(new TenantAwareAuthenticationDetails(tenantId, true)); @@ -200,8 +169,7 @@ public class SystemSecurityContext { @Serial private static final long serialVersionUID = 1L; - private static final List AUTHORITIES = - Collections.singletonList(new SimpleGrantedAuthority(SpringEvalExpressions.SYSTEM_ROLE)); + private static final List AUTHORITIES = List.of(new SimpleGrantedAuthority(SpringEvalExpressions.SYSTEM_ROLE)); private final Authentication oldAuthentication; private SystemCodeAuthentication(final Authentication oldAuthentication) { @@ -240,7 +208,7 @@ public class SystemSecurityContext { @Override public void setAuthenticated(final boolean isAuthenticated) { - // not needed + throw new UnsupportedOperationException(); } } } \ No newline at end of file