use of io.cdap.cdap.security.spi.authorization.AccessController in project cdap by caskdata.
the class AuthorizationTest method testApps.
@Test
@Category(SlowTests.class)
public void testApps() throws Exception {
try {
deployApplication(NamespaceId.DEFAULT, DummyApp.class);
Assert.fail("App deployment should fail because alice does not have ADMIN privilege on the application");
} catch (UnauthorizedException e) {
// Expected
}
createAuthNamespace();
AccessController accessController = getAccessController();
ApplicationId dummyAppId = AUTH_NAMESPACE.app(DummyApp.class.getSimpleName());
Map<EntityId, Set<? extends Permission>> neededPrivileges = ImmutableMap.<EntityId, Set<? extends Permission>>builder().put(dummyAppId, EnumSet.of(StandardPermission.CREATE, StandardPermission.GET, StandardPermission.DELETE)).put(AUTH_NAMESPACE.artifact(DummyApp.class.getSimpleName(), "1.0-SNAPSHOT"), EnumSet.of(StandardPermission.CREATE)).put(AUTH_NAMESPACE.dataset("whom"), EnumSet.of(StandardPermission.GET, StandardPermission.CREATE)).put(AUTH_NAMESPACE.dataset("customDataset"), EnumSet.of(StandardPermission.GET, StandardPermission.CREATE)).put(AUTH_NAMESPACE.datasetType(KeyValueTable.class.getName()), EnumSet.of(StandardPermission.UPDATE)).build();
setUpPrivilegeAndRegisterForDeletion(ALICE, neededPrivileges);
// alice will not be able to deploy the app since she does not have privilege on the implicit dataset module
try {
deployApplication(AUTH_NAMESPACE, DummyApp.class);
Assert.fail();
} catch (UnauthorizedException e) {
// expected
}
// grant alice the required implicit type and module
grantAndAssertSuccess(AUTH_NAMESPACE.datasetType(DummyApp.CustomDummyDataset.class.getName()), ALICE, EnumSet.of(StandardPermission.GET, StandardPermission.CREATE));
cleanUpEntities.add(AUTH_NAMESPACE.datasetType(DummyApp.CustomDummyDataset.class.getName()));
grantAndAssertSuccess(AUTH_NAMESPACE.datasetModule(DummyApp.CustomDummyDataset.class.getName()), ALICE, EnumSet.of(StandardPermission.CREATE, StandardPermission.GET));
cleanUpEntities.add(AUTH_NAMESPACE.datasetModule(DummyApp.CustomDummyDataset.class.getName()));
// this time it should be successful
ApplicationManager appManager = deployApplication(AUTH_NAMESPACE, DummyApp.class);
// Bob should not have any privileges on Alice's app
Assert.assertTrue("Bob should not have any privileges on alice's app", accessController.listGrants(BOB).isEmpty());
// update should succeed because alice has admin privileges on the app
appManager.update(new AppRequest(new ArtifactSummary(DummyApp.class.getSimpleName(), "1.0-SNAPSHOT")));
// Update should fail for Bob
SecurityRequestContext.setUserId(BOB.getName());
try {
appManager.update(new AppRequest(new ArtifactSummary(DummyApp.class.getSimpleName(), "1.0-SNAPSHOT")));
Assert.fail("App update should have failed because Bob does not have admin privileges on the app.");
} catch (UnauthorizedException expected) {
// expected
}
// grant READ and WRITE to Bob
grantAndAssertSuccess(AUTH_NAMESPACE, BOB, ImmutableSet.of(StandardPermission.GET));
grantAndAssertSuccess(dummyAppId, BOB, ImmutableSet.of(StandardPermission.GET, StandardPermission.UPDATE));
// delete should fail
try {
appManager.delete();
} catch (UnauthorizedException expected) {
// expected
}
// grant DELETE to Bob. Now delete should succeed
grantAndAssertSuccess(dummyAppId, BOB, ImmutableSet.of(StandardPermission.DELETE));
// deletion should succeed since BOB has privileges on the app
appManager.delete();
// Should still have the privilege for the app since we no longer revoke privileges after deletion of an entity
Assert.assertTrue(!getAccessController().isVisible(Collections.singleton(dummyAppId), BOB).isEmpty());
// bob should still have privileges granted to him
Assert.assertEquals(4, accessController.listGrants(BOB).size());
// switch back to Alice
SecurityRequestContext.setUserId(ALICE.getName());
// Deploy a couple of apps in the namespace
// Deploy dummy app should be successful since we already pre-grant the required privileges
deployApplication(AUTH_NAMESPACE, DummyApp.class);
final ApplicationId appId = AUTH_NAMESPACE.app(AllProgramsApp.NAME);
Map<EntityId, Set<? extends Permission>> anotherAppNeededPrivilege = ImmutableMap.<EntityId, Set<? extends Permission>>builder().put(appId, EnumSet.of(StandardPermission.GET, StandardPermission.CREATE, StandardPermission.DELETE)).put(AUTH_NAMESPACE.artifact(AllProgramsApp.class.getSimpleName(), "1.0-SNAPSHOT"), EnumSet.of(StandardPermission.GET, StandardPermission.CREATE)).put(AUTH_NAMESPACE.dataset(AllProgramsApp.DATASET_NAME), EnumSet.of(StandardPermission.GET, StandardPermission.CREATE)).put(AUTH_NAMESPACE.dataset(AllProgramsApp.DATASET_NAME2), EnumSet.of(StandardPermission.GET, StandardPermission.CREATE)).put(AUTH_NAMESPACE.dataset(AllProgramsApp.DATASET_NAME3), EnumSet.of(StandardPermission.GET, StandardPermission.CREATE)).put(AUTH_NAMESPACE.dataset(AllProgramsApp.DS_WITH_SCHEMA_NAME), EnumSet.of(StandardPermission.GET, StandardPermission.CREATE)).put(AUTH_NAMESPACE.datasetType(ObjectMappedTable.class.getName()), EnumSet.of(StandardPermission.GET, StandardPermission.CREATE)).build();
setUpPrivilegeAndRegisterForDeletion(ALICE, anotherAppNeededPrivilege);
Map<EntityId, Set<? extends Permission>> bobDatasetPrivileges = ImmutableMap.<EntityId, Set<? extends Permission>>builder().put(AUTH_NAMESPACE.dataset(AllProgramsApp.DATASET_NAME), EnumSet.of(StandardPermission.UPDATE)).put(AUTH_NAMESPACE.dataset(AllProgramsApp.DATASET_NAME2), EnumSet.of(StandardPermission.UPDATE)).build();
Map<EntityId, Set<? extends Permission>> bobProgramPrivileges = ImmutableMap.<EntityId, Set<? extends Permission>>builder().put(appId, EnumSet.of(StandardPermission.GET)).put(appId.program(ProgramType.SERVICE, AllProgramsApp.NoOpService.NAME), EnumSet.of(ApplicationPermission.EXECUTE)).put(appId.program(ProgramType.WORKER, AllProgramsApp.NoOpWorker.NAME), EnumSet.of(ApplicationPermission.EXECUTE)).build();
setUpPrivilegeAndRegisterForDeletion(BOB, bobDatasetPrivileges);
setUpPrivilegeAndRegisterForDeletion(BOB, bobProgramPrivileges);
deployApplication(AUTH_NAMESPACE, AllProgramsApp.class);
// Switch to BOB since he does not have any privilege
SecurityRequestContext.setUserId(BOB.getName());
// deleting all apps should fail because bob does not have admin privileges on the apps and the namespace
try {
deleteAllApplications(AUTH_NAMESPACE);
Assert.fail("Deleting all applications in the namespace should have failed because bob does not have ADMIN " + "privilege on the workflow app.");
} catch (UnauthorizedException expected) {
// expected
}
// Switch to ALICE, deletion should be successful since ALICE has ADMIN privileges
SecurityRequestContext.setUserId(ALICE.getName());
deleteAllApplications(AUTH_NAMESPACE);
}
use of io.cdap.cdap.security.spi.authorization.AccessController in project cdap by caskdata.
the class AuthorizationTest method testNamespaces.
@Test
public void testNamespaces() throws Exception {
NamespaceAdmin namespaceAdmin = getNamespaceAdmin();
AccessController accessController = getAccessController();
try {
namespaceAdmin.create(AUTH_NAMESPACE_META);
Assert.fail("Namespace create should have failed because alice is not authorized on " + AUTH_NAMESPACE);
} catch (UnauthorizedException expected) {
// expected
}
createAuthNamespace();
Assert.assertTrue(namespaceAdmin.list().contains(AUTH_NAMESPACE_META));
namespaceAdmin.get(AUTH_NAMESPACE);
// revoke privileges
revokeAndAssertSuccess(AUTH_NAMESPACE);
try {
Assert.assertTrue(namespaceAdmin.list().isEmpty());
namespaceAdmin.exists(AUTH_NAMESPACE);
Assert.fail("Namespace existence check should fail since the privilege of alice has been revoked");
} catch (UnauthorizedException expected) {
// expected
}
// grant privileges again
grantAndAssertSuccess(AUTH_NAMESPACE, ALICE, ImmutableSet.of(StandardPermission.GET, StandardPermission.UPDATE));
namespaceAdmin.exists(AUTH_NAMESPACE);
Assert.assertEquals(ImmutableSet.of(new GrantedPermission(AUTH_NAMESPACE, StandardPermission.GET), new GrantedPermission(AUTH_NAMESPACE, StandardPermission.UPDATE)), accessController.listGrants(ALICE));
NamespaceMeta updated = new NamespaceMeta.Builder(AUTH_NAMESPACE_META).setDescription("new desc").build();
namespaceAdmin.updateProperties(AUTH_NAMESPACE, updated);
Assert.assertEquals(updated, namespaceAdmin.get(AUTH_NAMESPACE));
}
use of io.cdap.cdap.security.spi.authorization.AccessController in project cdap by caskdata.
the class AuthorizationTest method afterTest.
@After
@Override
public void afterTest() throws Exception {
AccessController accessController = getAccessController();
SecurityRequestContext.setUserId(ALICE.getName());
grantAndAssertSuccess(AUTH_NAMESPACE, SecurityRequestContext.toPrincipal(), EnumSet.of(StandardPermission.DELETE, StandardPermission.GET));
for (EntityId entityId : cleanUpEntities) {
grantAndAssertSuccess(entityId, SecurityRequestContext.toPrincipal(), EnumSet.of(StandardPermission.DELETE, StandardPermission.GET));
}
// clean up. remove the namespace if it exists
if (getNamespaceAdmin().exists(AUTH_NAMESPACE)) {
getNamespaceAdmin().delete(AUTH_NAMESPACE);
Assert.assertFalse(getNamespaceAdmin().exists(AUTH_NAMESPACE));
}
revokeAndAssertSuccess(AUTH_NAMESPACE);
for (EntityId entityId : cleanUpEntities) {
revokeAndAssertSuccess(entityId);
}
Assert.assertEquals(Collections.emptySet(), accessController.listGrants(ALICE));
}
use of io.cdap.cdap.security.spi.authorization.AccessController in project cdap by caskdata.
the class AuthorizationTest method assertNoAccess.
private void assertNoAccess(Principal principal, final EntityId entityId) throws Exception {
AccessController accessController = getAccessController();
Predicate<GrantedPermission> entityFilter = new Predicate<GrantedPermission>() {
@Override
public boolean apply(GrantedPermission input) {
return Authorizable.fromEntityId(entityId).equals(input.getAuthorizable());
}
};
Assert.assertTrue(Sets.filter(accessController.listGrants(principal), entityFilter).isEmpty());
}
use of io.cdap.cdap.security.spi.authorization.AccessController in project cdap by caskdata.
the class AuthorizationHandlerTest method testDisabled.
private void testDisabled(CConfiguration cConf, FeatureDisabledException.Feature feature, String configSetting) throws Exception {
final InMemoryAccessController accessController = new InMemoryAccessController();
NettyHttpService service = new CommonNettyHttpServiceBuilder(cConf, getClass().getSimpleName()).setHttpHandlers(new AuthorizationHandler(accessController, new AccessControllerInstantiator(cConf, FACTORY) {
@Override
public AccessController get() {
return accessController;
}
}, cConf, new MasterAuthenticationContext())).build();
service.start();
try {
final AuthorizationClient client = new AuthorizationClient(ClientConfig.builder().setConnectionConfig(ConnectionConfig.builder().setHostname(service.getBindAddress().getHostName()).setPort(service.getBindAddress().getPort()).setSSLEnabled(false).build()).build());
final NamespaceId ns1 = Ids.namespace("ns1");
final Role admins = new Role("admins");
// Test that the right exception is thrown when any Authorization REST API is called with authorization disabled
verifyFeatureDisabled(new DisabledFeatureCaller() {
@Override
public void call() throws Exception {
client.grant(Authorizable.fromEntityId(ns1), admin, ImmutableSet.of(StandardPermission.GET));
}
}, feature, configSetting);
verifyFeatureDisabled(new DisabledFeatureCaller() {
@Override
public void call() throws Exception {
client.revoke(Authorizable.fromEntityId(ns1), admin, ImmutableSet.of(StandardPermission.GET));
}
}, feature, configSetting);
verifyFeatureDisabled(new DisabledFeatureCaller() {
@Override
public void call() throws Exception {
client.revoke(Authorizable.fromEntityId(ns1));
}
}, feature, configSetting);
verifyFeatureDisabled(new DisabledFeatureCaller() {
@Override
public void call() throws Exception {
client.listGrants(admin);
}
}, feature, configSetting);
verifyFeatureDisabled(new DisabledFeatureCaller() {
@Override
public void call() throws Exception {
client.addRoleToPrincipal(admins, admin);
}
}, feature, configSetting);
verifyFeatureDisabled(new DisabledFeatureCaller() {
@Override
public void call() throws Exception {
client.removeRoleFromPrincipal(admins, admin);
}
}, feature, configSetting);
verifyFeatureDisabled(new DisabledFeatureCaller() {
@Override
public void call() throws Exception {
client.createRole(admins);
}
}, feature, configSetting);
verifyFeatureDisabled(new DisabledFeatureCaller() {
@Override
public void call() throws Exception {
client.dropRole(admins);
}
}, feature, configSetting);
verifyFeatureDisabled(new DisabledFeatureCaller() {
@Override
public void call() throws Exception {
client.listAllRoles();
}
}, feature, configSetting);
} finally {
service.stop();
}
}
Aggregations