Search in sources :

Example 16 with UnauthorizedException

use of co.cask.cdap.security.spi.authorization.UnauthorizedException in project cdap by caskdata.

the class AuthorizationUtil method ensureOnePrivilege.

/**
 * Ensures that the principal has at least one {@link Action privilege} in the expected action set
 * on the specified entity id.
 * <p>
 * TODO: remove this once we have api support for OR privilege enforce
 *
 * @param entityId the entity to be checked
 * @param actionSet the set of privileges
 * @param authorizationEnforcer enforcer to make the authorization check
 * @param principal the principal to be checked
 * @throws UnauthorizedException if the principal does not have any privilege in the action set on the entity
 */
public static void ensureOnePrivilege(co.cask.cdap.proto.id.EntityId entityId, Set<Action> actionSet, AuthorizationEnforcer authorizationEnforcer, Principal principal) throws Exception {
    boolean isAuthorized = false;
    for (Action action : actionSet) {
        try {
            authorizationEnforcer.enforce(entityId, principal, action);
            isAuthorized = true;
            break;
        } catch (UnauthorizedException e) {
        // continue to next action
        }
    }
    if (!isAuthorized) {
        throw new UnauthorizedException(principal, actionSet, entityId, false);
    }
}
Also used : Action(co.cask.cdap.proto.security.Action) UnauthorizedException(co.cask.cdap.security.spi.authorization.UnauthorizedException)

Example 17 with UnauthorizedException

use of co.cask.cdap.security.spi.authorization.UnauthorizedException in project cdap by caskdata.

the class StreamAdminTest method testCreateExist.

@Test
public void testCreateExist() throws Exception {
    SecurityRequestContext.setUserId(USER.getName());
    StreamAdmin streamAdmin = getStreamAdmin();
    String streamName = "streamName";
    StreamId streamId = FOO_NAMESPACE.stream(streamName);
    StreamId otherStreamId = OTHER_NAMESPACE.stream(streamName);
    // grant some privileges to the stream so that the user can check the existence
    grantAndAssertSuccess(streamId, USER, EnumSet.of(Action.EXECUTE));
    grantAndAssertSuccess(otherStreamId, USER, EnumSet.of(Action.EXECUTE));
    Assert.assertFalse(streamAdmin.exists(streamId));
    Assert.assertFalse(streamAdmin.exists(otherStreamId));
    try {
        streamAdmin.create(streamId);
        Assert.fail("User should not be able to create a stream in this namespace.");
    } catch (UnauthorizedException e) {
    // expected
    }
    // grant admin access for user to stream
    grantAndAssertSuccess(streamId, USER, ImmutableSet.of(Action.ADMIN));
    streamAdmin.create(streamId);
    // Even though both streams have the same name, {@code otherStreamId} does not exist because it is in a different
    // namespace than the one created above.
    Assert.assertTrue(streamAdmin.exists(streamId));
    Assert.assertFalse(streamAdmin.exists(otherStreamId));
    try {
        streamAdmin.create(otherStreamId);
        Assert.fail("User should not be able to create a stream in this namespace.");
    } catch (UnauthorizedException e) {
    // expected
    }
    // grant admin access for user to stream in other_namespace
    grantAndAssertSuccess(otherStreamId, USER, ImmutableSet.of(Action.ADMIN));
    streamAdmin.create(otherStreamId);
    Assert.assertTrue(streamAdmin.exists(otherStreamId));
    // the user should be able to drop the stream, they had created
    streamAdmin.drop(otherStreamId);
    Assert.assertFalse(streamAdmin.exists(otherStreamId));
    // revoke the permission for the user on the stream in foo_namespace
    revokeAndAssertSuccess(streamId, USER, EnumSet.allOf(Action.class));
    try {
        streamAdmin.drop(streamId);
        Assert.fail("User should not be able to delete a stream in this namespace.");
    } catch (UnauthorizedException e) {
    // expected
    }
    // grant WRITE permission to the user but they still should not be able to drop the stream
    grantAndAssertSuccess(streamId, USER, ImmutableSet.of(Action.WRITE));
    try {
        streamAdmin.drop(streamId);
        Assert.fail("User should not be able to delete a stream with only Write Action access.");
    } catch (UnauthorizedException e) {
    // expected
    }
    // grant admin access and the user should then be able to drop the stream
    grantAndAssertSuccess(streamId, USER, ImmutableSet.of(Action.ADMIN));
    streamAdmin.drop(streamId);
    Assert.assertFalse(streamAdmin.exists(streamId));
    // clean up privilege
    getAuthorizer().revoke(Authorizable.fromEntityId(streamId));
    getAuthorizer().revoke(Authorizable.fromEntityId(otherStreamId));
}
Also used : StreamId(co.cask.cdap.proto.id.StreamId) Action(co.cask.cdap.proto.security.Action) UnauthorizedException(co.cask.cdap.security.spi.authorization.UnauthorizedException) Test(org.junit.Test)

Example 18 with UnauthorizedException

use of co.cask.cdap.security.spi.authorization.UnauthorizedException in project cdap by caskdata.

the class StreamAdminTest method testOwner.

@Test
public void testOwner() throws Exception {
    // create a stream with owner
    StreamAdmin streamAdmin = getStreamAdmin();
    OwnerAdmin ownerAdmin = getOwnerAdmin();
    StreamId stream = FOO_NAMESPACE.stream("stream");
    Properties properties = new Properties();
    String ownerPrincipal = "user/somehost@somekdc.net";
    KerberosPrincipalId principalId = new KerberosPrincipalId(ownerPrincipal);
    properties.put(Constants.Security.PRINCIPAL, ownerPrincipal);
    try {
        streamAdmin.create(stream, properties);
        Assert.fail();
    } catch (UnauthorizedException e) {
    // expected since user does not have privilege on the stream and the owner principal
    }
    // grant privilege on the stream to the user
    grantAndAssertSuccess(stream, USER, EnumSet.of(Action.ADMIN));
    try {
        streamAdmin.create(stream, properties);
        Assert.fail();
    } catch (UnauthorizedException e) {
    // expected since user doesn ot have privilege on the owner principal
    }
    // grant privilege to the owner principal
    grantAndAssertSuccess(principalId, USER, EnumSet.of(Action.ADMIN));
    // creation should work this time
    streamAdmin.create(stream, properties);
    Assert.assertTrue(streamAdmin.exists(stream));
    // Check that the owner information got stored in owner store
    Assert.assertTrue(ownerAdmin.exists(stream));
    // also verify that we are able to get owner information back in properties
    Assert.assertEquals(ownerPrincipal, streamAdmin.getProperties(stream).getOwnerPrincipal());
    // updating stream owner should fail
    try {
        streamAdmin.updateConfig(stream, new StreamProperties(1L, null, null, null, "user/somekdc.net"));
        Assert.fail();
    } catch (UnauthorizedException e) {
    // expected
    }
    // trying to create same stream with different owner should fail
    properties.put(Constants.Security.PRINCIPAL, "someOtherUser/someHost@somekdc.net");
    try {
        streamAdmin.create(stream, properties);
        Assert.fail("Should have failed to add the same stream with different owner");
    } catch (UnauthorizedException e) {
    // expected
    }
    // ensure that the previous owner still exists
    Assert.assertEquals(ownerPrincipal, streamAdmin.getProperties(stream).getOwnerPrincipal());
    // drop the stream which should also delete the owner info
    streamAdmin.drop(stream);
    Assert.assertFalse(ownerAdmin.exists(stream));
    // clean up the privileges
    revokeAndAssertSuccess(stream, USER, EnumSet.of(Action.ADMIN));
    revokeAndAssertSuccess(principalId, USER, EnumSet.of(Action.ADMIN));
}
Also used : StreamId(co.cask.cdap.proto.id.StreamId) OwnerAdmin(co.cask.cdap.security.impersonation.OwnerAdmin) UnauthorizedException(co.cask.cdap.security.spi.authorization.UnauthorizedException) StreamProperties(co.cask.cdap.proto.StreamProperties) StreamProperties(co.cask.cdap.proto.StreamProperties) Properties(java.util.Properties) KerberosPrincipalId(co.cask.cdap.proto.id.KerberosPrincipalId) Test(org.junit.Test)

Example 19 with UnauthorizedException

use of co.cask.cdap.security.spi.authorization.UnauthorizedException in project cdap by caskdata.

the class StreamAdminTest method testDropAllInNamespace.

@Test
public void testDropAllInNamespace() throws Exception {
    StreamAdmin streamAdmin = getStreamAdmin();
    StreamId otherStream = OTHER_NAMESPACE.stream("otherStream");
    List<StreamId> fooStreams = Lists.newArrayList();
    for (int i = 0; i < 4; i++) {
        fooStreams.add(FOO_NAMESPACE.stream("stream" + i));
    }
    List<StreamId> allStreams = Lists.newArrayList();
    allStreams.addAll(fooStreams);
    allStreams.add(otherStream);
    for (StreamId stream : allStreams) {
        // grant privilege to the stream
        grantAndAssertSuccess(stream, USER, EnumSet.of(Action.ADMIN));
        streamAdmin.create(stream);
        writeEvent(stream);
        // all of the streams should have data in it after writing to them
        Assert.assertNotEquals(0, getStreamSize(stream));
    }
    // revoke ADMIN from one of the streams and grant READ on the stream to make sure USER is not able to delete but
    // able to list
    revokeAndAssertSuccess(fooStreams.get(0), USER, EnumSet.of(Action.ADMIN));
    grantAndAssertSuccess(fooStreams.get(0), USER, EnumSet.of(Action.READ));
    // the drop all should fail since USER does not have ADMIN on one of the streams in the namespace
    try {
        streamAdmin.dropAllInNamespace(FOO_NAMESPACE);
        Assert.fail();
    } catch (UnauthorizedException e) {
    // expected
    }
    // all streams should exist
    Assert.assertEquals(fooStreams.size(), streamAdmin.listStreams(FOO_NAMESPACE).size());
    // grant ADMIN again and this time drop all should succeed
    grantAndAssertSuccess(fooStreams.get(0), USER, EnumSet.of(Action.ADMIN));
    revokeAndAssertSuccess(fooStreams.get(0), USER, EnumSet.of(Action.READ));
    streamAdmin.dropAllInNamespace(FOO_NAMESPACE);
    // All of the streams within the default namespace should no longer exist
    for (StreamId defaultStream : fooStreams) {
        Assert.assertFalse(streamAdmin.exists(defaultStream));
    }
    // otherStream isn't in the foo namespace so its data is not deleted in the above call to dropAllInNamespace.
    Assert.assertNotEquals(0, getStreamSize(otherStream));
    // truncate should also delete all the data of a stream
    streamAdmin.truncate(otherStream);
    Assert.assertEquals(0, getStreamSize(otherStream));
    // clean up privileges
    for (StreamId stream : allStreams) {
        // revoke privilege to the stream
        revokeAndAssertSuccess(stream, USER, EnumSet.of(Action.ADMIN));
    }
}
Also used : StreamId(co.cask.cdap.proto.id.StreamId) UnauthorizedException(co.cask.cdap.security.spi.authorization.UnauthorizedException) Test(org.junit.Test)

Example 20 with UnauthorizedException

use of co.cask.cdap.security.spi.authorization.UnauthorizedException in project cdap by caskdata.

the class DatasetInstanceService method create.

/**
 * Creates a dataset instance.
 *
 * @param namespaceId the namespace to create the dataset instance in
 * @param name the name of the new dataset instance
 * @param props the properties for the new dataset instance
 * @throws NamespaceNotFoundException if the specified namespace was not found
 * @throws DatasetAlreadyExistsException if a dataset with the same name already exists
 * @throws DatasetTypeNotFoundException if the dataset type was not found
 * @throws UnauthorizedException if perimeter security and authorization are enabled, and the current user does not
 *  have {@link Action#WRITE} privilege on the #instance's namespace
 */
void create(String namespaceId, String name, DatasetInstanceConfiguration props) throws Exception {
    NamespaceId namespace = ConversionHelpers.toNamespaceId(namespaceId);
    DatasetId datasetId = ConversionHelpers.toDatasetInstanceId(namespaceId, name);
    Principal requestingUser = authenticationContext.getPrincipal();
    String ownerPrincipal = props.getOwnerPrincipal();
    // need to enforce on the principal id if impersonation is involved
    KerberosPrincipalId effectiveOwner = SecurityUtil.getEffectiveOwner(ownerAdmin, namespace, ownerPrincipal);
    if (!DatasetsUtil.isSystemDatasetInUserNamespace(datasetId)) {
        if (effectiveOwner != null) {
            authorizationEnforcer.enforce(effectiveOwner, requestingUser, Action.ADMIN);
        }
        authorizationEnforcer.enforce(datasetId, requestingUser, Action.ADMIN);
    }
    ensureNamespaceExists(namespace);
    DatasetSpecification existing = instanceManager.get(datasetId);
    if (existing != null) {
        throw new DatasetAlreadyExistsException(datasetId);
    }
    // for creation, we need enforcement for dataset type for user dataset, but bypass for system datasets
    DatasetTypeMeta typeMeta = getTypeInfo(namespace, props.getTypeName(), DatasetsUtil.isSystemDatasetInUserNamespace(datasetId));
    if (typeMeta == null) {
        // Type not found in the instance's namespace and the system namespace. Bail out.
        throw new DatasetTypeNotFoundException(ConversionHelpers.toDatasetTypeId(namespace, props.getTypeName()));
    }
    LOG.info("Creating dataset {}.{}, type name: {}, properties: {}", namespaceId, name, props.getTypeName(), props.getProperties());
    // exists or not
    if (ownerPrincipal != null) {
        KerberosPrincipalId owner = new KerberosPrincipalId(ownerPrincipal);
        ownerAdmin.add(datasetId, owner);
    }
    try {
        DatasetSpecification spec = opExecutorClient.create(datasetId, typeMeta, DatasetProperties.builder().addAll(props.getProperties()).setDescription(props.getDescription()).build());
        instanceManager.add(namespace, spec);
        metaCache.invalidate(datasetId);
        publishAudit(datasetId, AuditType.CREATE);
        // Enable explore
        enableExplore(datasetId, spec, props);
    } catch (Exception e) {
        // there was a problem in creating the dataset instance so delete the owner if it got added earlier
        // safe to call for entities which does not have an owner too
        ownerAdmin.delete(datasetId);
        throw e;
    }
}
Also used : DatasetSpecification(co.cask.cdap.api.dataset.DatasetSpecification) DatasetTypeMeta(co.cask.cdap.proto.DatasetTypeMeta) DatasetAlreadyExistsException(co.cask.cdap.common.DatasetAlreadyExistsException) NamespaceId(co.cask.cdap.proto.id.NamespaceId) DatasetTypeNotFoundException(co.cask.cdap.common.DatasetTypeNotFoundException) KerberosPrincipalId(co.cask.cdap.proto.id.KerberosPrincipalId) Principal(co.cask.cdap.proto.security.Principal) NamespaceNotFoundException(co.cask.cdap.common.NamespaceNotFoundException) DatasetNotFoundException(co.cask.cdap.common.DatasetNotFoundException) DatasetTypeNotFoundException(co.cask.cdap.common.DatasetTypeNotFoundException) UnauthorizedException(co.cask.cdap.security.spi.authorization.UnauthorizedException) HandlerException(co.cask.cdap.common.HandlerException) DatasetAlreadyExistsException(co.cask.cdap.common.DatasetAlreadyExistsException) IOException(java.io.IOException) ExecutionException(java.util.concurrent.ExecutionException) NotFoundException(co.cask.cdap.common.NotFoundException) DatasetId(co.cask.cdap.proto.id.DatasetId)

Aggregations

UnauthorizedException (co.cask.cdap.security.spi.authorization.UnauthorizedException)49 Test (org.junit.Test)18 IOException (java.io.IOException)15 EntityId (co.cask.cdap.proto.id.EntityId)13 Principal (co.cask.cdap.proto.security.Principal)13 Action (co.cask.cdap.proto.security.Action)12 BadRequestException (co.cask.cdap.common.BadRequestException)11 ApplicationId (co.cask.cdap.proto.id.ApplicationId)10 NamespaceNotFoundException (co.cask.cdap.common.NamespaceNotFoundException)9 JsonSyntaxException (com.google.gson.JsonSyntaxException)9 ExecutionException (java.util.concurrent.ExecutionException)9 NotFoundException (co.cask.cdap.common.NotFoundException)8 NamespaceId (co.cask.cdap.proto.id.NamespaceId)7 DatasetManagementException (co.cask.cdap.api.dataset.DatasetManagementException)6 ConflictException (co.cask.cdap.common.ConflictException)6 StreamId (co.cask.cdap.proto.id.StreamId)6 ArtifactAlreadyExistsException (co.cask.cdap.common.ArtifactAlreadyExistsException)5 ArtifactNotFoundException (co.cask.cdap.common.ArtifactNotFoundException)5 WriteConflictException (co.cask.cdap.internal.app.runtime.artifact.WriteConflictException)5 NamespaceMeta (co.cask.cdap.proto.NamespaceMeta)5