use of io.cdap.cdap.security.spi.authorization.UnauthorizedException in project cdap by cdapio.
the class RemoteAccessEnforcer method doEnforce.
private EnforcementResponse doEnforce(AuthorizationPrivilege authorizationPrivilege) throws IOException {
HttpRequest request = remoteClient.requestBuilder(HttpMethod.POST, "enforce").withBody(GSON.toJson(authorizationPrivilege)).build();
LOG.trace("Remotely enforcing on authorization privilege {}", authorizationPrivilege);
try {
HttpResponse response = remoteClient.execute(request);
if (response.getResponseCode() == HttpURLConnection.HTTP_OK) {
return new EnforcementResponse(true, null);
}
return new EnforcementResponse(false, new IOException(String.format("Failed to enforce with code %d: %s", response.getResponseCode(), response.getResponseBodyAsString())));
} catch (UnauthorizedException e) {
return new EnforcementResponse(false, e);
}
}
use of io.cdap.cdap.security.spi.authorization.UnauthorizedException in project cdap by cdapio.
the class DefaultNamespaceAdmin method get.
/**
* Gets details of a namespace
*
* @param namespaceId the {@link Id.Namespace} of the requested namespace
* @return the {@link NamespaceMeta} of the requested namespace
* @throws NamespaceNotFoundException if the requested namespace is not found
* @throws UnauthorizedException if the namespace is not authorized to the logged-user
*/
@Override
public NamespaceMeta get(NamespaceId namespaceId) throws Exception {
Principal principal = authenticationContext.getPrincipal();
UnauthorizedException lastUnauthorizedException = null;
// See: CDAP-7387
if (masterShortUserName == null || !masterShortUserName.equals(principal.getName())) {
try {
accessEnforcer.enforce(namespaceId, principal, StandardPermission.GET);
} catch (UnauthorizedException e) {
lastUnauthorizedException = e;
}
}
NamespaceMeta namespaceMeta = null;
try {
namespaceMeta = namespaceMetaCache.get(namespaceId);
} catch (Exception e) {
if (lastUnauthorizedException == null) {
Throwable cause = e.getCause();
if (cause instanceof NamespaceNotFoundException || cause instanceof IOException || cause instanceof UnauthorizedException) {
throw (Exception) cause;
}
throw e;
}
}
// If the requesting user is same as namespace owner, we do not care about if the user is authorized or not
if (namespaceMeta != null && principal.getName().equals(namespaceMeta.getConfig().getPrincipal())) {
return namespaceMeta;
}
if (lastUnauthorizedException != null) {
throw lastUnauthorizedException;
}
return namespaceMeta;
}
use of io.cdap.cdap.security.spi.authorization.UnauthorizedException in project cdap by cdapio.
the class DefaultSecureStoreServiceTest method testSecureStoreAccess.
@Test
public void testSecureStoreAccess() throws Exception {
final SecureKeyId secureKeyId1 = NamespaceId.DEFAULT.secureKey(KEY1);
SecurityRequestContext.setUserId(ALICE.getName());
try {
secureStoreManager.put(NamespaceId.DEFAULT.getNamespace(), KEY1, VALUE1, DESCRIPTION1, Collections.<String, String>emptyMap());
Assert.fail("Alice should not be able to store a key since she does not have WRITE privileges on the namespace");
} catch (UnauthorizedException expected) {
// expected
}
// Grant ALICE admin access to the secure key
grantAndAssertSuccess(NamespaceId.DEFAULT, ALICE, EnumSet.of(StandardPermission.GET));
grantAndAssertSuccess(Authorizable.fromEntityId(NamespaceId.DEFAULT, EntityType.SECUREKEY), ALICE, EnumSet.of(StandardPermission.LIST));
grantAndAssertSuccess(secureKeyId1, ALICE, EnumSet.allOf(StandardPermission.class));
// Write should succeed
secureStoreManager.put(NamespaceId.DEFAULT.getNamespace(), KEY1, VALUE1, DESCRIPTION1, Collections.<String, String>emptyMap());
// Listing should return the value just written
List<SecureStoreMetadata> metadatas = secureStore.list(NamespaceId.DEFAULT.getNamespace());
Assert.assertEquals(1, metadatas.size());
Assert.assertEquals(KEY1, metadatas.get(0).getName());
Assert.assertEquals(DESCRIPTION1, metadatas.get(0).getDescription());
revokeAndAssertSuccess(secureKeyId1, ALICE, EnumSet.allOf(StandardPermission.class));
// Should not be able to list the keys since ALICE does not have privilege on the secure key
try {
secureStore.list(NamespaceId.DEFAULT.getNamespace());
} catch (UnauthorizedException e) {
// expected
}
// Give BOB read access and verify that he can read the stored data
SecurityRequestContext.setUserId(BOB.getName());
grantAndAssertSuccess(NamespaceId.DEFAULT, BOB, EnumSet.of(StandardPermission.GET));
grantAndAssertSuccess(secureKeyId1, BOB, EnumSet.of(StandardPermission.GET));
grantAndAssertSuccess(Authorizable.fromEntityId(NamespaceId.DEFAULT, EntityType.SECUREKEY), BOB, EnumSet.of(StandardPermission.LIST));
Assert.assertEquals(VALUE1, new String(secureStore.get(NamespaceId.DEFAULT.getNamespace(), KEY1).get(), Charsets.UTF_8));
metadatas = secureStore.list(NamespaceId.DEFAULT.getNamespace());
Assert.assertEquals(1, metadatas.size());
// BOB should not be able to delete the key
try {
secureStoreManager.delete(NamespaceId.DEFAULT.getNamespace(), KEY1);
Assert.fail("Bob should not be able to delete a key since he does not have ADMIN privileges on the key");
} catch (UnauthorizedException expected) {
// expected
}
// Grant Bob ADMIN access and he should be able to delete the key
grantAndAssertSuccess(secureKeyId1, BOB, ImmutableSet.of(StandardPermission.DELETE));
secureStoreManager.delete(NamespaceId.DEFAULT.getNamespace(), KEY1);
Assert.assertEquals(0, secureStore.list(NamespaceId.DEFAULT.getNamespace()).size());
Predicate<GrantedPermission> secureKeyIdFilter = new Predicate<GrantedPermission>() {
@Override
public boolean apply(GrantedPermission input) {
return input.getAuthorizable().equals(Authorizable.fromEntityId(secureKeyId1));
}
};
}
use of io.cdap.cdap.security.spi.authorization.UnauthorizedException in project cdap by cdapio.
the class MonitorHandlerAuthorizationTest method testRestartServiceInstanceAuthorization.
@Test
public void testRestartServiceInstanceAuthorization() throws Exception {
SystemServiceId systemServiceId = new SystemServiceId(SERVICE_NAME);
MonitorHandler handler = createMonitorHandler(Authorizable.fromEntityId(systemServiceId), Arrays.asList(ApplicationPermission.EXECUTE));
FullHttpRequest request = mock(FullHttpRequest.class);
HttpResponder responder = mock(HttpResponder.class);
AuthenticationTestContext.actAsPrincipal(UNPRIVILEGED_PRINCIPAL);
try {
handler.restartServiceInstance(request, responder, SERVICE_NAME, 0);
} catch (UnauthorizedException e) {
// expected
}
AuthenticationTestContext.actAsPrincipal(MASTER_PRINCIPAL);
handler.restartServiceInstance(request, responder, SERVICE_NAME, 0);
}
use of io.cdap.cdap.security.spi.authorization.UnauthorizedException in project cdap by cdapio.
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 StandardPermission#UPDATE} 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.isUserDataset(datasetId)) {
LOG.trace("Authorizing impersonation for dataset {}", name);
if (effectiveOwner != null) {
accessEnforcer.enforce(effectiveOwner, requestingUser, AccessPermission.SET_OWNER);
}
accessEnforcer.enforce(datasetId, requestingUser, StandardPermission.CREATE);
LOG.trace("Authorized impersonation for dataset {}", name);
}
LOG.trace("Ensuring existence of namespace {} for dataset {}", namespace, name);
ensureNamespaceExists(namespace);
LOG.trace("Ensured existence of namespace {} for dataset {}", namespace, name);
LOG.trace("Retrieving instance metadata from MDS for dataset {}", name);
DatasetSpecification existing = instanceManager.get(datasetId);
if (existing != null) {
throw new DatasetAlreadyExistsException(datasetId);
}
LOG.trace("Retrieved instance metadata from MDS for dataset {}", name);
// for creation, we need enforcement for dataset type for user dataset, but bypass for system datasets
DatasetTypeMeta typeMeta = getTypeInfo(namespace, props.getTypeName(), !DatasetsUtil.isUserDataset(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) {
LOG.trace("Adding owner for dataset {}", name);
KerberosPrincipalId owner = new KerberosPrincipalId(ownerPrincipal);
ownerAdmin.add(datasetId, owner);
LOG.trace("Added owner {} for dataset {}", owner, name);
}
try {
DatasetProperties datasetProperties = DatasetProperties.builder().addAll(props.getProperties()).setDescription(props.getDescription()).build();
LOG.trace("Calling op executor service to configure dataset {}", name);
DatasetCreationResponse response = opExecutorClient.create(datasetId, typeMeta, datasetProperties);
LOG.trace("Received spec and metadata from op executor service for dataset {}: {}", name, response);
LOG.trace("Adding instance metadata for dataset {}", name);
DatasetSpecification spec = response.getSpec();
instanceManager.add(namespace, spec);
LOG.trace("Added instance metadata for dataset {}", name);
metaCache.invalidate(datasetId);
LOG.trace("Publishing audit for creation of dataset {}", name);
publishAudit(datasetId, AuditType.CREATE);
LOG.trace("Published audit for creation of dataset {}", name);
SystemMetadata metadata = response.getMetadata();
LOG.trace("Publishing system metadata for creation of dataset {}: {}", name, metadata);
publishMetadata(datasetId, metadata);
LOG.trace("Published system metadata for creation of dataset {}", name);
// 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;
}
}
Aggregations