External ref for actions and status-update events (#830)
* Add feature to listen to rollout status update * With this feature, extensions can update back the status of a given rollout using an event(containing distributionSetId and targetId). * In future, AmqpMessageHandlerService can make use of this feature and de-couple its own implementation from performing status update of an action. * Implement ActionStatusUpdateHandlerService using actionId * Extend actions to support externalRef * Update the action status using externalRef. * Update securityContext to support running a callable under specific authorities. * Fixing the review comments * Increase length of externalRef to 128 chars * Remove actionStatusUpdateEvent and the handler service * Use 256 chars for externalRef * Increment the version for migration script * Another feature had use v1_12_12 in a recent PR. So incrementing the version. * Create length limit for externalRef and add it to index * Externalref will be much longer than 256 chars if controllerId is as long as 256 chars * Adding tests for verifying externalRef in controllerManagement * Improve test to consider multiple externalRefs * Fix issue in migration script for mssql server * Fix documentation Signed-off-by: Ravindranath Sandeep (INST-IOT/ESW-Imb) <Sandeep.Ravindranath@bosch-si.com>
This commit is contained in:
committed by
Stefan Behl
parent
e80399bc79
commit
fba6cf9787
@@ -11,12 +11,18 @@ package org.eclipse.hawkbit.security;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
import org.eclipse.hawkbit.im.authentication.TenantAwareAuthenticationDetails;
|
||||
import org.eclipse.hawkbit.im.authentication.SpPermission.SpringEvalExpressions;
|
||||
import org.eclipse.hawkbit.tenancy.TenantAware;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.security.authentication.AnonymousAuthenticationToken;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
||||
@@ -111,6 +117,42 @@ public class SystemSecurityContext {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs a given {@link Callable} within a system security context, which has
|
||||
* the provided {@link GrantedAuthority}s to successfully run the
|
||||
* {@link Callable}.
|
||||
*
|
||||
* The security context will be switched to the a new
|
||||
* {@link SecurityContext} and back after the callable is called.
|
||||
*
|
||||
* @param tenant
|
||||
* under which the {@link Callable#call()} must be executed.
|
||||
* @param callable
|
||||
* to call within the security context
|
||||
* @return the return value of the {@link Callable#call()} method.
|
||||
*/
|
||||
// The callable API throws a Exception and not a specific one
|
||||
@SuppressWarnings({ "squid:S2221", "squid:S00112" })
|
||||
public <T> T runAsControllerAsTenant(@NotEmpty final String tenant, @NotNull final Callable<T> callable) {
|
||||
final SecurityContext oldContext = SecurityContextHolder.getContext();
|
||||
List<SimpleGrantedAuthority> authorities = Collections
|
||||
.singletonList(new SimpleGrantedAuthority(SpringEvalExpressions.CONTROLLER_ROLE_ANONYMOUS));
|
||||
try {
|
||||
return tenantAware.runAsTenant(tenant, () -> {
|
||||
try {
|
||||
setCustomSecurityContext(tenant, oldContext.getAuthentication().getPrincipal(), authorities);
|
||||
return callable.call();
|
||||
|
||||
} catch (final Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
});
|
||||
|
||||
} finally {
|
||||
SecurityContextHolder.setContext(oldContext);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {@code true} if the current running code is running as system
|
||||
* code block.
|
||||
@@ -119,6 +161,16 @@ public class SystemSecurityContext {
|
||||
return SecurityContextHolder.getContext().getAuthentication() instanceof SystemCodeAuthentication;
|
||||
}
|
||||
|
||||
private void setCustomSecurityContext(final String tenantId, final Object principal,
|
||||
final Collection<? extends GrantedAuthority> authorities) {
|
||||
final AnonymousAuthenticationToken authenticationToken = new AnonymousAuthenticationToken(
|
||||
UUID.randomUUID().toString(), principal, authorities);
|
||||
authenticationToken.setDetails(new TenantAwareAuthenticationDetails(tenantId, true));
|
||||
final SecurityContextImpl securityContextImpl = new SecurityContextImpl();
|
||||
securityContextImpl.setAuthentication(authenticationToken);
|
||||
SecurityContextHolder.setContext(securityContextImpl);
|
||||
}
|
||||
|
||||
private static void setSystemContext(final SecurityContext oldContext) {
|
||||
final Authentication oldAuthentication = oldContext.getAuthentication();
|
||||
final SecurityContextImpl securityContextImpl = new SecurityContextImpl();
|
||||
|
||||
Reference in New Issue
Block a user