Fix auth -> authentication in some props in SDK (#2839)

Signed-off-by: Avgustin Marinov <Avgustin.Marinov@bosch.com>
This commit is contained in:
Avgustin Marinov
2025-11-28 09:13:41 +02:00
committed by GitHub
parent 42384b7e31
commit 203598f3a4
29 changed files with 129 additions and 121 deletions

View File

@@ -12,7 +12,7 @@ information. In
hawkBit [SecurityAutoConfiguration](https://github.com/eclipse-hawkbit/hawkbit/blob/master/hawkbit-autoconfigure/src/main/java/org/eclipse/hawkbit/autoconfigure/security/SecurityAutoConfiguration.java) hawkBit [SecurityAutoConfiguration](https://github.com/eclipse-hawkbit/hawkbit/blob/master/hawkbit-autoconfigure/src/main/java/org/eclipse/hawkbit/autoconfigure/security/SecurityAutoConfiguration.java)
is a good starting point for integration. is a good starting point for integration.
The default implementation is single user/tenant with basic auth and the logged in user is provided with all The default implementation is single user/tenant with basic authentication and the logged-in user is provided with all
permissions. Additionally, the application properties may be configured for multiple static users; permissions. Additionally, the application properties may be configured for multiple static users;
see [Multiple Users](#multiple-users) for details. see [Multiple Users](#multiple-users) for details.

View File

@@ -23,7 +23,7 @@ import org.springframework.security.access.prepost.PreAuthorize;
* hasRole([role]) Returns true if the current principal has the specified role. * 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) * hasAnyRole([role1,role2]) Returns true if the current principal has any of the supplied roles (given as a comma-separated list of strings)
* principal Allows direct access to the principal object representing the current user * principal Allows direct access to the principal object representing the current user
* auth Allows direct access to the current Authentication object obtained from the SecurityContext * authentication Allows direct access to the current Authentication object obtained from the SecurityContext
* permitAll Always evaluates to true * permitAll Always evaluates to true
* denyAll Always evaluates to false * denyAll Always evaluates to false
* isAnonymous() Returns true if the current principal is an anonymous user * isAnonymous() Returns true if the current principal is an anonymous user

View File

@@ -332,7 +332,7 @@ public class AccessContext {
} }
// simplified info for the security context keeping just the basic info needed for background execution of // simplified info for the security context keeping just the basic info needed for background execution of
// controller auth is not supported - always is false // controller authentication is not supported - always is false
// only authenticated user is supported // only authenticated user is supported
@NoArgsConstructor @NoArgsConstructor
@Data @Data
@@ -342,7 +342,6 @@ public class AccessContext {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
private String tenant; private String tenant;
// auditor / username (auth principal name)
private String auditor = "n/a"; // default value "n/a" is used only on deserialization if field is missing private String auditor = "n/a"; // default value "n/a" is used only on deserialization if field is missing
@JsonProperty(required = true) @JsonProperty(required = true)
private String[] authorities; private String[] authorities;
@@ -354,7 +353,7 @@ public class AccessContext {
} }
if (authentication.getDetails() instanceof TenantAwareAuthenticationDetails tenantAwareDetails) { if (authentication.getDetails() instanceof TenantAwareAuthenticationDetails tenantAwareDetails) {
if (tenantAwareDetails.controller()) { if (tenantAwareDetails.controller()) {
throw new IllegalStateException("Controller auth context is not supported"); throw new IllegalStateException("Controller authentication context is not supported");
} }
tenant = tenantAwareDetails.tenant(); tenant = tenantAwareDetails.tenant();
} else if (authentication.getPrincipal() instanceof TenantAwareUser tenantAwareUser) { } else if (authentication.getPrincipal() instanceof TenantAwareUser tenantAwareUser) {
@@ -362,7 +361,7 @@ public class AccessContext {
} }
// keep the auditor, ofr audit purposes, // keep the auditor, ofr audit purposes,
// sets principal to the resolved auditor and then deserialized auth will return it as principal // 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 // since the class is not known to auditor aware - it shall used default - principal as auditor
auditor = resolve(authentication); auditor = resolve(authentication);
authorities = authentication.getAuthorities().stream().map(Object::toString).toArray(String[]::new); authorities = authentication.getAuthorities().stream().map(Object::toString).toArray(String[]::new);
@@ -417,7 +416,7 @@ public class AccessContext {
/** /**
* An implementation of the Spring's {@link Authentication} object which is used within a system security code block and * An implementation of the Spring's {@link Authentication} object which is used within a system security code block and
* wraps the original auth object. The wrapped object contains the necessary {@link SpRole#SYSTEM_ROLE} * wraps the original authentication object. The wrapped object contains the necessary {@link SpRole#SYSTEM_ROLE}
* which is allowed to execute all secured methods. * which is allowed to execute all secured methods.
*/ */
static final class SystemCodeAuthentication implements Authentication { static final class SystemCodeAuthentication implements Authentication {

View File

@@ -49,7 +49,7 @@ public class Mdc {
} }
/** /**
* Executes callable and returns the result. If MDC is enabled, it sets the tenant and / or actor from the auth in the MDC context. * Executes callable and returns the result. If MDC is enabled, it sets the tenant and / or actor from the authentication in the MDC context.
* *
* @param <T> the return type * @param <T> the return type
* @param callable the callable to execute * @param callable the callable to execute
@@ -81,7 +81,7 @@ public class Mdc {
} }
/** /**
* Executes callable and returns the result. If MDC is enabled, it sets the tenant and / or actor from the auth in the MDC context. * Executes callable and returns the result. If MDC is enabled, it sets the tenant and / or actor from the authentication in the MDC context.
* Calls the {@link #withAuth(Callable)} method and wraps any catchable exception into a {@link RuntimeException}. * Calls the {@link #withAuth(Callable)} method and wraps any catchable exception into a {@link RuntimeException}.
* *
* @param <T> the return type * @param <T> the return type
@@ -116,7 +116,7 @@ public class Mdc {
} }
/** /**
* Executes callable and returns the result. If MDC is enabled, it sets the tenant and / or actor from the auth in the MDC context. * Executes callable and returns the result. If MDC is enabled, it sets the tenant and / or actor from the authentication in the MDC context.
* Calls the {@link #asTenantAsActor(String, String, Callable)} method and wraps any catchable exception into a {@link RuntimeException}. * Calls the {@link #asTenantAsActor(String, String, Callable)} method and wraps any catchable exception into a {@link RuntimeException}.
* *
* @param <T> the return type * @param <T> the return type

View File

@@ -43,11 +43,11 @@ public class HawkbitSecurityProperties {
*/ */
private List<String> httpFirewallIgnoredPaths; private List<String> httpFirewallIgnoredPaths;
/** /**
* Basic auth realm, see https://tools.ietf.org/html/rfc2617#page-3 . * Basic authentication realm, see https://tools.ietf.org/html/rfc2617#page-3 .
*/ */
private String basicRealm = "hawkBit"; private String basicRealm = "hawkBit";
/** /**
* If to allow http auth when there is OAuth2 auth enabled. * If to allow http authentication when there is OAuth2 authentication enabled.
*/ */
private boolean allowHttpBasicOnOAuthEnabled = false; private boolean allowHttpBasicOnOAuthEnabled = false;

View File

@@ -15,8 +15,8 @@ import java.io.Serializable;
import org.springframework.security.authentication.AbstractAuthenticationToken; import org.springframework.security.authentication.AbstractAuthenticationToken;
/** /**
* An auth details object {@link AbstractAuthenticationToken#getDetails()} which is stored in the * An authentication details object {@link AbstractAuthenticationToken#getDetails()} which is stored in the
* spring security auth token details to transport the principal and tenant in the security context session. * 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 { public record TenantAwareAuthenticationDetails(String tenant, boolean controller) implements Serializable {

View File

@@ -27,39 +27,39 @@ class AccessContextAsSystemTest {
@Test @Test
void test() { void test() {
final UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken( final UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(
"test", "pass", List.of(new SimpleGrantedAuthority("anonymous"))); "test", "pass", List.of(new SimpleGrantedAuthority("anonymous")));
auth.setDetails("string details"); authentication.setDetails("string details");
test(auth); test(authentication);
} }
@Test @Test
void testWithNullPrincipal() { void testWithNullPrincipal() {
final UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken( final UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(
null, "pass", List.of(new SimpleGrantedAuthority("anonymous"))); null, "pass", List.of(new SimpleGrantedAuthority("anonymous")));
auth.setDetails("string details"); authentication.setDetails("string details");
test(auth); test(authentication);
} }
@Test @Test
void testWithNullCredentials() { void testWithNullCredentials() {
final UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken( final UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(
"test", null, List.of(new SimpleGrantedAuthority("anonymous"))); "test", null, List.of(new SimpleGrantedAuthority("anonymous")));
auth.setDetails("string details"); authentication.setDetails("string details");
test(auth); test(authentication);
} }
@Test @Test
void testWitAllNull() { void testWitAllNull() {
final UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken( final UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(
null, null, List.of(new SimpleGrantedAuthority("anonymous"))); null, null, List.of(new SimpleGrantedAuthority("anonymous")));
auth.setDetails(null); authentication.setDetails(null);
test(auth); test(authentication);
} }
private static void test(final UsernamePasswordAuthenticationToken auth) { private static void test(final UsernamePasswordAuthenticationToken authentication) {
final SecurityContext sc = SecurityContextHolder.createEmptyContext(); final SecurityContext sc = SecurityContextHolder.createEmptyContext();
sc.setAuthentication(auth); sc.setAuthentication(authentication);
SecurityContextHolder.setContext(sc); SecurityContextHolder.setContext(sc);
asSystemAsTenant("tenant", () -> { asSystemAsTenant("tenant", () -> {
final Authentication currentAuth = SecurityContextHolder.getContext().getAuthentication(); final Authentication currentAuth = SecurityContextHolder.getContext().getAuthentication();

View File

@@ -31,10 +31,10 @@ import org.springframework.security.core.authority.SimpleGrantedAuthority;
public interface Authenticator { public interface Authenticator {
/** /**
* If the auth mechanism is not enabled for the tenant - it just returns null. * If the authentication mechanism is not enabled for the tenant - it just returns null.
* If the auth mechanism is supported, the filter extracts from the security token the related credentials, * If the authentication mechanism is supported, the filter extracts from the security token the related credentials,
* validate them (do authenticate the caller). * validate them (do authenticate the caller).
* If validation / auth is successful returns an authenticated auth object. Otherwise, * If validation / authentication is successful returns an authenticated authentication object. Otherwise,
* throws BadCredentialsException. * throws BadCredentialsException.
* *
* @param controllerSecurityToken the securityToken * @param controllerSecurityToken the securityToken

View File

@@ -89,7 +89,7 @@ public class DdiSecurityProperties {
public static class Gatewaytoken { public static class Gatewaytoken {
/** /**
* Gateway token based auth enabled. * Gateway token based authentication enabled.
*/ */
private boolean enabled = false; private boolean enabled = false;

View File

@@ -43,7 +43,7 @@ public class GatewayTokenAuthenticator extends Authenticator.AbstractAuthenticat
} }
if (!isEnabled(controllerSecurityToken)) { if (!isEnabled(controllerSecurityToken)) {
log.debug("The gateway token auth is disabled"); log.debug("The gateway token authentication is disabled");
return null; return null;
} }

View File

@@ -67,7 +67,7 @@ public class SecurityHeaderAuthenticator extends Authenticator.AbstractAuthentic
} }
if (!isEnabled(controllerSecurityToken)) { if (!isEnabled(controllerSecurityToken)) {
log.debug("The gateway header auth is disabled"); log.debug("The gateway header authentication is disabled");
return null; return null;
} }

View File

@@ -47,7 +47,7 @@ public class SecurityTokenAuthenticator extends Authenticator.AbstractAuthentica
} }
if (!isEnabled(controllerSecurityToken)) { if (!isEnabled(controllerSecurityToken)) {
log.debug("The target security token auth is disabled"); log.debug("The target security token authentication is disabled");
return null; return null;
} }

View File

@@ -26,7 +26,7 @@ import org.mockito.junit.jupiter.MockitoExtension;
/** /**
* Feature: Unit Tests - Security<br/> * Feature: Unit Tests - Security<br/>
* Story: Gateway token auth * Story: Gateway token authentication
*/ */
@ExtendWith(MockitoExtension.class) @ExtendWith(MockitoExtension.class)
class GatewayTokenAuthenticatorTest { class GatewayTokenAuthenticatorTest {
@@ -54,7 +54,7 @@ class GatewayTokenAuthenticatorTest {
} }
/** /**
* Tests successful auth with gateway token * Tests successful authentication with gateway token
*/ */
@Test @Test
void testWithGwToken() { void testWithGwToken() {
@@ -70,7 +70,7 @@ class GatewayTokenAuthenticatorTest {
} }
/** /**
* Tests that if gateway token doesn't match, the auth fails * Tests that if gateway token doesn't match, the authentication fails
*/ */
@Test @Test
void testWithBadGwToken() { void testWithBadGwToken() {
@@ -84,7 +84,7 @@ class GatewayTokenAuthenticatorTest {
} }
/** /**
* Tests that if gateway token miss, the auth fails * Tests that if gateway token miss, the authentication fails
*/ */
@Test @Test
void testWithoutGwToken() { void testWithoutGwToken() {
@@ -92,7 +92,7 @@ class GatewayTokenAuthenticatorTest {
} }
/** /**
* Tests that if disabled, the auth fails * Tests that if disabled, the authentication fails
*/ */
@Test @Test
void testWithGwTokenButDisabled() { void testWithGwTokenButDisabled() {

View File

@@ -63,7 +63,7 @@ class SecurityHeaderAuthenticatorTest {
} }
/** /**
* Tests successful auth with multiple a single hashes * Tests successful authentication with multiple a single hashes
*/ */
@Test @Test
void testWithSingleKnownHash() { void testWithSingleKnownHash() {
@@ -79,7 +79,7 @@ class SecurityHeaderAuthenticatorTest {
} }
/** /**
* Tests successful auth with multiple hashes * Tests successful authentication with multiple hashes
*/ */
@Test @Test
void testWithMultipleKnownHashes() { void testWithMultipleKnownHashes() {
@@ -100,7 +100,7 @@ class SecurityHeaderAuthenticatorTest {
} }
/** /**
* Tests that if the hash is unknown, the auth fails * Tests that if the hash is unknown, the authentication fails
*/ */
@Test @Test
void testWithUnknownHash() { void testWithUnknownHash() {
@@ -114,7 +114,7 @@ class SecurityHeaderAuthenticatorTest {
} }
/** /**
* Tests that if CN doesn't match the CN in the security token, the auth fails * Tests that if CN doesn't match the CN in the security token, the authentication fails
*/ */
@Test @Test
void testWithNonMatchingCN() { void testWithNonMatchingCN() {
@@ -126,7 +126,7 @@ class SecurityHeaderAuthenticatorTest {
} }
/** /**
* Tests that if the hash miss, the auth fails * Tests that if the hash miss, the authentication fails
*/ */
@Test @Test
void testWithoutHash() { void testWithoutHash() {
@@ -134,7 +134,7 @@ class SecurityHeaderAuthenticatorTest {
} }
/** /**
* Tests that if disabled, the auth fails * Tests that if disabled, the authentication fails
*/ */
@Test @Test
void testWithSingleKnownHashButDisabled() { void testWithSingleKnownHashButDisabled() {

View File

@@ -29,7 +29,7 @@ import org.mockito.junit.jupiter.MockitoExtension;
/** /**
* Feature: Unit Tests - Security<br/> * Feature: Unit Tests - Security<br/>
* Story: Gateway token auth * Story: Gateway token authentication
*/ */
@ExtendWith(MockitoExtension.class) @ExtendWith(MockitoExtension.class)
class SecurityTokenAuthenticatorTest { class SecurityTokenAuthenticatorTest {
@@ -57,7 +57,7 @@ class SecurityTokenAuthenticatorTest {
} }
/** /**
* Tests successful auth with gateway token * Tests successful authentication with gateway token
*/ */
@Test @Test
void testWithSecToken() { void testWithSecToken() {
@@ -76,7 +76,7 @@ class SecurityTokenAuthenticatorTest {
} }
/** /**
* Tests that if gateway token doesn't match, the auth fails * Tests that if gateway token doesn't match, the authentication fails
*/ */
@Test @Test
void testWithBadSecToken() { void testWithBadSecToken() {
@@ -88,7 +88,7 @@ class SecurityTokenAuthenticatorTest {
} }
/** /**
* Tests that if gateway token miss, the auth fails * Tests that if gateway token miss, the authentication fails
*/ */
@Test @Test
void testWithoutSecToken() { void testWithoutSecToken() {
@@ -96,7 +96,7 @@ class SecurityTokenAuthenticatorTest {
} }
/** /**
* Tests that if disabled, the auth fails * Tests that if disabled, the authentication fails
*/ */
@Test @Test
void testWithSecTokenButDisabled() { void testWithSecTokenButDisabled() {

View File

@@ -30,7 +30,7 @@ server.servlet.encoding.charset=UTF-8
server.servlet.encoding.enabled=true server.servlet.encoding.enabled=true
server.servlet.encoding.force=true server.servlet.encoding.force=true
# DDI auth configuration # DDI authentication configuration
hawkbit.server.ddi.security.authentication.targettoken.enabled=false hawkbit.server.ddi.security.authentication.targettoken.enabled=false
hawkbit.server.ddi.security.authentication.gatewaytoken.enabled=false hawkbit.server.ddi.security.authentication.gatewaytoken.enabled=false

View File

@@ -148,7 +148,7 @@ public class DmfApiConfiguration {
} }
/** /**
* Create the DMF API receiver queue for auth requests called by 3rd * Create the DMF API receiver queue for authentication requests called by 3rd
* party artifact storages for download authorization by devices. * party artifact storages for download authorization by devices.
* *
* @return the receiver queue * @return the receiver queue

View File

@@ -22,11 +22,11 @@ import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
/** /**
* Api for handling basic auth user validation * Api for handling basic authentication user validation
*/ */
@SuppressWarnings("squid:S1609") @SuppressWarnings("squid:S1609")
@Tag( @Tag(
name = "Basic Authentication", description = "API for basic auth user validation.", name = "Basic Authentication", description = "API for basic authentication user validation.",
extensions = @Extension(name = OpenApi.X_HAWKBIT, properties = @ExtensionProperty(name = "order", value = BASIC_AUTH_ORDER))) extensions = @Extension(name = OpenApi.X_HAWKBIT, properties = @ExtensionProperty(name = "order", value = BASIC_AUTH_ORDER)))
// no request mapping specified here to avoid CVE-2021-22044 in Feign client // no request mapping specified here to avoid CVE-2021-22044 in Feign client
public interface MgmtBasicAuthRestApi { public interface MgmtBasicAuthRestApi {

View File

@@ -81,7 +81,7 @@ public final class MgmtRestConstants {
*/ */
public static final String ROLLOUT_V1_REQUEST_MAPPING = BASE_V1_REQUEST_MAPPING + "/rollouts"; public static final String ROLLOUT_V1_REQUEST_MAPPING = BASE_V1_REQUEST_MAPPING + "/rollouts";
/** /**
* The basic auth validation mapping * The basic authentication validation mapping
*/ */
public static final String AUTH_V1_REQUEST_MAPPING = BASE_V1_REQUEST_MAPPING + "/userinfo"; public static final String AUTH_V1_REQUEST_MAPPING = BASE_V1_REQUEST_MAPPING + "/userinfo";
/** /**

View File

@@ -20,7 +20,7 @@ import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
/** /**
* REST Resource handling basic auth validation. * REST Resource handling basic authentication validation.
*/ */
@RestController @RestController
public class MgmtBasicAuthResource implements MgmtBasicAuthRestApi { public class MgmtBasicAuthResource implements MgmtBasicAuthRestApi {

View File

@@ -51,7 +51,7 @@ import org.springframework.web.context.WebApplicationContext;
* Test for {@link MgmtBasicAuthResource}. * Test for {@link MgmtBasicAuthResource}.
* <p/> * <p/>
* Feature: Component Tests - Management API<br/> * Feature: Component Tests - Management API<br/>
* Story: Basic auth Userinfo Resource * Story: Basic authentication Userinfo Resource
*/ */
@ActiveProfiles({ "test" }) @ActiveProfiles({ "test" })
@ExtendWith({ TestLoggerExtension.class, SharedSqlTestDatabaseExtension.class }) @ExtendWith({ TestLoggerExtension.class, SharedSqlTestDatabaseExtension.class })
@@ -80,7 +80,7 @@ class MgmtBasicAuthResourceTest {
MockMvc defaultMock; MockMvc defaultMock;
/** /**
* Test of userinfo api with basic auth validation * Test of userinfo api with basic authentication validation
*/ */
@Test @Test
@WithUser(principal = TEST_USER, authorities = {"READ", "WRITE", "DELETE"}) @WithUser(principal = TEST_USER, authorities = {"READ", "WRITE", "DELETE"})
@@ -97,7 +97,7 @@ class MgmtBasicAuthResourceTest {
} }
/** /**
* Test of userinfo api with invalid basic auth fails * Test of userinfo api with invalid basic authentication fails
*/ */
@Test @Test
void validateBasicAuthFailsWithInvalidCredentials() throws Exception { void validateBasicAuthFailsWithInvalidCredentials() throws Exception {

View File

@@ -106,7 +106,7 @@ public class MgmtSecurityConfiguration {
final HttpSecurity http, final HttpSecurity http,
@Autowired(required = false) @Qualifier("hawkbitOAuth2ResourceServerCustomizer") final Customizer<OAuth2ResourceServerConfigurer<HttpSecurity>> oauth2ResourceServerCustomizer, @Autowired(required = false) @Qualifier("hawkbitOAuth2ResourceServerCustomizer") final Customizer<OAuth2ResourceServerConfigurer<HttpSecurity>> oauth2ResourceServerCustomizer,
// called just before build of the SecurityFilterChain. // called just before build of the SecurityFilterChain.
// could be used for instance to set auth provider // could be used for instance to set authentication provider
// Note: implementation of the customizer shall always take in account what is the already set by the hawkBit // Note: implementation of the customizer shall always take in account what is the already set by the hawkBit
@Autowired(required = false) @Qualifier("hawkbitHttpSecurityCustomizer") final Customizer<HttpSecurity> httpSecurityCustomizer, @Autowired(required = false) @Qualifier("hawkbitHttpSecurityCustomizer") final Customizer<HttpSecurity> httpSecurityCustomizer,
final SystemManagement systemManagement) throws Exception { final SystemManagement systemManagement) throws Exception {
@@ -120,7 +120,7 @@ public class MgmtSecurityConfiguration {
.anonymous(AbstractHttpConfigurer::disable) .anonymous(AbstractHttpConfigurer::disable)
.csrf(AbstractHttpConfigurer::disable) .csrf(AbstractHttpConfigurer::disable)
.addFilterAfter( .addFilterAfter(
// Servlet filter to create metadata after successful auth over RESTful. // Servlet filter to create metadata after successful authentication over RESTful.
(request, response, chain) -> { (request, response, chain) -> {
final Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); final Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (authentication != null && authentication.isAuthenticated()) { if (authentication != null && authentication.isAuthenticated()) {

View File

@@ -32,7 +32,7 @@ server.servlet.encoding.charset=UTF-8
server.servlet.encoding.enabled=true server.servlet.encoding.enabled=true
server.servlet.encoding.force=true server.servlet.encoding.force=true
# DDI auth configuration # DDI authentication configuration
hawkbit.server.ddi.security.authentication.targettoken.enabled=false hawkbit.server.ddi.security.authentication.targettoken.enabled=false
hawkbit.server.ddi.security.authentication.gatewaytoken.enabled=false hawkbit.server.ddi.security.authentication.gatewaytoken.enabled=false

View File

@@ -18,6 +18,7 @@ import java.time.Duration;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import org.eclipse.hawkbit.repository.TenantConfigurationManagement;
import org.eclipse.hawkbit.repository.exception.InvalidTenantConfigurationKeyException; import org.eclipse.hawkbit.repository.exception.InvalidTenantConfigurationKeyException;
import org.eclipse.hawkbit.repository.exception.TenantConfigurationValidatorException; import org.eclipse.hawkbit.repository.exception.TenantConfigurationValidatorException;
import org.eclipse.hawkbit.repository.jpa.AbstractJpaIntegrationTest; import org.eclipse.hawkbit.repository.jpa.AbstractJpaIntegrationTest;
@@ -25,6 +26,7 @@ import org.eclipse.hawkbit.repository.model.TenantConfigurationValue;
import org.eclipse.hawkbit.tenancy.configuration.DurationHelper; import org.eclipse.hawkbit.tenancy.configuration.DurationHelper;
import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties.TenantConfigurationKey; import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties.TenantConfigurationKey;
import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.springframework.context.EnvironmentAware; import org.springframework.context.EnvironmentAware;
import org.springframework.core.env.Environment; import org.springframework.core.env.Environment;
@@ -35,8 +37,16 @@ import org.springframework.core.env.Environment;
*/ */
class TenantConfigurationManagementTest extends AbstractJpaIntegrationTest implements EnvironmentAware { class TenantConfigurationManagementTest extends AbstractJpaIntegrationTest implements EnvironmentAware {
private TenantConfigurationManagement tenantConfigurationManagement;
private Environment env; private Environment env;
@BeforeEach
@Override
public void beforeAll() throws Exception {
super.beforeAll();
tenantConfigurationManagement = tenantConfigurationManagement();
}
@Override @Override
public void setEnvironment(final Environment env) { public void setEnvironment(final Environment env) {
this.env = env; this.env = env;
@@ -51,7 +61,7 @@ class TenantConfigurationManagementTest extends AbstractJpaIntegrationTest imple
assertThat(envPropertyDefault).isNotNull(); assertThat(envPropertyDefault).isNotNull();
// get the configuration from the system management // get the configuration from the system management
final TenantConfigurationValue<String> defaultConfigValue = tenantConfigurationManagement().getConfigurationValue( final TenantConfigurationValue<String> defaultConfigValue = tenantConfigurationManagement.getConfigurationValue(
TenantConfigurationKey.AUTHENTICATION_GATEWAY_SECURITY_TOKEN_KEY, String.class); TenantConfigurationKey.AUTHENTICATION_GATEWAY_SECURITY_TOKEN_KEY, String.class);
assertThat(defaultConfigValue.isGlobal()).isTrue(); assertThat(defaultConfigValue.isGlobal()).isTrue();
@@ -60,11 +70,11 @@ class TenantConfigurationManagementTest extends AbstractJpaIntegrationTest imple
// update the tenant specific configuration, create // update the tenant specific configuration, create
final String newConfigurationValue = "thisIsAnotherTokenName"; final String newConfigurationValue = "thisIsAnotherTokenName";
assertThat(newConfigurationValue).isNotEqualTo(defaultConfigValue.getValue()); assertThat(newConfigurationValue).isNotEqualTo(defaultConfigValue.getValue());
tenantConfigurationManagement().addOrUpdateConfiguration( tenantConfigurationManagement.addOrUpdateConfiguration(
TenantConfigurationKey.AUTHENTICATION_GATEWAY_SECURITY_TOKEN_KEY, newConfigurationValue); TenantConfigurationKey.AUTHENTICATION_GATEWAY_SECURITY_TOKEN_KEY, newConfigurationValue);
// verify that new configuration value is used // verify that new configuration value is used
final TenantConfigurationValue<String> updatedConfigurationValue = tenantConfigurationManagement() final TenantConfigurationValue<String> updatedConfigurationValue = tenantConfigurationManagement
.getConfigurationValue(TenantConfigurationKey.AUTHENTICATION_GATEWAY_SECURITY_TOKEN_KEY, String.class); .getConfigurationValue(TenantConfigurationKey.AUTHENTICATION_GATEWAY_SECURITY_TOKEN_KEY, String.class);
assertThat(updatedConfigurationValue.isGlobal()).isFalse(); assertThat(updatedConfigurationValue.isGlobal()).isFalse();
@@ -73,16 +83,15 @@ class TenantConfigurationManagementTest extends AbstractJpaIntegrationTest imple
// update the tenant specific configuration, create // update the tenant specific configuration, create
final String newConfigurationValue2 = "thisIsAnotherTokenName2"; final String newConfigurationValue2 = "thisIsAnotherTokenName2";
assertThat(newConfigurationValue2).isNotEqualTo(updatedConfigurationValue.getValue()); assertThat(newConfigurationValue2).isNotEqualTo(updatedConfigurationValue.getValue());
tenantConfigurationManagement().addOrUpdateConfiguration( tenantConfigurationManagement.addOrUpdateConfiguration(
TenantConfigurationKey.AUTHENTICATION_GATEWAY_SECURITY_TOKEN_KEY, newConfigurationValue2); TenantConfigurationKey.AUTHENTICATION_GATEWAY_SECURITY_TOKEN_KEY, newConfigurationValue2);
// verify that new configuration value is used // verify that new configuration value is used
final TenantConfigurationValue<String> updatedConfigurationValue2 = tenantConfigurationManagement() final TenantConfigurationValue<String> updatedConfigurationValue2 = tenantConfigurationManagement
.getConfigurationValue(TenantConfigurationKey.AUTHENTICATION_GATEWAY_SECURITY_TOKEN_KEY, String.class); .getConfigurationValue(TenantConfigurationKey.AUTHENTICATION_GATEWAY_SECURITY_TOKEN_KEY, String.class);
assertThat(updatedConfigurationValue2.isGlobal()).isFalse(); assertThat(updatedConfigurationValue2.isGlobal()).isFalse();
assertThat(updatedConfigurationValue2.getValue()).isEqualTo(newConfigurationValue2); assertThat(updatedConfigurationValue2.getValue()).isEqualTo(newConfigurationValue2);
// assertThat(tenantConfigurationManagement().getTenantConfigurations()).hasSize(1);
} }
/** /**
@@ -95,12 +104,12 @@ class TenantConfigurationManagementTest extends AbstractJpaIntegrationTest imple
final String value2 = "secondValue"; final String value2 = "secondValue";
// add value first // add value first
tenantConfigurationManagement().addOrUpdateConfiguration(configKey, value1); tenantConfigurationManagement.addOrUpdateConfiguration(configKey, value1);
assertThat(tenantConfigurationManagement().getConfigurationValue(configKey, String.class).getValue()).isEqualTo(value1); assertThat(tenantConfigurationManagement.getConfigurationValue(configKey, String.class).getValue()).isEqualTo(value1);
// update to value second // update to value second
tenantConfigurationManagement().addOrUpdateConfiguration(configKey, value2); tenantConfigurationManagement.addOrUpdateConfiguration(configKey, value2);
assertThat(tenantConfigurationManagement().getConfigurationValue(configKey, String.class).getValue()).isEqualTo(value2); assertThat(tenantConfigurationManagement.getConfigurationValue(configKey, String.class).getValue()).isEqualTo(value2);
} }
/** /**
@@ -114,12 +123,12 @@ class TenantConfigurationManagementTest extends AbstractJpaIntegrationTest imple
}}; }};
// add value first // add value first
tenantConfigurationManagement().addOrUpdateConfiguration(configuration); tenantConfigurationManagement.addOrUpdateConfiguration(configuration);
assertThat(tenantConfigurationManagement().getConfigurationValue( assertThat(tenantConfigurationManagement.getConfigurationValue(
TenantConfigurationKey.AUTHENTICATION_GATEWAY_SECURITY_TOKEN_KEY, String.class).getValue()) TenantConfigurationKey.AUTHENTICATION_GATEWAY_SECURITY_TOKEN_KEY, String.class).getValue())
.isEqualTo("token_123"); .isEqualTo("token_123");
assertThat( assertThat(
tenantConfigurationManagement().getConfigurationValue(TenantConfigurationKey.ROLLOUT_APPROVAL_ENABLED, Boolean.class).getValue()) tenantConfigurationManagement.getConfigurationValue(TenantConfigurationKey.ROLLOUT_APPROVAL_ENABLED, Boolean.class).getValue())
.isTrue(); .isTrue();
} }
@@ -130,11 +139,11 @@ class TenantConfigurationManagementTest extends AbstractJpaIntegrationTest imple
void storeAndUpdateTenantSpecificConfigurationAsBoolean() { void storeAndUpdateTenantSpecificConfigurationAsBoolean() {
final String configKey = TenantConfigurationKey.AUTHENTICATION_HEADER_ENABLED; final String configKey = TenantConfigurationKey.AUTHENTICATION_HEADER_ENABLED;
final Boolean value1 = true; final Boolean value1 = true;
tenantConfigurationManagement().addOrUpdateConfiguration(configKey, value1); tenantConfigurationManagement.addOrUpdateConfiguration(configKey, value1);
assertThat(tenantConfigurationManagement().getConfigurationValue(configKey, Boolean.class).getValue()).isEqualTo(value1); assertThat(tenantConfigurationManagement.getConfigurationValue(configKey, Boolean.class).getValue()).isEqualTo(value1);
final Boolean value2 = false; final Boolean value2 = false;
tenantConfigurationManagement().addOrUpdateConfiguration(configKey, value2); tenantConfigurationManagement.addOrUpdateConfiguration(configKey, value2);
assertThat(tenantConfigurationManagement().getConfigurationValue(configKey, Boolean.class).getValue()).isEqualTo(value2); assertThat(tenantConfigurationManagement.getConfigurationValue(configKey, Boolean.class).getValue()).isEqualTo(value2);
} }
/** /**
@@ -146,7 +155,7 @@ class TenantConfigurationManagementTest extends AbstractJpaIntegrationTest imple
final String value1 = "thisIsNotABoolean"; final String value1 = "thisIsNotABoolean";
// add value as String // add value as String
assertThatThrownBy(() -> tenantConfigurationManagement().addOrUpdateConfiguration(configKey, value1)) assertThatThrownBy(() -> tenantConfigurationManagement.addOrUpdateConfiguration(configKey, value1))
.as("Should not have worked as value is not a boolean") .as("Should not have worked as value is not a boolean")
.isInstanceOf(TenantConfigurationValidatorException.class); .isInstanceOf(TenantConfigurationValidatorException.class);
} }
@@ -163,15 +172,15 @@ class TenantConfigurationManagementTest extends AbstractJpaIntegrationTest imple
}}; }};
try { try {
tenantConfigurationManagement().addOrUpdateConfiguration(configuration); tenantConfigurationManagement.addOrUpdateConfiguration(configuration);
fail("should not have worked as type is wrong"); fail("should not have worked as type is wrong");
} catch (final TenantConfigurationValidatorException e) { } catch (final TenantConfigurationValidatorException e) {
assertThat( assertThat(
tenantConfigurationManagement().getConfigurationValue( tenantConfigurationManagement.getConfigurationValue(
TenantConfigurationKey.AUTHENTICATION_GATEWAY_SECURITY_TOKEN_KEY, String.class).getValue()) TenantConfigurationKey.AUTHENTICATION_GATEWAY_SECURITY_TOKEN_KEY, String.class).getValue())
.isNotEqualTo("token_123"); .isNotEqualTo("token_123");
assertThat( assertThat(
tenantConfigurationManagement().getConfigurationValue( tenantConfigurationManagement.getConfigurationValue(
TenantConfigurationKey.ROLLOUT_APPROVAL_ENABLED, Boolean.class).getValue()) TenantConfigurationKey.ROLLOUT_APPROVAL_ENABLED, Boolean.class).getValue())
.isNotEqualTo(true); .isNotEqualTo(true);
} }
@@ -185,22 +194,22 @@ class TenantConfigurationManagementTest extends AbstractJpaIntegrationTest imple
final String configKey = TenantConfigurationKey.AUTHENTICATION_GATEWAY_SECURITY_TOKEN_KEY; final String configKey = TenantConfigurationKey.AUTHENTICATION_GATEWAY_SECURITY_TOKEN_KEY;
// gateway token does not have default value so no configuration value should be available // gateway token does not have default value so no configuration value should be available
final String defaultConfigValue = tenantConfigurationManagement().getConfigurationValue(configKey, String.class).getValue(); final String defaultConfigValue = tenantConfigurationManagement.getConfigurationValue(configKey, String.class).getValue();
assertThat(defaultConfigValue).isEmpty(); assertThat(defaultConfigValue).isEmpty();
// update the tenant specific configuration // update the tenant specific configuration
final String newConfigurationValue = "thisIsAnotherValueForPolling"; final String newConfigurationValue = "thisIsAnotherValueForPolling";
assertThat(newConfigurationValue).isNotEqualTo(defaultConfigValue); assertThat(newConfigurationValue).isNotEqualTo(defaultConfigValue);
tenantConfigurationManagement().addOrUpdateConfiguration(configKey, newConfigurationValue); tenantConfigurationManagement.addOrUpdateConfiguration(configKey, newConfigurationValue);
// verify that new configuration value is used // verify that new configuration value is used
final String updatedConfigurationValue = tenantConfigurationManagement().getConfigurationValue(configKey, String.class).getValue(); final String updatedConfigurationValue = tenantConfigurationManagement.getConfigurationValue(configKey, String.class).getValue();
assertThat(updatedConfigurationValue).isEqualTo(newConfigurationValue); assertThat(updatedConfigurationValue).isEqualTo(newConfigurationValue);
// delete the tenant specific configuration // delete the tenant specific configuration
tenantConfigurationManagement().deleteConfiguration(configKey); tenantConfigurationManagement.deleteConfiguration(configKey);
// ensure that now gateway token is set again, because is deleted and must be empty now // ensure that now gateway token is set again, because is deleted and must be empty now
assertThat(tenantConfigurationManagement().getConfigurationValue(configKey, String.class).getValue()).isEmpty(); assertThat(tenantConfigurationManagement.getConfigurationValue(configKey, String.class).getValue()).isEmpty();
} }
/** /**
@@ -210,7 +219,7 @@ class TenantConfigurationManagementTest extends AbstractJpaIntegrationTest imple
void storesIntegerWhenStringIsExpected() { void storesIntegerWhenStringIsExpected() {
final String configKey = TenantConfigurationKey.AUTHENTICATION_GATEWAY_SECURITY_TOKEN_KEY; final String configKey = TenantConfigurationKey.AUTHENTICATION_GATEWAY_SECURITY_TOKEN_KEY;
final Integer wrongDatType = 123; final Integer wrongDatType = 123;
assertThatThrownBy(() -> tenantConfigurationManagement().addOrUpdateConfiguration(configKey, wrongDatType)) assertThatThrownBy(() -> tenantConfigurationManagement.addOrUpdateConfiguration(configKey, wrongDatType))
.as("Should not have worked as integer is not a string") .as("Should not have worked as integer is not a string")
.isInstanceOf(TenantConfigurationValidatorException.class); .isInstanceOf(TenantConfigurationValidatorException.class);
} }
@@ -222,7 +231,7 @@ class TenantConfigurationManagementTest extends AbstractJpaIntegrationTest imple
void storesIntegerWhenBooleanIsExpected() { void storesIntegerWhenBooleanIsExpected() {
final String configKey = TenantConfigurationKey.AUTHENTICATION_GATEWAY_SECURITY_TOKEN_ENABLED; final String configKey = TenantConfigurationKey.AUTHENTICATION_GATEWAY_SECURITY_TOKEN_ENABLED;
final Integer wrongDataType = 123; final Integer wrongDataType = 123;
assertThatThrownBy(() -> tenantConfigurationManagement().addOrUpdateConfiguration(configKey, wrongDataType)) assertThatThrownBy(() -> tenantConfigurationManagement.addOrUpdateConfiguration(configKey, wrongDataType))
.as("Should not have worked as integer is not a boolean") .as("Should not have worked as integer is not a boolean")
.isInstanceOf(TenantConfigurationValidatorException.class); .isInstanceOf(TenantConfigurationValidatorException.class);
} }
@@ -234,7 +243,7 @@ class TenantConfigurationManagementTest extends AbstractJpaIntegrationTest imple
void storesIntegerWhenPollingIntervalIsExpected() { void storesIntegerWhenPollingIntervalIsExpected() {
final String configKey = TenantConfigurationKey.POLLING_TIME; final String configKey = TenantConfigurationKey.POLLING_TIME;
final Integer wrongDataType = 123; final Integer wrongDataType = 123;
assertThatThrownBy(() -> tenantConfigurationManagement().addOrUpdateConfiguration(configKey, wrongDataType)) assertThatThrownBy(() -> tenantConfigurationManagement.addOrUpdateConfiguration(configKey, wrongDataType))
.as("Should not have worked as integer is not a time field") .as("Should not have worked as integer is not a time field")
.isInstanceOf(TenantConfigurationValidatorException.class); .isInstanceOf(TenantConfigurationValidatorException.class);
} }
@@ -246,7 +255,7 @@ class TenantConfigurationManagementTest extends AbstractJpaIntegrationTest imple
void storesWrongFormattedStringAsPollingInterval() { void storesWrongFormattedStringAsPollingInterval() {
final String configKey = TenantConfigurationKey.POLLING_TIME; final String configKey = TenantConfigurationKey.POLLING_TIME;
final String wrongFormatted = "wrongFormatted"; final String wrongFormatted = "wrongFormatted";
assertThatThrownBy(() -> tenantConfigurationManagement().addOrUpdateConfiguration(configKey, wrongFormatted)) assertThatThrownBy(() -> tenantConfigurationManagement.addOrUpdateConfiguration(configKey, wrongFormatted))
.as("should not have worked as string is not a time field") .as("should not have worked as string is not a time field")
.isInstanceOf(TenantConfigurationValidatorException.class); .isInstanceOf(TenantConfigurationValidatorException.class);
} }
@@ -259,7 +268,7 @@ class TenantConfigurationManagementTest extends AbstractJpaIntegrationTest imple
final String configKey = TenantConfigurationKey.POLLING_TIME; final String configKey = TenantConfigurationKey.POLLING_TIME;
final String tooSmallDuration = DurationHelper.toString(getDurationByTimeValues(0, 0, 1)); final String tooSmallDuration = DurationHelper.toString(getDurationByTimeValues(0, 0, 1));
assertThatThrownBy(() -> tenantConfigurationManagement().addOrUpdateConfiguration(configKey, tooSmallDuration)) assertThatThrownBy(() -> tenantConfigurationManagement.addOrUpdateConfiguration(configKey, tooSmallDuration))
.as("Should not have worked as string has an invalid format") .as("Should not have worked as string has an invalid format")
.isInstanceOf(TenantConfigurationValidatorException.class); .isInstanceOf(TenantConfigurationValidatorException.class);
} }
@@ -274,9 +283,9 @@ class TenantConfigurationManagementTest extends AbstractJpaIntegrationTest imple
final Duration duration = getDurationByTimeValues(1, 2, 0); final Duration duration = getDurationByTimeValues(1, 2, 0);
assertThat(duration).isEqualTo(Duration.ofHours(1).plusMinutes(2)); assertThat(duration).isEqualTo(Duration.ofHours(1).plusMinutes(2));
tenantConfigurationManagement().addOrUpdateConfiguration(configKey, DurationHelper.toString(duration)); tenantConfigurationManagement.addOrUpdateConfiguration(configKey, DurationHelper.toString(duration));
final String storedDurationString = tenantConfigurationManagement().getConfigurationValue(configKey, String.class).getValue(); final String storedDurationString = tenantConfigurationManagement.getConfigurationValue(configKey, String.class).getValue();
assertThat(duration).isEqualTo(DurationHelper.fromString(storedDurationString)); assertThat(duration).isEqualTo(DurationHelper.fromString(storedDurationString));
} }
@@ -285,7 +294,7 @@ class TenantConfigurationManagementTest extends AbstractJpaIntegrationTest imple
*/ */
@Test @Test
void requestConfigValueWithWrongType() { void requestConfigValueWithWrongType() {
assertThatThrownBy(() -> tenantConfigurationManagement().getConfigurationValue( assertThatThrownBy(() -> tenantConfigurationManagement.getConfigurationValue(
TenantConfigurationKey.POLLING_TIME, Serializable.class)) TenantConfigurationKey.POLLING_TIME, Serializable.class))
.isInstanceOf(TenantConfigurationValidatorException.class); .isInstanceOf(TenantConfigurationValidatorException.class);
} }
@@ -319,7 +328,7 @@ class TenantConfigurationManagementTest extends AbstractJpaIntegrationTest imple
@Test @Test
void storeTenantConfigurationWhichIsNotDeclaredThrowsException() { void storeTenantConfigurationWhichIsNotDeclaredThrowsException() {
final String configKeyWhichDoesNotExists = "configKeyWhichDoesNotExists"; final String configKeyWhichDoesNotExists = "configKeyWhichDoesNotExists";
assertThatThrownBy(() -> tenantConfigurationManagement().addOrUpdateConfiguration(configKeyWhichDoesNotExists, "value")) assertThatThrownBy(() -> tenantConfigurationManagement.addOrUpdateConfiguration(configKeyWhichDoesNotExists, "value"))
.as("Expected InvalidTenantConfigurationKeyException for tenant configuration key which is not declared") .as("Expected InvalidTenantConfigurationKeyException for tenant configuration key which is not declared")
.isInstanceOf(InvalidTenantConfigurationKeyException.class); .isInstanceOf(InvalidTenantConfigurationKeyException.class);
} }
@@ -328,16 +337,16 @@ class TenantConfigurationManagementTest extends AbstractJpaIntegrationTest imple
void storeTenantConfigNumberValue() { void storeTenantConfigNumberValue() {
final String configKey = TenantConfigurationKey.ACTION_CLEANUP_AUTO_EXPIRY; final String configKey = TenantConfigurationKey.ACTION_CLEANUP_AUTO_EXPIRY;
// set auto cleanup for 1 day in Integer ms // set auto cleanup for 1 day in Integer ms
tenantConfigurationManagement().addOrUpdateConfiguration(configKey, 86400000); tenantConfigurationManagement.addOrUpdateConfiguration(configKey, 86400000);
// expect long // expect long
Long autoCleanupDaysInMs = tenantConfigurationManagement().getConfigurationValue(configKey, Long.class).getValue(); Long autoCleanupDaysInMs = tenantConfigurationManagement.getConfigurationValue(configKey, Long.class).getValue();
Assertions.assertEquals(86400000, autoCleanupDaysInMs); Assertions.assertEquals(86400000, autoCleanupDaysInMs);
tenantConfigurationManagement().addOrUpdateConfiguration(configKey, 86400000); tenantConfigurationManagement.addOrUpdateConfiguration(configKey, 86400000);
// 30 days 2,592,000,000 ms as Long // 30 days 2,592,000,000 ms as Long
tenantConfigurationManagement().addOrUpdateConfiguration(configKey, 2592000000L); tenantConfigurationManagement.addOrUpdateConfiguration(configKey, 2592000000L);
autoCleanupDaysInMs = tenantConfigurationManagement().getConfigurationValue(configKey, Long.class).getValue(); autoCleanupDaysInMs = tenantConfigurationManagement.getConfigurationValue(configKey, Long.class).getValue();
Assertions.assertEquals(2592000000L, autoCleanupDaysInMs); Assertions.assertEquals(2592000000L, autoCleanupDaysInMs);
} }
@@ -346,7 +355,7 @@ class TenantConfigurationManagementTest extends AbstractJpaIntegrationTest imple
final String configKey = TenantConfigurationKey.ACTION_CLEANUP_AUTO_EXPIRY; final String configKey = TenantConfigurationKey.ACTION_CLEANUP_AUTO_EXPIRY;
// set auto cleanup for 1 day in String ms // set auto cleanup for 1 day in String ms
assertThatThrownBy(() -> assertThatThrownBy(() ->
tenantConfigurationManagement().addOrUpdateConfiguration(configKey, "86400000")) tenantConfigurationManagement.addOrUpdateConfiguration(configKey, "86400000"))
.as("Cannot convert the value 86400000 of type String to the type Long defined by the configuration key.") .as("Cannot convert the value 86400000 of type String to the type Long defined by the configuration key.")
.isInstanceOf(TenantConfigurationValidatorException.class); .isInstanceOf(TenantConfigurationValidatorException.class);
} }

View File

@@ -32,7 +32,7 @@ import org.springframework.security.web.firewall.StrictHttpFirewall;
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils;
/** /**
* All configurations related to HawkBit's auth and authorization layer. * All configurations related to HawkBit's authentication and authorization layer.
*/ */
@Slf4j @Slf4j
@Configuration @Configuration

View File

@@ -106,7 +106,7 @@ public class HawkbitClient {
template.header(AUTHORIZATION, "GatewayToken " + tenant.getGatewayToken()); template.header(AUTHORIZATION, "GatewayToken " + tenant.getGatewayToken());
} else if (!ObjectUtils.isEmpty(controller.getSecurityToken())) { } else if (!ObjectUtils.isEmpty(controller.getSecurityToken())) {
template.header(AUTHORIZATION, "TargetToken " + controller.getSecurityToken()); template.header(AUTHORIZATION, "TargetToken " + controller.getSecurityToken());
} // else do not send auth, no auth or certificate based } // else do not send authentication, no authentication or certificate based
}; };
// @formatter:on // @formatter:on
private static final ErrorDecoder DEFAULT_ERROR_DECODER_0 = new ErrorDecoder.Default(); private static final ErrorDecoder DEFAULT_ERROR_DECODER_0 = new ErrorDecoder.Default();
@@ -279,7 +279,7 @@ public class HawkbitClient {
(controller == null ? hawkBitServer.getMgmtUrl() : hawkBitServer.getDdiUrl()) + path).openConnection(); (controller == null ? hawkBitServer.getMgmtUrl() : hawkBitServer.getDdiUrl()) + path).openConnection();
conn.setRequestMethod("POST"); conn.setRequestMethod("POST");
// deal with auth - only from headers1 // deal with authentication - only from headers1
final RequestTemplate requestTemplate = new RequestTemplate(); final RequestTemplate requestTemplate = new RequestTemplate();
requestInterceptorFn.apply(tenant, controller).apply(requestTemplate); requestInterceptorFn.apply(tenant, controller).apply(requestTemplate);
requestTemplate.headers().forEach((k, v) -> v.forEach(e -> conn.setRequestProperty(k, e))); requestTemplate.headers().forEach((k, v) -> v.forEach(e -> conn.setRequestProperty(k, e)));

View File

@@ -26,7 +26,7 @@ public class Tenant {
@NonNull @NonNull
private String tenantId = "DEFAULT"; private String tenantId = "DEFAULT";
// basic auth user, to access management api // basic authentication user, to access management api
@Nullable @Nullable
private String username = "admin"; private String username = "admin";
@ToString.Exclude @ToString.Exclude

View File

@@ -32,17 +32,17 @@ import org.eclipse.hawkbit.sdk.ca.CA;
import org.springframework.util.ObjectUtils; import org.springframework.util.ObjectUtils;
/** /**
* Helper for auth setup * Helper for authentication setup
*/ */
@Slf4j @Slf4j
@AllArgsConstructor @AllArgsConstructor
public class AuthenticationSetupHelper { public class AuthenticationSetupHelper {
private static final String AUTHENTICATION_MODE_GATEWAY_SECURITY_TOKEN_KEY = "auth.gatewaytoken.key"; private static final String AUTHENTICATION_MODE_GATEWAY_SECURITY_TOKEN_KEY = "authentication.gatewaytoken.key";
private static final String AUTHENTICATION_MODE_GATEWAY_SECURITY_TOKEN_ENABLED = "auth.gatewaytoken.enabled"; private static final String AUTHENTICATION_MODE_GATEWAY_SECURITY_TOKEN_ENABLED = "authentication.gatewaytoken.enabled";
private static final String AUTHENTICATION_MODE_TARGET_SECURITY_TOKEN_ENABLED = "auth.targettoken.enabled"; private static final String AUTHENTICATION_MODE_TARGET_SECURITY_TOKEN_ENABLED = "authentication.targettoken.enabled";
private static final String AUTHENTICATION_MODE_HEADER_ENABLED = "auth.header.enabled"; private static final String AUTHENTICATION_MODE_HEADER_ENABLED = "authentication.header.enabled";
private static final String AUTHENTICATION_MODE_HEADER_AUTHORITY_NAME = "auth.header.authority"; private static final String AUTHENTICATION_MODE_HEADER_AUTHORITY_NAME = "authentication.header.authority";
private static final Random RND = new SecureRandom(); private static final Random RND = new SecureRandom();
@@ -57,7 +57,7 @@ public class AuthenticationSetupHelper {
return Base64.getEncoder().encodeToString(rnd); return Base64.getEncoder().encodeToString(rnd);
} }
// sets up a certificate auth, if DdiCA is null - generate self signed CA // sets up a certificate authentication, if DdiCA is null - generate self signed CA
public void setupCertificateAuthentication() throws CertificateException { public void setupCertificateAuthentication() throws CertificateException {
final MgmtTenantManagementRestApi mgmtTenantManagementRestApi = hawkbitClient.mgmtService(MgmtTenantManagementRestApi.class, tenant); final MgmtTenantManagementRestApi mgmtTenantManagementRestApi = hawkbitClient.mgmtService(MgmtTenantManagementRestApi.class, tenant);
CA ddiCA = tenant.getDdiCA(); CA ddiCA = tenant.getDdiCA();
@@ -80,7 +80,7 @@ public class AuthenticationSetupHelper {
} }
} }
// enables secure token auth // enables secure token authentication
public void setupSecureTokenAuthentication() { public void setupSecureTokenAuthentication() {
final MgmtTenantManagementRestApi mgmtTenantManagementRestApi = hawkbitClient.mgmtService(MgmtTenantManagementRestApi.class, tenant); final MgmtTenantManagementRestApi mgmtTenantManagementRestApi = hawkbitClient.mgmtService(MgmtTenantManagementRestApi.class, tenant);
if (!(Boolean.TRUE.equals(Objects.requireNonNull(mgmtTenantManagementRestApi if (!(Boolean.TRUE.equals(Objects.requireNonNull(mgmtTenantManagementRestApi
@@ -90,7 +90,7 @@ public class AuthenticationSetupHelper {
} }
} }
// set gateway token auth (generate and sets gateway token to tenant, if not set up) // set gateway token authentication (generate and sets gateway token to tenant, if not set up)
// return the gateway token // return the gateway token
public void setupGatewayTokenAuthentication() { public void setupGatewayTokenAuthentication() {
String gatewayToken = tenant.getGatewayToken(); String gatewayToken = tenant.getGatewayToken();
@@ -112,8 +112,8 @@ public class AuthenticationSetupHelper {
} }
} }
// if gateway token is configured then the gateway auth is enabled, so all devices use gateway token auth. // if gateway token is configured then the gateway authentication is enabled, so all devices use gateway token authentication.
// otherwise, target token auth is enabled - then all devices shall be registered and the target token shall be set to the one from // otherwise, target token authentication is enabled - then all devices shall be registered and the target token shall be set to the one from
// the DDI controller instance // the DDI controller instance
public void setupTargetAuthentication() { public void setupTargetAuthentication() {
final String gatewayToken = tenant.getGatewayToken(); final String gatewayToken = tenant.getGatewayToken();

View File

@@ -128,8 +128,8 @@ public class HawkbitUiApp implements AppShellConfigurator {
final HttpURLConnection conn = (HttpURLConnection) url.openConnection(); final HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET"); conn.setRequestMethod("GET");
final String auth = username + ":" + password; final String authentication = username + ":" + password;
final String encodedAuth = Base64.getEncoder().encodeToString(auth.getBytes()); final String encodedAuth = Base64.getEncoder().encodeToString(authentication.getBytes());
conn.setRequestProperty(AUTHORIZATION_HEADER, "Basic " + encodedAuth); conn.setRequestProperty(AUTHORIZATION_HEADER, "Basic " + encodedAuth);
return conn.getResponseCode() != 401; return conn.getResponseCode() != 401;