use of co.cask.cdap.proto.security.Principal in project cdap by caskdata.
the class AuthorizationDatasetTypeService method deleteAll.
@Override
public void deleteAll(NamespaceId namespaceId) throws Exception {
Principal principal = authenticationContext.getPrincipal();
for (DatasetModuleMeta meta : delegate.listModules(namespaceId)) {
DatasetModuleId datasetModuleId = namespaceId.datasetModule(meta.getName());
authorizationEnforcer.enforce(datasetModuleId, principal, Action.ADMIN);
}
delegate.deleteAll(namespaceId);
}
use of co.cask.cdap.proto.security.Principal 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;
}
}
use of co.cask.cdap.proto.security.Principal in project cdap by caskdata.
the class DatasetInstanceService method dropAll.
/**
* Drops all datasets in the given namespace. If authorization is turned on, only datasets that the current
* principal that has {@link Action#ADMIN} privilege will be deleted
*
* @param namespaceId namespace to operate on
* @throws Exception if it fails to delete dataset
*/
void dropAll(NamespaceId namespaceId) throws Exception {
ensureNamespaceExists(namespaceId);
Principal principal = authenticationContext.getPrincipal();
Map<DatasetId, DatasetSpecification> datasets = new HashMap<>();
for (DatasetSpecification spec : instanceManager.getAll(namespaceId)) {
DatasetId datasetId = namespaceId.dataset(spec.getName());
if (!DatasetsUtil.isSystemDatasetInUserNamespace(datasetId)) {
authorizationEnforcer.enforce(datasetId, principal, Action.ADMIN);
}
datasets.put(datasetId, spec);
}
// auth check passed, we can start deleting the datasets
for (DatasetId datasetId : datasets.keySet()) {
dropDataset(datasetId, datasets.get(datasetId));
}
}
use of co.cask.cdap.proto.security.Principal in project cdap by caskdata.
the class DatasetInstanceService method executeAdmin.
/**
* Executes an admin operation on a dataset instance.
*
* @param instance the instance to execute the admin operation on
* @param method the type of admin operation to execute
* @return the {@link DatasetAdminOpResponse} from the HTTP handler
* @throws NamespaceNotFoundException if the requested namespace was not found
* @throws IOException if there was a problem in checking if the namespace exists over HTTP
* @throws UnauthorizedException if perimeter security and authorization are enabled, and the current user does not
* have -
* <ol>
* <li>{@link Action#ADMIN} privileges on the #instance (for "drop" or "truncate") </li>
* <li>any privileges on the #instance (for "exists")</li>
* <ol>
*/
DatasetAdminOpResponse executeAdmin(DatasetId instance, String method) throws Exception {
ensureNamespaceExists(instance.getParent());
Object result = null;
// NOTE: one cannot directly call create and drop, instead this should be called thru
// POST/DELETE @ /data/datasets/{instance-id}. Because we must create/drop metadata for these at same time
Principal principal = authenticationContext.getPrincipal();
switch(method) {
case "exists":
// ensure the user has some privilege on the dataset instance if it is not system dataset
if (!DatasetsUtil.isSystemDatasetInUserNamespace(instance)) {
AuthorizationUtil.ensureAccess(instance, authorizationEnforcer, principal);
}
result = opExecutorClient.exists(instance);
break;
case "truncate":
if (!DatasetsUtil.isSystemDatasetInUserNamespace(instance)) {
authorizationEnforcer.enforce(instance, principal, Action.ADMIN);
}
if (instanceManager.get(instance) == null) {
throw new DatasetNotFoundException(instance);
}
opExecutorClient.truncate(instance);
publishAudit(instance, AuditType.TRUNCATE);
break;
case "upgrade":
if (!DatasetsUtil.isSystemDatasetInUserNamespace(instance)) {
authorizationEnforcer.enforce(instance, principal, Action.ADMIN);
}
if (instanceManager.get(instance) == null) {
throw new DatasetNotFoundException(instance);
}
opExecutorClient.upgrade(instance);
publishAudit(instance, AuditType.UPDATE);
break;
default:
throw new HandlerException(HttpResponseStatus.NOT_FOUND, "Invalid admin operation: " + method);
}
return new DatasetAdminOpResponse(result, null);
}
use of co.cask.cdap.proto.security.Principal in project cdap by caskdata.
the class DefaultNamespaceAdmin method create.
/**
* Creates a new namespace
*
* @param metadata the {@link NamespaceMeta} for the new namespace to be created
* @throws NamespaceAlreadyExistsException if the specified namespace already exists
*/
@Override
public synchronized void create(final NamespaceMeta metadata) throws Exception {
// TODO: CDAP-1427 - This should be transactional, but we don't support transactions on files yet
Preconditions.checkArgument(metadata != null, "Namespace metadata should not be null.");
NamespaceId namespace = metadata.getNamespaceId();
if (exists(namespace)) {
throw new NamespaceAlreadyExistsException(namespace);
}
// need to enforce on the principal id if impersonation is involved
String ownerPrincipal = metadata.getConfig().getPrincipal();
Principal requestingUser = authenticationContext.getPrincipal();
if (ownerPrincipal != null) {
authorizationEnforcer.enforce(new KerberosPrincipalId(ownerPrincipal), requestingUser, Action.ADMIN);
}
authorizationEnforcer.enforce(namespace, requestingUser, Action.ADMIN);
// If this namespace has custom mapping then validate the given custom mapping
if (hasCustomMapping(metadata)) {
validateCustomMapping(metadata);
}
// check that the user has configured either both of none of the following configuration: principal and keytab URI
boolean hasValidKerberosConf = false;
if (metadata.getConfig() != null) {
String configuredPrincipal = metadata.getConfig().getPrincipal();
String configuredKeytabURI = metadata.getConfig().getKeytabURI();
if ((!Strings.isNullOrEmpty(configuredPrincipal) && Strings.isNullOrEmpty(configuredKeytabURI)) || (Strings.isNullOrEmpty(configuredPrincipal) && !Strings.isNullOrEmpty(configuredKeytabURI))) {
throw new BadRequestException(String.format("Either neither or both of the following two configurations must be configured. " + "Configured principal: %s, Configured keytabURI: %s", configuredPrincipal, configuredKeytabURI));
}
hasValidKerberosConf = true;
}
// check that if explore as principal is explicitly set to false then user has kerberos configuration
if (!metadata.getConfig().isExploreAsPrincipal() && !hasValidKerberosConf) {
throw new BadRequestException(String.format("No kerberos principal or keytab-uri was provided while '%s' was set to true.", NamespaceConfig.EXPLORE_AS_PRINCIPAL));
}
// store the meta first in the namespace store because namespacedLocationFactory needs to look up location
// mapping from namespace config
nsStore.create(metadata);
try {
UserGroupInformation ugi;
if (NamespaceId.DEFAULT.equals(namespace)) {
ugi = UserGroupInformation.getCurrentUser();
} else {
ugi = impersonator.getUGI(namespace);
}
ImpersonationUtils.doAs(ugi, new Callable<Void>() {
@Override
public Void call() throws Exception {
storageProviderNamespaceAdmin.get().create(metadata);
return null;
}
});
} catch (Throwable t) {
// failed to create namespace in underlying storage so delete the namespace meta stored in the store earlier
deleteNamespaceMeta(metadata.getNamespaceId());
throw new NamespaceCannotBeCreatedException(namespace, t);
}
LOG.info("Namespace {} created with meta {}", metadata.getNamespaceId(), metadata);
}
Aggregations