Search in sources :

Example 1 with Capability

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

the class RolesToGrantsMigration method migrateRoleToGrant.

private Set<String> migrateRoleToGrant(MigratableRole migratableRole) {
    final Set<String> migratedRolePermissions = new HashSet<>();
    final Collection<User> allRoleUsers = userService.loadAllForRole(migratableRole.role);
    migratableRole.migratableEntities.forEach((entityID, permissions) -> {
        final GrantsMetaMigration.GRNTypeCapability grnTypeCapability = MIGRATION_MAP.get(permissions);
        // Permissions are mappable to a grant
        if (grnTypeCapability != null) {
            final Capability capability = grnTypeCapability.capability;
            final GRNType grnType = grnTypeCapability.grnType;
            allRoleUsers.forEach(user -> {
                dbGrantService.ensure(grnRegistry.ofUser(user), capability, grnType.toGRN(entityID), rootUsername);
                LOG.info("Migrating entity <{}> permissions <{}> to <{}> grant for user <{}>", grnType.toGRN(entityID), permissions, capability, user.getName());
            });
            migratedRolePermissions.addAll(permissions.stream().map(p -> p + ":" + entityID).collect(Collectors.toSet()));
        } else {
            LOG.info("Skipping non-migratable entity <{}>. Permissions <{}> cannot be converted to a grant capability", entityID, permissions);
        }
    });
    return migratedRolePermissions;
}
Also used : User(org.graylog2.plugin.database.users.User) Capability(org.graylog.security.Capability) GRNType(org.graylog.grn.GRNType) HashSet(java.util.HashSet)

Example 2 with Capability

use of org.graylog.security.Capability 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 3 with Capability

use of org.graylog.security.Capability 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)

Example 4 with Capability

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

the class UserPermissionsToGrantsMigration method migrateUserPermissions.

private void migrateUserPermissions(User user, Map<String, Set<String>> migratableEntities) {
    migratableEntities.forEach((entityID, permissions) -> {
        final GRNTypeCapability grnTypeCapability = GrantsMetaMigration.MIGRATION_MAP.get(permissions);
        // Permissions are mappable to a grant
        if (grnTypeCapability != null) {
            final Capability capability = grnTypeCapability.capability;
            GRN targetGRN;
            if (permissions.stream().anyMatch(p -> p.contains(VIEW_READ))) {
                // For views we need to load the database object to be able to determine if it's a
                // search or a dashboard.
                targetGRN = getViewGRNType(entityID).map(grnType -> grnType.toGRN(entityID)).orElse(null);
            } else {
                targetGRN = requireNonNull(grnTypeCapability.grnType, "grnType cannot be null - this is a bug").toGRN(entityID);
            }
            if (targetGRN != null) {
                dbGrantService.ensure(grnRegistry.ofUser(user), capability, targetGRN, rootUsername);
            }
            final List<String> updatedPermissions = user.getPermissions();
            updatedPermissions.removeAll(permissions.stream().map(p -> p + ":" + entityID).collect(Collectors.toSet()));
            user.setPermissions(updatedPermissions);
            try {
                userService.save(user);
            } catch (ValidationException e) {
                LOG.error("Failed to update permssions on user <{}>", user.getName(), e);
            }
            LOG.info("Migrating entity <{}> permissions <{}> to <{}> grant for user <{}>", targetGRN, permissions, capability, user.getName());
        } else {
            LOG.info("Skipping non-migratable entity <{}>. Permissions <{}> cannot be converted to a grant capability", entityID, permissions);
        }
    });
}
Also used : GRN(org.graylog.grn.GRN) ValidationException(org.graylog2.plugin.database.ValidationException) Capability(org.graylog.security.Capability) GRNTypeCapability(org.graylog2.migrations.V20200803120800_GrantsMigrations.GrantsMetaMigration.GRNTypeCapability) GRNTypeCapability(org.graylog2.migrations.V20200803120800_GrantsMigrations.GrantsMetaMigration.GRNTypeCapability)

Aggregations

Capability (org.graylog.security.Capability)4 GRN (org.graylog.grn.GRN)3 User (org.graylog2.plugin.database.users.User)3 ImmutableMap (com.google.common.collect.ImmutableMap)2 ImmutableSet (com.google.common.collect.ImmutableSet)2 EventBus (com.google.common.eventbus.EventBus)2 ZoneOffset (java.time.ZoneOffset)2 ZonedDateTime (java.time.ZonedDateTime)2 ArrayList (java.util.ArrayList)2 Collection (java.util.Collection)2 List (java.util.List)2 Locale (java.util.Locale)2 Map (java.util.Map)2 Objects (java.util.Objects)2 Objects.requireNonNull (java.util.Objects.requireNonNull)2 Set (java.util.Set)2 Collectors (java.util.stream.Collectors)2 Inject (javax.inject.Inject)2 Subject (org.apache.shiro.subject.Subject)2 GRNRegistry (org.graylog.grn.GRNRegistry)2