Search in sources :

Example 6 with GrantDTO

use of org.graylog.security.GrantDTO in project graylog2-server by Graylog2.

the class EntitySharesService method updateEntityShares.

/**
 * Share / unshare an entity with one or more grantees.
 * The grants in the request are created or, if they already exist, updated.
 *
 * @param ownedEntity the target entity for the updated grants
 * @param request     the request containing grantees and their capabilities
 * @param sharingUser the user executing the request
 */
public EntityShareResponse updateEntityShares(GRN ownedEntity, EntityShareRequest request, User sharingUser) {
    requireNonNull(ownedEntity, "ownedEntity cannot be null");
    requireNonNull(request, "request cannot be null");
    requireNonNull(sharingUser, "sharingUser cannot be null");
    final ImmutableMap<GRN, Capability> selectedGranteeCapabilities = request.selectedGranteeCapabilities().orElse(ImmutableMap.of());
    final String userName = sharingUser.getName();
    final GRN sharingUserGRN = grnRegistry.ofUser(sharingUser);
    final Set<Grantee> availableGrantees = granteeService.getAvailableGrantees(sharingUser);
    final Set<GRN> availableGranteeGRNs = availableGrantees.stream().map(Grantee::grn).collect(Collectors.toSet());
    final List<GrantDTO> existingGrants = grantService.getForTargetExcludingGrantee(ownedEntity, sharingUserGRN);
    existingGrants.removeIf(grant -> !availableGranteeGRNs.contains(grant.grantee()));
    final EntityShareResponse.Builder responseBuilder = EntityShareResponse.builder().entity(ownedEntity.toString()).sharingUser(sharingUserGRN).availableGrantees(availableGrantees).availableCapabilities(getAvailableCapabilities()).missingPermissionsOnDependencies(checkMissingPermissionsOnDependencies(ownedEntity, sharingUserGRN, ImmutableSet.of(), request));
    final EntitySharesUpdateEvent.Builder updateEventBuilder = EntitySharesUpdateEvent.builder().user(sharingUser).entity(ownedEntity);
    // Abort if validation fails, but try to return a complete EntityShareResponse
    final ValidationResult validationResult = validateRequest(ownedEntity, request, sharingUser, availableGranteeGRNs);
    if (validationResult.failed()) {
        final ImmutableSet<ActiveShare> activeShares = getActiveShares(ownedEntity, sharingUser, availableGranteeGRNs);
        return responseBuilder.activeShares(activeShares).selectedGranteeCapabilities(getSelectedGranteeCapabilities(activeShares, request)).validationResult(validationResult).build();
    }
    // Update capabilities of existing grants (for a grantee)
    existingGrants.stream().filter(grantDTO -> request.grantees().contains(grantDTO.grantee())).forEach((g -> {
        final Capability newCapability = selectedGranteeCapabilities.get(g.grantee());
        if (!g.capability().equals(newCapability)) {
            grantService.save(g.toBuilder().capability(newCapability).updatedBy(userName).updatedAt(ZonedDateTime.now(ZoneOffset.UTC)).build());
            updateEventBuilder.addUpdates(g.grantee(), newCapability, g.capability());
        }
    }));
    // Create newly added grants
    // TODO Create multiple entries with one db query
    selectedGranteeCapabilities.forEach((grantee, capability) -> {
        if (existingGrants.stream().noneMatch(eg -> eg.grantee().equals(grantee))) {
            grantService.create(GrantDTO.builder().grantee(grantee).capability(capability).target(ownedEntity).build(), sharingUser);
            updateEventBuilder.addCreates(grantee, capability);
        }
    });
    // remove grants that are not present anymore
    // TODO delete multiple entries with one db query
    existingGrants.forEach((g) -> {
        if (!selectedGranteeCapabilities.containsKey(g.grantee())) {
            grantService.delete(g.id());
            updateEventBuilder.addDeletes(g.grantee(), g.capability());
        }
    });
    postUpdateEvent(updateEventBuilder.build());
    final ImmutableSet<ActiveShare> activeShares = getActiveShares(ownedEntity, sharingUser, availableGranteeGRNs);
    return responseBuilder.activeShares(activeShares).selectedGranteeCapabilities(getSelectedGranteeCapabilities(activeShares, request)).build();
}
Also used : GrantDTO(org.graylog.security.GrantDTO) EntityDependencyPermissionChecker(org.graylog.security.entities.EntityDependencyPermissionChecker) BuiltinCapabilities(org.graylog.security.BuiltinCapabilities) Capability(org.graylog.security.Capability) ZonedDateTime(java.time.ZonedDateTime) GRNRegistry(org.graylog.grn.GRNRegistry) ArrayList(java.util.ArrayList) EventBus(com.google.common.eventbus.EventBus) Inject(javax.inject.Inject) DBGrantService(org.graylog.security.DBGrantService) GrantDTO(org.graylog.security.GrantDTO) Subject(org.apache.shiro.subject.Subject) Locale(java.util.Locale) Map(java.util.Map) Objects.requireNonNull(java.util.Objects.requireNonNull) ZoneOffset(java.time.ZoneOffset) ImmutableSet(com.google.common.collect.ImmutableSet) EntityDependencyResolver(org.graylog.security.entities.EntityDependencyResolver) ImmutableMap(com.google.common.collect.ImmutableMap) Collection(java.util.Collection) Set(java.util.Set) ActiveShare(org.graylog.security.shares.EntityShareResponse.ActiveShare) Collectors(java.util.stream.Collectors) GRN(org.graylog.grn.GRN) Objects(java.util.Objects) List(java.util.List) EntityDescriptor(org.graylog.security.entities.EntityDescriptor) EntitySharesUpdateEvent(org.graylog.security.events.EntitySharesUpdateEvent) ValidationResult(org.graylog2.plugin.rest.ValidationResult) User(org.graylog2.plugin.database.users.User) AvailableCapability(org.graylog.security.shares.EntityShareResponse.AvailableCapability) GRN(org.graylog.grn.GRN) Capability(org.graylog.security.Capability) AvailableCapability(org.graylog.security.shares.EntityShareResponse.AvailableCapability) ActiveShare(org.graylog.security.shares.EntityShareResponse.ActiveShare) ValidationResult(org.graylog2.plugin.rest.ValidationResult) EntitySharesUpdateEvent(org.graylog.security.events.EntitySharesUpdateEvent)

Example 7 with GrantDTO

use of org.graylog.security.GrantDTO in project graylog2-server by Graylog2.

the class EntitySharesService method validateRequest.

private ValidationResult validateRequest(GRN ownedEntity, EntityShareRequest request, User sharingUser, Set<GRN> availableGranteeGRNs) {
    final ValidationResult validationResult = new ValidationResult();
    final List<GrantDTO> allEntityGrants = grantService.getForTarget(ownedEntity);
    final List<GrantDTO> existingGrants = grantService.getForTargetExcludingGrantee(ownedEntity, grnRegistry.ofUser(sharingUser));
    // The initial request doesn't submit a grantee selection. Just return.
    if (!request.selectedGranteeCapabilities().isPresent()) {
        return validationResult;
    }
    final ImmutableMap<GRN, Capability> selectedGranteeCapabilities = request.selectedGranteeCapabilities().get();
    // If there is still an owner in the selection, everything is fine
    if (selectedGranteeCapabilities.containsValue(Capability.OWN)) {
        return validationResult;
    }
    // If this entity is already ownerless, things can't get any worse. Let this request pass.
    if (allEntityGrants.stream().noneMatch(g -> g.capability().equals(Capability.OWN))) {
        return validationResult;
    }
    // Iterate over all existing owner grants and find modifications
    ArrayList<GRN> removedOwners = new ArrayList<>();
    existingGrants.stream().filter(g -> g.capability().equals(Capability.OWN)).forEach((g) -> {
        // owner got removed
        if (!selectedGranteeCapabilities.containsKey(g.grantee())) {
            // Ignore owners that were invisible to the requesting user
            if (availableGranteeGRNs.contains(g.grantee())) {
                removedOwners.add(g.grantee());
            }
        // owner capability got changed
        } else if (!selectedGranteeCapabilities.get(g.grantee()).equals(Capability.OWN)) {
            removedOwners.add(g.grantee());
        }
    });
    // If all removedOwners are applied, is there still at least one owner left?
    if (allEntityGrants.stream().filter(g -> g.capability().equals(Capability.OWN)).map(GrantDTO::grantee).anyMatch(grantee -> !removedOwners.contains(grantee))) {
        return validationResult;
    }
    validationResult.addError(EntityShareRequest.SELECTED_GRANTEE_CAPABILITIES, String.format(Locale.US, "Removing the following owners <%s> will leave the entity ownerless.", removedOwners));
    // Also return the grantees as list to be used by the frontend
    validationResult.addContext(EntityShareRequest.SELECTED_GRANTEE_CAPABILITIES, removedOwners.stream().map(Objects::toString).collect(Collectors.toSet()));
    return validationResult;
}
Also used : GrantDTO(org.graylog.security.GrantDTO) EntityDependencyPermissionChecker(org.graylog.security.entities.EntityDependencyPermissionChecker) BuiltinCapabilities(org.graylog.security.BuiltinCapabilities) Capability(org.graylog.security.Capability) ZonedDateTime(java.time.ZonedDateTime) GRNRegistry(org.graylog.grn.GRNRegistry) ArrayList(java.util.ArrayList) EventBus(com.google.common.eventbus.EventBus) Inject(javax.inject.Inject) DBGrantService(org.graylog.security.DBGrantService) GrantDTO(org.graylog.security.GrantDTO) Subject(org.apache.shiro.subject.Subject) Locale(java.util.Locale) Map(java.util.Map) Objects.requireNonNull(java.util.Objects.requireNonNull) ZoneOffset(java.time.ZoneOffset) ImmutableSet(com.google.common.collect.ImmutableSet) EntityDependencyResolver(org.graylog.security.entities.EntityDependencyResolver) ImmutableMap(com.google.common.collect.ImmutableMap) Collection(java.util.Collection) Set(java.util.Set) ActiveShare(org.graylog.security.shares.EntityShareResponse.ActiveShare) Collectors(java.util.stream.Collectors) GRN(org.graylog.grn.GRN) Objects(java.util.Objects) List(java.util.List) EntityDescriptor(org.graylog.security.entities.EntityDescriptor) EntitySharesUpdateEvent(org.graylog.security.events.EntitySharesUpdateEvent) ValidationResult(org.graylog2.plugin.rest.ValidationResult) User(org.graylog2.plugin.database.users.User) AvailableCapability(org.graylog.security.shares.EntityShareResponse.AvailableCapability) GRN(org.graylog.grn.GRN) Capability(org.graylog.security.Capability) AvailableCapability(org.graylog.security.shares.EntityShareResponse.AvailableCapability) ArrayList(java.util.ArrayList) Objects(java.util.Objects) ValidationResult(org.graylog2.plugin.rest.ValidationResult)

Aggregations

GrantDTO (org.graylog.security.GrantDTO)7 User (org.graylog2.plugin.database.users.User)7 Test (org.junit.jupiter.api.Test)5 ImmutableMap (com.google.common.collect.ImmutableMap)3 ImmutableSet (com.google.common.collect.ImmutableSet)3 EventBus (com.google.common.eventbus.EventBus)3 Set (java.util.Set)3 Collectors (java.util.stream.Collectors)3 Subject (org.apache.shiro.subject.Subject)3 GRN (org.graylog.grn.GRN)3 GRNRegistry (org.graylog.grn.GRNRegistry)3 BuiltinCapabilities (org.graylog.security.BuiltinCapabilities)3 Capability (org.graylog.security.Capability)3 DBGrantService (org.graylog.security.DBGrantService)3 EntityDependencyPermissionChecker (org.graylog.security.entities.EntityDependencyPermissionChecker)3 EntityDependencyResolver (org.graylog.security.entities.EntityDependencyResolver)3 ZoneOffset (java.time.ZoneOffset)2 ZonedDateTime (java.time.ZonedDateTime)2 ArrayList (java.util.ArrayList)2 Collection (java.util.Collection)2