Search in sources :

Example 36 with AccessController

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);
}
Also used : ApplicationManager(io.cdap.cdap.test.ApplicationManager) PartitionedFileSet(io.cdap.cdap.api.dataset.lib.PartitionedFileSet) EnumSet(java.util.EnumSet) Set(java.util.Set) ImmutableSet(com.google.common.collect.ImmutableSet) HashSet(java.util.HashSet) AppRequest(io.cdap.cdap.proto.artifact.AppRequest) EntityId(io.cdap.cdap.proto.id.EntityId) InMemoryAccessController(io.cdap.cdap.security.authorization.InMemoryAccessController) AccessController(io.cdap.cdap.security.spi.authorization.AccessController) ArtifactSummary(io.cdap.cdap.api.artifact.ArtifactSummary) KeyValueTable(io.cdap.cdap.api.dataset.lib.KeyValueTable) UnauthorizedException(io.cdap.cdap.security.spi.authorization.UnauthorizedException) DummyApp(io.cdap.cdap.test.app.DummyApp) GrantedPermission(io.cdap.cdap.proto.security.GrantedPermission) ApplicationPermission(io.cdap.cdap.proto.security.ApplicationPermission) AccessPermission(io.cdap.cdap.proto.security.AccessPermission) Permission(io.cdap.cdap.proto.security.Permission) StandardPermission(io.cdap.cdap.proto.security.StandardPermission) ApplicationId(io.cdap.cdap.proto.id.ApplicationId) ObjectMappedTable(io.cdap.cdap.api.dataset.lib.ObjectMappedTable) Category(org.junit.experimental.categories.Category) Test(org.junit.Test)

Example 37 with AccessController

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));
}
Also used : InMemoryAccessController(io.cdap.cdap.security.authorization.InMemoryAccessController) AccessController(io.cdap.cdap.security.spi.authorization.AccessController) NamespaceMeta(io.cdap.cdap.proto.NamespaceMeta) NamespaceAdmin(io.cdap.cdap.common.namespace.NamespaceAdmin) UnauthorizedException(io.cdap.cdap.security.spi.authorization.UnauthorizedException) GrantedPermission(io.cdap.cdap.proto.security.GrantedPermission) Test(org.junit.Test)

Example 38 with AccessController

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));
}
Also used : EntityId(io.cdap.cdap.proto.id.EntityId) InMemoryAccessController(io.cdap.cdap.security.authorization.InMemoryAccessController) AccessController(io.cdap.cdap.security.spi.authorization.AccessController) After(org.junit.After)

Example 39 with AccessController

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());
}
Also used : InMemoryAccessController(io.cdap.cdap.security.authorization.InMemoryAccessController) AccessController(io.cdap.cdap.security.spi.authorization.AccessController) GrantedPermission(io.cdap.cdap.proto.security.GrantedPermission) Predicate(com.google.common.base.Predicate)

Example 40 with AccessController

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();
    }
}
Also used : MasterAuthenticationContext(io.cdap.cdap.security.auth.context.MasterAuthenticationContext) CommonNettyHttpServiceBuilder(io.cdap.cdap.common.http.CommonNettyHttpServiceBuilder) AccessControllerInstantiator(io.cdap.cdap.security.authorization.AccessControllerInstantiator) AccessException(io.cdap.cdap.api.security.AccessException) FeatureDisabledException(io.cdap.cdap.common.FeatureDisabledException) AlreadyExistsException(io.cdap.cdap.security.spi.authorization.AlreadyExistsException) Role(io.cdap.cdap.proto.security.Role) InMemoryAccessController(io.cdap.cdap.security.authorization.InMemoryAccessController) AccessController(io.cdap.cdap.security.spi.authorization.AccessController) InMemoryAccessController(io.cdap.cdap.security.authorization.InMemoryAccessController) NettyHttpService(io.cdap.http.NettyHttpService) AuthorizationClient(io.cdap.cdap.client.AuthorizationClient) NamespaceId(io.cdap.cdap.proto.id.NamespaceId)

Aggregations

AccessController (io.cdap.cdap.security.spi.authorization.AccessController)50 NoOpAccessController (io.cdap.cdap.security.spi.authorization.NoOpAccessController)30 Test (org.junit.Test)24 InMemoryAccessController (io.cdap.cdap.security.authorization.InMemoryAccessController)18 CConfiguration (io.cdap.cdap.common.conf.CConfiguration)12 Principal (io.cdap.cdap.proto.security.Principal)12 Credential (io.cdap.cdap.proto.security.Credential)10 GrantedPermission (io.cdap.cdap.proto.security.GrantedPermission)10 DatasetId (io.cdap.cdap.proto.id.DatasetId)8 StandardPermission (io.cdap.cdap.proto.security.StandardPermission)8 ImmutableSet (com.google.common.collect.ImmutableSet)6 SConfiguration (io.cdap.cdap.common.conf.SConfiguration)6 EntityId (io.cdap.cdap.proto.id.EntityId)6 NamespaceId (io.cdap.cdap.proto.id.NamespaceId)6 TinkCipher (io.cdap.cdap.security.auth.TinkCipher)6 File (java.io.File)6 IOException (java.io.IOException)6 AuthorizationClient (io.cdap.cdap.client.AuthorizationClient)4 CommonNettyHttpServiceBuilder (io.cdap.cdap.common.http.CommonNettyHttpServiceBuilder)4 MasterAuthenticationContext (io.cdap.cdap.security.auth.context.MasterAuthenticationContext)4