package org.infinispan.scripting;
import static org.testng.AssertJUnit.assertEquals;
import java.security.PrivilegedAction;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import java.util.concurrent.ExecutionException;
import javax.security.auth.Subject;
import org.infinispan.Cache;
import org.infinispan.configuration.cache.AuthorizationConfigurationBuilder;
import org.infinispan.configuration.cache.ConfigurationBuilder;
import org.infinispan.configuration.global.GlobalAuthorizationConfigurationBuilder;
import org.infinispan.configuration.global.GlobalConfigurationBuilder;
import org.infinispan.manager.EmbeddedCacheManager;
import org.infinispan.security.AuthorizationPermission;
import org.infinispan.security.Security;
import org.infinispan.security.impl.IdentityRoleMapper;
import org.infinispan.tasks.TaskContext;
import org.infinispan.test.TestingUtil;
import org.infinispan.test.fwk.TestCacheManagerFactory;
import org.testng.annotations.Test;
@Test(groups = "functional", testName = "scripting.SecureScriptingTest")
public class SecureScriptingTest extends AbstractScriptingTest {
static final Subject ADMIN = TestingUtil.makeSubject("admin", ScriptingManager.SCRIPT_MANAGER_ROLE);
static final Subject RUNNER = TestingUtil.makeSubject("runner", "runner");
static final Subject PHEIDIPPIDES = TestingUtil.makeSubject("pheidippides", "pheidippides");
static final Subject ACHILLES = TestingUtil.makeSubject("achilles", "achilles");
static final String SECURE_CACHE_NAME = "secured-script-exec";
@Override
protected EmbeddedCacheManager createCacheManager() throws Exception {
GlobalConfigurationBuilder global = new GlobalConfigurationBuilder();
GlobalAuthorizationConfigurationBuilder globalRoles = global.security().authorization().enable().principalRoleMapper(new IdentityRoleMapper());
ConfigurationBuilder config = TestCacheManagerFactory.getDefaultCacheConfiguration(true);
AuthorizationConfigurationBuilder authConfig = config.security().authorization().enable();
globalRoles
.role("achilles")
.permission(AuthorizationPermission.READ)
.permission(AuthorizationPermission.WRITE)
.role("runner")
.permission(AuthorizationPermission.EXEC)
.permission(AuthorizationPermission.READ)
.permission(AuthorizationPermission.WRITE)
.role("pheidippides")
.permission(AuthorizationPermission.EXEC)
.permission(AuthorizationPermission.READ)
.permission(AuthorizationPermission.WRITE)
.role("admin")
.permission(AuthorizationPermission.ALL);
authConfig.role("runner").role("pheidippides").role("admin");
EmbeddedCacheManager cm = TestCacheManagerFactory.createCacheManager(global, config);
Security.doAs(ADMIN, (PrivilegedExceptionAction<Void>) () -> {
cm.defineConfiguration(ScriptingTest.CACHE_NAME, cm.getDefaultCacheConfiguration());
cm.getCache(ScriptingTest.CACHE_NAME);
cm.defineConfiguration(SecureScriptingTest.SECURE_CACHE_NAME, cm.getDefaultCacheConfiguration());
cm.getCache(SecureScriptingTest.SECURE_CACHE_NAME);
cm.defineConfiguration("nonSecuredCache", TestCacheManagerFactory.getDefaultCacheConfiguration(true).build());
return null;
});
return cm;
}
@Override
protected String[] getScripts() {
return new String[] { "test.js", "testRole.js", "testRoleWithCache.js" };
}
@Override
protected void setup() throws Exception {
Security.doAs(ADMIN, (PrivilegedExceptionAction<Void>) () -> {
SecureScriptingTest.super.setup();
return null;
});
}
@Override
protected void teardown() {
Security.doAs(ADMIN, (PrivilegedAction<Void>) () -> {
SecureScriptingTest.super.teardown();
return null;
});
}
@Override
protected void clearContent() {
Security.doAs(ADMIN, (PrivilegedAction<Void>) () -> {
cacheManager.getCache().clear();
return null;
});
}
@Test(expectedExceptions = SecurityException.class)
public void testSimpleScript() throws Exception {
String result = (String) scriptingManager.runScript("test.js", new TaskContext().addParameter("a", "a")).get();
assertEquals("a", result);
}
public void testSimpleScriptWithEXECPermissions() throws Exception {
String result = Security.doAs(RUNNER, (PrivilegedExceptionAction<String>) () -> (String) scriptingManager.runScript("test.js", new TaskContext().addParameter("a", "a")).get());
assertEquals("a", result);
}
@Test(expectedExceptions = PrivilegedActionException.class)
public void testSimpleScriptWithEXECPermissionsWrongRole() throws Exception {
String result = Security.doAs(RUNNER, (PrivilegedExceptionAction<String>) () -> (String) scriptingManager.runScript("testRole.js", new TaskContext().addParameter("a", "a")).get());
assertEquals("a", result);
}
public void testSimpleScriptWithEXECPermissionsRightRole() throws Exception {
String result = Security.doAs(PHEIDIPPIDES, (PrivilegedExceptionAction<String>) () -> (String) scriptingManager.runScript("testRole.js", new TaskContext().addParameter("a", "a")).get());
assertEquals("a", result);
}
@Test(expectedExceptions = PrivilegedActionException.class)
public void testSimpleScriptWithoutEXEC() throws Exception {
Security.doAs(ACHILLES, (PrivilegedExceptionAction<String>) () -> (String) scriptingManager.runScript("testRole.js", new TaskContext().addParameter("a", "a")).get());
}
@Test(expectedExceptions = PrivilegedActionException.class)
public void testUploadScriptWithEXECNotManager() throws Exception {
Security.doAs(PHEIDIPPIDES, (PrivilegedExceptionAction<Void>) () -> {
scriptingManager.addScript("my_script", "1+1");
return null;
});
}
@Test(expectedExceptions = PrivilegedActionException.class)
public void testUploadScriptWithoutEXECNotManager() throws Exception {
Security.doAs(ACHILLES, (PrivilegedExceptionAction<Void>) () -> {
scriptingManager.addScript("my_script", "1+1");
return null;
});
}
@Test(expectedExceptions = PrivilegedActionException.class)
public void testRemoveScriptWithEXECNotManager() throws Exception {
Security.doAs(PHEIDIPPIDES, (PrivilegedExceptionAction<Void>) () -> {
scriptingManager.removeScript("test.js");
return null;
});
}
@Test(expectedExceptions = PrivilegedActionException.class)
public void testUploadScriptDirectlyWithEXECNotManager() throws Exception {
Security.doAs(PHEIDIPPIDES, (PrivilegedExceptionAction<Void>) () -> {
cacheManager.getCache(ScriptingManager.SCRIPT_CACHE).put("my_script", "1+1");
return null;
});
}
@Test(expectedExceptions = PrivilegedActionException.class)
public void testRemoveScriptDirectlyWithEXECNotManager() throws Exception {
Security.doAs(PHEIDIPPIDES, (PrivilegedExceptionAction<Void>) () -> {
cacheManager.getCache(ScriptingManager.SCRIPT_CACHE).remove("test.js");
return null;
});
}
@Test(expectedExceptions = PrivilegedActionException.class)
public void testClearScriptDirectlyWithEXECNotManager() throws Exception {
Security.doAs(PHEIDIPPIDES, (PrivilegedExceptionAction<Void>) () -> {
cacheManager.getCache(ScriptingManager.SCRIPT_CACHE).clear();
return null;
});
}
public void testScriptOnNonSecuredCache() throws ExecutionException, InterruptedException, PrivilegedActionException {
Cache<String, String> nonSecCache = cache("nonSecuredCache");
nonSecCache.put("a", "value");
assertEquals("value", nonSecCache.get("a"));
String result = Security.doAs(PHEIDIPPIDES, (PrivilegedExceptionAction<String>) () -> (String) scriptingManager.runScript("testRoleWithCache.js", new TaskContext().addParameter("a", "a").cache(nonSecCache)).get());
assertEquals("a", result);
assertEquals("a", nonSecCache.get("a"));
}
@Test(expectedExceptions = PrivilegedActionException.class)
public void testScriptOnNonSecuredCacheWrongRole() throws ExecutionException, InterruptedException, PrivilegedActionException {
Security.doAs(RUNNER, (PrivilegedExceptionAction<String>) () -> (String) scriptingManager.runScript("testRoleWithCache.js", new TaskContext().addParameter("a", "a").cache(cache("nonSecuredCache"))).get());
}
}