Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -202,20 +202,15 @@ public ResponseEntity<Integer> getCasesCount(@PathVariable("userId") String user
@Header(name = "X-Permission-Error", description = "Indicates where permission check failed: PARENT_PERMISSION_DENIED, CHILD_PERMISSION_DENIED, or TARGET_PERMISSION_DENIED")
})
})
public ResponseEntity<Void> areElementsAccessible(@RequestParam("ids") List<UUID> elementUuids,
public ResponseEntity<PermissionCheckResult> areElementsAccessible(@RequestParam("ids") List<UUID> elementUuids,
@RequestParam(value = "accessType") PermissionType permissionType,
@RequestParam(value = "targetDirectoryUuid", required = false) UUID targetDirectoryUuid,
@RequestParam(value = "recursiveCheck", required = false, defaultValue = "false") boolean recursiveCheck,
@RequestHeader("userId") String userId) {
if (roleService.isUserExploreAdmin()) {
return ResponseEntity.ok().build();
}
PermissionCheckResult result = service.checkDirectoriesPermission(userId, elementUuids, targetDirectoryUuid, permissionType, recursiveCheck);
if (result == PermissionCheckResult.ALLOWED) {
return ResponseEntity.ok().build();
} else {
return ResponseEntity.status(HttpStatus.FORBIDDEN).header("X-Permission-Error", result.name()).build();
}
return ResponseEntity.ok(service.checkDirectoriesPermission(userId, elementUuids, targetDirectoryUuid, permissionType, recursiveCheck));
}

@GetMapping(value = "/directories/{directoryUuid}/permissions", produces = MediaType.APPLICATION_JSON_VALUE)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
import lombok.NonNull;

import java.util.Objects;
import java.util.UUID;

/**
* @author Abdelsalem Hedhili <abdelsalem.hedhili at rte-france.com>
Expand All @@ -19,7 +18,7 @@ public class DirectoryException extends RuntimeException {
private final Type type;

public DirectoryException(Type type) {
super(Objects.requireNonNull(type.name()));
super();
this.type = type;
}

Expand All @@ -32,10 +31,6 @@ public static DirectoryException createNotificationUnknown(@NonNull String actio
return new DirectoryException(Type.UNKNOWN_NOTIFICATION, String.format("The notification type '%s' is unknown", action));
}

public static DirectoryException createElementNotFound(@NonNull String type, @NonNull UUID uuid) {
return new DirectoryException(Type.NOT_FOUND, String.format("%s '%s' not found !", type, uuid));
}

public static DirectoryException createElementNameAlreadyExists(@NonNull String name) {
return new DirectoryException(Type.NAME_ALREADY_EXISTS, String.format("Element with the same name '%s' already exists in the directory !", name));
}
Expand All @@ -48,7 +43,6 @@ public enum Type {
NOT_ALLOWED,
NOT_FOUND,
NOT_DIRECTORY,
IS_DIRECTORY,
UNKNOWN_NOTIFICATION,
NAME_ALREADY_EXISTS,
MOVE_IN_DESCENDANT_NOT_ALLOWED,
Expand Down
102 changes: 38 additions & 64 deletions src/main/java/org/gridsuite/directory/server/DirectoryService.java
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,23 @@ public DirectoryService(DirectoryRepositoryService repositoryService,
this.roleService = roleService;
}

private DirectoryElementEntity getElementEntityOrThrow(UUID elementUuid) {
return directoryElementRepository.findById(elementUuid)
.orElseThrow(() -> new DirectoryException(NOT_FOUND, "Element %s not found".formatted(elementUuid)));
}

private void assertExistsAndIsDirectory(UUID elementUuid) {
DirectoryElementEntity elementEntity = getElementEntityOrThrow(elementUuid);
if (!elementEntity.getType().equals(DIRECTORY)) {
throw new DirectoryException(NOT_DIRECTORY);
}
}

public String getElementName(UUID elementUuid) {
DirectoryElementEntity element = getElementEntityOrThrow(elementUuid);
return element.getName();
}

//TODO: this consumer is the kept here at the moment, but it will be moved to explore server later on
@Transactional
public void studyUpdated(UUID studyUuid, String errorMessage, String userId) {
Expand All @@ -94,9 +111,9 @@ public ElementAttributes createElement(ElementAttributes elementAttributes, UUID

private ElementAttributes createElementWithNotif(ElementAttributes elementAttributes, UUID parentDirectoryUuid, String userId, boolean generateNewName) {
if (elementAttributes.getElementName().isBlank()) {
throw new DirectoryException(NOT_ALLOWED);
throw new DirectoryException(NOT_ALLOWED, "Empty name is not allowed for an element");
}
assertDirectoryExist(parentDirectoryUuid);
assertExistsAndIsDirectory(parentDirectoryUuid);
DirectoryElementEntity elementEntity = insertElement(elementAttributes, parentDirectoryUuid, userId, generateNewName);
if (DIRECTORY.equals(elementAttributes.getType())) {
insertManageUserPermission(elementEntity.getId(), userId, "");
Expand All @@ -111,7 +128,7 @@ private ElementAttributes createElementWithNotif(ElementAttributes elementAttrib
}

public ElementAttributes duplicateElement(UUID elementId, UUID newElementId, UUID targetDirectoryId, String userId) {
DirectoryElementEntity directoryElementEntity = directoryElementRepository.findById(elementId).orElseThrow(() -> new DirectoryException(NOT_FOUND));
DirectoryElementEntity directoryElementEntity = getElementEntityOrThrow(elementId);
String elementType = directoryElementEntity.getType();
UUID parentDirectoryUuid = targetDirectoryId != null ? targetDirectoryId : directoryElementEntity.getParentId();
ElementAttributes elementAttributes = ElementAttributes.builder()
Expand All @@ -122,7 +139,7 @@ public ElementAttributes duplicateElement(UUID elementId, UUID newElementId, UUI
.elementName(directoryElementEntity.getName())
.build();

assertDirectoryExist(parentDirectoryUuid);
assertExistsAndIsDirectory(parentDirectoryUuid);
DirectoryElementEntity elementEntity = insertElement(elementAttributes, parentDirectoryUuid, userId, true);

// Here we know that parentDirectoryUuid can't be null
Expand All @@ -131,18 +148,6 @@ public ElementAttributes duplicateElement(UUID elementId, UUID newElementId, UUI
return toElementAttributes(elementEntity);
}

private void assertRootDirectoryNotExist(String rootName) {
if (TRUE.equals(repositoryService.isRootDirectoryExist(rootName))) {
throw new DirectoryException(NOT_ALLOWED);
}
}

private void assertDirectoryExist(UUID dirUuid) {
if (!getElement(dirUuid).getType().equals(DIRECTORY)) {
throw new DirectoryException(NOT_DIRECTORY);
}
}

private DirectoryElementEntity insertElement(ElementAttributes elementAttributes, UUID parentDirectoryUuid) {
return insertElement(elementAttributes, parentDirectoryUuid, null, false);
}
Expand Down Expand Up @@ -192,10 +197,11 @@ public ElementAttributes createRootDirectory(RootDirectoryAttributes rootDirecto

private ElementAttributes createRootDirectoryWithNotif(RootDirectoryAttributes rootDirectoryAttributes, String userId) {
if (rootDirectoryAttributes.getElementName().isBlank()) {
throw new DirectoryException(NOT_ALLOWED);
throw new DirectoryException(NOT_ALLOWED, "Empty name is not allowed for root directory");
}
if (repositoryService.isRootDirectoryExist(rootDirectoryAttributes.getElementName())) {
throw new DirectoryException(NOT_ALLOWED, "Root directory %s already exists".formatted(rootDirectoryAttributes.getElementName()));
}

assertRootDirectoryNotExist(rootDirectoryAttributes.getElementName());
ElementAttributes elementAttributes = toElementAttributes(insertElement(toElementAttributes(rootDirectoryAttributes), null));
UUID elementUuid = elementAttributes.getElementUuid();
insertManageUserPermission(elementUuid, userId, "");
Expand Down Expand Up @@ -260,9 +266,6 @@ public List<ElementAttributes> getDirectoryElements(UUID directoryUuid, List<Str
return List.of();
}
ElementAttributes elementAttributes = getElement(directoryUuid);
if (elementAttributes == null) {
throw DirectoryException.createElementNotFound(DIRECTORY, directoryUuid);
}
if (!elementAttributes.getType().equals(DIRECTORY)) {
return List.of();
}
Expand Down Expand Up @@ -310,11 +313,11 @@ private Map<UUID, Long> getSubDirectoriesCountsMap(List<String> types, List<Dire
}

public void updateElement(UUID elementUuid, ElementAttributes newElementAttributes, String userId) {
DirectoryElementEntity directoryElement = getDirectoryElementEntity(elementUuid);
DirectoryElementEntity directoryElement = getElementEntityOrThrow(elementUuid);
if (!directoryElement.isAttributesUpdatable(newElementAttributes, userId) ||
!directoryElement.getName().equals(newElementAttributes.getElementName()) &&
directoryHasElementOfNameAndType(directoryElement.getParentId(), newElementAttributes.getElementName(), directoryElement.getType())) {
throw new DirectoryException(NOT_ALLOWED);
throw new DirectoryException(NOT_ALLOWED, "A directory named %s already exists".formatted(newElementAttributes.getElementName()));
}

DirectoryElementEntity elementEntity = repositoryService.saveElement(directoryElement.update(newElementAttributes));
Expand All @@ -324,20 +327,15 @@ public void updateElement(UUID elementUuid, ElementAttributes newElementAttribut

@Transactional
public void updateElementLastModifiedAttributes(UUID elementUuid, Instant lastModificationDate, String lastModifiedBy) {
DirectoryElementEntity elementToUpdate = getDirectoryElementEntity(elementUuid);
DirectoryElementEntity elementToUpdate = getElementEntityOrThrow(elementUuid);
elementToUpdate.updateModificationAttributes(lastModifiedBy, lastModificationDate);

}

@Transactional
public void moveElementsDirectory(List<UUID> elementsUuids, UUID newDirectoryUuid, String userId) {
if (elementsUuids.isEmpty()) {
throw new DirectoryException(NOT_ALLOWED);
}

validateNewDirectory(newDirectoryUuid);

elementsUuids.forEach(elementUuid -> moveElementDirectory(getDirectoryElementEntity(elementUuid), newDirectoryUuid, userId));
assertExistsAndIsDirectory(newDirectoryUuid);
elementsUuids.forEach(elementUuid -> moveElementDirectory(getElementEntityOrThrow(elementUuid), newDirectoryUuid, userId));
}

private void moveElementDirectory(DirectoryElementEntity element, UUID newDirectoryUuid, String userId) {
Expand Down Expand Up @@ -384,15 +382,6 @@ private void updateElementParentDirectory(DirectoryElementEntity element, UUID n
repositoryService.saveElement(element);
}

private void validateNewDirectory(UUID newDirectoryUuid) {
DirectoryElementEntity newDirectory = repositoryService.getElementEntity(newDirectoryUuid)
.orElseThrow(() -> DirectoryException.createElementNotFound(DIRECTORY, newDirectoryUuid));

if (!newDirectory.getType().equals(DIRECTORY)) {
throw new DirectoryException(NOT_DIRECTORY);
}
}

private boolean directoryHasElementOfNameAndType(UUID directoryUUID, String elementName, String elementType) {
return getOnlyElementsStream(directoryUUID, List.of(elementType))
.anyMatch(
Expand Down Expand Up @@ -464,22 +453,13 @@ public void deleteElements(List<UUID> elementsUuids, UUID parentDirectoryUuid, S
public List<ElementAttributes> getPath(UUID elementUuid) {
List<ElementAttributes> path = repositoryService.getPath(elementUuid).stream().map(ElementAttributes::toElementAttributes).toList();
if (path.isEmpty()) {
throw DirectoryException.createElementNotFound(ELEMENT, elementUuid);
throw new DirectoryException(NOT_FOUND, "Element %s not found".formatted(elementUuid));
}
return path;
}

public String getElementName(UUID elementUuid) {
DirectoryElementEntity element = repositoryService.getElementEntity(elementUuid).orElseThrow(() -> new DirectoryException(NOT_FOUND));
return element.getName();
}

public ElementAttributes getElement(UUID elementUuid) {
return toElementAttributes(getDirectoryElementEntity(elementUuid));
}

private DirectoryElementEntity getDirectoryElementEntity(UUID elementUuid) {
return repositoryService.getElementEntity(elementUuid).orElseThrow(() -> DirectoryException.createElementNotFound(ELEMENT, elementUuid));
return toElementAttributes(getElementEntityOrThrow(elementUuid));
}

public UUID getDirectoryUuid(String directoryName, UUID parentDirectoryUuid) {
Expand Down Expand Up @@ -507,7 +487,7 @@ public List<ElementAttributes> getElements(List<UUID> ids, boolean strictMode, L
}

if (strictMode && elementEntities.size() != ids.stream().distinct().count()) {
throw new DirectoryException(NOT_FOUND);
throw new DirectoryException(NOT_FOUND, "Not all IDs were found in strict mode (expected %d but found %d)".formatted(ids.stream().distinct().count(), elementEntities.size()));
}

Map<UUID, Long> subElementsCount = getSubDirectoriesCounts(elementEntities.stream().map(DirectoryElementEntity::getId).toList(), types);
Expand Down Expand Up @@ -544,9 +524,6 @@ private String nameCandidate(String elementName, int n) {
}

public String getDuplicateNameCandidate(UUID directoryUuid, String elementName, String elementType, String userId) {
if (!repositoryService.canRead(directoryUuid, userId)) {
throw new DirectoryException(NOT_ALLOWED);
}
var idLikes = new HashSet<>(repositoryService.getNameByTypeAndParentIdAndNameStartWith(elementType, directoryUuid, elementName));
if (!idLikes.contains(elementName)) {
return elementName;
Expand All @@ -569,7 +546,7 @@ public UUID getDirectoryUuidFromPath(List<String> directoryPath) {
for (String s : directoryPath) {
UUID currentDirectoryUuid = getDirectoryUuid(s, parentDirectoryUuid);
if (currentDirectoryUuid == null) {
throw new DirectoryException(NOT_FOUND);
throw new DirectoryException(NOT_FOUND, "No directory at path %s".formatted(s));
} else {
parentDirectoryUuid = currentDirectoryUuid;
}
Expand Down Expand Up @@ -653,7 +630,6 @@ public PermissionCheckResult checkDirectoriesPermission(String userId, List<UUID
case READ -> checkReadPermission(userId, elementUuids);
case WRITE -> checkWritePermission(userId, elementUuids, targetDirectoryUuid, recursiveCheck);
case MANAGE -> checkManagePermission(userId, elementUuids);
default -> PermissionCheckResult.PARENT_PERMISSION_DENIED;
};
}

Expand Down Expand Up @@ -771,7 +747,6 @@ private void addPermissionForAllUsers(UUID elementUuid, PermissionType permissio
case READ -> PermissionEntity.read(elementUuid, ALL_USERS, "");
case WRITE -> PermissionEntity.write(elementUuid, ALL_USERS, "");
case MANAGE -> PermissionEntity.manage(elementUuid, ALL_USERS, "");
default -> throw new IllegalArgumentException("Unknown permission type: " + permissionType);
};
permissionRepository.save(permissionEntity);
}
Expand All @@ -781,14 +756,13 @@ private void addPermissionForGroup(UUID elementUuid, String groupId, PermissionT
case READ -> PermissionEntity.read(elementUuid, "", groupId);
case WRITE -> PermissionEntity.write(elementUuid, "", groupId);
case MANAGE -> PermissionEntity.manage(elementUuid, "", groupId);
default -> throw new IllegalArgumentException("Unknown permission type: " + permissionType);
};
permissionRepository.save(permissionEntity);
}

public void validatePermissionsGetAccess(UUID directoryUuid, String userId) {
if (!roleService.isUserExploreAdmin() && !hasReadPermissions(userId, List.of(directoryUuid))) {
throw new DirectoryException(NOT_ALLOWED);
throw new DirectoryException(NOT_ALLOWED, "User %s is not authorized to read in directory %s".formatted(userId, directoryUuid));
}
}

Expand All @@ -802,7 +776,7 @@ public void validatePermissionsGetAccess(UUID directoryUuid, String userId) {
* @throws DirectoryException if the user doesn't have access or the directory doesn't exist
*/
public List<PermissionDTO> getDirectoryPermissions(UUID directoryUuid, String userId) {
assertDirectoryExist(directoryUuid);
assertExistsAndIsDirectory(directoryUuid);
validatePermissionsGetAccess(directoryUuid, userId);

List<PermissionEntity> permissions = permissionRepository.findAllByElementId(directoryUuid);
Expand Down Expand Up @@ -900,13 +874,13 @@ private Map<String, PermissionType> extractGroupPermissionLevels(List<Permission

private void validatePermissionUpdateAccess(UUID directoryUuid, String userId) {
if (!roleService.isUserExploreAdmin() && !hasManagePermission(userId, List.of(directoryUuid))) {
throw new DirectoryException(NOT_ALLOWED);
throw new DirectoryException(NOT_ALLOWED, "User %s is not authorized to manage directory %s".formatted(userId, directoryUuid));
}
}

@Transactional
public void setDirectoryPermissions(UUID directoryUuid, List<PermissionDTO> permissions, String userId) {
assertDirectoryExist(directoryUuid);
assertExistsAndIsDirectory(directoryUuid);
validatePermissionUpdateAccess(directoryUuid, userId);

// Remove all permissions for this directory except for the owner
Expand Down
Loading
Loading