Search in sources :

Example 21 with UnauthorizedException

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

the class AuthorizationTest method testScheduleAuth.

@Test
public void testScheduleAuth() throws Exception {
    createAuthNamespace();
    ApplicationId appId = AUTH_NAMESPACE.app(AppWithSchedule.class.getSimpleName());
    Map<EntityId, Set<? extends Permission>> neededPrivileges = ImmutableMap.<EntityId, Set<? extends Permission>>builder().put(appId, EnumSet.of(StandardPermission.CREATE, StandardPermission.GET)).put(AUTH_NAMESPACE.artifact(AppWithSchedule.class.getSimpleName(), "1.0-SNAPSHOT"), EnumSet.of(StandardPermission.CREATE)).put(AUTH_NAMESPACE.dataset(AppWithSchedule.INPUT_NAME), EnumSet.of(StandardPermission.CREATE, StandardPermission.GET)).put(AUTH_NAMESPACE.dataset(AppWithSchedule.OUTPUT_NAME), EnumSet.of(StandardPermission.CREATE, StandardPermission.GET)).put(AUTH_NAMESPACE.datasetType(ObjectStore.class.getName()), EnumSet.of(StandardPermission.UPDATE)).build();
    setUpPrivilegeAndRegisterForDeletion(ALICE, neededPrivileges);
    ApplicationManager appManager = deployApplication(AUTH_NAMESPACE, AppWithSchedule.class);
    String workflowName = AppWithSchedule.SampleWorkflow.class.getSimpleName();
    ProgramId workflowID = new ProgramId(AUTH_NAMESPACE.getNamespace(), AppWithSchedule.class.getSimpleName(), ProgramType.WORKFLOW, workflowName);
    cleanUpEntities.add(workflowID);
    final WorkflowManager workflowManager = appManager.getWorkflowManager(workflowName);
    ScheduleManager scheduleManager = workflowManager.getSchedule(AppWithSchedule.EVERY_HOUR_SCHEDULE);
    // switch to BOB
    SecurityRequestContext.setUserId(BOB.getName());
    // try to resume schedule as BOB. It should fail since BOB does not have execute privileges on the programs
    try {
        scheduleManager.resume();
        Assert.fail("Resuming schedule should have failed since BOB does not have EXECUTE on the program");
    } catch (UnauthorizedException e) {
    // Expected
    }
    // bob should also not be able see the status of the schedule
    try {
        scheduleManager.status(HttpURLConnection.HTTP_FORBIDDEN);
        Assert.fail("Getting schedule status should have failed since BOB does not have any privilege on the program");
    } catch (UnauthorizedException e) {
    // Expected
    }
    // give BOB READ permission in the workflow
    grantAndAssertSuccess(workflowID, BOB, EnumSet.of(StandardPermission.GET));
    // switch to BOB
    SecurityRequestContext.setUserId(BOB.getName());
    // try to resume schedule as BOB. It should fail since BOB has READ but not EXECUTE on the workflow
    try {
        scheduleManager.resume();
        Assert.fail("Resuming schedule should have failed since BOB does not have EXECUTE on the program");
    } catch (UnauthorizedException e) {
    // Expected
    }
    // but BOB should be able to get schedule status now
    Assert.assertEquals(ProgramScheduleStatus.SUSPENDED.name(), scheduleManager.status(HttpURLConnection.HTTP_OK));
    // give BOB EXECUTE permission in the workflow
    grantAndAssertSuccess(workflowID, BOB, EnumSet.of(ApplicationPermission.EXECUTE));
    // switch to BOB
    SecurityRequestContext.setUserId(BOB.getName());
    // try to resume the schedule. This should pass and workflow should run
    scheduleManager.resume();
    Assert.assertEquals(ProgramScheduleStatus.SCHEDULED.name(), scheduleManager.status(HttpURLConnection.HTTP_OK));
    // suspend the schedule so that it does not start running again
    scheduleManager.suspend();
    Assert.assertEquals(ProgramScheduleStatus.SUSPENDED.name(), scheduleManager.status(HttpURLConnection.HTTP_OK));
    ScheduleId scheduleId = new ScheduleId(appId.getNamespace(), appId.getApplication(), appId.getVersion(), "testSchedule");
    ScheduleDetail scheduleDetail = new ScheduleDetail(AUTH_NAMESPACE.getNamespace(), AppWithSchedule.class.getSimpleName(), "1.0-SNAPSHOT", "testSchedule", "Something 2", new ScheduleProgramInfo(SchedulableProgramType.WORKFLOW, workflowName), Collections.<String, String>emptyMap(), new TimeTrigger("*/1 * * * *"), Collections.<Constraint>emptyList(), TimeUnit.HOURS.toMillis(6), null, null);
    try {
        addSchedule(scheduleId, scheduleDetail);
        Assert.fail("Adding schedule should fail since BOB does not have AMDIN on the app");
    } catch (UnauthorizedException e) {
    // expected
    }
    // grant BOB EXECUTE on the app
    grantAndAssertSuccess(appId, BOB, EnumSet.of(ApplicationPermission.EXECUTE));
    // add schedule should succeed
    addSchedule(scheduleId, scheduleDetail);
    Assert.assertEquals(ProgramScheduleStatus.SUSPENDED.name(), workflowManager.getSchedule(scheduleId.getSchedule()).status(HttpURLConnection.HTTP_OK));
    // update schedule should succeed
    updateSchedule(scheduleId, scheduleDetail);
    Assert.assertEquals(ProgramScheduleStatus.SUSPENDED.name(), workflowManager.getSchedule(scheduleId.getSchedule()).status(HttpURLConnection.HTTP_OK));
    // revoke EXECUTE from BOB
    getAccessController().revoke(Authorizable.fromEntityId(appId), BOB, EnumSet.of(ApplicationPermission.EXECUTE));
    try {
        // delete schedule should fail since we revoke the ADMIN privilege from BOB
        deleteSchedule(scheduleId);
        Assert.fail("Deleting schedule should fail since BOB does not have AMDIN on the app");
    } catch (UnauthorizedException e) {
    // expected
    }
    try {
        updateSchedule(scheduleId, scheduleDetail);
        Assert.fail("Updating schedule should fail since BOB does not have AMDIN on the app");
    } catch (UnauthorizedException e) {
    // expected
    }
    // grant BOB EXECUTE on the app again
    grantAndAssertSuccess(appId, BOB, EnumSet.of(ApplicationPermission.EXECUTE));
    deleteSchedule(scheduleId);
    workflowManager.getSchedule(scheduleId.getSchedule()).status(HttpURLConnection.HTTP_NOT_FOUND);
    // switch to Alice
    SecurityRequestContext.setUserId(ALICE.getName());
}
Also used : ScheduleManager(io.cdap.cdap.test.ScheduleManager) ObjectStore(io.cdap.cdap.api.dataset.lib.ObjectStore) 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) TimeTrigger(io.cdap.cdap.internal.app.runtime.schedule.trigger.TimeTrigger) WorkflowManager(io.cdap.cdap.test.WorkflowManager) AppWithSchedule(io.cdap.cdap.test.app.AppWithSchedule) ProgramId(io.cdap.cdap.proto.id.ProgramId) ScheduleId(io.cdap.cdap.proto.id.ScheduleId) EntityId(io.cdap.cdap.proto.id.EntityId) 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) UnauthorizedException(io.cdap.cdap.security.spi.authorization.UnauthorizedException) ScheduleDetail(io.cdap.cdap.proto.ScheduleDetail) ApplicationId(io.cdap.cdap.proto.id.ApplicationId) ScheduleProgramInfo(io.cdap.cdap.api.workflow.ScheduleProgramInfo) Test(org.junit.Test)

Example 22 with UnauthorizedException

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

the class AuthorizationTest method testDeleteSystemDatasets.

/**
 * This test is to make sure we do not bypass the authorization check for datasets in system namespace
 */
@Test
public void testDeleteSystemDatasets() throws Exception {
    // create a random user and try to delete a system dataset
    UserGroupInformation remoteUser = UserGroupInformation.createRemoteUser("random");
    remoteUser.doAs(new PrivilegedAction<Void>() {

        @Override
        public Void run() {
            try {
                deleteDatasetInstance(NamespaceId.SYSTEM.dataset("app.meta"));
                Assert.fail();
            } catch (UnauthorizedException e) {
            // Expected
            } catch (Exception e) {
                if (!(e.getCause() instanceof UnauthorizedException)) {
                    throw new AssertionError("Getting incorrect exception", e);
                }
            }
            return null;
        }
    });
}
Also used : UnauthorizedException(io.cdap.cdap.security.spi.authorization.UnauthorizedException) UnauthorizedException(io.cdap.cdap.security.spi.authorization.UnauthorizedException) IOException(java.io.IOException) ExecutionException(java.util.concurrent.ExecutionException) TimeoutException(java.util.concurrent.TimeoutException) UserGroupInformation(org.apache.hadoop.security.UserGroupInformation) Test(org.junit.Test)

Example 23 with UnauthorizedException

use of io.cdap.cdap.security.spi.authorization.UnauthorizedException in project cdap by cdapio.

the class RESTClient method execute.

public HttpResponse execute(HttpRequest request, int... allowedErrorCodes) throws IOException, UnauthenticatedException, UnauthorizedException {
    int currentTry = 0;
    HttpResponse response;
    int responseCode;
    boolean allowUnavailable = ArrayUtils.contains(allowedErrorCodes, HttpURLConnection.HTTP_UNAVAILABLE);
    do {
        onRequest(request, currentTry);
        response = HttpRequests.execute(request, clientConfig.getDefaultRequestConfig());
        responseCode = response.getResponseCode();
        if (responseCode != HttpURLConnection.HTTP_UNAVAILABLE || allowUnavailable) {
            // only retry if unavailable
            break;
        }
        currentTry++;
        try {
            TimeUnit.MILLISECONDS.sleep(1000);
        } catch (InterruptedException e) {
            break;
        }
    } while (currentTry <= clientConfig.getUnavailableRetryLimit());
    onResponse(request, response, currentTry);
    if (responseCode == HttpURLConnection.HTTP_UNAUTHORIZED) {
        throw new UnauthenticatedException("Unauthorized status code received from the server.");
    }
    if (responseCode == HttpURLConnection.HTTP_FORBIDDEN) {
        throw new UnauthorizedException(response.getResponseBodyAsString());
    }
    if (!isSuccessful(responseCode) && !ArrayUtils.contains(allowedErrorCodes, responseCode)) {
        throw new IOException(responseCode + ": " + response.getResponseBodyAsString());
    }
    return response;
}
Also used : UnauthenticatedException(io.cdap.cdap.security.spi.authentication.UnauthenticatedException) UnauthorizedException(io.cdap.cdap.security.spi.authorization.UnauthorizedException) HttpResponse(io.cdap.common.http.HttpResponse) IOException(java.io.IOException)

Example 24 with UnauthorizedException

use of io.cdap.cdap.security.spi.authorization.UnauthorizedException in project cdap by cdapio.

the class DefaultAccessEnforcerTest method testPropagationDisabled.

@Test
public void testPropagationDisabled() throws IOException, AccessException {
    CConfiguration cConfCopy = CConfiguration.copy(CCONF);
    ControllerWrapper controllerWrapper = createControllerWrapper(cConfCopy, SCONF, null);
    controllerWrapper.accessController.grant(Authorizable.fromEntityId(NS), ALICE, ImmutableSet.of(StandardPermission.UPDATE));
    DefaultAccessEnforcer accessEnforcer = controllerWrapper.defaultAccessEnforcer;
    accessEnforcer.enforce(NS, ALICE, StandardPermission.UPDATE);
    try {
        accessEnforcer.enforce(APP, ALICE, StandardPermission.UPDATE);
        Assert.fail("Alice should not have ADMIN privilege on the APP.");
    } catch (UnauthorizedException ignored) {
    // expected
    }
    // Verify the metrics context was called with correct metrics
    verify(controllerWrapper.mockMetricsContext, times(1)).increment(Constants.Metrics.Authorization.EXTENSION_CHECK_SUCCESS_COUNT, 1);
    verify(controllerWrapper.mockMetricsContext, times(1)).increment(Constants.Metrics.Authorization.EXTENSION_CHECK_FAILURE_COUNT, 1);
    verify(controllerWrapper.mockMetricsContext, times(2)).gauge(eq(Constants.Metrics.Authorization.EXTENSION_CHECK_MILLIS), any(Long.class));
}
Also used : UnauthorizedException(io.cdap.cdap.security.spi.authorization.UnauthorizedException) CConfiguration(io.cdap.cdap.common.conf.CConfiguration) Test(org.junit.Test)

Example 25 with UnauthorizedException

use of io.cdap.cdap.security.spi.authorization.UnauthorizedException in project cdap by cdapio.

the class InMemoryAccessController method enforce.

private void enforce(EntityId entity, @Nullable EntityType childType, Principal principal, Set<? extends Permission> permissions) throws UnauthorizedException {
    // super users do not have any enforcement
    if (superUsers.contains(principal) || superUsers.contains(allSuperUsers)) {
        return;
    }
    // permissions allowed for this principal
    Set<? extends Permission> allowed = getPermissions(entity, childType, principal);
    if (allowed.containsAll(permissions)) {
        return;
    }
    Set<Permission> allowedForRoles = new HashSet<>();
    // permissions allowed for any of the roles to which this principal belongs if its not a role
    if (principal.getType() != Principal.PrincipalType.ROLE) {
        for (Role role : getRoles(principal)) {
            allowedForRoles.addAll(getPermissions(entity, role));
        }
    }
    if (!allowedForRoles.containsAll(permissions)) {
        throw new UnauthorizedException(principal, Sets.difference(permissions, allowed), entity, childType);
    }
}
Also used : Role(io.cdap.cdap.proto.security.Role) GrantedPermission(io.cdap.cdap.proto.security.GrantedPermission) Permission(io.cdap.cdap.proto.security.Permission) UnauthorizedException(io.cdap.cdap.security.spi.authorization.UnauthorizedException) HashSet(java.util.HashSet)

Aggregations

UnauthorizedException (io.cdap.cdap.security.spi.authorization.UnauthorizedException)98 Test (org.junit.Test)44 IOException (java.io.IOException)38 HttpResponder (io.cdap.http.HttpResponder)28 ApplicationId (io.cdap.cdap.proto.id.ApplicationId)26 BadRequestException (io.cdap.cdap.common.BadRequestException)22 NotFoundException (io.cdap.cdap.common.NotFoundException)22 DefaultFullHttpRequest (io.netty.handler.codec.http.DefaultFullHttpRequest)20 JsonSyntaxException (com.google.gson.JsonSyntaxException)18 DatasetManagementException (io.cdap.cdap.api.dataset.DatasetManagementException)18 NamespaceNotFoundException (io.cdap.cdap.common.NamespaceNotFoundException)18 MonitorHandler (io.cdap.cdap.gateway.handlers.MonitorHandler)18 NamespaceId (io.cdap.cdap.proto.id.NamespaceId)18 FullHttpRequest (io.netty.handler.codec.http.FullHttpRequest)18 ExecutionException (java.util.concurrent.ExecutionException)18 ConflictException (io.cdap.cdap.common.ConflictException)16 StandardPermission (io.cdap.cdap.proto.security.StandardPermission)16 SystemServiceId (io.cdap.cdap.proto.id.SystemServiceId)14 HttpRequest (io.netty.handler.codec.http.HttpRequest)14 HashSet (java.util.HashSet)14