use of co.cask.cdap.security.spi.authorization.Authorizer in project cdap by caskdata.
the class AuthorizerInstantiatorTest method testAuthorizerExtension.
@Test
public void testAuthorizerExtension() throws IOException, ClassNotFoundException {
Manifest manifest = new Manifest();
manifest.getMainAttributes().put(Attributes.Name.MAIN_CLASS, ValidExternalAuthorizer.class.getName());
Location externalAuthJar = AppJarHelper.createDeploymentJar(locationFactory, ValidExternalAuthorizer.class, manifest);
CConfiguration cConfCopy = CConfiguration.copy(CCONF);
cConfCopy.set(Constants.Security.Authorization.EXTENSION_JAR_PATH, externalAuthJar.toString());
cConfCopy.set(Constants.Security.Authorization.EXTENSION_CONFIG_PREFIX + "config.path", "/path/config.ini");
cConfCopy.set(Constants.Security.Authorization.EXTENSION_CONFIG_PREFIX + "service.address", "http://foo.bar.co:5555");
cConfCopy.set("foo." + Constants.Security.Authorization.EXTENSION_CONFIG_PREFIX + "dont.include", "not.prefix.should.not.be.included");
try (AuthorizerInstantiator instantiator = new AuthorizerInstantiator(cConfCopy, AUTH_CONTEXT_FACTORY)) {
// should be able to load the ExternalAuthorizer class via the AuthorizerInstantiatorService
Authorizer externalAuthorizer1 = instantiator.get();
Assert.assertNotNull(externalAuthorizer1);
Authorizer externalAuthorizer2 = instantiator.get();
Assert.assertNotNull(externalAuthorizer2);
// verify that get returns the same instance each time it is called.
Assert.assertEquals(externalAuthorizer1, externalAuthorizer2);
ClassLoader authorizerClassLoader = externalAuthorizer1.getClass().getClassLoader();
ClassLoader parent = authorizerClassLoader.getParent();
// should be able to load the Authorizer interface via the parent
parent.loadClass(Authorizer.class.getName());
// should not be able to load the ExternalAuthorizer class via the parent class loader
try {
parent.loadClass(ValidExternalAuthorizer.class.getName());
Assert.fail("Should not be able to load external authorizer classes via the parent classloader of the " + "Authorizer class loader.");
} catch (ClassNotFoundException expected) {
// expected
}
// should be able to load the ExternalAuthorizer class via the AuthorizerClassLoader
authorizerClassLoader.loadClass(ValidExternalAuthorizer.class.getName());
// have to do this because the external authorizer instance is created in a new classloader, so casting will
// not work.
Gson gson = new Gson();
ValidExternalAuthorizer validAuthorizer = gson.fromJson(gson.toJson(externalAuthorizer1), ValidExternalAuthorizer.class);
Properties expectedProps = new Properties();
expectedProps.put("config.path", "/path/config.ini");
expectedProps.put("service.address", "http://foo.bar.co:5555");
Properties actualProps = validAuthorizer.getProperties();
Assert.assertEquals(expectedProps, actualProps);
}
}
use of co.cask.cdap.security.spi.authorization.Authorizer in project cdap by caskdata.
the class DefaultAuthorizationEnforcerTest method testAuthEnforce.
@Test
public void testAuthEnforce() throws Exception {
try (AuthorizerInstantiator authorizerInstantiator = new AuthorizerInstantiator(CCONF, AUTH_CONTEXT_FACTORY)) {
Authorizer authorizer = authorizerInstantiator.get();
DefaultAuthorizationEnforcer authEnforcementService = new DefaultAuthorizationEnforcer(CCONF, authorizerInstantiator);
// update privileges for alice. Currently alice has not been granted any privileges.
assertAuthorizationFailure(authEnforcementService, NS, ALICE, Action.ADMIN);
// grant some test privileges
DatasetId ds = NS.dataset("ds");
authorizer.grant(NS, ALICE, ImmutableSet.of(Action.READ, Action.WRITE));
authorizer.grant(ds, BOB, ImmutableSet.of(Action.ADMIN));
// auth enforcement for alice should succeed on ns for actions read and write
authEnforcementService.enforce(NS, ALICE, ImmutableSet.of(Action.READ, Action.WRITE));
assertAuthorizationFailure(authEnforcementService, NS, ALICE, EnumSet.allOf(Action.class));
// since Alice has READ/WRITE on the NS, everything under that should have READ/WRITE as well.
authEnforcementService.enforce(ds, ALICE, Action.READ);
authEnforcementService.enforce(ds, ALICE, Action.WRITE);
// Alice doesn't have Admin right on NS, hence should fail.
assertAuthorizationFailure(authEnforcementService, NS, ALICE, Action.ADMIN);
// also, even though bob's privileges were never updated, auth enforcement for bob should not fail,
// because the LoadingCache should make a blocking call to retrieve his privileges
authEnforcementService.enforce(ds, BOB, Action.ADMIN);
// revoke all of alice's privileges
authorizer.revoke(NS, ALICE, ImmutableSet.of(Action.READ));
try {
authEnforcementService.enforce(NS, ALICE, Action.READ);
Assert.fail(String.format("Expected %s to not have '%s' privilege on %s but it does.", ALICE, Action.READ, NS));
} catch (UnauthorizedException ignored) {
// expected
}
authorizer.revoke(NS);
assertAuthorizationFailure(authEnforcementService, NS, ALICE, Action.READ);
assertAuthorizationFailure(authEnforcementService, NS, ALICE, Action.WRITE);
authEnforcementService.enforce(ds, BOB, Action.ADMIN);
}
}
use of co.cask.cdap.security.spi.authorization.Authorizer in project cdap by caskdata.
the class AuthorizationTest method grantAndAssertSuccess.
private void grantAndAssertSuccess(EntityId entityId, Principal principal, Set<Action> actions) throws Exception {
Authorizer authorizer = getAuthorizer();
Set<Privilege> existingPrivileges = authorizer.listPrivileges(principal);
authorizer.grant(entityId, principal, actions);
ImmutableSet.Builder<Privilege> expectedPrivilegesAfterGrant = ImmutableSet.builder();
for (Action action : actions) {
expectedPrivilegesAfterGrant.add(new Privilege(entityId, action));
}
Assert.assertEquals(Sets.union(existingPrivileges, expectedPrivilegesAfterGrant.build()), authorizer.listPrivileges(principal));
}
use of co.cask.cdap.security.spi.authorization.Authorizer in project cdap by caskdata.
the class AuthorizationTest method cleanupTest.
@After
public void cleanupTest() throws Exception {
Authorizer authorizer = getAuthorizer();
grantAndAssertSuccess(AUTH_NAMESPACE, SecurityRequestContext.toPrincipal(), EnumSet.allOf(Action.class));
// clean up. remove the namespace. all privileges on the namespace should be revoked
getNamespaceAdmin().delete(AUTH_NAMESPACE);
Assert.assertEquals(ImmutableSet.of(new Privilege(instance, Action.ADMIN)), authorizer.listPrivileges(ALICE));
// revoke privileges on the instance
revokeAndAssertSuccess(instance);
}
use of co.cask.cdap.security.spi.authorization.Authorizer in project cdap by caskdata.
the class AuthorizationTest method testMRStreamAuth.
@Test
@Category(SlowTests.class)
public void testMRStreamAuth() throws Exception {
createAuthNamespace();
Authorizer authorizer = getAuthorizer();
ApplicationManager appManager = deployApplication(AUTH_NAMESPACE, StreamAuthApp.class);
// After deploy, change Alice from ALL to ADMIN on the namespace
authorizer.revoke(AUTH_NAMESPACE, ALICE, EnumSet.allOf(Action.class));
authorizer.grant(AUTH_NAMESPACE, ALICE, EnumSet.of(Action.ADMIN));
StreamManager streamManager = getStreamManager(AUTH_NAMESPACE.stream(StreamAuthApp.STREAM));
streamManager.send("Hello");
final MapReduceManager mrManager = appManager.getMapReduceManager(StreamAuthApp.MAPREDUCE);
mrManager.start();
// Since Alice had full permissions, she should be able to execute the MR job successfully
mrManager.waitForRun(ProgramRunStatus.COMPLETED, 1, TimeUnit.MINUTES);
DataSetManager<KeyValueTable> kvManager = getDataset(AUTH_NAMESPACE.dataset(StreamAuthApp.KVTABLE));
try (KeyValueTable kvTable = kvManager.get()) {
byte[] value = kvTable.read("Hello");
Assert.assertArrayEquals(Bytes.toBytes("Hello"), value);
}
ProgramId mrId = AUTH_NAMESPACE.app(StreamAuthApp.APP).mr(StreamAuthApp.MAPREDUCE);
authorizer.grant(mrId.getNamespaceId(), BOB, ImmutableSet.of(Action.ADMIN));
ArtifactSummary artifactSummary = appManager.getInfo().getArtifact();
ArtifactId artifactId = AUTH_NAMESPACE.artifact(artifactSummary.getName(), artifactSummary.getVersion());
authorizer.grant(artifactId, BOB, EnumSet.allOf(Action.class));
authorizer.grant(mrId.getParent(), BOB, EnumSet.allOf(Action.class));
authorizer.grant(mrId, BOB, EnumSet.allOf(Action.class));
authorizer.grant(AUTH_NAMESPACE.stream(StreamAuthApp.STREAM), BOB, EnumSet.of(Action.ADMIN));
authorizer.grant(AUTH_NAMESPACE.dataset(StreamAuthApp.KVTABLE), BOB, EnumSet.allOf(Action.class));
streamManager.send("World");
// Switch user to Bob. Note that he doesn't have READ access on the stream.
SecurityRequestContext.setUserId(BOB.getName());
mrManager.start();
mrManager.waitForRun(ProgramRunStatus.FAILED, 1, TimeUnit.MINUTES);
kvManager = getDataset(AUTH_NAMESPACE.dataset(StreamAuthApp.KVTABLE));
try (KeyValueTable kvTable = kvManager.get()) {
byte[] value = kvTable.read("World");
Assert.assertNull(value);
}
// Now grant Bob, READ access on the stream. MR job should execute successfully now.
authorizer.grant(AUTH_NAMESPACE.stream(StreamAuthApp.STREAM), BOB, ImmutableSet.of(Action.READ));
mrManager.start();
mrManager.waitForRuns(ProgramRunStatus.COMPLETED, 2, 1, TimeUnit.MINUTES);
kvManager = getDataset(AUTH_NAMESPACE.dataset(StreamAuthApp.KVTABLE));
try (KeyValueTable kvTable = kvManager.get()) {
byte[] value = kvTable.read("World");
Assert.assertEquals("World", Bytes.toString(value));
}
SecurityRequestContext.setUserId(ALICE.getName());
appManager.delete();
assertNoAccess(AUTH_NAMESPACE.app(StreamAuthApp.APP));
}
Aggregations