Merge pull request #24 from bsinno/rollout_mgmt

Looks good, merged
This commit is contained in:
Kai Zimmermann
2016-02-04 18:47:35 +01:00
145 changed files with 14001 additions and 353 deletions

View File

@@ -23,8 +23,7 @@ import org.springframework.security.core.GrantedAuthority;
* The Permissions cover CRUD for two data areas of SP:<br/>
* <br/>
* XX_Target_CRUD which covers the following entities: {@link Target} entities
* including metadata, {@link TargetTag}s, {@link Action}s,
* {@link TargetRegistrationRule}s<br/>
* including metadata, {@link TargetTag}s, {@link TargetRegistrationRule}s<br/>
* XX_Repository CRUD which covers: {@link DistributionSet}s,
* {@link SoftwareModule}s, DS Tags<br/>
* </p>
@@ -131,6 +130,11 @@ public final class SpPermission {
*/
public static final String TENANT_CONFIGURATION = "TENANT_CONFIGURATION";
/**
* Permission to administrate a rollout management.
*/
public static final String ROLLOUT_MANAGEMENT = "ROLLOUT_MANAGEMENT";
private SpPermission() {
// Constants only
}
@@ -178,6 +182,12 @@ public final class SpPermission {
*/
public static final String CONTROLLER_ROLE_ANONYMOUS = "ROLE_CONTROLLER_ANONYMOUS";
/**
* The role which contains the spring security context in case the
* system is executing code which is necessary to be privileged.
*/
public static final String SYSTEM_ROLE = "ROLE_SYSTEM_CODE";
/**
* The spring security eval expression operator {@code or}.
*/
@@ -265,8 +275,15 @@ public final class SpPermission {
* context contains the anoynmous role or the controller specific role
* {@link SpPermission#CONTROLLER_ROLE}.
*/
public static final String IS_CONTROLLER = "hasAnyRole('" + CONTROLLER_ROLE_ANONYMOUS + "', '" + CONTROLLER_ROLE
+ "')";
public static final String IS_CONTROLLER = "hasAnyRole('" + CONTROLLER_ROLE_ANONYMOUS + "', '"
+ CONTROLLER_ROLE + "')";
/**
* Spring security eval hasAnyRole expression to check if the spring
* context contains system code role
* {@link SpringEvalExpressions#SYSTEM_ROLE}.
*/
public static final String IS_SYSTEM_CODE = HAS_AUTH_PREFIX + SYSTEM_ROLE + HAS_AUTH_SUFFIX;
/**
* Spring security eval hasAuthority expression to check if spring
@@ -276,6 +293,21 @@ public final class SpPermission {
public static final String HAS_AUTH_CREATE_REPOSITORY_AND_CREATE_TARGET = HAS_AUTH_PREFIX + CREATE_REPOSITORY
+ HAS_AUTH_SUFFIX + HAS_AUTH_AND + HAS_AUTH_PREFIX + CREATE_TARGET + HAS_AUTH_SUFFIX;
/**
* Spring security eval hasAuthority expression to check if spring
* context contains {@link SpPermission#ROLLOUT_MANAGEMENT}
*/
public static final String HAS_AUTH_ROLLOUT_MANAGEMENT_READ = HAS_AUTH_PREFIX + ROLLOUT_MANAGEMENT
+ HAS_AUTH_SUFFIX;
/**
* Spring security eval hasAuthority expression to check if spring
* context contains {@link SpPermission#ROLLOUT_MANAGEMENT} and
* {@link SpPermission#UPDATE_TARGET}.
*/
public static final String HAS_AUTH_ROLLOUT_MANAGEMENT_WRITE = HAS_AUTH_PREFIX + ROLLOUT_MANAGEMENT
+ HAS_AUTH_SUFFIX + HAS_AUTH_AND + HAS_AUTH_PREFIX + UPDATE_TARGET + HAS_AUTH_SUFFIX;
private SpringEvalExpressions() {
// utility class
}

View File

@@ -8,6 +8,8 @@
*/
package org.eclipse.hawkbit.security;
import java.util.concurrent.atomic.AtomicInteger;
import org.eclipse.hawkbit.im.authentication.TenantAwareAuthenticationDetails;
import org.eclipse.hawkbit.tenancy.TenantAware;
import org.springframework.security.core.Authentication;
@@ -27,6 +29,7 @@ import org.springframework.security.core.context.SecurityContextHolder;
public class SecurityContextTenantAware implements TenantAware {
private static final ThreadLocal<String> TENANT_THREAD_LOCAL = new ThreadLocal<>();
private static final ThreadLocal<AtomicInteger> RUN_AS_DEPTH = new ThreadLocal<>();
/*
* (non-Javadoc)
@@ -56,11 +59,21 @@ public class SecurityContextTenantAware implements TenantAware {
*/
@Override
public <T> T runAsTenant(final String tenant, final TenantRunner<T> callable) {
AtomicInteger runAsDepth = RUN_AS_DEPTH.get();
if (runAsDepth == null) {
runAsDepth = new AtomicInteger(1);
RUN_AS_DEPTH.set(runAsDepth);
} else {
runAsDepth.incrementAndGet();
}
TENANT_THREAD_LOCAL.set(tenant);
try {
return callable.run();
} finally {
TENANT_THREAD_LOCAL.remove();
if (runAsDepth.decrementAndGet() <= 0) {
RUN_AS_DEPTH.remove();
TENANT_THREAD_LOCAL.remove();
}
}
}
}

View File

@@ -0,0 +1,112 @@
/**
* Copyright (c) 2015 Bosch Software Innovations GmbH and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.eclipse.hawkbit.security;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.Callable;
import org.eclipse.hawkbit.im.authentication.SpPermission.SpringEvalExpressions;
import org.eclipse.hawkbit.tenancy.TenantAware;
import org.eclipse.hawkbit.tenancy.TenantAware.TenantRunner;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
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.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.context.SecurityContextImpl;
import org.springframework.stereotype.Service;
import com.google.common.base.Throwables;
/**
* @author Michael Hirsch
*
*/
@Service
public class SystemSecurityContext {
private static final Logger logger = LoggerFactory.getLogger(SystemSecurityContext.class);
@Autowired
private TenantAware tenantAware;
public <T> T runAsSystem(final Callable<T> callable) {
final SecurityContext oldContext = SecurityContextHolder.getContext();
try {
logger.debug("entering system code execution");
return tenantAware.runAsTenant(tenantAware.getCurrentTenant(), new TenantRunner<T>() {
@Override
public T run() {
try {
setSystemContext();
return callable.call();
} catch (final Exception e) {
throw Throwables.propagate(e);
}
}
});
} finally {
SecurityContextHolder.setContext(oldContext);
logger.debug("leaving system code execution");
}
}
private static void setSystemContext() {
final SecurityContextImpl securityContextImpl = new SecurityContextImpl();
securityContextImpl.setAuthentication(new SystemCodeAuthentication());
SecurityContextHolder.setContext(securityContextImpl);
}
public static class SystemCodeAuthentication implements Authentication {
private static final long serialVersionUID = 1L;
private static final List<SimpleGrantedAuthority> AUTHORITIES = Collections
.singletonList(new SimpleGrantedAuthority(SpringEvalExpressions.SYSTEM_ROLE));
@Override
public String getName() {
return null;
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return AUTHORITIES;
}
@Override
public Object getCredentials() {
return null;
}
@Override
public Object getDetails() {
return null;
}
@Override
public Object getPrincipal() {
return null;
}
@Override
public boolean isAuthenticated() {
return true;
}
@Override
public void setAuthenticated(final boolean isAuthenticated) throws IllegalArgumentException {
}
}
}