package org.infinispan.security;
import static org.testng.AssertJUnit.assertEquals;
import java.io.Serializable;
import java.security.Policy;
import java.security.PrivilegedAction;
import java.security.PrivilegedExceptionAction;
import java.util.concurrent.Callable;
import java.util.concurrent.CompletableFuture;
import javax.security.auth.Subject;
import org.infinispan.configuration.cache.CacheMode;
import org.infinispan.configuration.cache.ConfigurationBuilder;
import org.infinispan.configuration.global.GlobalConfigurationBuilder;
import org.infinispan.distexec.DefaultExecutorService;
import org.infinispan.manager.EmbeddedCacheManager;
import org.infinispan.marshall.core.ExternalPojo;
import org.infinispan.security.impl.IdentityRoleMapper;
import org.infinispan.test.MultipleCacheManagersTest;
import org.infinispan.test.TestingUtil;
import org.testng.annotations.AfterClass;
import org.testng.annotations.Test;
/**
* ExecutionAuthorizationTest.
*
* @author Tristan Tarrant
* @since 7.0
*/
@Test(groups = "functional", testName = "security.ExecutionAuthorizationTest")
public class ExecutionAuthorizationTest extends MultipleCacheManagersTest {
private static final String EXECUTION_CACHE = "executioncache";
private static Subject ADMIN = TestingUtil.makeSubject("admin");
private static Subject EXEC = TestingUtil.makeSubject("exec");
private static Subject NOEXEC = TestingUtil.makeSubject("noexec");
@Override
protected void createCacheManagers() throws Throwable {
final ConfigurationBuilder builder = getDefaultClusteredCacheConfig(CacheMode.DIST_SYNC, true);
builder.security().authorization().enable().role("admin").role("exec").role("noexec");
Subject.doAs(ADMIN, (PrivilegedAction<Void>) () -> {
addClusterEnabledCacheManager(getSecureClusteredGlobalConfiguration(), builder);
addClusterEnabledCacheManager(getSecureClusteredGlobalConfiguration(), builder);
for (EmbeddedCacheManager cm : cacheManagers) {
cm.defineConfiguration(EXECUTION_CACHE, builder.build());
cm.getCache(EXECUTION_CACHE);
}
waitForClusterToForm(EXECUTION_CACHE);
return null;
});
}
private GlobalConfigurationBuilder getSecureClusteredGlobalConfiguration() {
GlobalConfigurationBuilder global = GlobalConfigurationBuilder.defaultClusteredBuilder();
global.security().authorization()
.enable()
.principalRoleMapper(new IdentityRoleMapper())
.role("admin")
.permission(AuthorizationPermission.ALL)
.role("exec")
.permission(AuthorizationPermission.READ)
.permission(AuthorizationPermission.WRITE)
.permission(AuthorizationPermission.EXEC)
.role("noexec")
.permission(AuthorizationPermission.READ)
.permission(AuthorizationPermission.WRITE);
return global;
}
@Override
@AfterClass(alwaysRun = true)
protected void destroy() {
Subject.doAs(ADMIN, (PrivilegedAction<Void>) () -> {
ExecutionAuthorizationTest.super.destroy();
return null;
});
}
@Override
@AfterClass(alwaysRun = true)
protected void clearContent() throws Exception {
Subject.doAs(ADMIN, (PrivilegedExceptionAction<Void>) () -> {
try {
ExecutionAuthorizationTest.super.clearContent();
} catch (Throwable e) {
throw new Exception(e);
}
return null;
});
}
private void distExecTest() throws Exception {
DefaultExecutorService des = new DefaultExecutorService(cache(0, EXECUTION_CACHE));
CompletableFuture<Integer> future = des.submit(new SimpleCallable());
assertEquals(Integer.valueOf(1), future.get());
}
public void testExecDistExec() throws Exception {
Policy.setPolicy(new SurefireTestingPolicy());
System.setSecurityManager(new SecurityManager());
try {
Subject.doAs(EXEC, (PrivilegedExceptionAction<Void>) () -> {
distExecTest();
return null;
});
} finally {
System.setSecurityManager(null);
Policy.setPolicy(null);
}
}
@Test(expectedExceptions=SecurityException.class)
public void testNoExecDistExec() throws Exception {
Policy.setPolicy(new SurefireTestingPolicy());
try {
System.setSecurityManager(new SecurityManager());
Subject.doAs(NOEXEC, (PrivilegedExceptionAction<Void>) () -> {
distExecTest();
return null;
});
} finally {
System.setSecurityManager(null);
Policy.setPolicy(null);
}
}
static class SimpleCallable implements Callable<Integer>, Serializable, ExternalPojo {
/** The serialVersionUID */
private static final long serialVersionUID = -8589149500259272402L;
public SimpleCallable() {
}
@Override
public Integer call() throws Exception {
return 1;
}
}
}