use of org.graylog2.plugin.database.validators.ValidationResult 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();
}
use of org.graylog2.plugin.database.validators.ValidationResult 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;
}
use of org.graylog2.plugin.database.validators.ValidationResult in project graylog2-server by Graylog2.
the class PersistedServiceImpl method save.
@Override
public <T extends Persisted> String save(T model) throws ValidationException {
Map<String, List<ValidationResult>> errors = validate(model, model.getFields());
if (!errors.isEmpty()) {
throw new ValidationException(errors);
}
BasicDBObject doc = new BasicDBObject(model.getFields());
// ID was created in constructor or taken from original doc already.
doc.put("_id", new ObjectId(model.getId()));
// Do field transformations
fieldTransformations(doc);
/*
* We are running an upsert. This means that the existing
* document will be updated if the ID already exists and
* a new document will be created if it doesn't.
*/
BasicDBObject q = new BasicDBObject("_id", new ObjectId(model.getId()));
collection(model).update(q, doc, true, false);
return model.getId();
}
use of org.graylog2.plugin.database.validators.ValidationResult in project graylog2-server by Graylog2.
the class PersistedServiceImpl method embed.
protected <T extends Persisted> void embed(T model, String key, EmbeddedPersistable o) throws ValidationException {
Map<String, List<ValidationResult>> errors = validate(model.getEmbeddedValidations(key), o.getPersistedFields());
if (!errors.isEmpty()) {
throw new ValidationException(errors);
}
Map<String, Object> fields = Maps.newHashMap(o.getPersistedFields());
fieldTransformations(fields);
BasicDBObject dbo = new BasicDBObject(fields);
collection(model).update(new BasicDBObject("_id", new ObjectId(model.getId())), new BasicDBObject("$push", new BasicDBObject(key, dbo)));
}
use of org.graylog2.plugin.database.validators.ValidationResult in project graylog2-server by Graylog2.
the class MigrationDashboardService method validate.
private Map<String, List<ValidationResult>> validate(Map<String, Validator> validators, Map<String, Object> fields) {
if (validators == null || validators.isEmpty()) {
return Collections.emptyMap();
}
final Map<String, List<ValidationResult>> validationErrors = new HashMap<>();
for (Map.Entry<String, Validator> validation : validators.entrySet()) {
Validator v = validation.getValue();
String field = validation.getKey();
try {
ValidationResult validationResult = v.validate(fields.get(field));
if (validationResult instanceof ValidationResult.ValidationFailed) {
LOG.debug("Validation failure: [{}] on field [{}]", v.getClass().getCanonicalName(), field);
validationErrors.computeIfAbsent(field, k -> new ArrayList<>());
validationErrors.get(field).add(validationResult);
}
} catch (Exception e) {
final String error = "Error while trying to validate <" + field + ">, got exception: " + e;
LOG.debug(error);
validationErrors.computeIfAbsent(field, k -> new ArrayList<>());
validationErrors.get(field).add(new ValidationResult.ValidationFailed(error));
}
}
return validationErrors;
}
Aggregations