diff --git a/hawkbit-autoconfigure/src/main/java/org/eclipse/hawkbit/autoconfigure/security/SecurityAutoConfiguration.java b/hawkbit-autoconfigure/src/main/java/org/eclipse/hawkbit/autoconfigure/security/SecurityAutoConfiguration.java index 1c49a58f4..e26fc99cc 100644 --- a/hawkbit-autoconfigure/src/main/java/org/eclipse/hawkbit/autoconfigure/security/SecurityAutoConfiguration.java +++ b/hawkbit-autoconfigure/src/main/java/org/eclipse/hawkbit/autoconfigure/security/SecurityAutoConfiguration.java @@ -12,6 +12,7 @@ package org.eclipse.hawkbit.autoconfigure.security; import java.util.Optional; import org.eclipse.hawkbit.audit.AuditLoggingAspect; +import org.eclipse.hawkbit.auth.SpRole; import org.eclipse.hawkbit.context.AccessContext; import org.eclipse.hawkbit.repository.RepositoryConfiguration; import org.eclipse.hawkbit.security.HawkbitSecurityProperties; @@ -47,7 +48,7 @@ public class SecurityAutoConfiguration { @Bean @ConditionalOnMissingBean public AuditorAware auditorAware() { - return () -> Optional.ofNullable(AccessContext.actor()); + return () -> Optional.ofNullable(SpRole.isController() ? "CONTROLLER_PLUG_AND_PLAY" : AccessContext.actor()); } @Bean diff --git a/hawkbit-core/src/main/java/org/eclipse/hawkbit/auth/SpRole.java b/hawkbit-core/src/main/java/org/eclipse/hawkbit/auth/SpRole.java index d281b60d3..011d58c57 100644 --- a/hawkbit-core/src/main/java/org/eclipse/hawkbit/auth/SpRole.java +++ b/hawkbit-core/src/main/java/org/eclipse/hawkbit/auth/SpRole.java @@ -9,9 +9,16 @@ */ package org.eclipse.hawkbit.auth; +import java.util.Collection; +import java.util.List; + import lombok.AccessLevel; import lombok.NoArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.core.context.SecurityContextHolder; /** * Software provisioning roles that implies set of permissions and reflects high-level roles. @@ -29,6 +36,7 @@ public final class SpRole { public static final String SYSTEM_ROLE = "ROLE_SYSTEM_CODE"; /** The role which contains in the spring security context in case a controller is authenticated */ public static final String CONTROLLER_ROLE = "ROLE_CONTROLLER"; + public static final Collection CONTROLLER_AUTHORITIES = List.of(new SimpleGrantedAuthority(CONTROLLER_ROLE)); private static final String IMPLIES = " > "; private static final String LINE_BREAK = "\n"; @@ -85,4 +93,16 @@ public final class SpRole { TENANT_ADMIN_HIERARCHY + SYSTEM_ROLE_HIERARCHY; // @formatter:on + + public static boolean isController() { + final Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + if (authentication == null) { + return false; + } + final Collection authorities = authentication.getAuthorities(); + if (authorities == CONTROLLER_AUTHORITIES) { + return true; + } + return authorities.size() == 1 && CONTROLLER_ROLE.equals(authorities.iterator().next().getAuthority()); + } } \ No newline at end of file diff --git a/hawkbit-core/src/main/java/org/eclipse/hawkbit/auth/StaticAuthenticationProvider.java b/hawkbit-core/src/main/java/org/eclipse/hawkbit/auth/StaticAuthenticationProvider.java index f4a404176..9c65921f9 100644 --- a/hawkbit-core/src/main/java/org/eclipse/hawkbit/auth/StaticAuthenticationProvider.java +++ b/hawkbit-core/src/main/java/org/eclipse/hawkbit/auth/StaticAuthenticationProvider.java @@ -17,8 +17,8 @@ import java.util.List; import java.util.function.Supplier; import java.util.regex.Pattern; -import org.eclipse.hawkbit.tenancy.TenantAwareAuthenticationDetails; -import org.eclipse.hawkbit.tenancy.TenantAwareUser; +import lombok.Data; +import org.eclipse.hawkbit.context.Principal; import org.eclipse.hawkbit.tenancy.TenantAwareUserProperties; import org.jspecify.annotations.NonNull; import org.springframework.boot.security.autoconfigure.SecurityProperties; @@ -47,12 +47,11 @@ public class StaticAuthenticationProvider extends DaoAuthenticationProvider { @Override protected @NonNull Authentication createSuccessAuthentication( @NonNull final Object principal, final Authentication authentication, final UserDetails user) { - final UsernamePasswordAuthenticationToken result = new UsernamePasswordAuthenticationToken( - principal, authentication.getCredentials(), user.getAuthorities()); - result.setDetails(user instanceof TenantAwareUser tenantAwareUser - ? new TenantAwareAuthenticationDetails(tenantAwareUser.getTenant(), false) - : user); - return result; + return new UsernamePasswordAuthenticationToken( + user instanceof TenantAwareUser tenantAwareUser + ? new Principal(tenantAwareUser.getTenant(), tenantAwareUser.getUsername()) + : principal, + authentication.getCredentials(), user.getAuthorities()); } private static UserDetailsService userDetailsService( @@ -61,9 +60,7 @@ public class StaticAuthenticationProvider extends DaoAuthenticationProvider { tenantAwareUserProperties.getUser().forEach((username, user) -> { final String password = password(user.getPassword()); final List credentials = createAuthorities(user.getRoles(), user.getPermissions(), Collections::emptyList); - userPrincipals.add(ObjectUtils.isEmpty(user.getTenant()) - ? new User(username, password, credentials) - : new TenantAwareUser(username, password, credentials, user.getTenant())); + userPrincipals.add(new TenantAwareUser(username, password, credentials, user.getTenant())); }); if (securityProperties != null && !securityProperties.getUser().isPasswordGenerated()) { @@ -136,4 +133,20 @@ public class StaticAuthenticationProvider extends DaoAuthenticationProvider { } } } + + @Data + private static class TenantAwareUser extends User { + + private final String tenant; + + private TenantAwareUser( + final String username, final String password, final Collection authorities, final String tenant) { + super(username, password, authorities); + this.tenant = tenant; + } + + private String getTenant() { + return tenant; + } + } } \ No newline at end of file diff --git a/hawkbit-core/src/main/java/org/eclipse/hawkbit/context/AccessContext.java b/hawkbit-core/src/main/java/org/eclipse/hawkbit/context/AccessContext.java index 6bcbbce94..abe7d8479 100644 --- a/hawkbit-core/src/main/java/org/eclipse/hawkbit/context/AccessContext.java +++ b/hawkbit-core/src/main/java/org/eclipse/hawkbit/context/AccessContext.java @@ -12,7 +12,6 @@ package org.eclipse.hawkbit.context; import java.io.Serial; import java.io.Serializable; import java.util.Collection; -import java.util.Collections; import java.util.List; import java.util.Objects; import java.util.Optional; @@ -25,8 +24,7 @@ import lombok.Data; import lombok.NoArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.eclipse.hawkbit.auth.SpRole; -import org.eclipse.hawkbit.tenancy.TenantAwareAuthenticationDetails; -import org.eclipse.hawkbit.tenancy.TenantAwareUser; +import org.jspecify.annotations.NonNull; import org.springframework.security.core.Authentication; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority; @@ -57,7 +55,7 @@ public class AccessContext { * @return could be empty if there is nothing to serialize or context aware is not supported. */ public static Optional securityContext() { - return Optional.ofNullable(SecurityContextHolder.getContext()).map(AccessContext::serialize); + return Optional.of(SecurityContextHolder.getContext()).map(AccessContext::serialize); } /** @@ -69,9 +67,7 @@ public class AccessContext { final Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); if (authentication != null) { final Object principal = authentication.getPrincipal(); - if (authentication.getDetails() instanceof TenantAwareAuthenticationDetails tenantAwareAuthenticationDetails) { - return tenantAwareAuthenticationDetails.tenant(); - } else if (principal instanceof TenantAwareUser tenantAwareUser) { + if (principal instanceof Principal tenantAwareUser) { return tenantAwareUser.getTenant(); } } @@ -270,12 +266,9 @@ public class AccessContext { } private static String resolve(final Authentication authentication) { - if (authentication.getDetails() instanceof TenantAwareAuthenticationDetails tenantAwareDetails && tenantAwareDetails.controller()) { - return "CONTROLLER_PLUG_AND_PLAY"; - } final Object principal = authentication.getPrincipal(); - if (principal instanceof ActorAware actorAware) { - return actorAware.getActor(); + if (principal instanceof Principal hawkbitPrincipal) { + return hawkbitPrincipal.getActor(); } if (principal instanceof UserDetails userDetails) { return userDetails.getUsername(); @@ -316,11 +309,6 @@ public class AccessContext { return authentication == null || !authentication.isAuthenticated() || authentication.getPrincipal() == null; } - public interface ActorAware { - - String getActor(); - } - // simplified info for the security context keeping just the basic info needed for background execution of // controller authentication is not supported - always is false // only authenticated user is supported @@ -343,16 +331,12 @@ public class AccessContext { if (!authentication.isAuthenticated()) { throw new IllegalStateException("Only authenticated context could be serialized"); } - if (authentication.getDetails() instanceof TenantAwareAuthenticationDetails tenantAwareDetails) { - if (tenantAwareDetails.controller()) { - throw new IllegalStateException("Controller authentication context is not supported"); - } - tenant = tenantAwareDetails.tenant(); - } else if (authentication.getPrincipal() instanceof TenantAwareUser tenantAwareUser) { - tenant = tenantAwareUser.getTenant(); + + if (authentication.getPrincipal() instanceof Principal principal) { + tenant = principal.getTenant(); } - // keep the auditor, ofr audit purposes, + // keep the auditor, for audit purposes, // sets principal to the resolved auditor and then deserialized authentication will return it as principal // since the class is not known to auditor aware - it shall used default - principal as auditor auditor = resolve(authentication); @@ -361,8 +345,7 @@ public class AccessContext { private SecurityContext toSecurityContext() { final SecurityContext ctx = SecurityContextHolder.createEmptyContext(); - final Object details = tenant == null ? null : new TenantAwareAuthenticationDetails(tenant, false); - final ActorAware principal = () -> auditor; + final Principal principal = new Principal(tenant, auditor); final Collection grantedAuthorities = Stream.of(authorities).map(SimpleGrantedAuthority::new).toList(); ctx.setAuthentication(new Authentication() { @@ -372,7 +355,7 @@ public class AccessContext { } @Override - public Collection getAuthorities() { + public @NonNull Collection getAuthorities() { return grantedAuthorities; } @@ -383,7 +366,7 @@ public class AccessContext { @Override public Object getDetails() { - return details; + return null; } @Override @@ -417,12 +400,10 @@ public class AccessContext { private static final List AUTHORITIES = List.of(new SimpleGrantedAuthority(SpRole.SYSTEM_ROLE)); - private final TenantAwareAuthenticationDetails details; - private final TenantAwareUser principal; + private final Principal principal; private SystemCodeAuthentication(final String tenant) { - details = new TenantAwareAuthenticationDetails(tenant, false); - principal = new TenantAwareUser(SYSTEM_ACTOR, SYSTEM_ACTOR, AUTHORITIES, tenant); + principal = new Principal(tenant, SYSTEM_ACTOR); } @Override @@ -431,7 +412,7 @@ public class AccessContext { } @Override - public Collection getAuthorities() { + public @NonNull Collection getAuthorities() { return AUTHORITIES; } @@ -442,7 +423,7 @@ public class AccessContext { @Override public Object getDetails() { - return details; + return null; } @Override @@ -471,13 +452,11 @@ public class AccessContext { private static final long serialVersionUID = 1L; private final Authentication delegate; - private final TenantAwareUser principal; - private final TenantAwareAuthenticationDetails tenantAwareAuthenticationDetails; + private final Principal principal; private AuthenticationDelegate(final String tenant, final String username, final Authentication delegate) { this.delegate = delegate; - principal = new TenantAwareUser(username, username, delegate == null ? Collections.emptyList() : delegate.getAuthorities(), tenant); - tenantAwareAuthenticationDetails = new TenantAwareAuthenticationDetails(tenant, false); + principal = new Principal(tenant, username); } @Override @@ -489,8 +468,7 @@ public class AccessContext { public boolean equals(final Object another) { if (another instanceof Authentication anotherAuthentication) { return Objects.equals(delegate, anotherAuthentication) && - Objects.equals(principal, anotherAuthentication.getPrincipal()) && - Objects.equals(tenantAwareAuthenticationDetails, anotherAuthentication.getDetails()); + Objects.equals(principal, anotherAuthentication.getPrincipal()); } else { return false; } @@ -507,8 +485,8 @@ public class AccessContext { } @Override - public Collection getAuthorities() { - return principal.getAuthorities(); + public @NonNull Collection getAuthorities() { + return delegate.getAuthorities(); } @Override @@ -518,7 +496,7 @@ public class AccessContext { @Override public Object getDetails() { - return tenantAwareAuthenticationDetails; + return delegate.getDetails(); } @Override diff --git a/hawkbit-core/src/main/java/org/eclipse/hawkbit/context/Mdc.java b/hawkbit-core/src/main/java/org/eclipse/hawkbit/context/Mdc.java index e42b7c852..66bd0afd2 100644 --- a/hawkbit-core/src/main/java/org/eclipse/hawkbit/context/Mdc.java +++ b/hawkbit-core/src/main/java/org/eclipse/hawkbit/context/Mdc.java @@ -21,7 +21,6 @@ import jakarta.servlet.http.HttpServletResponse; import lombok.AccessLevel; import lombok.NoArgsConstructor; -import org.eclipse.hawkbit.tenancy.TenantAwareAuthenticationDetails; import org.slf4j.MDC; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.core.Authentication; @@ -61,22 +60,14 @@ public class Mdc { return callable.call(); } - final Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); - if (authentication == null) { + if (SecurityContextHolder.getContext().getAuthentication() == null) { return callable.call(); } - final String tenant; - if (authentication.getDetails() instanceof TenantAwareAuthenticationDetails tenantAwareAuthenticationDetails) { - tenant = tenantAwareAuthenticationDetails.tenant(); - } else { - tenant = null; - } - + final String tenant = AccessContext.tenant(); final String actor = Optional.ofNullable(AccessContext.actor()) .filter(ctxActor -> !ctxActor.equals(AccessContext.SYSTEM_ACTOR)) // null and system are the same - system actor .orElse(null); - return asTenantAsActor0(tenant, actor, callable); } diff --git a/hawkbit-core/src/main/java/org/eclipse/hawkbit/context/Principal.java b/hawkbit-core/src/main/java/org/eclipse/hawkbit/context/Principal.java new file mode 100644 index 000000000..578ec49d1 --- /dev/null +++ b/hawkbit-core/src/main/java/org/eclipse/hawkbit/context/Principal.java @@ -0,0 +1,30 @@ +/** + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.eclipse.hawkbit.context; + +import java.io.Serial; +import java.io.Serializable; + +import lombok.Value; +import lombok.experimental.NonFinal; + +/** + * Represent an actor in the scope of the tenant + */ +@Value +@NonFinal +public class Principal implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + String tenant; + String actor; +} \ No newline at end of file diff --git a/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/TenantAwareAuthenticationDetails.java b/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/TenantAwareAuthenticationDetails.java deleted file mode 100644 index 3acc7b42f..000000000 --- a/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/TenantAwareAuthenticationDetails.java +++ /dev/null @@ -1,25 +0,0 @@ -/** - * Copyright (c) 2015 Bosch Software Innovations GmbH and others - * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - */ -package org.eclipse.hawkbit.tenancy; - -import java.io.Serial; -import java.io.Serializable; - -import org.springframework.security.authentication.AbstractAuthenticationToken; - -/** - * An authentication details object {@link AbstractAuthenticationToken#getDetails()} which is stored in the - * spring security authentication token details to transport the principal and tenant in the security context session. - */ -public record TenantAwareAuthenticationDetails(String tenant, boolean controller) implements Serializable { - - @Serial - private static final long serialVersionUID = 1L; -} \ No newline at end of file diff --git a/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/TenantAwareUser.java b/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/TenantAwareUser.java deleted file mode 100644 index 5b097261d..000000000 --- a/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/TenantAwareUser.java +++ /dev/null @@ -1,62 +0,0 @@ -/** - * Copyright (c) 2015 Bosch Software Innovations GmbH and others - * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - */ -package org.eclipse.hawkbit.tenancy; - -import java.io.Serial; -import java.util.Collection; -import java.util.Collections; - -import lombok.EqualsAndHashCode; -import lombok.Getter; -import lombok.ToString; -import org.springframework.security.core.GrantedAuthority; -import org.springframework.security.core.context.SecurityContext; -import org.springframework.security.core.userdetails.User; - -/** - * A software provisioning user principal definition stored in the {@link SecurityContext} which contains the user specific attributes. - */ -@Getter -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -public class TenantAwareUser extends User { - - @Serial - private static final long serialVersionUID = 1L; - - private final String tenant; - - public TenantAwareUser( - final String username, final String password, final Collection authorities, - final String tenant) { - super(username, password, authorities == null ? Collections.emptyList() : authorities); - this.tenant = tenant; - } - - @Override - public boolean isEnabled() { - return true; - } - - @Override - public boolean isAccountNonExpired() { - return true; - } - - @Override - public boolean isAccountNonLocked() { - return true; - } - - @Override - public boolean isCredentialsNonExpired() { - return true; - } -} \ No newline at end of file diff --git a/hawkbit-core/src/test/java/org/eclipse/hawkbit/context/AccessContextAsSystemTest.java b/hawkbit-core/src/test/java/org/eclipse/hawkbit/context/AccessContextAsSystemTest.java index 5296f9041..edf074e72 100644 --- a/hawkbit-core/src/test/java/org/eclipse/hawkbit/context/AccessContextAsSystemTest.java +++ b/hawkbit-core/src/test/java/org/eclipse/hawkbit/context/AccessContextAsSystemTest.java @@ -15,7 +15,6 @@ import static org.eclipse.hawkbit.context.AccessContext.asSystemAsTenant; import java.util.List; import org.eclipse.hawkbit.auth.SpRole; -import org.eclipse.hawkbit.tenancy.TenantAwareAuthenticationDetails; import org.junit.jupiter.api.Test; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.Authentication; @@ -66,7 +65,6 @@ class AccessContextAsSystemTest { assertThat(currentAuth.getClass().getSimpleName()).isEqualTo("SystemCodeAuthentication"); assertThat(currentAuth.getCredentials()).isNull(); assertThat(currentAuth.getAuthorities()).isEqualTo(List.of(new SimpleGrantedAuthority(SpRole.SYSTEM_ROLE))); - assertThat(currentAuth.getDetails()).isEqualTo(new TenantAwareAuthenticationDetails("tenant", false)); }); SecurityContextHolder.clearContext(); } diff --git a/hawkbit-core/src/test/java/org/eclipse/hawkbit/context/SecurityContextSerializerTest.java b/hawkbit-core/src/test/java/org/eclipse/hawkbit/context/SecurityContextSerializerTest.java index 70f6c35ef..26909bb7b 100644 --- a/hawkbit-core/src/test/java/org/eclipse/hawkbit/context/SecurityContextSerializerTest.java +++ b/hawkbit-core/src/test/java/org/eclipse/hawkbit/context/SecurityContextSerializerTest.java @@ -17,7 +17,6 @@ import java.util.Set; import java.util.stream.Collectors; import org.eclipse.hawkbit.auth.SpPermission; -import org.eclipse.hawkbit.tenancy.TenantAwareAuthenticationDetails; import org.junit.jupiter.api.Test; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.Authentication; @@ -33,31 +32,28 @@ class SecurityContextSerializerTest { @Test void testJsonSerialization() { final SecurityContext securityContext = SecurityContextHolder.getContext(); + final Principal principal = new Principal("my_tenant", "user"); final UsernamePasswordAuthenticationToken userPassAuthentication = new UsernamePasswordAuthenticationToken( - "user", null, AUTHORITIES.stream().map(SimpleGrantedAuthority::new).toList()); - final TenantAwareAuthenticationDetails details = new TenantAwareAuthenticationDetails("my_tenant", false); - userPassAuthentication.setDetails(details); + principal, null, AUTHORITIES.stream().map(SimpleGrantedAuthority::new).toList()); securityContext.setAuthentication(userPassAuthentication); final String serialized = serialize(securityContext); final SecurityContext deserialized = deserialize(serialized); final Authentication authentication = deserialized.getAuthentication(); assertThat(resolve(authentication)).hasToString("user"); + assertThat(authentication.getPrincipal()).isEqualTo(principal); assertThat(authentication.getAuthorities().stream().map(GrantedAuthority::getAuthority).collect(Collectors.toSet())) .isEqualTo(AUTHORITIES); assertThat(authentication.isAuthenticated()).isTrue(); - assertThat(authentication.getDetails()).isEqualTo(details); } @Test void testJsonSerializationSize() { final SecurityContext securityContext = SecurityContextHolder.getContext(); final UsernamePasswordAuthenticationToken userPassAuthentication = new UsernamePasswordAuthenticationToken( - "FirstName.FamilyName@domain1.domain0.com", + new Principal("my_test_enant", "FirstName.FamilyName@domain1.domain0.com"), Map.of("should not be in" + bigString(10_000), "the output" + bigString(15_000)), AUTHORITIES.stream().map(SimpleGrantedAuthority::new).toList()); - final TenantAwareAuthenticationDetails details = new TenantAwareAuthenticationDetails("my_test_enant", false); - userPassAuthentication.setDetails(details); securityContext.setAuthentication(userPassAuthentication); final String serialized = serialize(securityContext); diff --git a/hawkbit-ddi/hawkbit-ddi-resource/src/test/java/org/eclipse/hawkbit/ddi/rest/resource/DdiRootControllerTest.java b/hawkbit-ddi/hawkbit-ddi-resource/src/test/java/org/eclipse/hawkbit/ddi/rest/resource/DdiRootControllerTest.java index 41a9d3009..e9ffbe358 100644 --- a/hawkbit-ddi/hawkbit-ddi-resource/src/test/java/org/eclipse/hawkbit/ddi/rest/resource/DdiRootControllerTest.java +++ b/hawkbit-ddi/hawkbit-ddi-resource/src/test/java/org/eclipse/hawkbit/ddi/rest/resource/DdiRootControllerTest.java @@ -130,7 +130,7 @@ class DdiRootControllerTest extends AbstractDDiApiIntegrationTest { final Target findTargetByControllerID = targetManagement.getByControllerId(knownTargetControllerId); assertThat(findTargetByControllerID.getCreatedBy()).isEqualTo(knownCreatedBy); // make a poll, audit information should not be changed, run as controller principal! - callAs(withController("controller", CONTROLLER_ROLE), () -> { + callAs(withController("controller"), () -> { mvc.perform(get(CONTROLLER_BASE, AccessContext.tenant(), knownTargetControllerId)) .andDo(MockMvcResultPrinter.print()) .andExpect(status().isOk()); @@ -376,7 +376,7 @@ class DdiRootControllerTest extends AbstractDDiApiIntegrationTest { final String knownControllerId1 = "0815"; final long create = System.currentTimeMillis(); // make a poll, audit information should be set on plug and play - callAs(withController("controller", CONTROLLER_ROLE), () -> { + callAs(withController("controller"), () -> { mvc.perform(get(CONTROLLER_BASE, AccessContext.tenant(), knownControllerId1)) .andDo(MockMvcResultPrinter.print()) .andExpect(status().isOk()); @@ -385,9 +385,9 @@ class DdiRootControllerTest extends AbstractDDiApiIntegrationTest { // verify assertThat(targetManagement.getByControllerId(knownControllerId1)).satisfies(target -> { assertThat(target.getAddress()).isEqualTo(IpUtil.createHttpUri("127.0.0.1").toString()); - assertThat(target.getCreatedBy()).isEqualTo("CONTROLLER_PLUG_AND_PLAY"); + assertThat(target.getCreatedBy()).isEqualTo(CONTROLLER_PLUG_AND_PLAY); assertThat(target.getCreatedAt()).isGreaterThanOrEqualTo(create); - assertThat(target.getLastModifiedBy()).isEqualTo("CONTROLLER_PLUG_AND_PLAY"); + assertThat(target.getLastModifiedBy()).isEqualTo(CONTROLLER_PLUG_AND_PLAY); assertThat(target.getLastModifiedAt()).isGreaterThanOrEqualTo(create); }); } diff --git a/hawkbit-ddi/hawkbit-ddi-resource/src/test/resources/ddi-test.properties b/hawkbit-ddi/hawkbit-ddi-resource/src/test/resources/ddi-test.properties index eaa93d23e..8cb37a448 100644 --- a/hawkbit-ddi/hawkbit-ddi-resource/src/test/resources/ddi-test.properties +++ b/hawkbit-ddi/hawkbit-ddi-resource/src/test/resources/ddi-test.properties @@ -9,6 +9,7 @@ # # Logging START - activate to see request/response details +logging.level.root=WARN #logging.level.org.eclipse.hawkbit.rest.util.MockMvcResultPrinter=DEBUG # Logging END diff --git a/hawkbit-ddi/hawkbit-ddi-security/src/main/java/org/eclipse/hawkbit/security/controller/Authenticator.java b/hawkbit-ddi/hawkbit-ddi-security/src/main/java/org/eclipse/hawkbit/security/controller/Authenticator.java index 79b658e09..0b0542b89 100644 --- a/hawkbit-ddi/hawkbit-ddi-security/src/main/java/org/eclipse/hawkbit/security/controller/Authenticator.java +++ b/hawkbit-ddi/hawkbit-ddi-security/src/main/java/org/eclipse/hawkbit/security/controller/Authenticator.java @@ -12,19 +12,15 @@ package org.eclipse.hawkbit.security.controller; import static org.eclipse.hawkbit.context.AccessContext.asTenant; import java.io.Serial; -import java.util.Collection; -import java.util.List; import java.util.Objects; import lombok.EqualsAndHashCode; import org.eclipse.hawkbit.auth.SpRole; +import org.eclipse.hawkbit.context.Principal; import org.eclipse.hawkbit.repository.helper.TenantConfigHelper; -import org.eclipse.hawkbit.tenancy.TenantAwareAuthenticationDetails; import org.slf4j.Logger; import org.springframework.security.authentication.AbstractAuthenticationToken; import org.springframework.security.core.Authentication; -import org.springframework.security.core.GrantedAuthority; -import org.springframework.security.core.authority.SimpleGrantedAuthority; /** * Interface for Authentication mechanism. @@ -65,14 +61,11 @@ public interface Authenticator { @Serial private static final long serialVersionUID = 1L; - private static final Collection CONTROLLER_AUTHORITY = - List.of(new SimpleGrantedAuthority(SpRole.CONTROLLER_ROLE)); - private final String controllerId; + private final Principal principal; AuthenticatedController(final String tenant, final String controllerId) { - super(CONTROLLER_AUTHORITY); - super.setDetails(new TenantAwareAuthenticationDetails(tenant, true)); - this.controllerId = controllerId; + super(SpRole.CONTROLLER_AUTHORITIES); + this.principal = new Principal(tenant, controllerId); setAuthenticated(true); } @@ -83,7 +76,7 @@ public interface Authenticator { @Override public Object getPrincipal() { - return controllerId; + return principal; } } } diff --git a/hawkbit-ddi/hawkbit-ddi-security/src/test/java/org/eclipse/hawkbit/security/controller/GatewayTokenAuthenticatorTest.java b/hawkbit-ddi/hawkbit-ddi-security/src/test/java/org/eclipse/hawkbit/security/controller/GatewayTokenAuthenticatorTest.java index 0a6596393..db9a123cb 100644 --- a/hawkbit-ddi/hawkbit-ddi-security/src/test/java/org/eclipse/hawkbit/security/controller/GatewayTokenAuthenticatorTest.java +++ b/hawkbit-ddi/hawkbit-ddi-security/src/test/java/org/eclipse/hawkbit/security/controller/GatewayTokenAuthenticatorTest.java @@ -15,6 +15,7 @@ import static org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationPrope import static org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties.TenantConfigurationKey.AUTHENTICATION_GATEWAY_SECURITY_TOKEN_KEY; import static org.mockito.Mockito.when; +import org.eclipse.hawkbit.context.Principal; import org.eclipse.hawkbit.repository.TenantConfigurationManagement; import org.eclipse.hawkbit.repository.helper.TenantConfigHelper; import org.eclipse.hawkbit.repository.model.TenantConfigurationValue; @@ -66,7 +67,7 @@ class GatewayTokenAuthenticatorTest { assertThat(authenticator.authenticate(securityToken)) .isNotNull() - .hasFieldOrPropertyWithValue("principal", CONTROLLER_ID); + .hasFieldOrPropertyWithValue("principal", new Principal("DEFAULT", CONTROLLER_ID)); } /** diff --git a/hawkbit-ddi/hawkbit-ddi-security/src/test/java/org/eclipse/hawkbit/security/controller/SecurityHeaderAuthenticatorTest.java b/hawkbit-ddi/hawkbit-ddi-security/src/test/java/org/eclipse/hawkbit/security/controller/SecurityHeaderAuthenticatorTest.java index 79fde36c7..c953ee282 100644 --- a/hawkbit-ddi/hawkbit-ddi-security/src/test/java/org/eclipse/hawkbit/security/controller/SecurityHeaderAuthenticatorTest.java +++ b/hawkbit-ddi/hawkbit-ddi-security/src/test/java/org/eclipse/hawkbit/security/controller/SecurityHeaderAuthenticatorTest.java @@ -14,6 +14,7 @@ import static org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationPrope import static org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties.TenantConfigurationKey.AUTHENTICATION_HEADER_ENABLED; import static org.mockito.Mockito.when; +import org.eclipse.hawkbit.context.Principal; import org.eclipse.hawkbit.repository.TenantConfigurationManagement; import org.eclipse.hawkbit.repository.helper.TenantConfigHelper; import org.eclipse.hawkbit.repository.model.TenantConfigurationValue; @@ -77,7 +78,7 @@ class SecurityHeaderAuthenticatorTest { assertThat(authenticator.authenticate(securityToken)) .isNotNull() - .hasFieldOrPropertyWithValue("principal", CA_COMMON_NAME_VALUE); + .hasFieldOrPropertyWithValue("principal", new Principal("DEFAULT", CA_COMMON_NAME_VALUE)); } /** @@ -92,13 +93,13 @@ class SecurityHeaderAuthenticatorTest { assertThat(authenticator.authenticate(prepareSecurityToken(SINGLE_AUTHORITY))) .isNotNull() - .hasFieldOrPropertyWithValue("principal", CA_COMMON_NAME_VALUE); + .hasFieldOrPropertyWithValue("principal", new Principal("DEFAULT", CA_COMMON_NAME_VALUE)); assertThat(authenticator.authenticate(prepareSecurityToken(SECOND_AUTHORITY))) .isNotNull() - .hasFieldOrPropertyWithValue("principal", CA_COMMON_NAME_VALUE); + .hasFieldOrPropertyWithValue("principal", new Principal("DEFAULT", CA_COMMON_NAME_VALUE)); assertThat(authenticator.authenticate(prepareSecurityToken(THIRD_AUTHORITY))) .isNotNull() - .hasFieldOrPropertyWithValue("principal", CA_COMMON_NAME_VALUE); + .hasFieldOrPropertyWithValue("principal", new Principal("DEFAULT", CA_COMMON_NAME_VALUE)); } /** diff --git a/hawkbit-ddi/hawkbit-ddi-security/src/test/java/org/eclipse/hawkbit/security/controller/SecurityTokenAuthenticatorTest.java b/hawkbit-ddi/hawkbit-ddi-security/src/test/java/org/eclipse/hawkbit/security/controller/SecurityTokenAuthenticatorTest.java index 990f83ef9..94d1cfe42 100644 --- a/hawkbit-ddi/hawkbit-ddi-security/src/test/java/org/eclipse/hawkbit/security/controller/SecurityTokenAuthenticatorTest.java +++ b/hawkbit-ddi/hawkbit-ddi-security/src/test/java/org/eclipse/hawkbit/security/controller/SecurityTokenAuthenticatorTest.java @@ -15,6 +15,7 @@ import static org.mockito.Mockito.when; import java.util.Optional; +import org.eclipse.hawkbit.context.Principal; import org.eclipse.hawkbit.repository.ControllerManagement; import org.eclipse.hawkbit.repository.TenantConfigurationManagement; import org.eclipse.hawkbit.repository.helper.TenantConfigHelper; @@ -72,7 +73,7 @@ class SecurityTokenAuthenticatorTest { assertThat(authenticator.authenticate(securityToken)) .isNotNull() - .hasFieldOrPropertyWithValue("principal", CONTROLLER_ID); + .hasFieldOrPropertyWithValue("principal", new Principal("DEFAULT", CONTROLLER_ID)); } /** diff --git a/hawkbit-dmf/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerService.java b/hawkbit-dmf/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerService.java index 246f74dc2..3c39541f6 100644 --- a/hawkbit-dmf/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerService.java +++ b/hawkbit-dmf/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerService.java @@ -24,6 +24,7 @@ import jakarta.validation.constraints.NotNull; import lombok.extern.slf4j.Slf4j; import org.eclipse.hawkbit.audit.AuditLog; import org.eclipse.hawkbit.auth.SpRole; +import org.eclipse.hawkbit.context.Principal; import org.eclipse.hawkbit.dmf.amqp.api.EventTopic; import org.eclipse.hawkbit.dmf.amqp.api.MessageHeaderKey; import org.eclipse.hawkbit.dmf.amqp.api.MessageType; @@ -47,7 +48,6 @@ import org.eclipse.hawkbit.repository.model.ActionProperties; import org.eclipse.hawkbit.repository.model.DistributionSet; import org.eclipse.hawkbit.repository.model.SoftwareModule; import org.eclipse.hawkbit.repository.model.Target; -import org.eclipse.hawkbit.tenancy.TenantAwareAuthenticationDetails; import org.eclipse.hawkbit.utils.IpUtil; import org.springframework.amqp.AmqpRejectAndDontRequeueException; import org.springframework.amqp.core.Message; @@ -170,11 +170,9 @@ public class AmqpMessageHandlerService extends BaseAmqpService { } private static void setTenantSecurityContext(final String tenant) { - final AnonymousAuthenticationToken authenticationToken = new AnonymousAuthenticationToken( - UUID.randomUUID().toString(), "AMQP-Controller", - List.of(new SimpleGrantedAuthority(SpRole.CONTROLLER_ROLE))); - authenticationToken.setDetails(new TenantAwareAuthenticationDetails(tenant, true)); - setSecurityContext(authenticationToken); + setSecurityContext(new AnonymousAuthenticationToken( + UUID.randomUUID().toString(), new Principal(tenant, "AMQP-Controller"), + List.of(new SimpleGrantedAuthority(SpRole.CONTROLLER_ROLE)))); } private static boolean isOptionalMessageBodyEmpty(final Message message) { diff --git a/hawkbit-dmf/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/integration/AbstractAmqpServiceIntegrationTest.java b/hawkbit-dmf/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/integration/AbstractAmqpServiceIntegrationTest.java index 4b9161ea3..7b9c57445 100644 --- a/hawkbit-dmf/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/integration/AbstractAmqpServiceIntegrationTest.java +++ b/hawkbit-dmf/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/integration/AbstractAmqpServiceIntegrationTest.java @@ -70,7 +70,6 @@ import org.springframework.util.CollectionUtils; abstract class AbstractAmqpServiceIntegrationTest extends AbstractAmqpIntegrationTest { protected static final String TENANT_EXIST = "DEFAULT"; - protected static final String CREATED_BY = "CONTROLLER_PLUG_AND_PLAY"; protected static final String CORRELATION_ID = UUID.randomUUID().toString(); protected ReplyToListener replyToListener; @@ -132,7 +131,7 @@ abstract class AbstractAmqpServiceIntegrationTest extends AbstractAmqpIntegratio protected DistributionSetAssignmentResult registerTargetAndAssignDistributionSet(final Long assignDs, final TargetUpdateStatus expectedStatus, final Set expectedSoftwareModulesInMessage, final String controllerId) { - registerAndAssertTargetWithExistingTenant(controllerId, 1, expectedStatus, CREATED_BY); + registerAndAssertTargetWithExistingTenant(controllerId, 1, expectedStatus, CONTROLLER_PLUG_AND_PLAY); final DistributionSetAssignmentResult assignmentResult = assignDistributionSet(assignDs, controllerId); if (isConfirmationFlowEnabled()) { @@ -253,7 +252,7 @@ abstract class AbstractAmqpServiceIntegrationTest extends AbstractAmqpIntegratio protected void registerAndAssertTargetWithExistingTenant(final String controllerId, final int existingTargetsAfterCreation) { registerAndAssertTargetWithExistingTenant(controllerId, existingTargetsAfterCreation, - TargetUpdateStatus.REGISTERED, CREATED_BY); + TargetUpdateStatus.REGISTERED, CONTROLLER_PLUG_AND_PLAY); } protected void registerAndAssertTargetWithExistingTenant(final String controllerId, @@ -282,7 +281,7 @@ abstract class AbstractAmqpServiceIntegrationTest extends AbstractAmqpIntegratio final Map attributes) { final int version = controllerManagement.findByControllerId(controllerId).get().getOptLockRevision(); registerAndAssertTargetWithExistingTenant(controllerId, name, existingTargetsAfterCreation, - expectedTargetStatus, CREATED_BY, attributes, () -> findTargetBasedOnNewVersion(controllerId, version)); + expectedTargetStatus, CONTROLLER_PLUG_AND_PLAY, attributes, () -> findTargetBasedOnNewVersion(controllerId, version)); } protected Message createTargetMessage(final String controllerId, final String tenant) { diff --git a/hawkbit-dmf/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/integration/AmqpMessageHandlerServiceIntegrationTest.java b/hawkbit-dmf/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/integration/AmqpMessageHandlerServiceIntegrationTest.java index bfc203d1b..81169d5f9 100644 --- a/hawkbit-dmf/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/integration/AmqpMessageHandlerServiceIntegrationTest.java +++ b/hawkbit-dmf/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/integration/AmqpMessageHandlerServiceIntegrationTest.java @@ -133,7 +133,7 @@ class AmqpMessageHandlerServiceIntegrationTest extends AbstractAmqpServiceIntegr void registerTargetWithName() { final String controllerId = TARGET_PREFIX + "registerTargetWithName"; final String name = "NonDefaultTargetName"; - registerAndAssertTargetWithExistingTenant(controllerId, name, 1, TargetUpdateStatus.REGISTERED, CREATED_BY, null); + registerAndAssertTargetWithExistingTenant(controllerId, name, 1, TargetUpdateStatus.REGISTERED, CONTROLLER_PLUG_AND_PLAY, null); registerSameTargetAndAssertBasedOnVersion(controllerId, name + "_updated", 1, TargetUpdateStatus.REGISTERED, null); Mockito.verifyNoInteractions(getDeadletterListener()); @@ -153,7 +153,7 @@ class AmqpMessageHandlerServiceIntegrationTest extends AbstractAmqpServiceIntegr attributes.put("testKey1", "testValue1"); attributes.put("testKey2", "testValue2"); - registerAndAssertTargetWithExistingTenant(controllerId, null, 1, TargetUpdateStatus.REGISTERED, CREATED_BY, attributes); + registerAndAssertTargetWithExistingTenant(controllerId, null, 1, TargetUpdateStatus.REGISTERED, CONTROLLER_PLUG_AND_PLAY, attributes); attributes.put("testKey3", "testValue3"); registerSameTargetAndAssertBasedOnVersion(controllerId, null, 1, TargetUpdateStatus.REGISTERED, attributes); @@ -176,7 +176,7 @@ class AmqpMessageHandlerServiceIntegrationTest extends AbstractAmqpServiceIntegr final Map attributes = new HashMap<>(); attributes.put("testKey1", "testValue1"); attributes.put("testKey2", "testValue2"); - registerAndAssertTargetWithExistingTenant(controllerId, name, 1, TargetUpdateStatus.REGISTERED, CREATED_BY, attributes); + registerAndAssertTargetWithExistingTenant(controllerId, name, 1, TargetUpdateStatus.REGISTERED, CONTROLLER_PLUG_AND_PLAY, attributes); attributes.put("testKey3", "testValue3"); registerSameTargetAndAssertBasedOnVersion(controllerId, name + "_updated", 1, TargetUpdateStatus.REGISTERED, attributes); diff --git a/hawkbit-mgmt/hawkbit-mgmt-resource/src/test/resources/mgmt-test.properties b/hawkbit-mgmt/hawkbit-mgmt-resource/src/test/resources/mgmt-test.properties index 220c6899a..858eb020e 100644 --- a/hawkbit-mgmt/hawkbit-mgmt-resource/src/test/resources/mgmt-test.properties +++ b/hawkbit-mgmt/hawkbit-mgmt-resource/src/test/resources/mgmt-test.properties @@ -9,6 +9,7 @@ # # Logging START - activate to see request/response details +logging.level.root=WARN #logging.level.org.eclipse.hawkbit.rest.util.MockMvcResultPrinter=DEBUG # Logging END hawkbit.events.remote.enabled=false diff --git a/hawkbit-mgmt/hawkbit-mgmt-starter/src/main/java/org/eclipse/hawkbit/autoconfigure/mgmt/MgmtSecurityConfiguration.java b/hawkbit-mgmt/hawkbit-mgmt-starter/src/main/java/org/eclipse/hawkbit/autoconfigure/mgmt/MgmtSecurityConfiguration.java index afd951409..d3251a47e 100644 --- a/hawkbit-mgmt/hawkbit-mgmt-starter/src/main/java/org/eclipse/hawkbit/autoconfigure/mgmt/MgmtSecurityConfiguration.java +++ b/hawkbit-mgmt/hawkbit-mgmt-starter/src/main/java/org/eclipse/hawkbit/autoconfigure/mgmt/MgmtSecurityConfiguration.java @@ -21,8 +21,8 @@ import java.util.Optional; import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.extern.slf4j.Slf4j; -import org.eclipse.hawkbit.auth.SpPermission; import org.eclipse.hawkbit.context.Mdc; +import org.eclipse.hawkbit.context.Principal; import org.eclipse.hawkbit.mgmt.rest.api.MgmtRestConstants; import org.eclipse.hawkbit.oidc.OidcProperties; import org.eclipse.hawkbit.oidc.OidcProperties.Oauth2.ResourceServer.Jwt.Claim; @@ -30,8 +30,6 @@ import org.eclipse.hawkbit.repository.SystemManagement; import org.eclipse.hawkbit.rest.SecurityManagedConfiguration; import org.eclipse.hawkbit.rest.security.DosFilter; import org.eclipse.hawkbit.security.HawkbitSecurityProperties; -import org.eclipse.hawkbit.tenancy.TenantAwareAuthenticationDetails; -import org.eclipse.hawkbit.tenancy.TenantAwareUser; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; @@ -84,9 +82,7 @@ public class MgmtSecurityConfiguration { public FilterRegistrationBean dosFilterREST() { final FilterRegistrationBean filterRegBean = SecurityManagedConfiguration.dosFilter(null, securityProperties.getDos().getFilter(), securityProperties.getClients()); - filterRegBean.setUrlPatterns(List.of( - MgmtRestConstants.REST + "/*", - "/system/admin/*")); + filterRegBean.setUrlPatterns(List.of(MgmtRestConstants.REST + "/*", "/system/admin/*")); filterRegBean.setOrder(SecurityManagedConfiguration.DOS_FILTER_ORDER); filterRegBean.setName("dosMgmtFilter"); @@ -179,7 +175,7 @@ public class MgmtSecurityConfiguration { .map(GrantedAuthority.class::cast) .toList()) .orElseGet(Collections::emptyList); - return new HawkbitJwtAuthenticationToken(jwt, new TenantAwareUser(username, username, authorities, tenant), authorities); + return new HawkbitJwtAuthenticationToken(jwt, new Principal(tenant, username), authorities); })); } @@ -218,9 +214,8 @@ public class MgmtSecurityConfiguration { private final String name; - private HawkbitJwtAuthenticationToken(final Jwt jwt, TenantAwareUser user, final Collection authorities) { - super(jwt, user, jwt, authorities); - setDetails(new TenantAwareAuthenticationDetails(user.getTenant(), false)); + private HawkbitJwtAuthenticationToken(final Jwt jwt, Principal principal, final Collection authorities) { + super(jwt, principal, jwt, authorities); name = jwt.getSubject(); setAuthenticated(true); } diff --git a/hawkbit-repository/hawkbit-repository-jpa-eclipselink/src/main/java/org/eclipse/hawkbit/repository/jpa/model/AbstractJpaBaseEntity.java b/hawkbit-repository/hawkbit-repository-jpa-eclipselink/src/main/java/org/eclipse/hawkbit/repository/jpa/model/AbstractJpaBaseEntity.java index 65cb0b454..73ef95eee 100644 --- a/hawkbit-repository/hawkbit-repository-jpa-eclipselink/src/main/java/org/eclipse/hawkbit/repository/jpa/model/AbstractJpaBaseEntity.java +++ b/hawkbit-repository/hawkbit-repository-jpa-eclipselink/src/main/java/org/eclipse/hawkbit/repository/jpa/model/AbstractJpaBaseEntity.java @@ -26,16 +26,14 @@ import lombok.AccessLevel; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; +import org.eclipse.hawkbit.auth.SpRole; import org.eclipse.hawkbit.repository.jpa.executor.AfterTransactionCommitExecutor; import org.eclipse.hawkbit.repository.model.BaseEntity; -import org.eclipse.hawkbit.tenancy.TenantAwareAuthenticationDetails; import org.springframework.data.annotation.CreatedBy; import org.springframework.data.annotation.CreatedDate; import org.springframework.data.annotation.LastModifiedBy; import org.springframework.data.annotation.LastModifiedDate; import org.springframework.data.jpa.domain.support.AuditingEntityListener; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.context.SecurityContextHolder; /** * Base hawkBit entity class containing the common attributes for EclipseLink. @@ -95,7 +93,7 @@ public abstract class AbstractJpaBaseEntity implements BaseEntity { @LastModifiedBy public void setLastModifiedBy(final String lastModifiedBy) { - if (this.lastModifiedBy != null && isController()) { + if (this.lastModifiedBy != null && SpRole.isController()) { // initialized and controller = doesn't update return; } @@ -110,7 +108,7 @@ public abstract class AbstractJpaBaseEntity implements BaseEntity { @LastModifiedDate public void setLastModifiedAt(final long lastModifiedAt) { - if (this.lastModifiedAt != 0 && isController()) { + if (this.lastModifiedAt != 0 && SpRole.isController()) { // initialized and controller = doesn't update return; } @@ -197,11 +195,4 @@ public abstract class AbstractJpaBaseEntity implements BaseEntity { // fire events onl AFTER transaction commit AfterTransactionCommitExecutor.afterCommit(runnable); } - - protected boolean isController() { - final Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); - return authentication != null - && authentication.getDetails() instanceof TenantAwareAuthenticationDetails tenantAwareDetails - && tenantAwareDetails.controller(); - } } \ No newline at end of file diff --git a/hawkbit-repository/hawkbit-repository-jpa-eclipselink/src/main/java/org/eclipse/hawkbit/repository/jpa/model/AbstractJpaTenantAwareBaseEntity.java b/hawkbit-repository/hawkbit-repository-jpa-eclipselink/src/main/java/org/eclipse/hawkbit/repository/jpa/model/AbstractJpaTenantAwareBaseEntity.java index 76305e1a0..ef77f6412 100644 --- a/hawkbit-repository/hawkbit-repository-jpa-eclipselink/src/main/java/org/eclipse/hawkbit/repository/jpa/model/AbstractJpaTenantAwareBaseEntity.java +++ b/hawkbit-repository/hawkbit-repository-jpa-eclipselink/src/main/java/org/eclipse/hawkbit/repository/jpa/model/AbstractJpaTenantAwareBaseEntity.java @@ -86,9 +86,7 @@ public abstract class AbstractJpaTenantAwareBaseEntity extends AbstractJpaBaseEn final String currentTenant = AccessContext.tenant(); if (currentTenant == null) { throw new TenantNotExistException( - String.format( - "AccessContext %s does not exists, cannot create entity %s with id %d", - AccessContext.tenant(), getClass(), getId())); + String.format("Tenant not found in the context, cannot create entity %s with id %d", getClass(), getId())); } setTenant(currentTenant.toUpperCase()); } diff --git a/hawkbit-repository/hawkbit-repository-jpa-hibernate/src/main/java/org/eclipse/hawkbit/repository/jpa/model/AbstractJpaBaseEntity.java b/hawkbit-repository/hawkbit-repository-jpa-hibernate/src/main/java/org/eclipse/hawkbit/repository/jpa/model/AbstractJpaBaseEntity.java index 95e15bbf6..c8c39bc28 100644 --- a/hawkbit-repository/hawkbit-repository-jpa-hibernate/src/main/java/org/eclipse/hawkbit/repository/jpa/model/AbstractJpaBaseEntity.java +++ b/hawkbit-repository/hawkbit-repository-jpa-hibernate/src/main/java/org/eclipse/hawkbit/repository/jpa/model/AbstractJpaBaseEntity.java @@ -9,8 +9,6 @@ */ package org.eclipse.hawkbit.repository.jpa.model; -import java.io.Serial; - import jakarta.persistence.Access; import jakarta.persistence.AccessType; import jakarta.persistence.Column; @@ -28,16 +26,14 @@ import lombok.AccessLevel; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; +import org.eclipse.hawkbit.auth.SpRole; import org.eclipse.hawkbit.repository.jpa.executor.AfterTransactionCommitExecutor; import org.eclipse.hawkbit.repository.model.BaseEntity; -import org.eclipse.hawkbit.tenancy.TenantAwareAuthenticationDetails; import org.springframework.data.annotation.CreatedBy; import org.springframework.data.annotation.CreatedDate; import org.springframework.data.annotation.LastModifiedBy; import org.springframework.data.annotation.LastModifiedDate; import org.springframework.data.jpa.domain.support.AuditingEntityListener; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.context.SecurityContextHolder; /** * Base hawkBit entity class containing the common attributes for Hibernate. @@ -51,9 +47,6 @@ public abstract class AbstractJpaBaseEntity implements BaseEntity { protected static final int USERNAME_FIELD_LENGTH = 64; - @Serial - private static final long serialVersionUID = 1L; - @Setter // should be used just for test purposes @Getter @Id @@ -98,7 +91,7 @@ public abstract class AbstractJpaBaseEntity implements BaseEntity { @LastModifiedBy public void setLastModifiedBy(final String lastModifiedBy) { - if (this.lastModifiedBy != null && isController()) { + if (this.lastModifiedBy != null && SpRole.isController()) { // initialized and controller = doesn't update return; } @@ -114,7 +107,7 @@ public abstract class AbstractJpaBaseEntity implements BaseEntity { @LastModifiedDate public void setLastModifiedAt(final long lastModifiedAt) { - if (this.lastModifiedAt != 0 && isController()) { + if (this.lastModifiedAt != 0 && SpRole.isController()) { // initialized and controller = doesn't update return; } @@ -202,11 +195,4 @@ public abstract class AbstractJpaBaseEntity implements BaseEntity { // fire events onl AFTER transaction commit AfterTransactionCommitExecutor.afterCommit(runnable); } - - protected boolean isController() { - final Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); - return authentication != null - && authentication.getDetails() instanceof TenantAwareAuthenticationDetails tenantAwareDetails - && tenantAwareDetails.controller(); - } } \ No newline at end of file diff --git a/hawkbit-repository/hawkbit-repository-jpa-hibernate/src/main/java/org/eclipse/hawkbit/repository/jpa/model/AbstractJpaTenantAwareBaseEntity.java b/hawkbit-repository/hawkbit-repository-jpa-hibernate/src/main/java/org/eclipse/hawkbit/repository/jpa/model/AbstractJpaTenantAwareBaseEntity.java index 906b20bbf..e6ee184f1 100644 --- a/hawkbit-repository/hawkbit-repository-jpa-hibernate/src/main/java/org/eclipse/hawkbit/repository/jpa/model/AbstractJpaTenantAwareBaseEntity.java +++ b/hawkbit-repository/hawkbit-repository-jpa-hibernate/src/main/java/org/eclipse/hawkbit/repository/jpa/model/AbstractJpaTenantAwareBaseEntity.java @@ -9,7 +9,6 @@ */ package org.eclipse.hawkbit.repository.jpa.model; -import java.io.Serial; import java.util.Objects; import jakarta.persistence.Column; @@ -36,9 +35,6 @@ import org.hibernate.annotations.TenantId; @MappedSuperclass public abstract class AbstractJpaTenantAwareBaseEntity extends AbstractJpaBaseEntity implements TenantAwareBaseEntity { - @Serial - private static final long serialVersionUID = 1L; - @Column(name = "tenant", nullable = false, insertable = true, updatable = false, length = 40) @Size(min = 1, max = 40) @NotNull @@ -86,9 +82,7 @@ public abstract class AbstractJpaTenantAwareBaseEntity extends AbstractJpaBaseEn final String currentTenant = AccessContext.tenant(); if (currentTenant == null) { throw new TenantNotExistException( - String.format( - "AccessContext %s does not exists, cannot create entity %s with id %d", - AccessContext.tenant(), getClass(), getId())); + String.format("Tenant not found in the context, cannot create entity %s with id %d", getClass(), getId())); } setTenant(currentTenant.toUpperCase()); } diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/ql/rsql/RsqlToSqlTest.java b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/ql/rsql/RsqlToSqlTest.java index 34f1877b3..0803e53f7 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/ql/rsql/RsqlToSqlTest.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/ql/rsql/RsqlToSqlTest.java @@ -33,7 +33,7 @@ import org.springframework.test.context.ContextConfiguration; "hawkbit.rsql.caseInsensitiveDB=true", "spring.main.allow-bean-definition-overriding=true", "spring.main.banner-mode=off", - "logging.level.root=ERROR" }) + "logging.level.root=WARN" }) @ContextConfiguration(classes = { JpaRepositoryConfiguration.class, TestConfiguration.class }) @Disabled("For manual run only, while playing around with RSQL to SQL") @SuppressWarnings("java:S2699") // java:S2699 - manual test, don't actually does assertions diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/acm/SecurityContextCtxTest.java b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/acm/SecurityContextCtxTest.java index 40d281105..11c1ff85e 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/acm/SecurityContextCtxTest.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/acm/SecurityContextCtxTest.java @@ -21,11 +21,11 @@ import java.util.function.Supplier; import lombok.SneakyThrows; import org.eclipse.hawkbit.auth.SpPermission; import org.eclipse.hawkbit.context.AccessContext; +import org.eclipse.hawkbit.context.Principal; import org.eclipse.hawkbit.repository.AutoAssignHandler; import org.eclipse.hawkbit.repository.jpa.AbstractJpaIntegrationTest; import org.eclipse.hawkbit.repository.model.Rollout; import org.eclipse.hawkbit.repository.model.TargetFilterQuery; -import org.eclipse.hawkbit.tenancy.TenantAwareAuthenticationDetails; import org.junit.jupiter.api.Test; import org.mockito.MockedStatic; import org.mockito.Mockito; @@ -129,9 +129,7 @@ class SecurityContextCtxTest extends AbstractJpaIntegrationTest { private static SecurityContext createUserContext(final int testId) { final SecurityContext userContext = SecurityContextHolder.createEmptyContext(); final UsernamePasswordAuthenticationToken userPassAuthentication = new UsernamePasswordAuthenticationToken( - "user", null, AUTHORITIES.stream().map(SimpleGrantedAuthority::new).toList()); - final TenantAwareAuthenticationDetails details = new TenantAwareAuthenticationDetails("my_tenant_" + testId, false); - userPassAuthentication.setDetails(details); + new Principal("my_tenant_" + testId, "user"), null, AUTHORITIES.stream().map(SimpleGrantedAuthority::new).toList()); userContext.setAuthentication(userPassAuthentication); assertThat(userContext).isNotNull(); diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/ControllerManagementTest.java b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/ControllerManagementTest.java index f79f66cc0..8845d2fb1 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/ControllerManagementTest.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/ControllerManagementTest.java @@ -36,7 +36,6 @@ import jakarta.validation.ConstraintViolationException; import org.assertj.core.api.Assertions; import org.eclipse.hawkbit.auth.SpPermission; -import org.eclipse.hawkbit.ql.jpa.SpecificationBuilder; import org.eclipse.hawkbit.repository.RepositoryProperties; import org.eclipse.hawkbit.repository.TargetTypeManagement; import org.eclipse.hawkbit.repository.UpdateMode; @@ -108,7 +107,7 @@ class ControllerManagementTest extends AbstractJpaIntegrationTest { final int allowedAttributes = quotaManagement.getMaxAttributeEntriesPerTarget(); testdataFactory.createTarget(controllerId); - final WithUser withController = SecurityContextSwitch.withController("controller", CONTROLLER_ROLE); + final WithUser withController = SecurityContextSwitch.withController("controller"); assertThatExceptionOfType(AssignmentQuotaExceededException.class) .isThrownBy(() -> runAs(withController, () -> writeAttributes(controllerId, allowedAttributes + 1, "key", "value"))) .withMessageContaining("" + allowedAttributes); @@ -184,7 +183,7 @@ class ControllerManagementTest extends AbstractJpaIntegrationTest { final Long actionId = createTargetAndAssignDs(); SecurityContextSwitch - .getAs(SecurityContextSwitch.withController("controller", CONTROLLER_ROLE), () -> { + .getAs(SecurityContextSwitch.withController("controller"), () -> { // Fails as one entry is already in there from the assignment assertThatExceptionOfType(AssignmentQuotaExceededException.class) .isThrownBy(() -> writeStatus(actionId, allowStatusEntries)) @@ -243,7 +242,8 @@ class ControllerManagementTest extends AbstractJpaIntegrationTest { assertThat(actionId1).isNotNull(); final ActionStatusCreateBuilder status = ActionStatusCreate.builder().actionId(actionId1).status(Status.WARNING); for (int i = 0; i < maxStatusEntries; i++) { - controllerManagement.addInformationalActionStatus(status.messages(List.of("Msg " + i)).timestamp(System.currentTimeMillis()).build()); + controllerManagement.addInformationalActionStatus( + status.messages(List.of("Msg " + i)).timestamp(System.currentTimeMillis()).build()); } final ActionStatusCreate actionStatusCreate = status.build(); assertThatExceptionOfType(AssignmentQuotaExceededException.class) @@ -255,7 +255,8 @@ class ControllerManagementTest extends AbstractJpaIntegrationTest { assertThat(actionId2).isNotEqualTo(actionId1); final ActionStatusCreateBuilder statusWarning = ActionStatusCreate.builder().actionId(actionId2).status(Status.WARNING); for (int i = 0; i < maxStatusEntries; i++) { - controllerManagement.addUpdateActionStatus(statusWarning.messages(List.of("Msg " + i)).timestamp(System.currentTimeMillis()).build()); + controllerManagement.addUpdateActionStatus( + statusWarning.messages(List.of("Msg " + i)).timestamp(System.currentTimeMillis()).build()); } final ActionStatusCreate actionStatusCreateQE = statusWarning.build(); assertThatExceptionOfType(AssignmentQuotaExceededException.class) @@ -663,7 +664,7 @@ class ControllerManagementTest extends AbstractJpaIntegrationTest { new ByteArrayInputStream(random), null, artifactSize, null, findFirstModuleByType(ds, osType).orElseThrow().getId(), "file1", false)); final Artifact artifact2 = artifactManagement.create(new ArtifactUpload( - new ByteArrayInputStream(random), null, artifactSize, null, + new ByteArrayInputStream(random), null, artifactSize, null, findFirstModuleByType(ds2, osType).orElseThrow().getId(), "file1", false)); assertThat(artifact.getSha1Hash()).isEqualTo(artifact2.getSha1Hash()); @@ -867,7 +868,7 @@ class ControllerManagementTest extends AbstractJpaIntegrationTest { .as("Expected an ConcurrencyFailureException to be thrown!") .isThrownBy(() -> controllerManagement.findOrRegisterTargetIfItDoesNotExist("AA", LOCALHOST)); - verify(mockTargetRepository, times(10 /* default retry max */+ 1)).findOne(any(Specification.class)); + verify(mockTargetRepository, times(10 /* default retry max */ + 1)).findOne(any(Specification.class)); } finally { // revert ((JpaControllerManagement) controllerManagement).setTargetRepository(targetRepository); @@ -1161,7 +1162,7 @@ class ControllerManagementTest extends AbstractJpaIntegrationTest { final String controllerId = "test123"; final Target target = testdataFactory.createTarget(controllerId); - SecurityContextSwitch.getAs(SecurityContextSwitch.withController("controller", CONTROLLER_ROLE, SpPermission.READ_TARGET), () -> { + SecurityContextSwitch.getAs(SecurityContextSwitch.withController("controller"), () -> { addAttributeAndVerify(controllerId); addSecondAttributeAndVerify(controllerId); updateAttributeAndVerify(controllerId); @@ -1769,7 +1770,8 @@ class ControllerManagementTest extends AbstractJpaIntegrationTest { testData.put("test1", "testdata1"); controllerManagement.updateControllerAttributes(controllerId, testData, null); - assertThat(targetManagement.getControllerAttributes(controllerId)).as("Controller Attributes are wrong").isEqualTo(testData); + SecurityContextSwitch.getAs(SecurityContextSwitch.withUser("bumlux", SpPermission.READ_TARGET), () -> + assertThat(targetManagement.getControllerAttributes(controllerId)).as("Controller Attributes are wrong").isEqualTo(testData)); } private void addSecondAttributeAndVerify(final String controllerId) { @@ -1778,8 +1780,8 @@ class ControllerManagementTest extends AbstractJpaIntegrationTest { controllerManagement.updateControllerAttributes(controllerId, testData, null); testData.put("test1", "testdata1"); - assertThat(targetManagement.getControllerAttributes(controllerId)).as("Controller Attributes are wrong") - .isEqualTo(testData); + SecurityContextSwitch.getAs(SecurityContextSwitch.withUser("bumlux", SpPermission.READ_TARGET), () -> + assertThat(targetManagement.getControllerAttributes(controllerId)).as("Controller Attributes are wrong").isEqualTo(testData)); } private void updateAttributeAndVerify(final String controllerId) { @@ -1789,8 +1791,8 @@ class ControllerManagementTest extends AbstractJpaIntegrationTest { controllerManagement.updateControllerAttributes(controllerId, testData, null); testData.put("test2", "testdata20"); - assertThat(targetManagement.getControllerAttributes(controllerId)).as("Controller Attributes are wrong") - .isEqualTo(testData); + SecurityContextSwitch.getAs(SecurityContextSwitch.withUser("bumlux", SpPermission.READ_TARGET), () -> + assertThat(targetManagement.getControllerAttributes(controllerId)).as("Controller Attributes are wrong").isEqualTo(testData)); } private void updateTargetAttributesWithUpdateModeRemove(final String controllerId) { diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/ManagementSecurityTest.java b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/ManagementSecurityTest.java index 1be9d7d40..13978cdc4 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/ManagementSecurityTest.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/ManagementSecurityTest.java @@ -384,7 +384,7 @@ class ManagementSecurityTest extends AbstractJpaIntegrationTest { } catch (final NoSuchMethodException | IllegalAccessException | InvocationTargetException e1) { log.debug("{} is not a builder. Throws could not instantiate", clazz.getName()); } - log.error("Could not instantiate {}", clazz.getName(), e); + log.debug("Could not instantiate {} (but if inside instance, could be fine)", clazz.getName(), e); throw e; } } @@ -401,12 +401,12 @@ class ManagementSecurityTest extends AbstractJpaIntegrationTest { @SneakyThrows protected void assertPermissionsCheck(final Method managementInterfaceMethod, final Object managementObject, final String... permissions) { + final Object[] params = new Object[managementInterfaceMethod.getParameterCount()]; + for (int i = 0; i < params.length; i++) { + params[i] = instance(managementInterfaceMethod.getParameterTypes()[i]); + } final Callable callable = () -> { try { - final Object[] params = new Object[managementInterfaceMethod.getParameterCount()]; - for (int i = 0; i < params.length; i++) { - params[i] = instance(managementInterfaceMethod.getParameterTypes()[i]); - } return managementInterfaceMethod.invoke(managementObject, params); } catch (final InvocationTargetException e) { if (e.getCause() instanceof RuntimeException re) { diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/test/resources/jpa-test.properties b/hawkbit-repository/hawkbit-repository-jpa/src/test/resources/jpa-test.properties index 9a0cebec0..04a47f658 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/test/resources/jpa-test.properties +++ b/hawkbit-repository/hawkbit-repository-jpa/src/test/resources/jpa-test.properties @@ -8,6 +8,8 @@ # SPDX-License-Identifier: EPL-2.0 # +logging.level.root=WARN +# could be used to suppress some logging if the root level is set to INFO or DEBUG, e.g. when debugging a test case NOISE_SUPPRESS_LEVEL=WARN ### General logging configuration - START diff --git a/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/TestConfiguration.java b/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/TestConfiguration.java index d10295401..e8be0db11 100644 --- a/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/TestConfiguration.java +++ b/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/TestConfiguration.java @@ -23,6 +23,7 @@ import org.eclipse.hawkbit.artifact.fs.FileArtifactStorage; import org.eclipse.hawkbit.artifact.urlresolver.PropertyBasedArtifactUrlResolver; import org.eclipse.hawkbit.artifact.urlresolver.PropertyBasedArtifactUrlResolverProperties; import org.eclipse.hawkbit.auth.Hierarchy; +import org.eclipse.hawkbit.auth.SpRole; import org.eclipse.hawkbit.context.AccessContext; import org.eclipse.hawkbit.repository.RepositoryConfiguration; import org.eclipse.hawkbit.repository.RolloutApprovalStrategy; @@ -138,7 +139,7 @@ public class TestConfiguration implements AsyncConfigurer { @Bean AuditorAware auditorAware() { - return () -> Optional.ofNullable(AccessContext.actor()); + return () -> Optional.ofNullable(SpRole.isController() ? "CONTROLLER_PLUG_AND_PLAY" : AccessContext.actor()); } @Bean diff --git a/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/AbstractIntegrationTest.java b/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/AbstractIntegrationTest.java index 66f92b35c..784498fa1 100644 --- a/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/AbstractIntegrationTest.java +++ b/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/AbstractIntegrationTest.java @@ -122,6 +122,7 @@ public abstract class AbstractIntegrationTest { protected static final Pageable PAGE = PageRequest.of(0, 500, Sort.by(Direction.ASC, "id")); protected static final Pageable UNPAGED = Pageable.unpaged(); + protected static final String CONTROLLER_PLUG_AND_PLAY = "CONTROLLER_PLUG_AND_PLAY"; protected static final URI LOCALHOST = URI.create("http://127.0.0.1"); protected static final Random RND = TestdataFactory.RND; diff --git a/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/SecurityContextSwitch.java b/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/SecurityContextSwitch.java index 23cb85ac4..5bad99fb6 100644 --- a/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/SecurityContextSwitch.java +++ b/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/SecurityContextSwitch.java @@ -23,9 +23,8 @@ import java.util.function.Supplier; import lombok.AccessLevel; import lombok.NoArgsConstructor; import org.eclipse.hawkbit.auth.SpRole; +import org.eclipse.hawkbit.context.Principal; import org.eclipse.hawkbit.repository.SystemManagement; -import org.eclipse.hawkbit.tenancy.TenantAwareAuthenticationDetails; -import org.eclipse.hawkbit.tenancy.TenantAwareUser; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.authentication.TestingAuthenticationToken; import org.springframework.security.core.Authentication; @@ -92,8 +91,8 @@ public class SecurityContextSwitch { }); } - public static WithUser withController(final String principal, final String... authorities) { - return withTenantAndUser(DEFAULT_TENANT, principal, authorities, true, true); + public static WithUser withController(final String principal) { // authorized controller + return withTenantAndUser(DEFAULT_TENANT, principal, new String[] { CONTROLLER_ROLE }, true, true); } public static WithUser withUser(final String principal, final String... authorities) { @@ -146,12 +145,8 @@ public class SecurityContextSwitch { @Override public Authentication getAuthentication() { - final TestingAuthenticationToken testingAuthenticationToken = new TestingAuthenticationToken( - new TenantAwareUser(annotation.principal(), "***", null, annotation.tenant()), - annotation.credentials(), annotation.authorities()); - testingAuthenticationToken.setDetails( - new TenantAwareAuthenticationDetails(annotation.tenant(), annotation.controller())); - return testingAuthenticationToken; + return new TestingAuthenticationToken( + new Principal(annotation.tenant(), annotation.principal()), annotation.credentials(), annotation.authorities()); } @Override diff --git a/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/WithUser.java b/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/WithUser.java index d4f0ede2c..503f777e8 100644 --- a/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/WithUser.java +++ b/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/WithUser.java @@ -28,6 +28,13 @@ import org.springframework.security.test.context.support.WithSecurityContextFact @Inherited public @interface WithUser { + /** + * Gets the test actor. + * + * @return test actor + */ + String principal() default "TestActor"; + /** * Gets the test tenant id. * @@ -35,13 +42,6 @@ public @interface WithUser { */ String tenant() default "DEFAULT"; - /** - * Gets the test principal. - * - * @return test principal - */ - String principal() default "TestPrincipal"; - /** * Gets the test credentials. * diff --git a/hawkbit-repository/hawkbit-repository-test/src/main/resources/hawkbit-test-defaults.properties b/hawkbit-repository/hawkbit-repository-test/src/main/resources/hawkbit-test-defaults.properties index cec67aedd..4f2d8d137 100644 --- a/hawkbit-repository/hawkbit-repository-test/src/main/resources/hawkbit-test-defaults.properties +++ b/hawkbit-repository/hawkbit-repository-test/src/main/resources/hawkbit-test-defaults.properties @@ -10,7 +10,7 @@ # Test utility properties for easier fault investigation - START ## Logging - START -logging.level.root=ERROR +logging.level.root=WARN logging.level.org.eclipse.hawkbit.repository.test.matcher.EventVerifier=ERROR logging.level.org.eclipse.persistence=ERROR spring.jpa.properties.eclipselink.logging.level=FINE