Search in sources :

Example 51 with Principal

use of co.cask.cdap.proto.security.Principal in project cdap by caskdata.

the class DatasetTypeService method deleteAll.

/**
   * Deletes all {@link DatasetModuleMeta dataset modules} in the specified {@link NamespaceId namespace}.
   */
void deleteAll(NamespaceId namespaceId) throws Exception {
    Principal principal = authenticationContext.getPrincipal();
    authorizationEnforcer.enforce(namespaceId, principal, Action.ADMIN);
    if (NamespaceId.SYSTEM.equals(namespaceId)) {
        throw new UnauthorizedException(String.format("Cannot delete modules from '%s' namespace.", namespaceId));
    }
    ensureNamespaceExists(namespaceId);
    // revoke all privileges on all modules
    for (DatasetModuleMeta meta : typeManager.getModules(namespaceId)) {
        privilegesManager.revoke(namespaceId.datasetModule(meta.getName()));
    }
    try {
        typeManager.deleteModules(namespaceId);
    } catch (DatasetModuleConflictException e) {
        throw new ConflictException(e.getMessage(), e);
    }
}
Also used : DatasetModuleConflictException(co.cask.cdap.data2.datafabric.dataset.type.DatasetModuleConflictException) DatasetModuleMeta(co.cask.cdap.proto.DatasetModuleMeta) ConflictException(co.cask.cdap.common.ConflictException) DatasetModuleConflictException(co.cask.cdap.data2.datafabric.dataset.type.DatasetModuleConflictException) UnauthorizedException(co.cask.cdap.security.spi.authorization.UnauthorizedException) Principal(co.cask.cdap.proto.security.Principal)

Example 52 with Principal

use of co.cask.cdap.proto.security.Principal in project cdap by caskdata.

the class DatasetTypeService method addModule.

/**
   * Adds a new {@link DatasetModule}.
   *
   * @param datasetModuleId the {@link DatasetModuleId} for the module to be added
   * @param className the module class name specified in the HTTP header
   * @param forceUpdate if true, an update will be allowed even if there are conflicts with other modules, or if
   *                     removal of a type would break other modules' dependencies
   * @return a {@link BodyConsumer} to upload the module jar in chunks
   * @throws NotFoundException if the namespace in which the module is being added is not found
   * @throws IOException if there are issues while performing I/O like creating temporary directories, moving/unpacking
   *                      module jar files
   * @throws DatasetModuleConflictException if #forceUpdate is {@code false}, and there are conflicts with other modules
   */
BodyConsumer addModule(final DatasetModuleId datasetModuleId, final String className, final boolean forceUpdate) throws Exception {
    NamespaceId namespaceId = datasetModuleId.getParent();
    final Principal principal = authenticationContext.getPrincipal();
    // enforce that the principal has WRITE access on the namespace
    authorizationEnforcer.enforce(namespaceId, principal, Action.WRITE);
    if (NamespaceId.SYSTEM.equals(namespaceId)) {
        throw new UnauthorizedException(String.format("Cannot add module '%s' to '%s' namespace.", datasetModuleId.getModule(), datasetModuleId.getNamespace()));
    }
    ensureNamespaceExists(namespaceId);
    // It is now determined that a new dataset module will be deployed. First grant privileges, then deploy the module.
    // If creation fails, revoke the granted privileges. This ensures that just like delete, there may be orphaned
    // privileges in rare scenarios, but there can never be orphaned datasets.
    // If the module previously existed and was deleted, but revoking privileges somehow failed, there may be orphaned
    // privileges for the module. Revoke them first, so no users unintentionally get privileges on the dataset.
    revokeAllPrivilegesOnModule(datasetModuleId);
    grantAllPrivilegesOnModule(datasetModuleId, principal);
    try {
        return createModuleConsumer(datasetModuleId, className, forceUpdate, principal);
    } catch (Exception e) {
        revokeAllPrivilegesOnModule(datasetModuleId);
        throw e;
    }
}
Also used : UnauthorizedException(co.cask.cdap.security.spi.authorization.UnauthorizedException) NamespaceId(co.cask.cdap.proto.id.NamespaceId) Principal(co.cask.cdap.proto.security.Principal) NamespaceNotFoundException(co.cask.cdap.common.NamespaceNotFoundException) ConflictException(co.cask.cdap.common.ConflictException) DatasetModuleConflictException(co.cask.cdap.data2.datafabric.dataset.type.DatasetModuleConflictException) DatasetTypeNotFoundException(co.cask.cdap.common.DatasetTypeNotFoundException) UnauthorizedException(co.cask.cdap.security.spi.authorization.UnauthorizedException) DatasetModuleNotFoundException(co.cask.cdap.common.DatasetModuleNotFoundException) IOException(java.io.IOException) DatasetModuleCannotBeDeletedException(co.cask.cdap.common.DatasetModuleCannotBeDeletedException) NotFoundException(co.cask.cdap.common.NotFoundException)

Example 53 with Principal

use of co.cask.cdap.proto.security.Principal in project cdap by caskdata.

the class DatasetTypeService method delete.

/**
   * Deletes the specified {@link DatasetModuleId}
   */
void delete(DatasetModuleId datasetModuleId) throws Exception {
    NamespaceId namespaceId = datasetModuleId.getParent();
    if (NamespaceId.SYSTEM.equals(namespaceId)) {
        throw new UnauthorizedException(String.format("Cannot delete module '%s' from '%s' namespace.", datasetModuleId.getModule(), datasetModuleId.getNamespace()));
    }
    ensureNamespaceExists(namespaceId);
    DatasetModuleMeta moduleMeta = typeManager.getModule(datasetModuleId);
    if (moduleMeta == null) {
        throw new DatasetModuleNotFoundException(datasetModuleId);
    }
    Principal principal = authenticationContext.getPrincipal();
    authorizationEnforcer.enforce(datasetModuleId, principal, Action.ADMIN);
    try {
        typeManager.deleteModule(datasetModuleId);
    } catch (DatasetModuleConflictException e) {
        throw new DatasetModuleCannotBeDeletedException(datasetModuleId, e.getMessage());
    }
    // revoke all privileges on the module to be deleted
    revokeAllPrivilegesOnModule(datasetModuleId, moduleMeta);
}
Also used : DatasetModuleNotFoundException(co.cask.cdap.common.DatasetModuleNotFoundException) DatasetModuleConflictException(co.cask.cdap.data2.datafabric.dataset.type.DatasetModuleConflictException) DatasetModuleMeta(co.cask.cdap.proto.DatasetModuleMeta) UnauthorizedException(co.cask.cdap.security.spi.authorization.UnauthorizedException) NamespaceId(co.cask.cdap.proto.id.NamespaceId) DatasetModuleCannotBeDeletedException(co.cask.cdap.common.DatasetModuleCannotBeDeletedException) Principal(co.cask.cdap.proto.security.Principal)

Example 54 with Principal

use of co.cask.cdap.proto.security.Principal in project cdap by caskdata.

the class ArtifactRepository method addSystemArtifacts.

/**
   * Scan all files in the local system artifact directory, looking for jar files and adding them as system artifacts.
   * If the artifact already exists it will not be added again unless it is a snapshot version.
   *
   * @throws IOException if there was some IO error adding the system artifacts
   */
public void addSystemArtifacts() throws Exception {
    // to add system artifacts, users should have write privileges on the system namespace
    Principal principal = authenticationContext.getPrincipal();
    authorizationEnforcer.enforce(NamespaceId.SYSTEM, principal, Action.WRITE);
    // scan the directory for artifact .jar files and config files for those artifacts
    List<SystemArtifactInfo> systemArtifacts = new ArrayList<>();
    for (File systemArtifactDir : systemArtifactDirs) {
        for (File jarFile : DirUtils.listFiles(systemArtifactDir, "jar")) {
            // parse id from filename
            Id.Artifact artifactId;
            try {
                artifactId = Id.Artifact.parse(Id.Namespace.SYSTEM, jarFile.getName());
            } catch (IllegalArgumentException e) {
                LOG.warn(String.format("Skipping system artifact '%s' because the name is invalid: ", e.getMessage()));
                continue;
            }
            // first revoke any orphane privileges
            co.cask.cdap.proto.id.ArtifactId artifact = artifactId.toEntityId();
            privilegesManager.revoke(artifact);
            // then grant all on the artifact
            privilegesManager.grant(artifact, principal, EnumSet.allOf(Action.class));
            // check for a corresponding .json config file
            String artifactFileName = jarFile.getName();
            String configFileName = artifactFileName.substring(0, artifactFileName.length() - ".jar".length()) + ".json";
            File configFile = new File(systemArtifactDir, configFileName);
            try {
                // read and parse the config file if it exists. Otherwise use an empty config with the artifact filename
                ArtifactConfig artifactConfig = configFile.isFile() ? configReader.read(artifactId.getNamespace(), configFile) : new ArtifactConfig();
                validateParentSet(artifactId, artifactConfig.getParents());
                validatePluginSet(artifactConfig.getPlugins());
                systemArtifacts.add(new SystemArtifactInfo(artifactId, jarFile, artifactConfig));
            } catch (InvalidArtifactException e) {
                LOG.warn(String.format("Could not add system artifact '%s' because it is invalid.", artifactFileName), e);
                // since adding artifact failed, revoke privileges, since they may be orphane now
                privilegesManager.revoke(artifact);
            }
        }
    }
    // taking advantage of the fact that we only have 1 level of dependencies
    // so we can add all the parents first, then we know its safe to add everything else
    // add all parents
    Set<Id.Artifact> parents = new HashSet<>();
    for (SystemArtifactInfo child : systemArtifacts) {
        Id.Artifact childId = child.getArtifactId();
        for (SystemArtifactInfo potentialParent : systemArtifacts) {
            Id.Artifact potentialParentId = potentialParent.getArtifactId();
            // skip if we're looking at ourselves
            if (childId.equals(potentialParentId)) {
                continue;
            }
            if (child.getConfig().hasParent(potentialParentId)) {
                parents.add(potentialParentId);
            }
        }
    }
    // add all parents first
    for (SystemArtifactInfo systemArtifact : systemArtifacts) {
        if (parents.contains(systemArtifact.getArtifactId())) {
            addSystemArtifact(systemArtifact);
        }
    }
    // add children next
    for (SystemArtifactInfo systemArtifact : systemArtifacts) {
        if (!parents.contains(systemArtifact.getArtifactId())) {
            addSystemArtifact(systemArtifact);
        }
    }
}
Also used : Action(co.cask.cdap.proto.security.Action) ArtifactConfig(co.cask.cdap.common.conf.ArtifactConfig) ArrayList(java.util.ArrayList) ArtifactId(co.cask.cdap.api.artifact.ArtifactId) Id(co.cask.cdap.proto.Id) NamespaceId(co.cask.cdap.proto.id.NamespaceId) EntityId(co.cask.cdap.proto.id.EntityId) File(java.io.File) Principal(co.cask.cdap.proto.security.Principal) InvalidArtifactException(co.cask.cdap.common.InvalidArtifactException) HashSet(java.util.HashSet)

Example 55 with Principal

use of co.cask.cdap.proto.security.Principal in project cdap by caskdata.

the class ArtifactRepository method deleteArtifact.

/**
   * Delete the specified artifact. Programs that use the artifact will not be able to start.
   *
   * @param artifactId the artifact to delete
   * @throws IOException if there was some IO error deleting the artifact
   * @throws ArtifactNotFoundException if the given artifact does not exist
   * @throws UnauthorizedException if the current user is not authorized to delete the artifact. To delete an artifact,
   *                               a user needs {@link Action#ADMIN} permission on the artifact.
   */
public void deleteArtifact(Id.Artifact artifactId) throws Exception {
    // for deleting artifacts, users need admin privileges on the artifact being deleted.
    Principal principal = authenticationContext.getPrincipal();
    authorizationEnforcer.enforce(artifactId.toEntityId(), principal, Action.ADMIN);
    // delete the artifact first and then privileges. Not the other way to avoid orphan artifact
    // which does not have any privilege if the artifact delete from store fails. see CDAP-6648
    artifactStore.delete(artifactId);
    metadataStore.removeMetadata(artifactId.toEntityId());
    // revoke all privileges on the artifact
    privilegesManager.revoke(artifactId.toEntityId());
}
Also used : Principal(co.cask.cdap.proto.security.Principal)

Aggregations

Principal (co.cask.cdap.proto.security.Principal)58 EntityId (co.cask.cdap.proto.id.EntityId)24 UnauthorizedException (co.cask.cdap.security.spi.authorization.UnauthorizedException)16 Action (co.cask.cdap.proto.security.Action)14 NamespaceId (co.cask.cdap.proto.id.NamespaceId)11 Test (org.junit.Test)9 Role (co.cask.cdap.proto.security.Role)8 IOException (java.io.IOException)8 Path (javax.ws.rs.Path)7 Predicate (co.cask.cdap.api.Predicate)5 HashSet (java.util.HashSet)5 NamespaceNotFoundException (co.cask.cdap.common.NamespaceNotFoundException)4 DatasetModuleMeta (co.cask.cdap.proto.DatasetModuleMeta)4 SecureKeyId (co.cask.cdap.proto.id.SecureKeyId)4 ArtifactId (co.cask.cdap.api.artifact.ArtifactId)3 DatasetManagementException (co.cask.cdap.api.dataset.DatasetManagementException)3 DatasetSpecification (co.cask.cdap.api.dataset.DatasetSpecification)3 DatasetModuleNotFoundException (co.cask.cdap.common.DatasetModuleNotFoundException)3 DatasetModuleConflictException (co.cask.cdap.data2.datafabric.dataset.type.DatasetModuleConflictException)3 DatasetTypeMeta (co.cask.cdap.proto.DatasetTypeMeta)3