allow the getTargetSecurityToken can be called as system code
Signed-off-by: Michael Hirsch <michael.hirsch@bosch-si.com>
This commit is contained in:
@@ -54,6 +54,7 @@ import org.eclipse.hawkbit.repository.model.Target;
|
|||||||
import org.eclipse.hawkbit.repository.model.TargetInfo;
|
import org.eclipse.hawkbit.repository.model.TargetInfo;
|
||||||
import org.eclipse.hawkbit.repository.model.TargetUpdateStatus;
|
import org.eclipse.hawkbit.repository.model.TargetUpdateStatus;
|
||||||
import org.eclipse.hawkbit.repository.specifications.TargetSpecifications;
|
import org.eclipse.hawkbit.repository.specifications.TargetSpecifications;
|
||||||
|
import org.eclipse.hawkbit.security.SystemSecurityContext;
|
||||||
import org.hibernate.validator.constraints.NotEmpty;
|
import org.hibernate.validator.constraints.NotEmpty;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
@@ -118,6 +119,9 @@ public class DeploymentManagement {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private AfterTransactionCommitExecutor afterCommit;
|
private AfterTransactionCommitExecutor afterCommit;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private SystemSecurityContext systemSecurityContext;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* method assigns the {@link DistributionSet} to all {@link Target}s.
|
* method assigns the {@link DistributionSet} to all {@link Target}s.
|
||||||
*
|
*
|
||||||
@@ -422,11 +426,14 @@ public class DeploymentManagement {
|
|||||||
private void assignDistributionSetEvent(final Target target, final Long actionId,
|
private void assignDistributionSetEvent(final Target target, final Long actionId,
|
||||||
final List<SoftwareModule> softwareModules) {
|
final List<SoftwareModule> softwareModules) {
|
||||||
target.getTargetInfo().setUpdateStatus(TargetUpdateStatus.PENDING);
|
target.getTargetInfo().setUpdateStatus(TargetUpdateStatus.PENDING);
|
||||||
|
final String targetSecurityToken = systemSecurityContext.runAsSystem(() -> {
|
||||||
|
return target.getSecurityToken();
|
||||||
|
});
|
||||||
afterCommit.afterCommit(() -> {
|
afterCommit.afterCommit(() -> {
|
||||||
eventBus.post(new TargetInfoUpdateEvent(target.getTargetInfo()));
|
eventBus.post(new TargetInfoUpdateEvent(target.getTargetInfo()));
|
||||||
eventBus.post(new TargetAssignDistributionSetEvent(target.getOptLockRevision(), target.getTenant(),
|
eventBus.post(new TargetAssignDistributionSetEvent(target.getOptLockRevision(), target.getTenant(),
|
||||||
target.getControllerId(), actionId, softwareModules, target.getTargetInfo().getAddress(),
|
target.getControllerId(), actionId, softwareModules, target.getTargetInfo().getAddress(),
|
||||||
target.getSecurityToken()));
|
targetSecurityToken));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ import javax.validation.constraints.Size;
|
|||||||
import org.eclipse.hawkbit.im.authentication.SpPermission;
|
import org.eclipse.hawkbit.im.authentication.SpPermission;
|
||||||
import org.eclipse.hawkbit.repository.model.helper.SecurityChecker;
|
import org.eclipse.hawkbit.repository.model.helper.SecurityChecker;
|
||||||
import org.eclipse.hawkbit.repository.model.helper.SecurityTokenGeneratorHolder;
|
import org.eclipse.hawkbit.repository.model.helper.SecurityTokenGeneratorHolder;
|
||||||
|
import org.eclipse.hawkbit.repository.model.helper.SystemSecurityContextHolder;
|
||||||
import org.eclipse.persistence.annotations.CascadeOnDelete;
|
import org.eclipse.persistence.annotations.CascadeOnDelete;
|
||||||
import org.springframework.data.domain.Persistable;
|
import org.springframework.data.domain.Persistable;
|
||||||
|
|
||||||
@@ -193,10 +194,14 @@ public class Target extends NamedEntity implements Persistable<Long> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the securityToken
|
* @return the securityToken if the current security context contains the
|
||||||
|
* necessary permission {@link SpPermission#READ_TARGET_SEC_TOKEN}
|
||||||
|
* or the current context is executed as system code, otherwise
|
||||||
|
* {@code null}.
|
||||||
*/
|
*/
|
||||||
public String getSecurityToken() {
|
public String getSecurityToken() {
|
||||||
if (SecurityChecker.hasPermission(SpPermission.READ_TARGET_SEC_TOKEN)) {
|
if (SystemSecurityContextHolder.getInstance().getSystemSecurityContext().isCurrentThreadSystemCode()
|
||||||
|
|| SecurityChecker.hasPermission(SpPermission.READ_TARGET_SEC_TOKEN)) {
|
||||||
return securityToken;
|
return securityToken;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
@@ -49,6 +49,21 @@ public class SystemSecurityContext {
|
|||||||
this.tenantAware = tenantAware;
|
this.tenantAware = tenantAware;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Runs a given {@link Callable} within a system security context, which is
|
||||||
|
* permitted to call secured system code. Often the system needs to call
|
||||||
|
* secured methods by it's own without relying on the current security
|
||||||
|
* context e.g. if the current security context does not contain the
|
||||||
|
* necessary permission it's necessary to execute code as system code to
|
||||||
|
* execute necessary methods and functionality.
|
||||||
|
*
|
||||||
|
* The security context will be switched to the system code and back after
|
||||||
|
* the callable is called.
|
||||||
|
*
|
||||||
|
* @param callable
|
||||||
|
* the callable to call within the system security context
|
||||||
|
* @return the return value of the {@link Callable#call()} method.
|
||||||
|
*/
|
||||||
public <T> T runAsSystem(final Callable<T> callable) {
|
public <T> T runAsSystem(final Callable<T> callable) {
|
||||||
final SecurityContext oldContext = SecurityContextHolder.getContext();
|
final SecurityContext oldContext = SecurityContextHolder.getContext();
|
||||||
try {
|
try {
|
||||||
@@ -68,6 +83,17 @@ public class SystemSecurityContext {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return {@code true} if the current running code is running as system
|
||||||
|
* code block.
|
||||||
|
*/
|
||||||
|
public boolean isCurrentThreadSystemCode() {
|
||||||
|
if (SecurityContextHolder.getContext().getAuthentication() instanceof SystemCodeAuthentication) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
private static void setSystemContext() {
|
private static void setSystemContext() {
|
||||||
final SecurityContextImpl securityContextImpl = new SecurityContextImpl();
|
final SecurityContextImpl securityContextImpl = new SecurityContextImpl();
|
||||||
securityContextImpl.setAuthentication(new SystemCodeAuthentication());
|
securityContextImpl.setAuthentication(new SystemCodeAuthentication());
|
||||||
|
|||||||
Reference in New Issue
Block a user