use of co.cask.cdap.proto.DatasetDetail in project cdap by caskdata.
the class ApplicationLifecycleService method filterApplicationDetail.
/**
* Filter the {@link ApplicationDetail} by only returning the visible entities
*/
private ApplicationDetail filterApplicationDetail(final ApplicationId appId, ApplicationDetail applicationDetail) throws Exception {
Principal principal = authenticationContext.getPrincipal();
List<ProgramRecord> filteredPrograms = AuthorizationUtil.isVisible(applicationDetail.getPrograms(), authorizationEnforcer, principal, new Function<ProgramRecord, EntityId>() {
@Override
public EntityId apply(ProgramRecord input) {
return appId.program(input.getType(), input.getName());
}
}, null);
List<StreamDetail> filteredStreams = AuthorizationUtil.isVisible(applicationDetail.getStreams(), authorizationEnforcer, principal, new Function<StreamDetail, EntityId>() {
@Override
public EntityId apply(StreamDetail input) {
return appId.getNamespaceId().stream(input.getName());
}
}, null);
List<DatasetDetail> filteredDatasets = AuthorizationUtil.isVisible(applicationDetail.getDatasets(), authorizationEnforcer, principal, new Function<DatasetDetail, EntityId>() {
@Override
public EntityId apply(DatasetDetail input) {
return appId.getNamespaceId().dataset(input.getName());
}
}, null);
return new ApplicationDetail(applicationDetail.getName(), applicationDetail.getAppVersion(), applicationDetail.getDescription(), applicationDetail.getConfiguration(), filteredStreams, filteredDatasets, filteredPrograms, applicationDetail.getPlugins(), applicationDetail.getArtifact(), applicationDetail.getOwnerPrincipal());
}
use of co.cask.cdap.proto.DatasetDetail 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();
Authorizer authorizer = getAuthorizer();
ApplicationId dummyAppId = AUTH_NAMESPACE.app(DummyApp.class.getSimpleName());
Map<EntityId, Set<Action>> neededPrivileges = ImmutableMap.<EntityId, Set<Action>>builder().put(dummyAppId, EnumSet.of(Action.ADMIN)).put(AUTH_NAMESPACE.artifact(DummyApp.class.getSimpleName(), "1.0-SNAPSHOT"), EnumSet.of(Action.ADMIN)).put(AUTH_NAMESPACE.dataset("whom"), EnumSet.of(Action.ADMIN)).put(AUTH_NAMESPACE.stream("who"), EnumSet.of(Action.ADMIN)).put(AUTH_NAMESPACE.dataset("customDataset"), EnumSet.of(Action.ADMIN)).put(AUTH_NAMESPACE.datasetType(KeyValueTable.class.getName()), EnumSet.of(Action.ADMIN)).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(Action.ADMIN));
cleanUpEntities.add(AUTH_NAMESPACE.datasetType(DummyApp.CustomDummyDataset.class.getName()));
grantAndAssertSuccess(AUTH_NAMESPACE.datasetModule(DummyApp.CustomDummyDataset.class.getName()), ALICE, EnumSet.of(Action.ADMIN));
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", authorizer.listPrivileges(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(dummyAppId, BOB, ImmutableSet.of(Action.READ, Action.WRITE));
// delete should fail
try {
appManager.delete();
} catch (UnauthorizedException expected) {
// expected
}
// grant ADMIN to Bob. Now delete should succeed
grantAndAssertSuccess(dummyAppId, BOB, ImmutableSet.of(Action.ADMIN));
// 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(!getAuthorizer().isVisible(Collections.singleton(dummyAppId), BOB).isEmpty());
// bob should still have privileges granted to him
Assert.assertEquals(3, authorizer.listPrivileges(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<Action>> anotherAppNeededPrivilege = ImmutableMap.<EntityId, Set<Action>>builder().put(appId, EnumSet.of(Action.ADMIN)).put(AUTH_NAMESPACE.artifact(AllProgramsApp.class.getSimpleName(), "1.0-SNAPSHOT"), EnumSet.of(Action.ADMIN)).put(AUTH_NAMESPACE.dataset(AllProgramsApp.DATASET_NAME), EnumSet.of(Action.ADMIN)).put(AUTH_NAMESPACE.dataset(AllProgramsApp.DATASET_NAME2), EnumSet.of(Action.ADMIN)).put(AUTH_NAMESPACE.dataset(AllProgramsApp.DATASET_NAME3), EnumSet.of(Action.ADMIN)).put(AUTH_NAMESPACE.dataset(AllProgramsApp.DS_WITH_SCHEMA_NAME), EnumSet.of(Action.ADMIN)).put(AUTH_NAMESPACE.stream(AllProgramsApp.STREAM_NAME), EnumSet.of(Action.ADMIN)).put(AUTH_NAMESPACE.datasetType(ObjectMappedTable.class.getName()), EnumSet.of(Action.ADMIN)).build();
setUpPrivilegeAndRegisterForDeletion(ALICE, anotherAppNeededPrivilege);
Map<EntityId, Set<Action>> bobDatasetPrivileges = ImmutableMap.<EntityId, Set<Action>>builder().put(AUTH_NAMESPACE.dataset(AllProgramsApp.DATASET_NAME), EnumSet.of(Action.ADMIN)).put(AUTH_NAMESPACE.dataset(AllProgramsApp.DATASET_NAME2), EnumSet.of(Action.ADMIN)).build();
Map<EntityId, Set<Action>> bobProgramPrivileges = ImmutableMap.<EntityId, Set<Action>>builder().put(appId.program(ProgramType.FLOW, AllProgramsApp.NoOpFlow.NAME), EnumSet.of(Action.EXECUTE)).put(appId.program(ProgramType.SERVICE, AllProgramsApp.NoOpService.NAME), EnumSet.of(Action.EXECUTE)).put(appId.program(ProgramType.WORKER, AllProgramsApp.NoOpWorker.NAME), EnumSet.of(Action.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
}
ApplicationDetail applicationDetail = getAppDetail(appId);
Assert.assertEquals(bobDatasetPrivileges.keySet(), Sets.<EntityId>newHashSet(Iterables.transform(applicationDetail.getDatasets(), new Function<DatasetDetail, DatasetId>() {
@Override
public DatasetId apply(DatasetDetail input) {
return appId.getNamespaceId().dataset(input.getName());
}
})));
Assert.assertEquals(bobProgramPrivileges.keySet(), Sets.<EntityId>newHashSet(Iterables.transform(applicationDetail.getPrograms(), new Function<ProgramRecord, ProgramId>() {
@Override
public ProgramId apply(ProgramRecord input) {
return appId.program(input.getType(), input.getName());
}
})));
Assert.assertEquals(Collections.emptyList(), applicationDetail.getStreams());
// Switch to ALICE, deletion should be successful since ALICE has ADMIN privileges
SecurityRequestContext.setUserId(ALICE.getName());
deleteAllApplications(AUTH_NAMESPACE);
}
Aggregations