Fix Json serializer defaults (#2663)
Signed-off-by: Avgustin Marinov <Avgustin.Marinov@bosch.com>
This commit is contained in:
@@ -31,7 +31,7 @@ public class PropertyBasedArtifactUrlResolverAutoConfiguration {
|
|||||||
@ConditionalOnMissingBean(ArtifactUrlResolver.class)
|
@ConditionalOnMissingBean(ArtifactUrlResolver.class)
|
||||||
PropertyBasedArtifactUrlResolver propertyBasedArtifactUrlHandler(
|
PropertyBasedArtifactUrlResolver propertyBasedArtifactUrlHandler(
|
||||||
final PropertyBasedArtifactUrlResolverProperties urlHandlerProperties,
|
final PropertyBasedArtifactUrlResolverProperties urlHandlerProperties,
|
||||||
@Value("${server.servlet.context-path:}") final String contextPath) {
|
@Value("${hawkbit.server.servlet.context-path:}") final String contextPath) {
|
||||||
return new PropertyBasedArtifactUrlResolver(urlHandlerProperties, contextPath);
|
return new PropertyBasedArtifactUrlResolver(urlHandlerProperties, contextPath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -25,4 +25,4 @@ spring.servlet.multipart.max-file-size=5MB
|
|||||||
hawkbit.server.security.dos.maxStatusEntriesPerAction=100
|
hawkbit.server.security.dos.maxStatusEntriesPerAction=100
|
||||||
hawkbit.server.security.dos.maxAttributeEntriesPerTarget=10
|
hawkbit.server.security.dos.maxAttributeEntriesPerTarget=10
|
||||||
# Quota - END
|
# Quota - END
|
||||||
org.eclipse.hawkbit.events.remote-enabled=false
|
hawkbit.events.remote-enabled=false
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ import org.springframework.test.context.TestPropertySource;
|
|||||||
@ActiveProfiles({ "test" })
|
@ActiveProfiles({ "test" })
|
||||||
@SpringBootTest(classes = { JpaRepositoryConfiguration.class }, webEnvironment = SpringBootTest.WebEnvironment.NONE)
|
@SpringBootTest(classes = { JpaRepositoryConfiguration.class }, webEnvironment = SpringBootTest.WebEnvironment.NONE)
|
||||||
@TestPropertySource(properties = {
|
@TestPropertySource(properties = {
|
||||||
"org.eclipse.hawkbit.events.remote-enabled=false",
|
"hawkbit.events.remote-enabled=false",
|
||||||
"spring.main.allow-bean-definition-overriding=true" })
|
"spring.main.allow-bean-definition-overriding=true" })
|
||||||
class AmqpMessageDispatcherServiceTest extends AbstractIntegrationTest {
|
class AmqpMessageDispatcherServiceTest extends AbstractIntegrationTest {
|
||||||
|
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ import org.springframework.test.context.TestPropertySource;
|
|||||||
// Dirty context is necessary to create a new vhost and recreate all necessary beans after every test class.
|
// Dirty context is necessary to create a new vhost and recreate all necessary beans after every test class.
|
||||||
@DirtiesContext(classMode = ClassMode.AFTER_CLASS)
|
@DirtiesContext(classMode = ClassMode.AFTER_CLASS)
|
||||||
@TestPropertySource(properties = {
|
@TestPropertySource(properties = {
|
||||||
"org.eclipse.hawkbit.events.remote-enabled=false",
|
"hawkbit.events.remote-enabled=false",
|
||||||
"spring.main.allow-bean-definition-overriding=true" })
|
"spring.main.allow-bean-definition-overriding=true" })
|
||||||
@SuppressWarnings("java:S6813") // constructor injects are not possible for test classes
|
@SuppressWarnings("java:S6813") // constructor injects are not possible for test classes
|
||||||
public abstract class AbstractAmqpIntegrationTest extends AbstractIntegrationTest {
|
public abstract class AbstractAmqpIntegrationTest extends AbstractIntegrationTest {
|
||||||
|
|||||||
@@ -11,4 +11,4 @@
|
|||||||
# Logging START - activate to see request/response details
|
# Logging START - activate to see request/response details
|
||||||
#logging.level.org.eclipse.hawkbit.rest.util.MockMvcResultPrinter=DEBUG
|
#logging.level.org.eclipse.hawkbit.rest.util.MockMvcResultPrinter=DEBUG
|
||||||
# Logging END
|
# Logging END
|
||||||
org.eclipse.hawkbit.events.remote-enabled=false
|
hawkbit.events.remote-enabled=false
|
||||||
|
|||||||
@@ -49,8 +49,8 @@ spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.amqp.RabbitA
|
|||||||
|
|
||||||
## Uncomment bellow to Enable communication between services (disabled by default) - no cluster support.
|
## Uncomment bellow to Enable communication between services (disabled by default) - no cluster support.
|
||||||
# To enable it, enable RabbitMQ (see above)
|
# To enable it, enable RabbitMQ (see above)
|
||||||
# and set below 'org.eclipse.hawkbit.events.remote-enabled=true'
|
# and set below 'hawkbit.events.remote-enabled=true'
|
||||||
org.eclipse.hawkbit.events.remote-enabled=false
|
hawkbit.events.remote-enabled=false
|
||||||
|
|
||||||
## Disable DMF (by default) - no DMF support. To enable it, enable RabbitMQ (see above) and comment the line
|
## Disable DMF (by default) - no DMF support. To enable it, enable RabbitMQ (see above) and comment the line
|
||||||
## (hawkbit.dmf.rabbitmq.enabled=false) set hawkbit.dmf.rabbitmq.enabled=true
|
## (hawkbit.dmf.rabbitmq.enabled=false) set hawkbit.dmf.rabbitmq.enabled=true
|
||||||
|
|||||||
@@ -57,9 +57,9 @@ public class RepositoryConfiguration {
|
|||||||
@SuppressWarnings("java:S3358") // java:S3358 better readable this way
|
@SuppressWarnings("java:S3358") // java:S3358 better readable this way
|
||||||
RoleHierarchy roleHierarchy(
|
RoleHierarchy roleHierarchy(
|
||||||
// if configured replaces the hierarchy completely
|
// if configured replaces the hierarchy completely
|
||||||
@Value("${org.eclipse.hawkbit.hierarchy:}") final String hierarchy,
|
@Value("${hawkbit.hierarchy:}") final String hierarchy,
|
||||||
// if the "hierarchy" property is empty, and this property is configured it is appended to the default hierarchy
|
// if the "hierarchy" property is empty, and this property is configured it is appended to the default hierarchy
|
||||||
@Value("${org.eclipse.hawkbit.hierarchy.ext:}") final String hierarchyExt) {
|
@Value("${hawkbit.hierarchy.ext:}") final String hierarchyExt) {
|
||||||
return RoleHierarchyImpl.fromHierarchy(
|
return RoleHierarchyImpl.fromHierarchy(
|
||||||
ObjectUtils.isEmpty(hierarchy)
|
ObjectUtils.isEmpty(hierarchy)
|
||||||
? (ObjectUtils.isEmpty(hierarchyExt) ? Hierarchy.DEFAULT : Hierarchy.DEFAULT + hierarchyExt)
|
? (ObjectUtils.isEmpty(hierarchyExt) ? Hierarchy.DEFAULT : Hierarchy.DEFAULT + hierarchyExt)
|
||||||
|
|||||||
@@ -44,13 +44,13 @@ import org.springframework.context.ApplicationEventPublisher;
|
|||||||
@Slf4j
|
@Slf4j
|
||||||
public final class EventPublisherHolder {
|
public final class EventPublisherHolder {
|
||||||
|
|
||||||
@Value("${org.eclipse.hawkbit.events.remote-enabled:true}")
|
@Value("${hawkbit.events.remote-enabled:true}")
|
||||||
private boolean remoteEventsEnabled;
|
private boolean remoteEventsEnabled;
|
||||||
@Value("${org.eclipse.hawkbit.events.remote.destination:fanoutEventChannel}")
|
@Value("${hawkbit.events.remote.destination:fanoutEventChannel}")
|
||||||
private String fanoutEventChannel;
|
private String fanoutEventChannel;
|
||||||
@Value("${org.eclipse.hawkbit.events.remote-service-enabled:true}")
|
@Value("${hawkbit.events.remote-service-enabled:true}")
|
||||||
private boolean remoteServiceEventsEnabled;
|
private boolean remoteServiceEventsEnabled;
|
||||||
@Value("${org.eclipse.hawkbit.events.remote.service.destination:serviceEventChannel}")
|
@Value("${hawkbit.events.remote.service.destination:serviceEventChannel}")
|
||||||
private String serviceEventChannel;
|
private String serviceEventChannel;
|
||||||
|
|
||||||
|
|
||||||
@@ -65,7 +65,7 @@ public final class EventPublisherHolder {
|
|||||||
@PostConstruct
|
@PostConstruct
|
||||||
private void validateRemoteEventConfig() {
|
private void validateRemoteEventConfig() {
|
||||||
if (remoteEventsEnabled && streamBridge == null) {
|
if (remoteEventsEnabled && streamBridge == null) {
|
||||||
throw new IllegalStateException("'org.eclipse.hawkbit.events.remote-enabled' is true but streamBridge is not configured. Check if 'spring-cloud-starter-stream-rabbit' dependency is included.");
|
throw new IllegalStateException("'hawkbit.events.remote-enabled' is true but streamBridge is not configured. Check if 'spring-cloud-starter-stream-rabbit' dependency is included.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -120,7 +120,7 @@ public class JpaRolloutManagement implements RolloutManagement {
|
|||||||
RolloutStatus.CREATING, RolloutStatus.READY, RolloutStatus.WAITING_FOR_APPROVAL, RolloutStatus.STARTING, RolloutStatus.RUNNING,
|
RolloutStatus.CREATING, RolloutStatus.READY, RolloutStatus.WAITING_FOR_APPROVAL, RolloutStatus.STARTING, RolloutStatus.RUNNING,
|
||||||
RolloutStatus.PAUSED, RolloutStatus.APPROVAL_DENIED);
|
RolloutStatus.PAUSED, RolloutStatus.APPROVAL_DENIED);
|
||||||
|
|
||||||
@Value("${org.eclipse.hawkbit.repository.jpa.management.rollout.max.actions.per.transaction:5000}")
|
@Value("${hawkbit.repository.jpa.management.rollout.max.actions.per.transaction:5000}")
|
||||||
private int MAX_ACTIONS;
|
private int MAX_ACTIONS;
|
||||||
|
|
||||||
private final EntityManager entityManager;
|
private final EntityManager entityManager;
|
||||||
|
|||||||
@@ -64,4 +64,4 @@ hawkbit.repository.cluster.lock.refreshOnRemainPercent=10
|
|||||||
## reduce scheduler tic period to speed up tests
|
## reduce scheduler tic period to speed up tests
|
||||||
hawkbit.repository.cluster.lock.ticPeriodMS=10
|
hawkbit.repository.cluster.lock.ticPeriodMS=10
|
||||||
|
|
||||||
org.eclipse.hawkbit.events.remote-enabled=false
|
hawkbit.events.remote-enabled=false
|
||||||
@@ -80,4 +80,4 @@ hawkbit.server.security.dos.maxActionsPerTarget=20
|
|||||||
# Quota - END
|
# Quota - END
|
||||||
|
|
||||||
# Properties that are managed by autoconfigure module at runtime and not available during test - END
|
# Properties that are managed by autoconfigure module at runtime and not available during test - END
|
||||||
org.eclipse.hawkbit.events.remote-enabled=false
|
hawkbit.events.remote-enabled=false
|
||||||
@@ -32,6 +32,7 @@ import org.eclipse.hawkbit.security.SpringSecurityAuditorAware.AuditorAwarePrinc
|
|||||||
import org.eclipse.hawkbit.tenancy.TenantAwareAuthenticationDetails;
|
import org.eclipse.hawkbit.tenancy.TenantAwareAuthenticationDetails;
|
||||||
import org.eclipse.hawkbit.tenancy.TenantAwareUser;
|
import org.eclipse.hawkbit.tenancy.TenantAwareUser;
|
||||||
import org.springframework.security.core.Authentication;
|
import org.springframework.security.core.Authentication;
|
||||||
|
import org.springframework.security.core.AuthenticationException;
|
||||||
import org.springframework.security.core.GrantedAuthority;
|
import org.springframework.security.core.GrantedAuthority;
|
||||||
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
||||||
import org.springframework.security.core.context.SecurityContext;
|
import org.springframework.security.core.context.SecurityContext;
|
||||||
@@ -106,7 +107,7 @@ public interface SecurityContextSerializer {
|
|||||||
|
|
||||||
private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
|
private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
|
||||||
private static final boolean FALLBACK_TO_JAVA_SERIALIZATION =
|
private static final boolean FALLBACK_TO_JAVA_SERIALIZATION =
|
||||||
!Boolean.getBoolean("org.hawkbit.security.contextSerializer.json.no-fallback-to-java");
|
!Boolean.getBoolean("hawkbit.security.contextSerializer.json.no-fallback-to-java");
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String serialize(final SecurityContext securityContext) {
|
public String serialize(final SecurityContext securityContext) {
|
||||||
@@ -137,6 +138,8 @@ public interface SecurityContextSerializer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 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 authentication is not supported - always is false
|
||||||
|
// only authenticated user is supported
|
||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
@Data
|
@Data
|
||||||
private static class SecCtxInfo implements Serializable {
|
private static class SecCtxInfo implements Serializable {
|
||||||
@@ -145,19 +148,21 @@ public interface SecurityContextSerializer {
|
|||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
private String tenant;
|
private String tenant;
|
||||||
private boolean controller;
|
|
||||||
// auditor / username (authentication principal name)
|
// auditor / username (authentication principal name)
|
||||||
private String auditor;
|
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;
|
||||||
@JsonProperty(defaultValue = "true")
|
|
||||||
private boolean authenticated;
|
|
||||||
|
|
||||||
SecCtxInfo(final SecurityContext securityContext) {
|
SecCtxInfo(final SecurityContext securityContext) {
|
||||||
final Authentication authentication = securityContext.getAuthentication();
|
final Authentication authentication = securityContext.getAuthentication();
|
||||||
|
if (!authentication.isAuthenticated()) {
|
||||||
|
throw new IllegalStateException("Only authenticated context could be serialized");
|
||||||
|
}
|
||||||
if (authentication.getDetails() instanceof TenantAwareAuthenticationDetails tenantAwareDetails) {
|
if (authentication.getDetails() instanceof TenantAwareAuthenticationDetails tenantAwareDetails) {
|
||||||
|
if (tenantAwareDetails.controller()) {
|
||||||
|
throw new IllegalStateException("Controller authentication context is not supported");
|
||||||
|
}
|
||||||
tenant = tenantAwareDetails.tenant();
|
tenant = tenantAwareDetails.tenant();
|
||||||
controller = tenantAwareDetails.controller();
|
|
||||||
} else if (authentication.getPrincipal() instanceof TenantAwareUser tenantAwareUser) {
|
} else if (authentication.getPrincipal() instanceof TenantAwareUser tenantAwareUser) {
|
||||||
tenant = tenantAwareUser.getTenant();
|
tenant = tenantAwareUser.getTenant();
|
||||||
}
|
}
|
||||||
@@ -167,10 +172,10 @@ public interface SecurityContextSerializer {
|
|||||||
// 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 = SpringSecurityAuditorAware.resolveAuditor(authentication);
|
auditor = SpringSecurityAuditorAware.resolveAuditor(authentication);
|
||||||
authorities = authentication.getAuthorities().stream().map(Object::toString).toArray(String[]::new);
|
authorities = authentication.getAuthorities().stream().map(Object::toString).toArray(String[]::new);
|
||||||
authenticated = authentication.isAuthenticated();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// allows setting for auditor also as username (so supported auditor/username in json)
|
// TODO - remove it in future
|
||||||
|
// auditor alias, allows setting for auditor also as username (so supported auditor/username in json)
|
||||||
@JsonSetter("username")
|
@JsonSetter("username")
|
||||||
private void setUsername(final String username) {
|
private void setUsername(final String username) {
|
||||||
this.auditor = username;
|
this.auditor = username;
|
||||||
@@ -178,7 +183,7 @@ public interface SecurityContextSerializer {
|
|||||||
|
|
||||||
private SecurityContext toSecurityContext() {
|
private SecurityContext toSecurityContext() {
|
||||||
final SecurityContext ctx = SecurityContextHolder.createEmptyContext();
|
final SecurityContext ctx = SecurityContextHolder.createEmptyContext();
|
||||||
final Object details = tenant == null ? null : new TenantAwareAuthenticationDetails(tenant, controller);
|
final Object details = tenant == null ? null : new TenantAwareAuthenticationDetails(tenant, false);
|
||||||
final AuditorAwarePrincipal principal = () -> auditor;
|
final AuditorAwarePrincipal principal = () -> auditor;
|
||||||
final Collection<? extends GrantedAuthority> grantedAuthorities =
|
final Collection<? extends GrantedAuthority> grantedAuthorities =
|
||||||
Stream.of(authorities).map(SimpleGrantedAuthority::new).toList();
|
Stream.of(authorities).map(SimpleGrantedAuthority::new).toList();
|
||||||
@@ -196,7 +201,7 @@ public interface SecurityContextSerializer {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isAuthenticated() {
|
public boolean isAuthenticated() {
|
||||||
return authenticated;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
Reference in New Issue
Block a user