diff --git a/.run/RestApplication-debug.run.xml b/.run/RestApplication-debug.run.xml
new file mode 100644
index 00000000..3e74c1c2
--- /dev/null
+++ b/.run/RestApplication-debug.run.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/java/de/filefighter/rest/configuration/CorsConfig.java b/src/main/java/de/filefighter/rest/configuration/CorsConfig.java
index 1bbf1ecd..1aee717a 100644
--- a/src/main/java/de/filefighter/rest/configuration/CorsConfig.java
+++ b/src/main/java/de/filefighter/rest/configuration/CorsConfig.java
@@ -25,7 +25,7 @@ public CorsConfig() {
}
@Bean
- @Profile({"dev","stage"})
+ @Profile({"dev", "stage", "debug"})
public CorsFilter corsFilterDev() {
final CorsConfiguration config = new CorsConfiguration().applyPermitDefaultValues();
ArrayList allowedOrigins = new ArrayList<>();
@@ -39,7 +39,7 @@ public CorsFilter corsFilterDev() {
}
@Bean
- @Profile({"prod","test"})
+ @Profile({"prod"})
public CorsFilter corsFilterProd() {
final CorsConfiguration config = new CorsConfiguration();
config.setAllowedMethods(allowedMethods);
diff --git a/src/main/java/de/filefighter/rest/configuration/PrepareDataBase.java b/src/main/java/de/filefighter/rest/configuration/PrepareDataBase.java
index a5879e23..9f5fdf15 100644
--- a/src/main/java/de/filefighter/rest/configuration/PrepareDataBase.java
+++ b/src/main/java/de/filefighter/rest/configuration/PrepareDataBase.java
@@ -45,7 +45,7 @@ public class PrepareDataBase {
String date;
@Bean
- @Profile({"dev", "prod, stage"})
+ @Profile({"dev", "prod, stage", "debug"})
@Autowired
CommandLineRunner veryImportantFileFighterStartScript(Environment environment) {
return args -> {
@@ -70,12 +70,6 @@ CommandLineRunner veryImportantFileFighterStartScript(Environment environment) {
System.out.println();
System.out.println("-------------------------------< REST API >-------------------------------");
System.out.println();
-
- /*
- System.out.println("╭---╮")
- System.out.println("| |")
- System.out.println("╰---╯")
- */
};
}
@@ -91,26 +85,28 @@ CommandLineRunner initDataBaseProd(UserRepository userRepository, FileSystemRepo
addDefaultAdminAndRuntimeUser(userRepository);
log.info("Inserting Home directories and default structure: {} {}.", fileSystemRepository.save(FileSystemEntity
.builder()
- .createdByUserId(RUNTIME_USER_ID)
+ .lastUpdatedBy(RUNTIME_USER_ID)
+ .lastUpdated(Instant.now().getEpochSecond())
+ .ownerId(1)
.fileSystemId(0)
.isFile(false)
.path("/")
.itemIds(new long[0])
- .lastUpdated(Instant.now().getEpochSecond())
- .name("HOME_Admin")
+ .name("HOME_1")
.size(420)
.typeId(FOLDER.getId())
.visibleForGroupIds(new long[]{UNDEFINED.getGroupId(), FAMILY.getGroupId(), ADMIN.getGroupId()})
.itemIds(new long[]{1})
.build()),
fileSystemRepository.save(FileSystemEntity.builder()
- .createdByUserId(1)
- .fileSystemId(1)
- .isFile(true)
+ .lastUpdatedBy(RUNTIME_USER_ID)
.lastUpdated(Instant.now().getEpochSecond())
+ .ownerId(1).fileSystemId(1)
+ .isFile(true)
.name("dummyFile.txt")
.size(420)
.typeId(TEXT.getId())
+ .mimeType("text/plain")
.editableFoGroupIds(new long[]{FAMILY.getGroupId()})
.visibleForGroupIds(new long[]{FAMILY.getGroupId()})
.build()));
@@ -136,7 +132,7 @@ CommandLineRunner initDataBaseProd(UserRepository userRepository, FileSystemRepo
}
@Bean
- @Profile("dev")
+ @Profile({"dev", "debug"})
CommandLineRunner initDataBaseDev(UserRepository userRepository, AccessTokenRepository accessTokenRepository, FileSystemRepository fileSystemRepository) {
return args -> {
log.info("Starting with clean user collection.");
@@ -198,7 +194,7 @@ CommandLineRunner initDataBaseDev(UserRepository userRepository, AccessTokenRepo
log.error("Inserting Users " + MESSAGE_ON_FAILURE);
}
- if (fileSystemRepository.findAll().size() == 6) {
+ if (fileSystemRepository.findAll().size() == 8) {
log.info("Inserting FileSystemEntities " + MESSAGE_ON_SUCCESS);
} else {
log.error("Inserting FileSystemEntities " + MESSAGE_ON_FAILURE);
@@ -266,75 +262,111 @@ private void addDefaultAdminAndRuntimeUser(UserRepository userRepository) {
}
private void addTestingFileSystemItems(FileSystemRepository fileSystemRepository) {
- log.info("Inserting default fsItems:\n {}\n {}\n {}\n {}\n {}\n {}.",
+ log.info("Inserting default fsItems:\n {}\n {}\n {}\n {}\n {}\n {}\n {}\n {}.",
fileSystemRepository.save(FileSystemEntity.builder()
- .createdByUserId(RUNTIME_USER_ID)
+ .lastUpdatedBy(RUNTIME_USER_ID)
+ .ownerId(1)
+ .lastUpdated(Instant.now().getEpochSecond())
.fileSystemId(0)
.isFile(false)
.path("/")
- .itemIds(new long[]{2, 3})
- .lastUpdated(Instant.now().getEpochSecond())
- .name("HOME_User")
+ .name("HOME_1")
.size(4866)
.typeId(FOLDER.getId())
+ .itemIds(new long[]{2, 3, 7})
.visibleForGroupIds(new long[]{FAMILY.getGroupId(), ADMIN.getGroupId()})
+ .visibleForUserIds(new long[]{0})
+ .editableForUserIds(new long[]{0})
.build()),
fileSystemRepository.save(FileSystemEntity.builder()
- .createdByUserId(RUNTIME_USER_ID)
+ .lastUpdatedBy(RUNTIME_USER_ID)
+ .lastUpdated(Instant.now().getEpochSecond())
+ .ownerId(2)
.fileSystemId(1)
.isFile(false)
.path("/")
- .lastUpdated(Instant.now().getEpochSecond())
- .name("HOME_User1")
+ .name("HOME_2")
.size(0)
.typeId(FOLDER.getId())
.visibleForGroupIds(new long[]{UNDEFINED.getGroupId(), FAMILY.getGroupId(), ADMIN.getGroupId()})
+ .visibleForUserIds(new long[]{1})
+ .editableForUserIds(new long[]{1})
.build()),
fileSystemRepository.save(FileSystemEntity.builder()
- .createdByUserId(1)
+ .lastUpdatedBy(1)
+ .lastUpdated(Instant.now().getEpochSecond())
+ .ownerId(1)
.fileSystemId(2)
.isFile(true)
- .lastUpdated(Instant.now().getEpochSecond())
.name("dummyFile.txt")
.size(420)
.typeId(TEXT.getId())
+ .mimeType("text/plain")
.editableFoGroupIds(new long[]{FAMILY.getGroupId()})
.visibleForGroupIds(new long[]{FAMILY.getGroupId()})
.build()),
fileSystemRepository.save(FileSystemEntity.builder()
- .createdByUserId(1)
+ .lastUpdatedBy(1)
+ .lastUpdated(Instant.now().getEpochSecond())
+ .ownerId(1)
+ .fileSystemId(7)
+ .isFile(true)
+ .name("visibleNonDeletableText.tex")
+ .size(42)
+ .typeId(TEXT.getId())
+ .mimeType("text/plain")
+ .visibleForGroupIds(new long[]{FAMILY.getGroupId()})
+ .build()),
+ fileSystemRepository.save(FileSystemEntity.builder()
+ .lastUpdatedBy(1)
+ .lastUpdated(Instant.now().getEpochSecond())
+ .ownerId(1)
.fileSystemId(3)
.isFile(false)
.path("/somefolder")
.name("SomeFolder")
- .lastUpdated(Instant.now().getEpochSecond())
.size(4446)
.typeId(FOLDER.getId())
.editableFoGroupIds(new long[]{FAMILY.getGroupId()})
.visibleForGroupIds(new long[]{FAMILY.getGroupId()})
- .itemIds(new long[]{4, 5})
+ .itemIds(new long[]{4, 5, 6})
.build()),
fileSystemRepository.save(FileSystemEntity.builder()
- .createdByUserId(1)
+ .lastUpdatedBy(1)
+ .lastUpdated(Instant.now().getEpochSecond())
+ .ownerId(1)
.fileSystemId(4)
.isFile(true)
- .lastUpdated(Instant.now().getEpochSecond())
.name("secretFileInSomeFolder.txt")
.size(3214)
.typeId(TEXT.getId())
+ .mimeType("text/plain")
.editableFoGroupIds(new long[]{FAMILY.getGroupId()})
.visibleForGroupIds(new long[]{FAMILY.getGroupId()})
.build()),
fileSystemRepository.save(FileSystemEntity.builder()
- .createdByUserId(1)
+ .lastUpdatedBy(1)
+ .lastUpdated(Instant.now().getEpochSecond())
+ .ownerId(1)
.fileSystemId(5)
.isFile(true)
- .lastUpdated(Instant.now().getEpochSecond())
.name("definitelyNotPorn.mp4")
.size(1232)
.typeId(VIDEO.getId())
+ .mimeType("video/mp4")
.editableFoGroupIds(new long[]{FAMILY.getGroupId()})
.visibleForGroupIds(new long[]{FAMILY.getGroupId()})
+ .build()),
+ fileSystemRepository.save(FileSystemEntity.builder()
+ .lastUpdatedBy(1)
+ .lastUpdated(Instant.now().getEpochSecond())
+ .ownerId(1)
+ .fileSystemId(6)
+ .isFile(true)
+ .name("invisible_secret_video.mp4")
+ .size(1232)
+ .typeId(VIDEO.getId())
+ .mimeType("video/mp4")
.build())
);
}
diff --git a/src/main/java/de/filefighter/rest/domain/authentication/AuthenticationBusinessService.java b/src/main/java/de/filefighter/rest/domain/authentication/AuthenticationBusinessService.java
index 43cc13a7..664fd5e1 100644
--- a/src/main/java/de/filefighter/rest/domain/authentication/AuthenticationBusinessService.java
+++ b/src/main/java/de/filefighter/rest/domain/authentication/AuthenticationBusinessService.java
@@ -1,6 +1,6 @@
package de.filefighter.rest.domain.authentication;
-import de.filefighter.rest.domain.common.exceptions.InputSanitizerService;
+import de.filefighter.rest.domain.common.InputSanitizerService;
import de.filefighter.rest.domain.common.exceptions.RequestDidntMeetFormalRequirementsException;
import de.filefighter.rest.domain.token.data.dto.AccessToken;
import de.filefighter.rest.domain.user.business.UserDTOService;
@@ -21,10 +21,12 @@ public class AuthenticationBusinessService {
private final UserRepository userRepository;
private final UserDTOService userDtoService;
+ private final InputSanitizerService inputSanitizerService;
- public AuthenticationBusinessService(UserRepository userRepository, UserDTOService userDtoService) {
+ public AuthenticationBusinessService(UserRepository userRepository, UserDTOService userDtoService, InputSanitizerService inputSanitizerService) {
this.userRepository = userRepository;
this.userDtoService = userDtoService;
+ this.inputSanitizerService = inputSanitizerService;
}
public User authenticateUserWithUsernameAndPassword(String base64encodedUserAndPassword) {
@@ -42,8 +44,8 @@ public User authenticateUserWithUsernameAndPassword(String base64encodedUserAndP
if (split.length != 2)
throw new RequestDidntMeetFormalRequirementsException("Credentials didnt meet formal requirements.");
- String lowerCaseUsername = InputSanitizerService.sanitizeString(split[0].toLowerCase());
- String password = InputSanitizerService.sanitizeString(split[1]);
+ String lowerCaseUsername = inputSanitizerService.sanitizeString(split[0].toLowerCase());
+ String password = inputSanitizerService.sanitizeString(split[1]);
UserEntity userEntity = userRepository.findByLowercaseUsernameAndPassword(lowerCaseUsername, password);
if (null == userEntity)
diff --git a/src/main/java/de/filefighter/rest/domain/authentication/AuthenticationService.java b/src/main/java/de/filefighter/rest/domain/authentication/AuthenticationService.java
index 8998f511..9a787298 100644
--- a/src/main/java/de/filefighter/rest/domain/authentication/AuthenticationService.java
+++ b/src/main/java/de/filefighter/rest/domain/authentication/AuthenticationService.java
@@ -1,6 +1,6 @@
package de.filefighter.rest.domain.authentication;
-import de.filefighter.rest.domain.common.exceptions.InputSanitizerService;
+import de.filefighter.rest.domain.common.InputSanitizerService;
import de.filefighter.rest.domain.token.business.AccessTokenBusinessService;
import de.filefighter.rest.domain.token.data.dto.AccessToken;
import de.filefighter.rest.domain.user.data.dto.User;
diff --git a/src/main/java/de/filefighter/rest/domain/common/exceptions/InputSanitizerService.java b/src/main/java/de/filefighter/rest/domain/common/InputSanitizerService.java
similarity index 54%
rename from src/main/java/de/filefighter/rest/domain/common/exceptions/InputSanitizerService.java
rename to src/main/java/de/filefighter/rest/domain/common/InputSanitizerService.java
index 9218dcf3..c9771a0c 100644
--- a/src/main/java/de/filefighter/rest/domain/common/exceptions/InputSanitizerService.java
+++ b/src/main/java/de/filefighter/rest/domain/common/InputSanitizerService.java
@@ -1,7 +1,11 @@
-package de.filefighter.rest.domain.common.exceptions;
+package de.filefighter.rest.domain.common;
+import de.filefighter.rest.domain.common.exceptions.RequestDidntMeetFormalRequirementsException;
import org.springframework.stereotype.Service;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
@Service
public class InputSanitizerService {
@@ -10,18 +14,25 @@ public static boolean stringIsValid(String s) {
}
/**
- *
* Sanitizes a String, so it can be used.
+ *
* @param string String that needs to be sanitized.
* @return string without whitespaces and without illegal characters.
* @throws RequestDidntMeetFormalRequirementsException when string was empty.
*/
- public static String sanitizeString(String string) {
- if(!InputSanitizerService.stringIsValid(string))
+ public String sanitizeString(String string) {
+ if (!InputSanitizerService.stringIsValid(string))
throw new RequestDidntMeetFormalRequirementsException("String was empty.");
return string.replaceAll("\\s", "");
}
+ public String sanitizePath(String path) {
+ if (!pathIsValid(path))
+ throw new RequestDidntMeetFormalRequirementsException("Path was not valid.");
+
+ return sanitizeString(path);
+ }
+
public String sanitizeRequestHeader(String header, String testString) {
if (!(stringIsValid(testString) && stringIsValid(header)))
throw new RequestDidntMeetFormalRequirementsException("Header does not contain a valid String.");
@@ -32,7 +43,18 @@ public String sanitizeRequestHeader(String header, String testString) {
return split[1];
}
- public String sanitizeTokenValue(String tokenValue){
- return InputSanitizerService.sanitizeString(tokenValue);
+ public boolean pathIsValid(String path) {
+ String validString = sanitizeString(path);
+
+ Pattern pattern = Pattern.compile("[~#@*+:!?&%<>|\"^\\\\]");
+ Matcher matcher = pattern.matcher(validString);
+
+ boolean stringContainsDoubleSlash = validString.contains("//");
+
+ return !(matcher.find() || stringContainsDoubleSlash);
+ }
+
+ public String sanitizeTokenValue(String tokenValue) {
+ return this.sanitizeString(tokenValue);
}
}
diff --git a/src/main/java/de/filefighter/rest/domain/filesystem/business/FileSystemBusinessService.java b/src/main/java/de/filefighter/rest/domain/filesystem/business/FileSystemBusinessService.java
index 94237a83..ee866220 100644
--- a/src/main/java/de/filefighter/rest/domain/filesystem/business/FileSystemBusinessService.java
+++ b/src/main/java/de/filefighter/rest/domain/filesystem/business/FileSystemBusinessService.java
@@ -1,8 +1,7 @@
package de.filefighter.rest.domain.filesystem.business;
-import de.filefighter.rest.configuration.RestConfiguration;
import de.filefighter.rest.domain.common.exceptions.FileFighterDataException;
-import de.filefighter.rest.domain.common.exceptions.InputSanitizerService;
+import de.filefighter.rest.domain.filesystem.data.InteractionType;
import de.filefighter.rest.domain.filesystem.data.dto.FileSystemItem;
import de.filefighter.rest.domain.filesystem.data.persistence.FileSystemEntity;
import de.filefighter.rest.domain.filesystem.data.persistence.FileSystemRepository;
@@ -13,76 +12,111 @@
import de.filefighter.rest.domain.filesystem.type.FileSystemTypeRepository;
import de.filefighter.rest.domain.user.business.UserBusinessService;
import de.filefighter.rest.domain.user.data.dto.User;
-import de.filefighter.rest.domain.user.data.persistence.UserEntity;
import de.filefighter.rest.domain.user.exceptions.UserNotFoundException;
-import de.filefighter.rest.domain.user.group.Group;
+import lombok.AllArgsConstructor;
import lombok.extern.log4j.Log4j2;
-import org.springframework.data.mongodb.core.MongoTemplate;
-import org.springframework.data.mongodb.core.query.Criteria;
-import org.springframework.data.mongodb.core.query.Query;
-import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service;
-import java.time.Instant;
-import java.util.*;
-import java.util.stream.Collectors;
-import java.util.stream.LongStream;
+import java.util.ArrayList;
+import java.util.List;
@Log4j2
@Service
public class FileSystemBusinessService {
private final FileSystemRepository fileSystemRepository;
- private final UserBusinessService userBusinessService;
+ private final FileSystemHelperService fileSystemHelperService;
private final FileSystemTypeRepository fileSystemTypeRepository;
- private final MongoTemplate mongoTemplate;
+ private final UserBusinessService userBusinessService;
- private static final String DELETION_FAILED_MSG = "Failed to delete FileSystemEntity with id ";
+ public static final String DELETION_FAILED_MSG = "Failed to delete FileSystemEntity with id ";
- public FileSystemBusinessService(FileSystemRepository fileSystemRepository, UserBusinessService userBusinessService, FileSystemTypeRepository fileSystemTypeRepository, MongoTemplate mongoTemplate) {
+ public FileSystemBusinessService(FileSystemRepository fileSystemRepository, FileSystemHelperService fileSystemHelperService, FileSystemTypeRepository fileSystemTypeRepository, UserBusinessService userBusinessService) {
this.fileSystemRepository = fileSystemRepository;
- this.userBusinessService = userBusinessService;
+ this.fileSystemHelperService = fileSystemHelperService;
this.fileSystemTypeRepository = fileSystemTypeRepository;
- this.mongoTemplate = mongoTemplate;
+ this.userBusinessService = userBusinessService;
}
+ @SuppressWarnings("java:S3776")
public List getFolderContentsByPath(String path, User authenticatedUser) {
- if (!InputSanitizerService.stringIsValid(path))
- throw new FileSystemContentsNotAccessibleException("Path was not valid.");
-
String[] pathWithoutSlashes = path.split("/");
- if (!path.equals("/") && pathWithoutSlashes.length < 2)
- throw new FileSystemContentsNotAccessibleException("Path was in wrong format.");
+ String pathToFind;
+ User ownerOfRequestedFolder = null;
- if (!path.equals("/") && !"".equals(pathWithoutSlashes[0]))
- throw new FileSystemContentsNotAccessibleException("Path was in wrong format. Use a leading backslash.");
+ if (path.equals("/")) {
+ pathToFind = "/";
+ } else {
+ if (pathWithoutSlashes.length < 2)
+ throw new FileSystemContentsNotAccessibleException("Path was in wrong format.");
+
+ if (!"".equals(pathWithoutSlashes[0]))
+ throw new FileSystemContentsNotAccessibleException("Path was in wrong format. Use a leading backslash.");
+
+ // the first path must be the the username.
+ try {
+ ownerOfRequestedFolder = userBusinessService.findUserByUsername(pathWithoutSlashes[1]);
+ String[] fileSystemPath = path.split(ownerOfRequestedFolder.getUsername());
+ if (fileSystemPath.length == 1) {
+ if (!fileSystemPath[0].equals("/"))
+ throw new FileSystemContentsNotAccessibleException();
+
+ pathToFind = "/";
+ } else {
+ pathToFind = fileSystemPath[1];
+ }
+ } catch (UserNotFoundException exception) {
+ throw new FileSystemContentsNotAccessibleException();
+ }
+ }
- String pathToFind = removeTrailingBackSlashes(path).toLowerCase();
+ pathToFind = fileSystemHelperService.removeTrailingBackSlashes(pathToFind).toLowerCase();
// find the folder with matching path.
- ArrayList listOfFileSystemEntities = fileSystemRepository.findByPath(pathToFind);
- if (null == listOfFileSystemEntities) // does return null and not a empty collection.
+ ArrayList listOfPossibleDirectories = fileSystemRepository.findByPath(pathToFind);
+ if (null == listOfPossibleDirectories) // does return null and not a empty collection.
throw new FileSystemContentsNotAccessibleException();
// remove all not accessible items.
- listOfFileSystemEntities.removeIf(entity -> entity.isFile() || entity.getTypeId() != FileSystemType.FOLDER.getId() || !userIsAllowedToSeeFileSystemEntity(entity, authenticatedUser));
+ // this is only the case if the real / was requested. -> filter by visibility
+ boolean actualRootWasRequested = null == ownerOfRequestedFolder;
+ if (actualRootWasRequested) {
+ listOfPossibleDirectories.removeIf(entity -> entity.isFile() || entity.getTypeId() != FileSystemType.FOLDER.getId() || !fileSystemHelperService.userIsAllowedToInteractWithFileSystemEntity(entity, authenticatedUser, InteractionType.READ));
+
+ // do not get the actual contents here but display the folder names as a fake directory.
+ ArrayList fileSystemItems = new ArrayList<>();
+ for (FileSystemEntity folder : listOfPossibleDirectories) {
+ // change names here accordingly.
+ fileSystemItems.add(fileSystemHelperService.createDTO(folder, authenticatedUser, "/"));
+ }
- if (listOfFileSystemEntities.isEmpty())
- throw new FileSystemContentsNotAccessibleException();
+ return fileSystemItems;
+ } else {
+ User finalOwnerOfRequestedFolder = ownerOfRequestedFolder;
+ listOfPossibleDirectories.removeIf(entity -> (entity.isFile() || entity.getTypeId() != FileSystemType.FOLDER.getId() || entity.getOwnerId() != finalOwnerOfRequestedFolder.getUserId()));
+
+ if (listOfPossibleDirectories.isEmpty())
+ throw new FileSystemContentsNotAccessibleException();
- // now only own or shared folders are left.
- ArrayList fileSystemItems = new ArrayList<>();
- String pathWithTrailingSlash = pathToFind.equals("/") ? pathToFind : (pathToFind + "/"); //NOSONAR
+ // now one Folder should remain
+ if (listOfPossibleDirectories.size() != 1)
+ throw new FileFighterDataException("Found more than one folder with the path " + pathToFind);
+
+ // check if the autheticatedUser can access this.
+ if (!fileSystemHelperService.userIsAllowedToInteractWithFileSystemEntity(listOfPossibleDirectories.get(0), authenticatedUser, InteractionType.READ))
+ throw new FileSystemContentsNotAccessibleException();
+
+ ArrayList fileSystemItems = new ArrayList<>();
+ List folderContents =
+ fileSystemHelperService.getFolderContentsOfEntityAndPermissions(listOfPossibleDirectories.get(0), authenticatedUser, true, false);
- // Well this is just O(n * m)
- for (FileSystemEntity folder : listOfFileSystemEntities) {
- ArrayList folderContents = (ArrayList) getFolderContentsOfEntityAndPermissions(folder, authenticatedUser, true, false);
for (FileSystemEntity fileSystemEntityInFolder : folderContents) {
- fileSystemItems.add(this.createDTO(fileSystemEntityInFolder, authenticatedUser, pathWithTrailingSlash));
+ fileSystemItems.add(fileSystemHelperService.createDTO(fileSystemEntityInFolder, authenticatedUser, "/" + ownerOfRequestedFolder.getUsername() + pathToFind));
}
+
+ return fileSystemItems;
}
- return fileSystemItems;
}
public FileSystemItem getFileSystemItemInfo(long fsItemId, User authenticatedUser) {
@@ -90,317 +124,84 @@ public FileSystemItem getFileSystemItemInfo(long fsItemId, User authenticatedUse
if (null == fileSystemEntity)
throw new FileSystemItemNotFoundException(fsItemId);
- if (!userIsAllowedToSeeFileSystemEntity(fileSystemEntity, authenticatedUser))
+ if (!fileSystemHelperService.userIsAllowedToInteractWithFileSystemEntity(fileSystemEntity, authenticatedUser, InteractionType.READ))
throw new FileSystemItemNotFoundException(fsItemId);
- return createDTO(fileSystemEntity, authenticatedUser, null);
+ return fileSystemHelperService.createDTO(fileSystemEntity, authenticatedUser, null);
}
- public boolean deleteFileSystemItemById(long fsItemId, User authenticatedUser) {
- FileSystemEntity fileSystemEntity = fileSystemRepository.findByFileSystemId(fsItemId);
- if (null == fileSystemEntity)
+ public List deleteFileSystemItemById(long fsItemId, User authenticatedUser) {
+ FileSystemEntity parentEntity = fileSystemRepository.findByFileSystemId(fsItemId);
+ if (null == parentEntity)
throw new FileSystemItemCouldNotBeDeletedException(fsItemId);
- if (!(userIsAllowedToSeeFileSystemEntity(fileSystemEntity, authenticatedUser) && userIsAllowedToEditFileSystemEntity(fileSystemEntity, authenticatedUser)))
+ if (!(fileSystemHelperService.userIsAllowedToInteractWithFileSystemEntity(parentEntity, authenticatedUser, InteractionType.READ) && fileSystemHelperService.userIsAllowedToInteractWithFileSystemEntity(parentEntity, authenticatedUser, InteractionType.DELETE)))
throw new FileSystemItemCouldNotBeDeletedException(fsItemId);
- return recursivelyDeleteFileSystemEntity(fileSystemEntity, authenticatedUser);
+ // update the time stamps in the file tree
+ fileSystemHelperService.recursivlyUpdateTimeStamps(parentEntity, authenticatedUser, fileSystemHelperService.getCurrentTimeStamp());
+
+ log.info("User is {}.", authenticatedUser);
+
+ ArrayList returnList = new ArrayList<>();
+ recursivlyDeleteFileSystemEntity(parentEntity, authenticatedUser, returnList);
+ return returnList;
}
- /**
- * Deletes the folder recursively.
- *
- * @param parentFileSystemEntity parent fileSystem entity, can be both folder and file.
- * @param authenticatedUser user that wants to delete
- * @return true if the folder and all the folders / items were deleted.
- */
- @SuppressWarnings({"squid:S3776", "squid:S1192"})
- public boolean recursivelyDeleteFileSystemEntity(FileSystemEntity parentFileSystemEntity, User authenticatedUser) {
- boolean everythingWasDeleted = false;
- if (parentFileSystemEntity.isFile() && fileSystemTypeRepository.findFileSystemTypeById(parentFileSystemEntity.getTypeId()) != FileSystemType.FOLDER) {
- // 1. Base of recursion
- // Delete File and update parentFolder.
- Long countDeleted = fileSystemRepository.deleteByFileSystemId(parentFileSystemEntity.getFileSystemId());
- if (countDeleted != 1)
- throw new FileFighterDataException(DELETION_FAILED_MSG + parentFileSystemEntity.getFileSystemId());
-
- // update.
- Query query = new Query().addCriteria(Criteria.where("itemIds").is(parentFileSystemEntity.getFileSystemId()));
- Update newUpdate = new Update().pull("itemIds", parentFileSystemEntity.getFileSystemId());
- mongoTemplate.findAndModify(query, newUpdate, FileSystemEntity.class);
-
- everythingWasDeleted = true;
- } else if (!parentFileSystemEntity.isFile() && fileSystemTypeRepository.findFileSystemTypeById(parentFileSystemEntity.getTypeId()) == FileSystemType.FOLDER) {
- ArrayList foundEntities = (ArrayList) getFolderContentsOfEntityAndPermissions(parentFileSystemEntity, authenticatedUser, false, false);
-
- if (null == foundEntities || foundEntities.isEmpty()) {
- // 2. Base of recursion
- Long countDeleted = fileSystemRepository.deleteByFileSystemId(parentFileSystemEntity.getFileSystemId());
- if (countDeleted != 1)
- throw new FileFighterDataException(DELETION_FAILED_MSG + parentFileSystemEntity.getFileSystemId());
-
- everythingWasDeleted = true;
- } else {
- ArrayList invisibleEntities = new ArrayList<>();
- List updatedItemIds = LongStream.of(parentFileSystemEntity.getItemIds()).boxed().collect(Collectors.toList());
- int deletedEntities = 0;
-
- for (FileSystemEntity childrenEntity : foundEntities) {
- if (userIsAllowedToSeeFileSystemEntity(childrenEntity, authenticatedUser)) {
- if (userIsAllowedToEditFileSystemEntity(childrenEntity, authenticatedUser)) {
-
- // Folder.
- if (!childrenEntity.isFile() && fileSystemTypeRepository.findFileSystemTypeById(childrenEntity.getTypeId()) == FileSystemType.FOLDER) {
- // Step of recursion
- if (recursivelyDeleteFileSystemEntity(childrenEntity, authenticatedUser)) {
- // there is no need to remove the child entity, because it was already deleted in the recursive function call.
- // if it wasn't removed (if = false) we don't remove the folder and we don't delete it.
- updatedItemIds.remove(childrenEntity.getFileSystemId());
- deletedEntities++;
- }
- // File
- } else if (childrenEntity.isFile() && fileSystemTypeRepository.findFileSystemTypeById(childrenEntity.getTypeId()) != FileSystemType.FOLDER) {
- // 3. Base of recursion
- Long countDeleted = fileSystemRepository.deleteByFileSystemId(childrenEntity.getFileSystemId());
- if (countDeleted != 1)
- throw new FileFighterDataException(DELETION_FAILED_MSG + childrenEntity.getFileSystemId());
-
- updatedItemIds.remove(childrenEntity.getFileSystemId());
- deletedEntities++;
- } else {
- throw new FileFighterDataException("FileType was wrong. " + childrenEntity);
- }
+ private RecursiveReturn recursivlyDeleteFileSystemEntity(FileSystemEntity parentEntity, User authenticatedUser, ArrayList returnList) {
+ boolean foundNonDeletable = false;
+ boolean foundInvisible = false;
+
+ // the parentEntity is already checked.
+ if (parentEntity.isFile() && fileSystemTypeRepository.findFileSystemTypeById(parentEntity.getTypeId()) != FileSystemType.FOLDER) {
+ log.debug("Found file to delete: {}.", parentEntity);
+ fileSystemHelperService.deleteAndUnbindFileSystemEntity(parentEntity);
+ returnList.add(fileSystemHelperService.createDTO(parentEntity, authenticatedUser, null));
+ } else {
+ if (parentEntity.getItemIds().length != 0) {
+ List items = fileSystemHelperService.getFolderContentsOfEntityAndPermissions(parentEntity, authenticatedUser, false, false);
+ for (FileSystemEntity item : items) {
+ if (fileSystemHelperService.userIsAllowedToInteractWithFileSystemEntity(item, authenticatedUser, InteractionType.READ)) {
+ if (fileSystemHelperService.userIsAllowedToInteractWithFileSystemEntity(item, authenticatedUser, InteractionType.DELETE)) {
+ RecursiveReturn recursiveReturn = recursivlyDeleteFileSystemEntity(item, authenticatedUser, returnList);
+ foundInvisible = recursiveReturn.foundInvisibleEntities || foundInvisible;
+ foundNonDeletable = recursiveReturn.foundNonDeletableEntities || foundNonDeletable;
+ } else {
+ // a entity could not be removed disable the deletion of the parent folder. (current Entity)
+ foundNonDeletable = true;
}
- // otherwise the item stays as it is.
} else {
- invisibleEntities.add(childrenEntity);
+ // the entity also cannot be deleted BUT the current User looses the permissions.
+ foundInvisible = true;
}
}
- // some entities could not be deleted because he is not allowed or cannot see them.
- if (foundEntities.size() != deletedEntities) {
-
- // update itemIds.
- parentFileSystemEntity.setItemIds(updatedItemIds.stream().mapToLong(Long::longValue).toArray());
-
- // save changes of parentFolder to db.
- Query query = new Query().addCriteria(Criteria.where("fileSystemId").is(parentFileSystemEntity.getFileSystemId()));
- Update newUpdate = new Update().set("itemIds", parentFileSystemEntity.getItemIds());
-
- // only problem appears when there are only invisible entities left.
- boolean onlyInvisibleEntitiesAreLeftAfterRemovingDeletableEntities = !invisibleEntities.isEmpty() && (invisibleEntities.size() == updatedItemIds.size());
- if (onlyInvisibleEntitiesAreLeftAfterRemovingDeletableEntities) {
- // some files do not include the current user to see them. By adding up all these permissions and applying them the the parent folder
- // we can make sure, that the views of the other users stay the same, while the current user cannot see the folder anymore.
- // EdgeCase: that the user who requests the deletion is owner of the folder but cannot see cannot happen anymore,
- // because he the owner has all rights on all files except ones created by runtime users.
- parentFileSystemEntity = sumUpAllPermissionsOfFileSystemEntities(parentFileSystemEntity, invisibleEntities);
-
- newUpdate.set("visibleForUserIds", parentFileSystemEntity.getVisibleForUserIds())
- .set("visibleForGroupIds", parentFileSystemEntity.getVisibleForGroupIds())
- .set("editableForUserIds", parentFileSystemEntity.getEditableForUserIds())
- .set("editableForGroupIds", parentFileSystemEntity.getEditableFoGroupIds());
- }
- mongoTemplate.findAndModify(query, newUpdate, FileSystemEntity.class);
+ log.info("Currently working on: {}.", parentEntity);
+
+ if (foundInvisible && !foundNonDeletable) {
+ // only invisible files left.
+ log.info("Found invisible FileSystemEntity {}", parentEntity);
+ fileSystemHelperService.removeVisibilityRightsOfFileSystemEntityForUser(parentEntity, authenticatedUser);
+ } else if (!foundInvisible && !foundNonDeletable) {
+ // every child item of the entity can be deleted.
+ log.info("Found no invisible or non deletable FileSystemEntities.");
+ fileSystemHelperService.deleteAndUnbindFileSystemEntity(parentEntity);
+ returnList.add(fileSystemHelperService.createDTO(parentEntity, authenticatedUser, null));
} else {
- // No FileSystemEntities left in folder. -> can be deleted.
- Long countDeleted = fileSystemRepository.deleteByFileSystemId(parentFileSystemEntity.getFileSystemId());
- if (countDeleted != 1)
- throw new FileFighterDataException(DELETION_FAILED_MSG + parentFileSystemEntity.getFileSystemId());
-
- everythingWasDeleted = true;
+ // else some files are left. invisible or not. but the entity cannot be deleted.
+ log.info("Some visible entites could not be deleted but are visible.");
}
- }
- } else {
- throw new FileFighterDataException("FileType was wrong. " + parentFileSystemEntity);
- }
- return everythingWasDeleted;
- }
-
- // ---------------- HELPER -------------------
-
- public FileSystemEntity sumUpAllPermissionsOfFileSystemEntities(FileSystemEntity parentFileSystemEntity, List fileSystemEntities) {
- HashSet visibleForUserIds = new HashSet<>();
- HashSet visibleForGroupIds = new HashSet<>();
- HashSet editableForUserIds = new HashSet<>();
- HashSet editableGroupIds = new HashSet<>();
-
- for (FileSystemEntity entity : fileSystemEntities) {
- addPermissionsToSets(visibleForUserIds, visibleForGroupIds, editableForUserIds, editableGroupIds, entity);
- }
-
- parentFileSystemEntity.setVisibleForUserIds(Arrays.stream(visibleForUserIds.toArray(new Long[0])).mapToLong(Long::longValue).toArray());
- parentFileSystemEntity.setVisibleForGroupIds(Arrays.stream(visibleForGroupIds.toArray(new Long[0])).mapToLong(Long::longValue).toArray());
- parentFileSystemEntity.setEditableForUserIds(Arrays.stream(editableForUserIds.toArray(new Long[0])).mapToLong(Long::longValue).toArray());
- parentFileSystemEntity.setEditableFoGroupIds(Arrays.stream(editableGroupIds.toArray(new Long[0])).mapToLong(Long::longValue).toArray());
- return parentFileSystemEntity;
- }
-
- public void addPermissionsToSets(Set visibleForUserIds, Set visibleForGroupIds, Set editableForUserIds, Set editableGroupIds, FileSystemEntity fileSystemEntity) {
- for (long i : fileSystemEntity.getVisibleForUserIds()) {
- visibleForUserIds.add(i);
- }
- for (long i : fileSystemEntity.getVisibleForGroupIds()) {
- visibleForGroupIds.add(i);
- }
- for (long i : fileSystemEntity.getEditableForUserIds()) {
- editableForUserIds.add(i);
- }
- for (long i : fileSystemEntity.getEditableFoGroupIds()) {
- editableGroupIds.add(i);
- }
- }
-
- public List getFolderContentsOfEntityAndPermissions(FileSystemEntity fileSystemEntity, User authenticatedUser, boolean needsToBeVisible, boolean needsToBeEditable) {
- long[] folderContentItemIds = fileSystemEntity.getItemIds();
- List fileSystemEntities = new ArrayList<>(folderContentItemIds.length);
-
- // check if the contents are visible / editable.
- for (long fileSystemId : folderContentItemIds) {
- FileSystemEntity fileSystemEntityInFolder = fileSystemRepository.findByFileSystemId(fileSystemId);
-
- if (null == fileSystemEntityInFolder)
- throw new FileFighterDataException("FolderContents expected fileSystemItem with id " + fileSystemId + " but was empty.");
-
- if (needsToBeVisible && !needsToBeEditable && userIsAllowedToSeeFileSystemEntity(fileSystemEntityInFolder, authenticatedUser)) {
- fileSystemEntities.add(fileSystemEntityInFolder);
- }
- if (needsToBeEditable && !needsToBeVisible && userIsAllowedToEditFileSystemEntity(fileSystemEntityInFolder, authenticatedUser)) {
- fileSystemEntities.add(fileSystemEntityInFolder);
- }
- if (needsToBeVisible && needsToBeEditable && userIsAllowedToSeeFileSystemEntity(fileSystemEntityInFolder, authenticatedUser) && userIsAllowedToEditFileSystemEntity(fileSystemEntityInFolder, authenticatedUser)) {
- fileSystemEntities.add(fileSystemEntityInFolder);
- }
- if (!needsToBeVisible && !needsToBeEditable) {
- fileSystemEntities.add(fileSystemEntityInFolder);
- }
- }
- return fileSystemEntities;
- }
-
- public boolean userIsAllowedToSeeFileSystemEntity(FileSystemEntity fileSystemEntity, User authenticatedUser) {
- // user created the item
- if (fileSystemEntity.getCreatedByUserId() == authenticatedUser.getUserId())
- return true;
-
- // user created containing folder.
- if (null != fileSystemEntity.getOwnerIds() && Arrays.stream(fileSystemEntity.getOwnerIds()).asDoubleStream().anyMatch(id -> id == authenticatedUser.getUserId()))
- return true;
-
- // user got the item shared.
- for (long userId : fileSystemEntity.getVisibleForUserIds()) {
- if (userId == authenticatedUser.getUserId())
- return true;
- }
-
- // user is in group that got the item shared.
- long[] fileIsSharedToGroups = fileSystemEntity.getVisibleForGroupIds();
- for (Group group : authenticatedUser.getGroups()) {
- for (long groupId : fileIsSharedToGroups) {
- if (groupId == group.getGroupId())
- return true;
-
- }
- }
- return false;
- }
-
- public boolean userIsAllowedToEditFileSystemEntity(FileSystemEntity fileSystemEntity, User authenticatedUser) {
- // file was created by runtime user.
- if (fileSystemEntity.getCreatedByUserId() == RestConfiguration.RUNTIME_USER_ID)
- return false;
-
- // user created the item
- if (fileSystemEntity.getCreatedByUserId() == authenticatedUser.getUserId())
- return true;
-
- // user created containing folder.
- if (null != fileSystemEntity.getOwnerIds() && Arrays.stream(fileSystemEntity.getOwnerIds()).asDoubleStream().anyMatch(id -> id == authenticatedUser.getUserId()))
- return true;
-
- // user got the item shared.
- for (long userId : fileSystemEntity.getEditableForUserIds()) {
- if (userId == authenticatedUser.getUserId())
- return true;
- }
-
- // user is in group that got the item shared.
- long[] fileIsSharedToGroups = fileSystemEntity.getEditableFoGroupIds();
- for (Group group : authenticatedUser.getGroups()) {
- for (long groupId : fileIsSharedToGroups) {
- if (groupId == group.getGroupId())
- return true;
-
+ } else {
+ fileSystemHelperService.deleteAndUnbindFileSystemEntity(parentEntity);
+ returnList.add(fileSystemHelperService.createDTO(parentEntity, authenticatedUser, null));
}
}
- return false;
- }
-
- public String removeTrailingBackSlashes(String pathToFind) {
- char[] chars = pathToFind.toCharArray();
- // for the case of "/"
- if (chars.length != 1 && chars[chars.length - 1] == '/') {
- chars = Arrays.copyOf(chars, chars.length - 1);
- return new String(chars);
- }
- return pathToFind;
- }
-
- public FileSystemItem createDTO(FileSystemEntity fileSystemEntity, User authenticatedUser, String basePath) {
- // for better responses and internal problem handling.
- User ownerOfFileSystemItem;
- try {
- ownerOfFileSystemItem = userBusinessService.getUserById(fileSystemEntity.getCreatedByUserId());
- } catch (UserNotFoundException exception) {
- throw new FileFighterDataException("Owner of a file could not be found.");
- }
-
- boolean isShared = ownerOfFileSystemItem.getUserId() != authenticatedUser.getUserId();
- FileSystemType type = fileSystemTypeRepository.findFileSystemTypeById(fileSystemEntity.getTypeId());
- boolean isAFolder = type == FileSystemType.FOLDER && !fileSystemEntity.isFile();
-
- return FileSystemItem.builder()
- .createdByUser(ownerOfFileSystemItem)
- .fileSystemId(fileSystemEntity.getFileSystemId())
- .lastUpdated(fileSystemEntity.getLastUpdated())
- .name(fileSystemEntity.getName())
- .size(fileSystemEntity.getSize())
- .type(isAFolder ? FileSystemType.FOLDER : type)
- .path(null == basePath ? null : basePath + fileSystemEntity.getName())
- .isShared(isShared)
- .build();
- }
-
- public void createBasicFilesForNewUser(UserEntity registeredUserEntity) {
- fileSystemRepository.save(FileSystemEntity
- .builder()
- .createdByUserId(0)
- .typeId(FileSystemType.FOLDER.getId())
- .isFile(false)
- .name("HOME_" + registeredUserEntity.getUsername())
- .path("/")
- .lastUpdated(Instant.now().getEpochSecond())
- .fileSystemId(generateNextFileSystemId())
- .build());
- }
-
- public double getTotalFileSize() {
- ArrayList entities = fileSystemRepository.findByPath("/");
- if (null == entities)
- throw new FileFighterDataException("Couldn't find any Home directories!");
-
- double size = 0;
- for (FileSystemEntity entity : entities) {
- size += entity.getSize();
- }
- return size;
- }
-
- public long getFileSystemEntityCount() {
- return fileSystemRepository.count();
+ return new RecursiveReturn(foundInvisible, foundNonDeletable);
}
- public long generateNextFileSystemId() {
- return getFileSystemEntityCount() + 1;
+ @AllArgsConstructor
+ private static class RecursiveReturn {
+ private final boolean foundInvisibleEntities;
+ private final boolean foundNonDeletableEntities;
}
}
diff --git a/src/main/java/de/filefighter/rest/domain/filesystem/business/FileSystemHelperService.java b/src/main/java/de/filefighter/rest/domain/filesystem/business/FileSystemHelperService.java
new file mode 100644
index 00000000..37375d00
--- /dev/null
+++ b/src/main/java/de/filefighter/rest/domain/filesystem/business/FileSystemHelperService.java
@@ -0,0 +1,309 @@
+package de.filefighter.rest.domain.filesystem.business;
+
+import de.filefighter.rest.configuration.RestConfiguration;
+import de.filefighter.rest.domain.common.exceptions.FileFighterDataException;
+import de.filefighter.rest.domain.filesystem.data.InteractionType;
+import de.filefighter.rest.domain.filesystem.data.dto.FileSystemItem;
+import de.filefighter.rest.domain.filesystem.data.persistence.FileSystemEntity;
+import de.filefighter.rest.domain.filesystem.data.persistence.FileSystemRepository;
+import de.filefighter.rest.domain.filesystem.type.FileSystemType;
+import de.filefighter.rest.domain.filesystem.type.FileSystemTypeRepository;
+import de.filefighter.rest.domain.user.business.UserBusinessService;
+import de.filefighter.rest.domain.user.data.dto.User;
+import de.filefighter.rest.domain.user.data.persistence.UserEntity;
+import de.filefighter.rest.domain.user.exceptions.UserNotFoundException;
+import de.filefighter.rest.domain.user.group.Group;
+import lombok.extern.log4j.Log4j2;
+import org.springframework.data.mongodb.core.MongoTemplate;
+import org.springframework.data.mongodb.core.query.Criteria;
+import org.springframework.data.mongodb.core.query.Query;
+import org.springframework.data.mongodb.core.query.Update;
+import org.springframework.stereotype.Service;
+
+import java.time.Instant;
+import java.util.*;
+
+import static de.filefighter.rest.domain.filesystem.business.FileSystemBusinessService.DELETION_FAILED_MSG;
+
+@Service
+@Log4j2
+public class FileSystemHelperService {
+
+ private final FileSystemRepository fileSystemRepository;
+ private final FileSystemTypeRepository fileSystemTypeRepository;
+ private final UserBusinessService userBusinessService;
+ private final MongoTemplate mongoTemplate;
+
+ public FileSystemHelperService(FileSystemRepository fileSystemRepository, FileSystemTypeRepository fileSystemTypeRepository, UserBusinessService userBusinessService, MongoTemplate mongoTemplate) {
+ this.fileSystemRepository = fileSystemRepository;
+ this.fileSystemTypeRepository = fileSystemTypeRepository;
+ this.userBusinessService = userBusinessService;
+ this.mongoTemplate = mongoTemplate;
+ }
+
+ public FileSystemEntity sumUpAllPermissionsOfFileSystemEntities(FileSystemEntity parentFileSystemEntity, List fileSystemEntities) {
+ HashSet visibleForUserIds = new HashSet<>();
+ HashSet visibleForGroupIds = new HashSet<>();
+ HashSet editableForUserIds = new HashSet<>();
+ HashSet editableGroupIds = new HashSet<>();
+
+ for (FileSystemEntity entity : fileSystemEntities) {
+ addPermissionsToSets(visibleForUserIds, visibleForGroupIds, editableForUserIds, editableGroupIds, entity);
+ }
+
+ parentFileSystemEntity.setVisibleForUserIds(Arrays.stream(visibleForUserIds.toArray(new Long[0])).mapToLong(Long::longValue).toArray());
+ parentFileSystemEntity.setVisibleForGroupIds(Arrays.stream(visibleForGroupIds.toArray(new Long[0])).mapToLong(Long::longValue).toArray());
+ parentFileSystemEntity.setEditableForUserIds(Arrays.stream(editableForUserIds.toArray(new Long[0])).mapToLong(Long::longValue).toArray());
+ parentFileSystemEntity.setEditableFoGroupIds(Arrays.stream(editableGroupIds.toArray(new Long[0])).mapToLong(Long::longValue).toArray());
+ return parentFileSystemEntity;
+ }
+
+ public void addPermissionsToSets(Set visibleForUserIds, Set visibleForGroupIds, Set editableForUserIds, Set editableGroupIds, FileSystemEntity fileSystemEntity) {
+ for (long i : fileSystemEntity.getVisibleForUserIds()) {
+ visibleForUserIds.add(i);
+ }
+ for (long i : fileSystemEntity.getVisibleForGroupIds()) {
+ visibleForGroupIds.add(i);
+ }
+ for (long i : fileSystemEntity.getEditableForUserIds()) {
+ editableForUserIds.add(i);
+ }
+ for (long i : fileSystemEntity.getEditableFoGroupIds()) {
+ editableGroupIds.add(i);
+ }
+ }
+
+ public void removeVisibilityRightsOfFileSystemEntityForUser(FileSystemEntity entity, User authenticatedUser) {
+ Query query = new Query().addCriteria(Criteria.where("fileSystemId").is(entity.getFileSystemId()));
+ Update newUpdate = new Update();
+
+ // user is either directly in the visible ids or in a group that is visible.
+ long[] newIdsWithoutCurrentUserId = Arrays.stream(entity.getVisibleForUserIds()).filter(userId -> userId != authenticatedUser.getUserId()).toArray();
+ if (newIdsWithoutCurrentUserId.length != entity.getVisibleForUserIds().length) {
+ // apply it.
+ newUpdate.set("visibleForUserIds", newIdsWithoutCurrentUserId);
+ }
+
+ // or user is in a group that can see the filesystem entity.
+ long[] newGroupIds = entity.getVisibleForGroupIds();
+ if (newGroupIds.length != 0) {
+ for (Group group : authenticatedUser.getGroups()) {
+ newGroupIds = Arrays.stream(newGroupIds).filter(id -> id != group.getGroupId()).toArray();
+ }
+ newUpdate.set("visibleForGroupIds", newGroupIds);
+ }
+ mongoTemplate.findAndModify(query, newUpdate, FileSystemEntity.class);
+ }
+
+ public List getFolderContentsOfEntityAndPermissions(FileSystemEntity fileSystemEntity, User authenticatedUser, boolean needsToBeVisible, boolean needsToBeEditable) {
+ long[] folderContentItemIds = fileSystemEntity.getItemIds();
+ List fileSystemEntities = new ArrayList<>(folderContentItemIds.length);
+
+ // check if the contents are visible / editable.
+ for (long fileSystemId : folderContentItemIds) {
+ FileSystemEntity fileSystemEntityInFolder = fileSystemRepository.findByFileSystemId(fileSystemId);
+
+ if (null == fileSystemEntityInFolder)
+ throw new FileFighterDataException("FolderContents expected fileSystemItem with id " + fileSystemId + " but was empty.");
+
+ if (needsToBeVisible && !needsToBeEditable && userIsAllowedToInteractWithFileSystemEntity(fileSystemEntityInFolder, authenticatedUser, InteractionType.READ)) {
+ fileSystemEntities.add(fileSystemEntityInFolder);
+ }
+ if (needsToBeEditable && !needsToBeVisible && userIsAllowedToInteractWithFileSystemEntity(fileSystemEntityInFolder, authenticatedUser, InteractionType.CHANGE)) {
+ fileSystemEntities.add(fileSystemEntityInFolder);
+ }
+ if (needsToBeVisible && needsToBeEditable && userIsAllowedToInteractWithFileSystemEntity(fileSystemEntityInFolder, authenticatedUser, InteractionType.READ) && userIsAllowedToInteractWithFileSystemEntity(fileSystemEntityInFolder, authenticatedUser, InteractionType.CHANGE)) {
+ fileSystemEntities.add(fileSystemEntityInFolder);
+ }
+ if (!needsToBeVisible && !needsToBeEditable) {
+ fileSystemEntities.add(fileSystemEntityInFolder);
+ }
+ }
+ return fileSystemEntities;
+ }
+
+ @SuppressWarnings("java:S3776")
+ public boolean userIsAllowedToInteractWithFileSystemEntity(FileSystemEntity fileSystemEntity, User authenticatedUser, InteractionType interaction) {
+ // file was created by runtime user.
+ if ((interaction == InteractionType.DELETE)
+ && fileSystemEntity.getLastUpdatedBy() == RestConfiguration.RUNTIME_USER_ID)
+ return false;
+
+ // user own the file.
+ if (fileSystemEntity.getOwnerId() == authenticatedUser.getUserId())
+ return true;
+
+ // user got the item shared.
+ if (interaction == InteractionType.READ) {
+ for (long userId : fileSystemEntity.getVisibleForUserIds()) {
+ if (userId == authenticatedUser.getUserId())
+ return true;
+ }
+
+ // user is in group that got the item shared.
+ long[] fileIsSharedToGroups = fileSystemEntity.getVisibleForGroupIds();
+ for (Group group : authenticatedUser.getGroups()) {
+ for (long groupId : fileIsSharedToGroups) {
+ if (groupId == group.getGroupId())
+ return true;
+
+ }
+ }
+ }
+ if (interaction == InteractionType.CHANGE || interaction == InteractionType.DELETE) {
+ for (long userId : fileSystemEntity.getEditableForUserIds()) {
+ if (userId == authenticatedUser.getUserId())
+ return true;
+ }
+
+ // user is in group that got the item shared.
+ long[] fileIsSharedToGroups = fileSystemEntity.getEditableFoGroupIds();
+ for (Group group : authenticatedUser.getGroups()) {
+ for (long groupId : fileIsSharedToGroups) {
+ if (groupId == group.getGroupId())
+ return true;
+
+ }
+ }
+ }
+ return false;
+ }
+
+ public String removeTrailingBackSlashes(String pathToFind) {
+ char[] chars = pathToFind.toCharArray();
+ // for the case of "/"
+ if (chars.length != 1 && chars[chars.length - 1] == '/') {
+ chars = Arrays.copyOf(chars, chars.length - 1);
+ return new String(chars);
+ }
+ return pathToFind;
+ }
+
+ public FileSystemItem createDTO(FileSystemEntity fileSystemEntity, User authenticatedUser, String absolutePathWithUsername) {
+ // for better responses and internal problem handling.
+ User ownerOfFileSystemItem;
+ User lastUpdatedByUser;
+ try {
+ ownerOfFileSystemItem = userBusinessService.getUserById(fileSystemEntity.getOwnerId());
+ lastUpdatedByUser = userBusinessService.getUserById(fileSystemEntity.getLastUpdatedBy());
+ } catch (UserNotFoundException exception) {
+ log.debug("Found UserNotFoundException in createDTO. Entity: {}.", fileSystemEntity);
+ throw new FileFighterDataException("Owner or auther of last change could not be found.");
+ }
+
+ boolean isShared = ownerOfFileSystemItem.getUserId() != RestConfiguration.RUNTIME_USER_ID
+ && ownerOfFileSystemItem.getUserId() != authenticatedUser.getUserId();
+ FileSystemType type = fileSystemTypeRepository.findFileSystemTypeById(fileSystemEntity.getTypeId());
+ boolean isAFolder = type == FileSystemType.FOLDER && !fileSystemEntity.isFile();
+ String entityName = fileSystemEntity.getName();
+
+ if (absolutePathWithUsername != null) {
+ if (absolutePathWithUsername.equals("/")) {
+ absolutePathWithUsername = absolutePathWithUsername + ownerOfFileSystemItem.getUsername(); // this is only for the case of the path = "/"
+ entityName = ownerOfFileSystemItem.getUsername();
+ } else {
+ absolutePathWithUsername = this.removeTrailingBackSlashes(absolutePathWithUsername) + "/" + fileSystemEntity.getName();
+ }
+ }
+
+ return FileSystemItem.builder()
+ .lastUpdatedBy(lastUpdatedByUser)
+ .fileSystemId(fileSystemEntity.getFileSystemId())
+ .owner(ownerOfFileSystemItem)
+ .lastUpdated(fileSystemEntity.getLastUpdated())
+ .name(entityName)
+ .size(fileSystemEntity.getSize())
+ .type(isAFolder ? FileSystemType.FOLDER : type)
+ .path(absolutePathWithUsername)
+ .isShared(isShared)
+ .mimeType(fileSystemEntity.getMimeType())
+ .build();
+ }
+
+ public void createBasicFilesForNewUser(UserEntity registeredUserEntity) {
+ fileSystemRepository.save(FileSystemEntity
+ .builder()
+ .fileSystemId(generateNextFileSystemId())
+ .ownerId(registeredUserEntity.getUserId())
+ .lastUpdatedBy(RestConfiguration.RUNTIME_USER_ID)
+ .lastUpdated(getCurrentTimeStamp())
+ .typeId(FileSystemType.FOLDER.getId())
+ .isFile(false)
+ .name("HOME_" + registeredUserEntity.getUserId())
+ .path("/")
+ .lastUpdated(Instant.now().getEpochSecond())
+ .size(0)
+ .mimeType(null)
+ .build());
+ }
+
+ public void deleteAndUnbindFileSystemEntity(FileSystemEntity fileSystemEntity) {
+ Long countDeleted = fileSystemRepository.deleteByFileSystemId(fileSystemEntity.getFileSystemId());
+ if (countDeleted != 1)
+ throw new FileFighterDataException(DELETION_FAILED_MSG + fileSystemEntity.getFileSystemId());
+
+ Query query = new Query().addCriteria(Criteria.where("itemIds").is(fileSystemEntity.getFileSystemId()));
+ Update newUpdate;
+
+ // TODO: fix this sizing.
+ // only reduce size if the entity is a file.
+ if (fileSystemEntity.isFile() && fileSystemTypeRepository.findFileSystemTypeById(fileSystemEntity.getTypeId()) != FileSystemType.FOLDER) {
+ newUpdate = new Update().pull("itemIds", fileSystemEntity.getFileSystemId()).inc("size", fileSystemEntity.getSize() * -1); // hacky stuff.
+ } else {
+ newUpdate = new Update().pull("itemIds", fileSystemEntity.getFileSystemId());
+ }
+ mongoTemplate.findAndModify(query, newUpdate, FileSystemEntity.class);
+ }
+
+ public void recursivlyUpdateTimeStamps(FileSystemEntity currentEntity, User autheticatedUser, long currentTimeStamp) {
+ Query query = new Query().addCriteria(Criteria.where("fileSystemId").is(currentEntity.getFileSystemId()));
+ Update update = new Update().set("lastUpdated", currentTimeStamp).set("lastUpdatedBy", autheticatedUser.getUserId());
+ mongoTemplate.findAndModify(query, update, FileSystemEntity.class);
+
+ Query queryParentEntity = new Query().addCriteria(Criteria.where("itemIds").is(currentEntity.getFileSystemId()));
+ List parentFileSystemEntities = mongoTemplate.find(queryParentEntity, FileSystemEntity.class);
+
+ if (parentFileSystemEntities.isEmpty()) {
+ // no parents found -> either root folder or an exception
+ boolean isFile = currentEntity.isFile() && currentEntity.getTypeId() != FileSystemType.FOLDER.getId();
+ boolean isRootFolder = !isFile && currentEntity.getPath().equals("/");
+ if (!isRootFolder) {
+ log.debug("Found no parent entity for a non root entity: " + currentEntity);
+ throw new FileFighterDataException("Found no parent entity for a non root entity.");
+ }
+ // else return.
+ } else {
+ if (parentFileSystemEntities.size() > 1) {
+ log.debug("Found more than one parent entity for entity: " + currentEntity);
+ throw new FileFighterDataException("Found more than one parent entity for entity.");
+ }
+
+ recursivlyUpdateTimeStamps(parentFileSystemEntities.get(0), autheticatedUser, currentTimeStamp);
+ }
+ }
+
+ public double getTotalFileSize() {
+ ArrayList entities = fileSystemRepository.findByPath("/");
+ if (null == entities)
+ throw new FileFighterDataException("Couldn't find any Home directories!");
+
+ double size = 0;
+ for (FileSystemEntity entity : entities) {
+ size += entity.getSize();
+ }
+ return size;
+ }
+
+ public long getFileSystemEntityCount() {
+ return fileSystemRepository.count();
+ }
+
+ // This will update the field. -> Everytime this function gets called a id gets taken. Which means some ids could be lost, when calling this function and not creating something.
+ public long generateNextFileSystemId() {
+ return getFileSystemEntityCount() + 1;
+ }
+
+ public long getCurrentTimeStamp() {
+ return Instant.now().getEpochSecond();
+ }
+}
diff --git a/src/main/java/de/filefighter/rest/domain/filesystem/data/InteractionType.java b/src/main/java/de/filefighter/rest/domain/filesystem/data/InteractionType.java
new file mode 100644
index 00000000..9ea77d94
--- /dev/null
+++ b/src/main/java/de/filefighter/rest/domain/filesystem/data/InteractionType.java
@@ -0,0 +1,7 @@
+package de.filefighter.rest.domain.filesystem.data;
+
+public enum InteractionType {
+ READ,
+ CHANGE,
+ DELETE
+}
diff --git a/src/main/java/de/filefighter/rest/domain/filesystem/data/dto/FileSystemItem.java b/src/main/java/de/filefighter/rest/domain/filesystem/data/dto/FileSystemItem.java
index 1768d341..df151489 100644
--- a/src/main/java/de/filefighter/rest/domain/filesystem/data/dto/FileSystemItem.java
+++ b/src/main/java/de/filefighter/rest/domain/filesystem/data/dto/FileSystemItem.java
@@ -15,8 +15,10 @@ public class FileSystemItem {
private String name;
private boolean isShared;
private double size;
- private User createdByUser; //uploadedBy
+ private User owner;
+ private User lastUpdatedBy;
private long lastUpdated;
private FileSystemType type;
+ private String mimeType;
}
diff --git a/src/main/java/de/filefighter/rest/domain/filesystem/data/dto/FileSystemItemUpdate.java b/src/main/java/de/filefighter/rest/domain/filesystem/data/dto/FileSystemItemUpdate.java
index 1110d6d3..f5e425d6 100644
--- a/src/main/java/de/filefighter/rest/domain/filesystem/data/dto/FileSystemItemUpdate.java
+++ b/src/main/java/de/filefighter/rest/domain/filesystem/data/dto/FileSystemItemUpdate.java
@@ -4,10 +4,14 @@
import lombok.Builder;
import lombok.Data;
+import java.util.List;
+
@Data
@Builder
public class FileSystemItemUpdate {
private String name;
private FileSystemType type;
private double size;
+ private boolean isInRoot;
+ private List children;
}
diff --git a/src/main/java/de/filefighter/rest/domain/filesystem/data/persistence/FileSystemEntity.java b/src/main/java/de/filefighter/rest/domain/filesystem/data/persistence/FileSystemEntity.java
index 8cc710d9..ca143f6f 100644
--- a/src/main/java/de/filefighter/rest/domain/filesystem/data/persistence/FileSystemEntity.java
+++ b/src/main/java/de/filefighter/rest/domain/filesystem/data/persistence/FileSystemEntity.java
@@ -18,14 +18,15 @@ public class FileSystemEntity {
private String path;
@Builder.Default
private long typeId = -1;
+ private String mimeType;
private double size;
private long lastUpdated;
@Builder.Default
- private boolean isFile = true;
+ private long lastUpdatedBy = -1;
@Builder.Default
- private long createdByUserId = -1;
+ private boolean isFile = true;
@Builder.Default
- private long[] ownerIds = new long[0];
+ private long ownerId = -1;
@Builder.Default
private long[] visibleForGroupIds = new long[0];
@Builder.Default
diff --git a/src/main/java/de/filefighter/rest/domain/filesystem/rest/FileSystemRestController.java b/src/main/java/de/filefighter/rest/domain/filesystem/rest/FileSystemRestController.java
index 45544f3f..d0337a85 100644
--- a/src/main/java/de/filefighter/rest/domain/filesystem/rest/FileSystemRestController.java
+++ b/src/main/java/de/filefighter/rest/domain/filesystem/rest/FileSystemRestController.java
@@ -2,13 +2,13 @@
import de.filefighter.rest.domain.filesystem.data.dto.FileSystemItem;
import de.filefighter.rest.domain.filesystem.data.dto.FileSystemItemUpdate;
-import de.filefighter.rest.rest.ServerResponse;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.log4j.Log4j2;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
+import java.util.List;
import static de.filefighter.rest.configuration.RestConfiguration.*;
@@ -27,7 +27,7 @@ public FileSystemRestController(FileSystemRestServiceInterface fileSystemRestSer
@GetMapping(FS_BASE_URI + "contents")
public ResponseEntity> getContentsOfFolder(
@RequestHeader(value = FS_PATH_HEADER, defaultValue = "/") String path,
- @RequestHeader(value = "Authorization", defaultValue = AUTHORIZATION_BEARER_PREFIX + "token") String accessToken
+ @RequestHeader(value = "Authorization") String accessToken
) {
log.info("Requested Folder contents of folder with path {}.", path);
@@ -37,49 +37,49 @@ public ResponseEntity> getContentsOfFolder(
@GetMapping(FS_BASE_URI + "{fsItemId}/info")
public ResponseEntity getFileOrFolderInfo(
@PathVariable long fsItemId,
- @RequestHeader(value = "Authorization", defaultValue = AUTHORIZATION_BEARER_PREFIX + "token") String accessToken
+ @RequestHeader(value = "Authorization") String accessToken
) {
log.info("Requested information about FileSystemItem with id {}.", fsItemId);
return fileSystemRestService.getInfoAboutFileOrFolderByIdAndAccessToken(fsItemId, accessToken);
}
- @GetMapping(FS_BASE_URI+"search")
+ @GetMapping(FS_BASE_URI + "search")
public ResponseEntity searchFileOrFolderByName(
@RequestParam(name = "name", defaultValue = "name") String name,
- @RequestHeader(value = "Authorization", defaultValue = AUTHORIZATION_BEARER_PREFIX + "token") String accessToken
- ){
+ @RequestHeader(value = "Authorization") String accessToken
+ ) {
log.info("Searching for file or folder with name {}", name);
return fileSystemRestService.findFileOrFolderByNameAndAccessToken(name, accessToken);
}
- @PostMapping(FS_BASE_URI+"upload")
+ @PostMapping(FS_BASE_URI + "upload")
public ResponseEntity uploadFileOrFolder(
@RequestBody FileSystemItemUpdate fileSystemItemUpdate,
- @RequestHeader(value = "Authorization", defaultValue = AUTHORIZATION_BEARER_PREFIX + "token") String accessToken
- ){
+ @RequestHeader(value = "Authorization") String accessToken
+ ) {
log.info("Tried uploading new FileSystemItem {}", fileSystemItemUpdate);
return fileSystemRestService.uploadFileSystemItemWithAccessToken(fileSystemItemUpdate, accessToken);
}
- @PutMapping(FS_BASE_URI+"{fsItemId}/update")
+ @PutMapping(FS_BASE_URI + "{fsItemId}/update")
public ResponseEntity updateExistingFileOrFolder(
@PathVariable long fsItemId,
@RequestBody FileSystemItemUpdate fileSystemItemUpdate,
- @RequestHeader(value = "Authorization", defaultValue = AUTHORIZATION_BEARER_PREFIX + "token") String accessToken
- ){
+ @RequestHeader(value = "Authorization") String accessToken
+ ) {
log.info("Tried updating FileSystemItem {} with {}.", fsItemId, fileSystemItemUpdate);
- return fileSystemRestService.updatedFileSystemItemWithIdAndAccessToken(fsItemId, fileSystemItemUpdate, accessToken);
+ return fileSystemRestService.updateFileSystemItemWithIdAndAccessToken(fsItemId, fileSystemItemUpdate, accessToken);
}
- @DeleteMapping(FS_BASE_URI+"{fsItemId}/delete")
- public ResponseEntity deleteFileOrFolder(
+ @DeleteMapping(FS_BASE_URI + "{fsItemId}/delete")
+ public ResponseEntity> deleteFileOrFolder(
@PathVariable long fsItemId,
- @RequestHeader(value = "Authorization", defaultValue = AUTHORIZATION_BEARER_PREFIX + "token") String accessToken
- ){
+ @RequestHeader(value = "Authorization") String accessToken
+ ) {
log.info("Tried deleting FileSystemItem with id {}", fsItemId);
return fileSystemRestService.deleteFileSystemItemWithIdAndAccessToken(fsItemId, accessToken);
diff --git a/src/main/java/de/filefighter/rest/domain/filesystem/rest/FileSystemRestService.java b/src/main/java/de/filefighter/rest/domain/filesystem/rest/FileSystemRestService.java
index ed469968..71e00ab1 100644
--- a/src/main/java/de/filefighter/rest/domain/filesystem/rest/FileSystemRestService.java
+++ b/src/main/java/de/filefighter/rest/domain/filesystem/rest/FileSystemRestService.java
@@ -1,33 +1,35 @@
package de.filefighter.rest.domain.filesystem.rest;
import de.filefighter.rest.domain.authentication.AuthenticationService;
-import de.filefighter.rest.domain.common.exceptions.InputSanitizerService;
+import de.filefighter.rest.domain.common.InputSanitizerService;
import de.filefighter.rest.domain.filesystem.business.FileSystemBusinessService;
import de.filefighter.rest.domain.filesystem.data.dto.FileSystemItem;
import de.filefighter.rest.domain.filesystem.data.dto.FileSystemItemUpdate;
import de.filefighter.rest.domain.user.data.dto.User;
-import de.filefighter.rest.rest.ServerResponse;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
+import java.util.List;
@Service
public class FileSystemRestService implements FileSystemRestServiceInterface {
private final FileSystemBusinessService fileSystemBusinessService;
private final AuthenticationService authenticationService;
+ private final InputSanitizerService inputSanitizerService;
- public FileSystemRestService(FileSystemBusinessService fileSystemBusinessService, AuthenticationService authenticationService) {
+ public FileSystemRestService(FileSystemBusinessService fileSystemBusinessService, AuthenticationService authenticationService, InputSanitizerService inputSanitizerService) {
this.fileSystemBusinessService = fileSystemBusinessService;
this.authenticationService = authenticationService;
+ this.inputSanitizerService = inputSanitizerService;
}
@Override
public ResponseEntity> getContentsOfFolderByPathAndAccessToken(String path, String accessTokenValue) {
User authenticatedUser = authenticationService.bearerAuthenticationWithAccessToken(accessTokenValue);
- String cleanPathString = InputSanitizerService.sanitizeString(path);
+ String cleanPathString = inputSanitizerService.sanitizePath(path);
ArrayList fileSystemItems = (ArrayList) fileSystemBusinessService.getFolderContentsByPath(cleanPathString, authenticatedUser);
return new ResponseEntity<>(fileSystemItems, HttpStatus.OK);
@@ -50,18 +52,13 @@ public ResponseEntity uploadFileSystemItemWithAccessToken(FileSy
}
@Override
- public ResponseEntity updatedFileSystemItemWithIdAndAccessToken(long fsItemId, FileSystemItemUpdate fileSystemItemUpdate, String accessToken) {
+ public ResponseEntity updateFileSystemItemWithIdAndAccessToken(long fsItemId, FileSystemItemUpdate fileSystemItemUpdate, String accessToken) {
return null;
}
@Override
- public ResponseEntity deleteFileSystemItemWithIdAndAccessToken(long fsItemId, String accessTokenValue) {
+ public ResponseEntity> deleteFileSystemItemWithIdAndAccessToken(long fsItemId, String accessTokenValue) {
User authenticatedUser = authenticationService.bearerAuthenticationWithAccessToken(accessTokenValue);
- boolean everythingWasDeleted = fileSystemBusinessService.deleteFileSystemItemById(fsItemId, authenticatedUser);
- if (everythingWasDeleted) {
- return new ResponseEntity<>(new ServerResponse(HttpStatus.OK, "Successfully deleted all requested FileSystemItems."), HttpStatus.OK);
- } else {
- return new ResponseEntity<>(new ServerResponse(HttpStatus.OK, "Not everything got deleted, because you are not allowed to edit some files."), HttpStatus.OK);
- }
+ return new ResponseEntity<>(fileSystemBusinessService.deleteFileSystemItemById(fsItemId, authenticatedUser), HttpStatus.OK);
}
}
diff --git a/src/main/java/de/filefighter/rest/domain/filesystem/rest/FileSystemRestServiceInterface.java b/src/main/java/de/filefighter/rest/domain/filesystem/rest/FileSystemRestServiceInterface.java
index b868aa7e..5217b07f 100644
--- a/src/main/java/de/filefighter/rest/domain/filesystem/rest/FileSystemRestServiceInterface.java
+++ b/src/main/java/de/filefighter/rest/domain/filesystem/rest/FileSystemRestServiceInterface.java
@@ -2,16 +2,21 @@
import de.filefighter.rest.domain.filesystem.data.dto.FileSystemItem;
import de.filefighter.rest.domain.filesystem.data.dto.FileSystemItemUpdate;
-import de.filefighter.rest.rest.ServerResponse;
import org.springframework.http.ResponseEntity;
import java.util.ArrayList;
+import java.util.List;
public interface FileSystemRestServiceInterface {
ResponseEntity> getContentsOfFolderByPathAndAccessToken(String path, String accessToken);
+
ResponseEntity getInfoAboutFileOrFolderByIdAndAccessToken(long fsItemId, String accessToken);
+
ResponseEntity findFileOrFolderByNameAndAccessToken(String name, String accessToken);
+
ResponseEntity uploadFileSystemItemWithAccessToken(FileSystemItemUpdate fileSystemItemUpdate, String accessToken);
- ResponseEntity updatedFileSystemItemWithIdAndAccessToken(long fsItemId, FileSystemItemUpdate fileSystemItemUpdate, String accessToken);
- ResponseEntity deleteFileSystemItemWithIdAndAccessToken(long fsItemId, String accessToken);
+
+ ResponseEntity updateFileSystemItemWithIdAndAccessToken(long fsItemId, FileSystemItemUpdate fileSystemItemUpdate, String accessToken);
+
+ ResponseEntity> deleteFileSystemItemWithIdAndAccessToken(long fsItemId, String accessToken);
}
diff --git a/src/main/java/de/filefighter/rest/domain/filesystem/type/FileSystemType.java b/src/main/java/de/filefighter/rest/domain/filesystem/type/FileSystemType.java
index cff30731..fc2bd93b 100644
--- a/src/main/java/de/filefighter/rest/domain/filesystem/type/FileSystemType.java
+++ b/src/main/java/de/filefighter/rest/domain/filesystem/type/FileSystemType.java
@@ -4,10 +4,10 @@ public enum FileSystemType {
UNDEFINED(-1),
FOLDER(0),
TEXT(1),
- PICTURE(2),
- PDF(3),
- AUDIO(4),
- VIDEO(5);
+ IMAGE(2),
+ AUDIO(3),
+ VIDEO(4),
+ APPLICATION(5);
private final long id;
diff --git a/src/main/java/de/filefighter/rest/domain/filesystem/type/FileSystemTypeRepository.java b/src/main/java/de/filefighter/rest/domain/filesystem/type/FileSystemTypeRepository.java
index a5c037f3..a666ad73 100644
--- a/src/main/java/de/filefighter/rest/domain/filesystem/type/FileSystemTypeRepository.java
+++ b/src/main/java/de/filefighter/rest/domain/filesystem/type/FileSystemTypeRepository.java
@@ -1,15 +1,42 @@
package de.filefighter.rest.domain.filesystem.type;
+import lombok.extern.log4j.Log4j2;
import org.springframework.stereotype.Service;
@Service
+@Log4j2
public class FileSystemTypeRepository {
- public FileSystemType findFileSystemTypeById(long id){
+ public FileSystemType findFileSystemTypeById(long id) {
FileSystemType[] values = FileSystemType.values();
- for(FileSystemType type : values){
- if(type.getId() == id) return type;
+ for (FileSystemType type : values) {
+ if (type.getId() == id) return type;
}
- throw new IllegalArgumentException("No FileSystemType found for id: "+ id);
+ throw new IllegalArgumentException("No FileSystemType found for id: " + id);
+ }
+
+ // https://www.sitepoint.com/mime-types-complete-list/
+ public FileSystemType parseMimeType(String mimeType) {
+ FileSystemType returnValue = FileSystemType.UNDEFINED;
+
+ // java sucks. Lets do kotlin next time.
+ if (null == mimeType) {
+ log.warn("Found null in mimeType");
+ return FileSystemType.UNDEFINED;
+ }
+
+ if (mimeType.contains("text/")) {
+ returnValue = FileSystemType.TEXT;
+ } else if (mimeType.contains("video/")) {
+ returnValue = FileSystemType.VIDEO;
+ } else if (mimeType.contains("audio/")) {
+ returnValue = FileSystemType.AUDIO;
+ } else if (mimeType.contains("image/")) {
+ returnValue = FileSystemType.IMAGE;
+ } else if (mimeType.contains("application/")) {
+ returnValue = FileSystemType.APPLICATION;
+ }
+
+ return returnValue;
}
}
diff --git a/src/main/java/de/filefighter/rest/domain/health/business/SystemHealthBusinessService.java b/src/main/java/de/filefighter/rest/domain/health/business/SystemHealthBusinessService.java
index 5d032d26..ce78be34 100644
--- a/src/main/java/de/filefighter/rest/domain/health/business/SystemHealthBusinessService.java
+++ b/src/main/java/de/filefighter/rest/domain/health/business/SystemHealthBusinessService.java
@@ -1,6 +1,6 @@
package de.filefighter.rest.domain.health.business;
-import de.filefighter.rest.domain.filesystem.business.FileSystemBusinessService;
+import de.filefighter.rest.domain.filesystem.business.FileSystemHelperService;
import de.filefighter.rest.domain.health.data.SystemHealth;
import de.filefighter.rest.domain.health.data.SystemHealth.DataIntegrity;
import de.filefighter.rest.domain.token.business.AccessTokenBusinessService;
@@ -16,7 +16,7 @@ public class SystemHealthBusinessService {
private final UserBusinessService userBusinessService;
private final AccessTokenBusinessService accessTokenBusinessService;
- private final FileSystemBusinessService fileSystemBusinessService;
+ private final FileSystemHelperService fileSystemHelperService;
private final Environment environment;
private final long serverStartedAt;
@@ -25,10 +25,10 @@ public class SystemHealthBusinessService {
@Value("${filefighter.version}")
String version;
- public SystemHealthBusinessService(UserBusinessService userBusinessService, AccessTokenBusinessService accessTokenBusinessService, FileSystemBusinessService fileSystemBusinessService, Environment environment) {
+ public SystemHealthBusinessService(UserBusinessService userBusinessService, AccessTokenBusinessService accessTokenBusinessService, FileSystemHelperService fileSystemHelperService, Environment environment) {
this.userBusinessService = userBusinessService;
this.accessTokenBusinessService = accessTokenBusinessService;
- this.fileSystemBusinessService = fileSystemBusinessService;
+ this.fileSystemHelperService = fileSystemHelperService;
this.environment = environment;
this.serverStartedAt = this.getCurrentEpochSeconds();
}
@@ -38,7 +38,7 @@ public SystemHealth getCurrentSystemHealthInfo() {
return SystemHealth.builder()
.uptimeInSeconds(currentEpoch - serverStartedAt)
.userCount(userBusinessService.getUserCount())
- .usedStorageInBytes(fileSystemBusinessService.getTotalFileSize())
+ .usedStorageInBytes(fileSystemHelperService.getTotalFileSize())
.dataIntegrity(calculateDataIntegrity())
.deployment(getDeploymentStatus())
.version("v" + this.version)
diff --git a/src/main/java/de/filefighter/rest/domain/user/business/UserBusinessService.java b/src/main/java/de/filefighter/rest/domain/user/business/UserBusinessService.java
index c3cb4269..9bb80493 100644
--- a/src/main/java/de/filefighter/rest/domain/user/business/UserBusinessService.java
+++ b/src/main/java/de/filefighter/rest/domain/user/business/UserBusinessService.java
@@ -22,7 +22,7 @@
import java.util.Arrays;
import java.util.regex.Pattern;
-import static de.filefighter.rest.domain.common.exceptions.InputSanitizerService.stringIsValid;
+import static de.filefighter.rest.domain.common.InputSanitizerService.stringIsValid;
@Service
public class UserBusinessService {
diff --git a/src/main/java/de/filefighter/rest/domain/user/rest/UserRestService.java b/src/main/java/de/filefighter/rest/domain/user/rest/UserRestService.java
index 8e3056fb..f8bb80da 100644
--- a/src/main/java/de/filefighter/rest/domain/user/rest/UserRestService.java
+++ b/src/main/java/de/filefighter/rest/domain/user/rest/UserRestService.java
@@ -1,8 +1,8 @@
package de.filefighter.rest.domain.user.rest;
import de.filefighter.rest.domain.authentication.AuthenticationService;
-import de.filefighter.rest.domain.common.exceptions.InputSanitizerService;
-import de.filefighter.rest.domain.filesystem.business.FileSystemBusinessService;
+import de.filefighter.rest.domain.common.InputSanitizerService;
+import de.filefighter.rest.domain.filesystem.business.FileSystemHelperService;
import de.filefighter.rest.domain.token.business.AccessTokenBusinessService;
import de.filefighter.rest.domain.token.data.dto.AccessToken;
import de.filefighter.rest.domain.token.data.dto.RefreshToken;
@@ -23,14 +23,16 @@ public class UserRestService implements UserRestServiceInterface {
private final UserBusinessService userBusinessService;
private final AccessTokenBusinessService accessTokenBusinessService;
- private final FileSystemBusinessService fileSystemBusinessService;
private final AuthenticationService authenticationService;
+ private final InputSanitizerService inputSanitizerService;
+ private final FileSystemHelperService fileSystemHelperService;
- public UserRestService(UserBusinessService userBusinessService, AccessTokenBusinessService accessTokenBusinessService, FileSystemBusinessService fileSystemBusinessService, AuthenticationService authenticationService) {
+ public UserRestService(UserBusinessService userBusinessService, AccessTokenBusinessService accessTokenBusinessService, AuthenticationService authenticationService, InputSanitizerService inputSanitizerService, FileSystemHelperService fileSystemHelperService) {
this.userBusinessService = userBusinessService;
this.accessTokenBusinessService = accessTokenBusinessService;
- this.fileSystemBusinessService = fileSystemBusinessService;
this.authenticationService = authenticationService;
+ this.inputSanitizerService = inputSanitizerService;
+ this.fileSystemHelperService = fileSystemHelperService;
}
@Override
@@ -66,13 +68,13 @@ public ResponseEntity updateUserByUserIdAuthenticateWithAccessTo
public ResponseEntity registerNewUserWithAccessToken(UserRegisterForm newUser, String accessTokenHeader) {
authenticationService.bearerAuthenticationWithAccessTokenAndGroup(accessTokenHeader, ADMIN);
UserEntity registeredUserEntity = userBusinessService.registerNewUser(newUser);
- fileSystemBusinessService.createBasicFilesForNewUser(registeredUserEntity);
+ fileSystemHelperService.createBasicFilesForNewUser(registeredUserEntity);
return new ResponseEntity<>(new ServerResponse(HttpStatus.CREATED, "User successfully created."), HttpStatus.CREATED);
}
@Override
public ResponseEntity findUserByUsernameAndAccessToken(String username, String accessTokenHeader) {
- String sanitizedUserName = InputSanitizerService.sanitizeString(username);
+ String sanitizedUserName = inputSanitizerService.sanitizeString(username);
authenticationService.bearerAuthenticationWithAccessToken(accessTokenHeader);
User foundUser = userBusinessService.findUserByUsername(sanitizedUserName);
return new ResponseEntity<>(foundUser, HttpStatus.OK);
diff --git a/src/main/resources/application-debug.properties b/src/main/resources/application-debug.properties
new file mode 100644
index 00000000..d897a5af
--- /dev/null
+++ b/src/main/resources/application-debug.properties
@@ -0,0 +1 @@
+logging.level.root=DEBUG
\ No newline at end of file
diff --git a/src/main/resources/application-test.properties b/src/main/resources/application-test.properties
new file mode 100644
index 00000000..d897a5af
--- /dev/null
+++ b/src/main/resources/application-test.properties
@@ -0,0 +1 @@
+logging.level.root=DEBUG
\ No newline at end of file
diff --git a/src/test/java/de/filefighter/rest/cucumber/CommonCucumberSteps.java b/src/test/java/de/filefighter/rest/cucumber/CommonCucumberSteps.java
index d0dca520..4c753d52 100644
--- a/src/test/java/de/filefighter/rest/cucumber/CommonCucumberSteps.java
+++ b/src/test/java/de/filefighter/rest/cucumber/CommonCucumberSteps.java
@@ -20,7 +20,10 @@
import org.springframework.data.mongodb.core.query.Update;
import java.io.IOException;
+import java.time.Instant;
+import static de.filefighter.rest.configuration.RestConfiguration.RUNTIME_USER_ID;
+import static de.filefighter.rest.domain.user.group.Group.SYSTEM;
import static org.junit.jupiter.api.Assertions.*;
@Log4j2
@@ -93,7 +96,19 @@ public void userWithIdIsInGroupWithId(long userId, long groupId) {
public void fileSystemItemWithTheFileSystemIdExistsAndHasThePath(long fileSystemId, long userId, String path, String name) {
fileSystemRepository.save(FileSystemEntity.builder()
.path(path)
- .createdByUserId(userId)
+ .ownerId(userId)
+ .lastUpdatedBy(userId)
+ .fileSystemId(fileSystemId)
+ .name(name)
+ .build());
+ }
+
+ @And("fileSystemItem with the fileSystemId {long} exists, has owner with userId {long} has the path {string} and name {string}")
+ public void filesystemitemWithTheFileSystemIdExistsHasOwnerWithUserIdHasThePathStringAndNameString(long fileSystemId, long ownerId, String path, String name) {
+ fileSystemRepository.save(FileSystemEntity.builder()
+ .path(path)
+ .lastUpdatedBy(ownerId)
+ .ownerId(ownerId)
.fileSystemId(fileSystemId)
.name(name)
.build());
@@ -103,7 +118,19 @@ public void fileSystemItemWithTheFileSystemIdExistsAndHasThePath(long fileSystem
public void fileSystemItemWithTheFileSystemIdExistsAndHasTheName(long fileSystemId, long userId, String name) {
fileSystemRepository.save(FileSystemEntity.builder()
.name(name)
- .createdByUserId(userId)
+ .ownerId(userId)
+ .lastUpdatedBy(userId)
+ .lastUpdated(Instant.now().getEpochSecond())
+ .fileSystemId(fileSystemId)
+ .build());
+ }
+
+ @And("fileSystemItem with the fileSystemId {long} exists, has owner with userId {int} and name {string}")
+ public void filesystemitemWithTheFileSystemIdExistsHasOwnerWithUserIdAndName(long fileSystemId, long ownerId, String name) {
+ fileSystemRepository.save(FileSystemEntity.builder()
+ .name(name)
+ .lastUpdatedBy(ownerId)
+ .ownerId(ownerId)
.fileSystemId(fileSystemId)
.build());
}
@@ -133,7 +160,7 @@ public void fileSystemItemWithTheFileSystemIdIsAFolder(long fileSystemId) {
public void userIsOwnerOfFileOrFolderWithId(long userId, long fsItemId) {
FileSystemEntity fileSystemEntity = fileSystemRepository.findByFileSystemId(fsItemId);
- fileSystemEntity.setCreatedByUserId(userId);
+ fileSystemEntity.setLastUpdatedBy(userId);
fileSystemRepository.save(fileSystemEntity);
}
@@ -167,6 +194,18 @@ public void responseContainsKeyAndValueOfAtLeast(String key, int value) throws J
assertTrue(actualValue >= value);
}
+ @And("response contains a valid timestamp at key {string}.")
+ public void responseContainsValidTimeStampAtKey(String key) throws JsonProcessingException {
+ JsonNode rootNode = objectMapper.readTree(latestResponse.getBody());
+ long actualValue = rootNode.get(key).asLong();
+
+ long validRange = 10;
+ long expected = Instant.now().getEpochSecond();
+
+ assertTrue(expected - validRange < actualValue && actualValue < expected + 10);
+ }
+
+
@And("response contains key {string} and a different value than {string}")
public void responseContainsKeyAndADifferentValueThan(String key, String differentValue) throws JsonProcessingException {
JsonNode rootNode = objectMapper.readTree(latestResponse.getBody());
@@ -175,4 +214,40 @@ public void responseContainsKeyAndADifferentValueThan(String key, String differe
assertNotEquals(differentValue, actualValue);
}
+ @And("user with userId {long} has HomeFolder with Id {long}")
+ public void userWithUserIdHasHomeFolderWithId(long userId, long folderId) {
+ fileSystemRepository.save(FileSystemEntity.builder()
+ .name("HOME_" + userId)
+ .lastUpdatedBy(RUNTIME_USER_ID)
+ .ownerId(userId)
+ .fileSystemId(folderId)
+ .path("/")
+ .typeId(0)
+ .isFile(false)
+ .editableForUserIds(new long[]{userId})
+ .build());
+ }
+
+ @And("runtime user exists")
+ public void runtimeUserExists() {
+ userRepository.save(UserEntity
+ .builder()
+ .userId(RUNTIME_USER_ID)
+ .username("FileFighter")
+ .lowercaseUsername("filefighter")
+ .password(null)
+ .refreshToken(null)
+ .groupIds(new long[]{SYSTEM.getGroupId()})
+ .build());
+ }
+
+
+ @And("response contains the user with userId {long} at key {string}")
+ public void responseContainsTheUserWithUserIdAtKey(long userId, String key) throws JsonProcessingException {
+ JsonNode rootNode = objectMapper.readTree(latestResponse.getBody());
+ JsonNode userNode = rootNode.get(key);
+ long actualUserId = userNode.get("userId").asLong();
+
+ assertEquals(userId, actualUserId);
+ }
}
diff --git a/src/test/java/de/filefighter/rest/cucumber/CrudFileSystemSteps.java b/src/test/java/de/filefighter/rest/cucumber/CrudFileSystemSteps.java
index e76d906e..48fcc8e8 100644
--- a/src/test/java/de/filefighter/rest/cucumber/CrudFileSystemSteps.java
+++ b/src/test/java/de/filefighter/rest/cucumber/CrudFileSystemSteps.java
@@ -29,4 +29,16 @@ public void userWithTokenWantsToDeleteTheFileSystemItemWithTheFileSystemId(Strin
executeRestApiCall(HttpMethod.DELETE, BASE_API_URI + FS_BASE_URI + fileSystemId + "/delete", authHeader);
}
+
+ @When("user with token {string} wants to get the info of fileSystemItem with the fileSystemId {long}")
+ public void userWithTokenWantsToGetTheInfoOfFileSystemItemWithTheFileSystemId(String accessTokenValue, long fileSystemId) {
+ String authHeaderString = AUTHORIZATION_BEARER_PREFIX + accessTokenValue;
+
+ HashMap authHeader = new HashMap<>();
+ authHeader.put("Authorization", authHeaderString);
+
+ executeRestApiCall(HttpMethod.GET, BASE_API_URI + FS_BASE_URI + fileSystemId + "/info", authHeader);
+
+ }
+
}
diff --git a/src/test/java/de/filefighter/rest/cucumber/ViewFolderContentsSteps.java b/src/test/java/de/filefighter/rest/cucumber/ViewFolderContentsSteps.java
index 73bfec8e..8119da7d 100644
--- a/src/test/java/de/filefighter/rest/cucumber/ViewFolderContentsSteps.java
+++ b/src/test/java/de/filefighter/rest/cucumber/ViewFolderContentsSteps.java
@@ -7,14 +7,13 @@
import de.filefighter.rest.RestApplicationIntegrationTest;
import io.cucumber.java.en.And;
import io.cucumber.java.en.When;
+import org.junit.jupiter.api.Assertions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpMethod;
import java.util.HashMap;
import static de.filefighter.rest.configuration.RestConfiguration.*;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
public class ViewFolderContentsSteps extends RestApplicationIntegrationTest {
@@ -50,7 +49,22 @@ public void theResponseContainsTheFileWithIdAndName(long fsItemId, String name)
!node.get("type").asText().equals("FOLDER"))
found = true;
}
- assertTrue(found);
+ Assertions.assertTrue(found);
+ }
+
+ @And("the response contains the file with name {string}")
+ public void theResponseContainsTheFileWithName(String name) throws JsonProcessingException {
+ ArrayNode rootNode = (ArrayNode) objectMapper.readTree(latestResponse.getBody());
+ if (!rootNode.isContainerNode() || rootNode.isEmpty())
+ throw new AssertionError("Response was not an Array or empty.");
+
+ boolean found = false;
+ for (JsonNode node : rootNode) {
+ if (node.get("name").asText().equals(name) &&
+ !node.get("type").asText().equals("FOLDER"))
+ found = true;
+ }
+ Assertions.assertTrue(found);
}
@And("the response contains an empty list for files and folders")
@@ -59,7 +73,7 @@ public void theResponseContainsAnEmptyListForFilesAndFolders() throws JsonProces
if (!rootNode.isContainerNode())
throw new AssertionError("Response was not an Array or empty.");
- assertTrue(rootNode.isEmpty());
+ Assertions.assertTrue(rootNode.isEmpty());
}
@And("the response does not contains the file with fileSystemId {long} and name {string}")
@@ -77,7 +91,7 @@ public void theResponseNotContainsTheFileWithFileSystemIdAndName(long fsItemId,
found = true;
}
}
- assertFalse(found);
+ Assertions.assertFalse(found);
}
}
@@ -94,6 +108,23 @@ public void theResponseContainsTheFolderWithFileSystemIdAndName(long fileSystemI
node.get("type").asText().equals("FOLDER"))
found = true;
}
- assertTrue(found);
+ Assertions.assertTrue(found);
+ }
+
+ @And("the response contains the folder with name {string}")
+ public void theResponseContainsTheFolderWithName(String name) throws JsonProcessingException {
+ ArrayNode rootNode = (ArrayNode) objectMapper.readTree(latestResponse.getBody());
+ if (!rootNode.isContainerNode() || rootNode.isEmpty())
+ throw new AssertionError("Response was not an Array or empty.");
+
+ boolean found = false;
+ for (JsonNode node : rootNode) {
+ if (node.get("name").asText().equals(name) &&
+ node.get("type").asText().equals("FOLDER"))
+ found = true;
+ }
+ Assertions.assertTrue(found);
}
+
+
}
diff --git a/src/test/java/de/filefighter/rest/domain/authentication/AuthenticationBusinessServiceUnitTest.java b/src/test/java/de/filefighter/rest/domain/authentication/AuthenticationBusinessServiceUnitTest.java
index efc07a95..db735566 100644
--- a/src/test/java/de/filefighter/rest/domain/authentication/AuthenticationBusinessServiceUnitTest.java
+++ b/src/test/java/de/filefighter/rest/domain/authentication/AuthenticationBusinessServiceUnitTest.java
@@ -1,5 +1,6 @@
package de.filefighter.rest.domain.authentication;
+import de.filefighter.rest.domain.common.InputSanitizerService;
import de.filefighter.rest.domain.common.exceptions.RequestDidntMeetFormalRequirementsException;
import de.filefighter.rest.domain.token.data.dto.AccessToken;
import de.filefighter.rest.domain.user.business.UserDTOService;
@@ -19,9 +20,10 @@ class AuthenticationBusinessServiceUnitTest {
private final UserRepository userRepositoryMock = mock(UserRepository.class);
private final UserDTOService userDtoServiceMock = mock(UserDTOService.class);
+ private final InputSanitizerService inputSanitizerServiceMock = mock(InputSanitizerService.class);
private final AuthenticationBusinessService authenticationBusinessService = new AuthenticationBusinessService(
userRepositoryMock,
- userDtoServiceMock);
+ userDtoServiceMock, inputSanitizerServiceMock);
@Test
void authenticateUserWithUsernameAndPasswordThrows() {
@@ -52,6 +54,8 @@ void authenticateUserWithUsernameAndPasswordWorksCorrectly() {
when(userRepositoryMock.findByLowercaseUsernameAndPassword("user", "password")).thenReturn(dummyEntity);
when(userDtoServiceMock.createDto(dummyEntity)).thenReturn(dummyUser);
+ when(inputSanitizerServiceMock.sanitizeString("user")).thenReturn("user");
+ when(inputSanitizerServiceMock.sanitizeString("password")).thenReturn("password");
User actual = authenticationBusinessService.authenticateUserWithUsernameAndPassword(usernameAndPassword);
assertEquals(dummyUser, actual);
diff --git a/src/test/java/de/filefighter/rest/domain/common/InputSanitizerServiceUnitTest.java b/src/test/java/de/filefighter/rest/domain/common/InputSanitizerServiceUnitTest.java
index 4e7cb15f..9ab14537 100644
--- a/src/test/java/de/filefighter/rest/domain/common/InputSanitizerServiceUnitTest.java
+++ b/src/test/java/de/filefighter/rest/domain/common/InputSanitizerServiceUnitTest.java
@@ -1,6 +1,5 @@
package de.filefighter.rest.domain.common;
-import de.filefighter.rest.domain.common.exceptions.InputSanitizerService;
import de.filefighter.rest.domain.common.exceptions.RequestDidntMeetFormalRequirementsException;
import org.junit.jupiter.api.Test;
@@ -25,12 +24,12 @@ void sanitizeStringThrows() {
String string1 = null;
RequestDidntMeetFormalRequirementsException ex = assertThrows(RequestDidntMeetFormalRequirementsException.class, () ->
- InputSanitizerService.sanitizeString(string0));
- assertEquals(RequestDidntMeetFormalRequirementsException.getErrorMessagePrefix()+" String was empty.", ex.getMessage());
+ inputSanitizerService.sanitizeString(string0));
+ assertEquals(RequestDidntMeetFormalRequirementsException.getErrorMessagePrefix() + " String was empty.", ex.getMessage());
ex = assertThrows(RequestDidntMeetFormalRequirementsException.class, () ->
- InputSanitizerService.sanitizeString(string1));
- assertEquals(RequestDidntMeetFormalRequirementsException.getErrorMessagePrefix()+" String was empty.", ex.getMessage());
+ inputSanitizerService.sanitizeString(string1));
+ assertEquals(RequestDidntMeetFormalRequirementsException.getErrorMessagePrefix() + " String was empty.", ex.getMessage());
}
@Test
@@ -40,8 +39,8 @@ void sanitizeStringWorks() {
String string0valid = "aaabbbbbbb";
String string1valid = "asd";
- assertEquals(string0valid, InputSanitizerService.sanitizeString(string0));
- assertEquals(string1valid, InputSanitizerService.sanitizeString(string1));
+ assertEquals(string0valid, inputSanitizerService.sanitizeString(string0));
+ assertEquals(string1valid, inputSanitizerService.sanitizeString(string1));
}
@Test
@@ -54,19 +53,19 @@ void sanitizeRequestHeaderThrows() {
RequestDidntMeetFormalRequirementsException ex = assertThrows(RequestDidntMeetFormalRequirementsException.class, () ->
inputSanitizerService.sanitizeRequestHeader(header, string0));
- assertEquals(RequestDidntMeetFormalRequirementsException.getErrorMessagePrefix()+" Header does not contain a valid String.", ex.getMessage());
+ assertEquals(RequestDidntMeetFormalRequirementsException.getErrorMessagePrefix() + " Header does not contain a valid String.", ex.getMessage());
ex = assertThrows(RequestDidntMeetFormalRequirementsException.class, () ->
inputSanitizerService.sanitizeRequestHeader(header, string1));
- assertEquals(RequestDidntMeetFormalRequirementsException.getErrorMessagePrefix()+" Header does not contain a valid String.", ex.getMessage());
+ assertEquals(RequestDidntMeetFormalRequirementsException.getErrorMessagePrefix() + " Header does not contain a valid String.", ex.getMessage());
ex = assertThrows(RequestDidntMeetFormalRequirementsException.class, () ->
inputSanitizerService.sanitizeRequestHeader(header, string2));
- assertEquals(RequestDidntMeetFormalRequirementsException.getErrorMessagePrefix()+" Header does not contain '" + header + "', or format is invalid.", ex.getMessage());
+ assertEquals(RequestDidntMeetFormalRequirementsException.getErrorMessagePrefix() + " Header does not contain '" + header + "', or format is invalid.", ex.getMessage());
ex = assertThrows(RequestDidntMeetFormalRequirementsException.class, () ->
inputSanitizerService.sanitizeRequestHeader(header, string3));
- assertEquals(RequestDidntMeetFormalRequirementsException.getErrorMessagePrefix()+" Header does not contain '" + header + "', or format is invalid.", ex.getMessage());
+ assertEquals(RequestDidntMeetFormalRequirementsException.getErrorMessagePrefix() + " Header does not contain '" + header + "', or format is invalid.", ex.getMessage());
}
@@ -88,11 +87,11 @@ void sanitizeTokenThrows() {
RequestDidntMeetFormalRequirementsException ex = assertThrows(RequestDidntMeetFormalRequirementsException.class, () ->
inputSanitizerService.sanitizeTokenValue(string0));
- assertEquals(RequestDidntMeetFormalRequirementsException.getErrorMessagePrefix()+" String was empty.", ex.getMessage());
+ assertEquals(RequestDidntMeetFormalRequirementsException.getErrorMessagePrefix() + " String was empty.", ex.getMessage());
ex = assertThrows(RequestDidntMeetFormalRequirementsException.class, () ->
inputSanitizerService.sanitizeTokenValue(string1));
- assertEquals(RequestDidntMeetFormalRequirementsException.getErrorMessagePrefix()+" String was empty.", ex.getMessage());
+ assertEquals(RequestDidntMeetFormalRequirementsException.getErrorMessagePrefix() + " String was empty.", ex.getMessage());
}
@@ -107,4 +106,46 @@ void sanitizeTokenWorks() {
assertEquals(string1valid, inputSanitizerService.sanitizeTokenValue(string1));
}
+ @Test
+ void sanitizePathThrows() {
+ String working0 = "/ foo / bar / ";
+ String working1 = "foo/bar/foobar";
+ String working2 = "foo/bar/foo-bar.txt";
+ String working3 = "foo/bar/foo_bar_BAUM_ASDASD.txt";
+ String nonWorking0 = "//foo/bar";
+ String nonWorking1 = "\\/foo/bar";
+ String nonWorking2 = "/~foo/bar";
+ String nonWorking3 = "/*()foo/bar";
+ String nonWorking4 = "/?foo/bar";
+ String nonWorking5 = "\\\\foo/bar";
+
+ assertEquals("/foo/bar/", inputSanitizerService.sanitizePath(working0));
+ assertEquals("foo/bar/foobar", inputSanitizerService.sanitizePath(working1));
+ assertEquals("foo/bar/foo-bar.txt", inputSanitizerService.sanitizePath(working2));
+ assertEquals("foo/bar/foo_bar_BAUM_ASDASD.txt", inputSanitizerService.sanitizePath(working3));
+
+ RequestDidntMeetFormalRequirementsException ex = assertThrows(RequestDidntMeetFormalRequirementsException.class, () ->
+ inputSanitizerService.sanitizePath(nonWorking0));
+ assertEquals(RequestDidntMeetFormalRequirementsException.getErrorMessagePrefix() + " Path was not valid.", ex.getMessage());
+
+ ex = assertThrows(RequestDidntMeetFormalRequirementsException.class, () ->
+ inputSanitizerService.sanitizePath(nonWorking1));
+ assertEquals(RequestDidntMeetFormalRequirementsException.getErrorMessagePrefix() + " Path was not valid.", ex.getMessage());
+
+ ex = assertThrows(RequestDidntMeetFormalRequirementsException.class, () ->
+ inputSanitizerService.sanitizePath(nonWorking2));
+ assertEquals(RequestDidntMeetFormalRequirementsException.getErrorMessagePrefix() + " Path was not valid.", ex.getMessage());
+
+ ex = assertThrows(RequestDidntMeetFormalRequirementsException.class, () ->
+ inputSanitizerService.sanitizePath(nonWorking3));
+ assertEquals(RequestDidntMeetFormalRequirementsException.getErrorMessagePrefix() + " Path was not valid.", ex.getMessage());
+
+ ex = assertThrows(RequestDidntMeetFormalRequirementsException.class, () ->
+ inputSanitizerService.sanitizePath(nonWorking4));
+ assertEquals(RequestDidntMeetFormalRequirementsException.getErrorMessagePrefix() + " Path was not valid.", ex.getMessage());
+
+ ex = assertThrows(RequestDidntMeetFormalRequirementsException.class, () ->
+ inputSanitizerService.sanitizePath(nonWorking5));
+ assertEquals(RequestDidntMeetFormalRequirementsException.getErrorMessagePrefix() + " Path was not valid.", ex.getMessage());
+ }
}
\ No newline at end of file
diff --git a/src/test/java/de/filefighter/rest/domain/filesystem/business/FileSystemBusinessServiceUnitTest.java b/src/test/java/de/filefighter/rest/domain/filesystem/business/FileSystemBusinessServiceUnitTest.java
index b0b02559..e5bb5c70 100644
--- a/src/test/java/de/filefighter/rest/domain/filesystem/business/FileSystemBusinessServiceUnitTest.java
+++ b/src/test/java/de/filefighter/rest/domain/filesystem/business/FileSystemBusinessServiceUnitTest.java
@@ -2,25 +2,27 @@
import de.filefighter.rest.configuration.RestConfiguration;
import de.filefighter.rest.domain.common.exceptions.FileFighterDataException;
+import de.filefighter.rest.domain.filesystem.data.InteractionType;
import de.filefighter.rest.domain.filesystem.data.dto.FileSystemItem;
import de.filefighter.rest.domain.filesystem.data.persistence.FileSystemEntity;
import de.filefighter.rest.domain.filesystem.data.persistence.FileSystemRepository;
import de.filefighter.rest.domain.filesystem.exceptions.FileSystemContentsNotAccessibleException;
import de.filefighter.rest.domain.filesystem.exceptions.FileSystemItemCouldNotBeDeletedException;
import de.filefighter.rest.domain.filesystem.exceptions.FileSystemItemNotFoundException;
-import de.filefighter.rest.domain.filesystem.type.FileSystemType;
import de.filefighter.rest.domain.filesystem.type.FileSystemTypeRepository;
import de.filefighter.rest.domain.user.business.UserBusinessService;
import de.filefighter.rest.domain.user.data.dto.User;
import de.filefighter.rest.domain.user.exceptions.UserNotFoundException;
import de.filefighter.rest.domain.user.group.Group;
import org.junit.jupiter.api.Test;
-import org.mockito.ArgumentCaptor;
-import org.springframework.data.mongodb.core.MongoTemplate;
-import org.springframework.data.mongodb.core.query.Update;
import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import static de.filefighter.rest.domain.filesystem.type.FileSystemType.FOLDER;
+import static de.filefighter.rest.domain.filesystem.type.FileSystemType.TEXT;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.*;
@@ -29,21 +31,24 @@ class FileSystemBusinessServiceUnitTest {
private final FileSystemRepository fileSystemRepositoryMock = mock(FileSystemRepository.class);
private final UserBusinessService userBusinessServiceMock = mock(UserBusinessService.class);
private final FileSystemTypeRepository fileSystemTypeRepositoryMock = mock(FileSystemTypeRepository.class);
- private final MongoTemplate mongoTemplateMock = mock(MongoTemplate.class);
- private final FileSystemBusinessService fileSystemBusinessService = new FileSystemBusinessService(fileSystemRepositoryMock, userBusinessServiceMock, fileSystemTypeRepositoryMock, mongoTemplateMock);
+ private final FileSystemHelperService fileSystemHelperServiceMock = mock(FileSystemHelperService.class);
+
+ private final FileSystemBusinessService fileSystemBusinessService = new FileSystemBusinessService(fileSystemRepositoryMock, fileSystemHelperServiceMock, fileSystemTypeRepositoryMock, userBusinessServiceMock);
@Test
void getFolderContentsByPathThrows() {
String notValid = "";
String wrongFormat = "asd";
String wrongFormat1 = "as/d";
- String validPath = "/uga/uga/as/sasda/sassasd";
+ String validUsername = "kevin";
+ String validPathToFind = "/path";
+ String validPath = "/" + validUsername + validPathToFind;
User dummyUser = User.builder().userId(0).build();
FileSystemContentsNotAccessibleException ex = assertThrows(FileSystemContentsNotAccessibleException.class, () ->
fileSystemBusinessService.getFolderContentsByPath(notValid, dummyUser));
- assertEquals(FileSystemContentsNotAccessibleException.getErrorMessagePrefix() + " Path was not valid.", ex.getMessage());
+ assertEquals(FileSystemContentsNotAccessibleException.getErrorMessagePrefix() + " Path was in wrong format.", ex.getMessage());
ex = assertThrows(FileSystemContentsNotAccessibleException.class, () ->
fileSystemBusinessService.getFolderContentsByPath(wrongFormat, dummyUser));
@@ -54,6 +59,8 @@ void getFolderContentsByPathThrows() {
assertEquals(FileSystemContentsNotAccessibleException.getErrorMessagePrefix() + " Path was in wrong format. Use a leading backslash.", ex.getMessage());
when(fileSystemRepositoryMock.findByPath(validPath)).thenReturn(null);
+ when(userBusinessServiceMock.findUserByUsername(validUsername)).thenReturn(User.builder().username(validUsername + "somethingelse").build());
+ when(fileSystemHelperServiceMock.removeTrailingBackSlashes(validPath)).thenReturn(validPath);
ex = assertThrows(FileSystemContentsNotAccessibleException.class, () ->
fileSystemBusinessService.getFolderContentsByPath(validPath, dummyUser));
@@ -62,305 +69,260 @@ void getFolderContentsByPathThrows() {
ArrayList fileSystemEntityArrayList = new ArrayList<>();
fileSystemEntityArrayList.add(FileSystemEntity.builder().isFile(true).build());
fileSystemEntityArrayList.add(FileSystemEntity.builder().isFile(false).typeId(-1).build());
- fileSystemEntityArrayList.add(FileSystemEntity.builder().createdByUserId(420).build());
+ fileSystemEntityArrayList.add(FileSystemEntity.builder().lastUpdatedBy(420).build());
when(fileSystemRepositoryMock.findByPath(validPath)).thenReturn(fileSystemEntityArrayList);
ex = assertThrows(FileSystemContentsNotAccessibleException.class, () ->
fileSystemBusinessService.getFolderContentsByPath(validPath, dummyUser));
assertEquals(FileSystemContentsNotAccessibleException.getErrorMessagePrefix(), ex.getMessage());
+
+ // throws because the user was not found.
+ when(userBusinessServiceMock.findUserByUsername(validUsername)).thenThrow(new UserNotFoundException("Like what?"));
+ ex = assertThrows(FileSystemContentsNotAccessibleException.class, () ->
+ fileSystemBusinessService.getFolderContentsByPath(validPath, dummyUser));
+ assertEquals(FileSystemContentsNotAccessibleException.getErrorMessagePrefix(), ex.getMessage());
}
@Test
- void getFolderContentsByPathWorks() {
- String path = "/uga/buga/buga";
- String pathToRequest = path + "/";
+ void getFolderContentsByPathStillThrows() {
+ String validUsername = "kevin";
+ String validPathToFind = "/path";
+ String validPath = "/" + validUsername + validPathToFind;
+ long dummyUserId = 420124;
+ User authenticatedUser = User.builder().userId(0).build();
+ User ownerOfFiles = User.builder().userId(dummyUserId).username(validUsername).build();
+
+ when(fileSystemHelperServiceMock.removeTrailingBackSlashes(validPathToFind)).thenReturn(validPathToFind);
+
+ // throws because no folder was found.
+ when(fileSystemRepositoryMock.findByPath(validPathToFind)).thenReturn(null);
+ when(userBusinessServiceMock.findUserByUsername(validUsername)).thenReturn(ownerOfFiles);
+ FileSystemContentsNotAccessibleException ex = assertThrows(FileSystemContentsNotAccessibleException.class, () ->
+ fileSystemBusinessService.getFolderContentsByPath(validPath, authenticatedUser));
+ assertEquals(FileSystemContentsNotAccessibleException.getErrorMessagePrefix(), ex.getMessage());
+
+ // collection is empty after removing files.
+ ArrayList listOfPossibleFolders = new ArrayList<>();
+ listOfPossibleFolders.add(FileSystemEntity.builder().isFile(true).typeId(FOLDER.getId()).build());
+ when(fileSystemRepositoryMock.findByPath(validPathToFind)).thenReturn(listOfPossibleFolders);
+
+ ex = assertThrows(FileSystemContentsNotAccessibleException.class, () ->
+ fileSystemBusinessService.getFolderContentsByPath(validPath, authenticatedUser));
+ assertEquals(FileSystemContentsNotAccessibleException.getErrorMessagePrefix(), ex.getMessage());
+
+ // more than one folder was found.
+ listOfPossibleFolders = new ArrayList<>();
+ listOfPossibleFolders.add(FileSystemEntity.builder().fileSystemId(-420).ownerId(dummyUserId).isFile(false).typeId(FOLDER.getId()).build());
+ listOfPossibleFolders.add(FileSystemEntity.builder().fileSystemId(1234).isFile(false).ownerId(dummyUserId).typeId(FOLDER.getId()).build());
+ when(fileSystemRepositoryMock.findByPath(validPathToFind)).thenReturn(listOfPossibleFolders);
+
+ FileFighterDataException dataException = assertThrows(FileFighterDataException.class, () ->
+ fileSystemBusinessService.getFolderContentsByPath(validPath, authenticatedUser));
+ assertEquals(FileFighterDataException.getErrorMessagePrefix() + " Found more than one folder with the path " + validPathToFind, dataException.getMessage());
+
+ // not the rights for the actual entity
+ listOfPossibleFolders = new ArrayList<>();
+ listOfPossibleFolders.add(FileSystemEntity.builder().fileSystemId(-420).ownerId(dummyUserId).isFile(false).typeId(FOLDER.getId()).build());
+ when(fileSystemRepositoryMock.findByPath(validPathToFind)).thenReturn(listOfPossibleFolders);
+ when(fileSystemHelperServiceMock.userIsAllowedToInteractWithFileSystemEntity(any(), eq(authenticatedUser), eq(InteractionType.READ))).thenReturn(false);
+
+ ex = assertThrows(FileSystemContentsNotAccessibleException.class, () ->
+ fileSystemBusinessService.getFolderContentsByPath(validPath, authenticatedUser));
+ assertEquals(FileSystemContentsNotAccessibleException.getErrorMessagePrefix(), ex.getMessage());
+ }
+
+ @Test
+ void getFolderContentsByPathWorksWhenRequestingRoot() {
+ String path = "/";
long userId = 420;
- long fileIdInFolder = 123;
User user = User.builder().userId(userId).build();
- FileSystemEntity foundFolder = FileSystemEntity.builder().isFile(false).createdByUserId(userId).typeId(0).itemIds(new long[]{fileIdInFolder}).build();
+ FileSystemEntity fileSystemEntity = FileSystemEntity.builder().path("/").ownerId(userId).lastUpdatedBy(RestConfiguration.RUNTIME_USER_ID).isFile(false).lastUpdatedBy(userId).typeId(FOLDER.getId()).build();
+ FileSystemItem fileSystemItem = FileSystemItem.builder().build();
ArrayList entities = new ArrayList<>();
- entities.add(foundFolder);
+ entities.add(fileSystemEntity);
+ when(fileSystemHelperServiceMock.removeTrailingBackSlashes(path)).thenReturn(path);
when(fileSystemRepositoryMock.findByPath(path)).thenReturn(entities);
- when(fileSystemRepositoryMock.findByFileSystemId(fileIdInFolder)).thenReturn(FileSystemEntity.builder().createdByUserId(userId).build());
- when(userBusinessServiceMock.getUserById(userId)).thenReturn(User.builder().build());
+ when(fileSystemHelperServiceMock.userIsAllowedToInteractWithFileSystemEntity(fileSystemEntity, user, InteractionType.READ)).thenReturn(true);
+ when(fileSystemHelperServiceMock.createDTO(fileSystemEntity, user, path)).thenReturn(fileSystemItem);
- ArrayList fileSystemItems = (ArrayList) fileSystemBusinessService.getFolderContentsByPath(pathToRequest, user);
+ ArrayList fileSystemItems = (ArrayList) fileSystemBusinessService.getFolderContentsByPath(path, user);
assertEquals(1, fileSystemItems.size());
+ assertEquals(fileSystemItem, fileSystemItems.get(0));
}
@Test
- void getFolderContentsOfEntityThrows() {
- long fileSystemId0 = 420;
- long fileSystemId1 = 1234;
+ void getFolderContentsByPathWorksWhenRequestingNonRoot() {
+ String ownerName = "foobar";
+ String path = "/";
+ String requestingPath = path + ownerName;
+ long userId = 420;
+ User user = User.builder().userId(userId).username(ownerName).build();
+ FileSystemEntity fileSystemEntity = FileSystemEntity.builder().path("/").ownerId(userId).lastUpdatedBy(RestConfiguration.RUNTIME_USER_ID).isFile(false).lastUpdatedBy(userId).typeId(FOLDER.getId()).build();
+ FileSystemItem fileSystemItem = FileSystemItem.builder().build();
+ ArrayList entities = new ArrayList<>();
+ entities.add(fileSystemEntity);
- User authenticatedUser = User.builder().build();
- FileSystemEntity rootFolder = FileSystemEntity.builder().itemIds(new long[]{fileSystemId0, fileSystemId1}).build();
+ ArrayList children = new ArrayList<>();
+ FileSystemEntity child = FileSystemEntity.builder().build();
+ FileSystemItem childItem = FileSystemItem.builder().build();
+ children.add(child);
- when(fileSystemRepositoryMock.findByFileSystemId(fileSystemId0)).thenReturn(FileSystemEntity.builder().build());
- when(fileSystemRepositoryMock.findByFileSystemId(fileSystemId1)).thenReturn(null);
+ when(userBusinessServiceMock.findUserByUsername(ownerName)).thenReturn(user);
+ when(fileSystemHelperServiceMock.removeTrailingBackSlashes(path)).thenReturn(path);
+ when(fileSystemRepositoryMock.findByPath(path)).thenReturn(entities);
+ when(fileSystemHelperServiceMock.userIsAllowedToInteractWithFileSystemEntity(fileSystemEntity, user, InteractionType.READ)).thenReturn(true);
+ when(fileSystemHelperServiceMock.getFolderContentsOfEntityAndPermissions(fileSystemEntity, user, true, false)).thenReturn(children);
+ when(fileSystemHelperServiceMock.createDTO(child, user, requestingPath + path)).thenReturn(childItem);
- FileFighterDataException ex = assertThrows(FileFighterDataException.class, () ->
- fileSystemBusinessService.getFolderContentsOfEntityAndPermissions(rootFolder, authenticatedUser, true, false));
- assertEquals(FileFighterDataException.getErrorMessagePrefix() + " FolderContents expected fileSystemItem with id " + fileSystemId1 + " but was empty.", ex.getMessage());
+ ArrayList fileSystemItems = (ArrayList) fileSystemBusinessService.getFolderContentsByPath(requestingPath, user);
+ assertEquals(1, fileSystemItems.size());
+ assertEquals(fileSystemItem, fileSystemItems.get(0));
}
@Test
- void recursivelyDeleteFileSystemEntityThrows() {
- long fsItemId = 12301231;
- long fileSystemId0 = 420;
-
+ void deleteFileSystemItemByIdThrows() {
+ long requestId = 420;
User authenticatedUser = User.builder().build();
+ FileSystemEntity entityToDelete = FileSystemEntity.builder().build();
- FileSystemEntity rootFile = FileSystemEntity.builder().fileSystemId(fsItemId).build();
- when(fileSystemRepositoryMock.findByFileSystemId(fsItemId)).thenReturn(rootFile);
- FileFighterDataException ex = assertThrows(FileFighterDataException.class, () ->
- fileSystemBusinessService.recursivelyDeleteFileSystemEntity(rootFile, authenticatedUser));
- assertEquals(FileFighterDataException.getErrorMessagePrefix() + " Failed to delete FileSystemEntity with id " + fsItemId, ex.getMessage());
-
- FileSystemEntity rootFolder = FileSystemEntity.builder().fileSystemId(fsItemId).isFile(false).typeId(0).build();
- when(fileSystemTypeRepositoryMock.findFileSystemTypeById(0)).thenReturn(FileSystemType.FOLDER);
-
- ex = assertThrows(FileFighterDataException.class, () ->
- fileSystemBusinessService.recursivelyDeleteFileSystemEntity(rootFolder, authenticatedUser));
- assertEquals(FileFighterDataException.getErrorMessagePrefix() + " Failed to delete FileSystemEntity with id " + fsItemId, ex.getMessage());
-
- FileSystemEntity rootFolder1 = FileSystemEntity.builder().fileSystemId(fsItemId).isFile(false).typeId(0).itemIds(new long[]{fileSystemId0}).build();
- when(fileSystemRepositoryMock.findByFileSystemId(fileSystemId0)).thenReturn(FileSystemEntity.builder().fileSystemId(fileSystemId0).build());
- when(fileSystemTypeRepositoryMock.findFileSystemTypeById(0)).thenReturn(FileSystemType.FOLDER);
+ FileSystemItemCouldNotBeDeletedException ex = assertThrows(FileSystemItemCouldNotBeDeletedException.class, () ->
+ fileSystemBusinessService.deleteFileSystemItemById(requestId, authenticatedUser));
+ assertEquals(FileSystemItemCouldNotBeDeletedException.getErrorMessagePrefix() + " FileSystemId was " + requestId, ex.getMessage());
- ex = assertThrows(FileFighterDataException.class, () ->
- fileSystemBusinessService.recursivelyDeleteFileSystemEntity(rootFolder1, authenticatedUser));
- assertEquals(FileFighterDataException.getErrorMessagePrefix() + " Failed to delete FileSystemEntity with id " + fileSystemId0, ex.getMessage());
+ when(fileSystemRepositoryMock.findByFileSystemId(requestId)).thenReturn(entityToDelete);
- when(fileSystemRepositoryMock.deleteByFileSystemId(fileSystemId0)).thenReturn(1L);
- ex = assertThrows(FileFighterDataException.class, () ->
- fileSystemBusinessService.recursivelyDeleteFileSystemEntity(rootFolder1, authenticatedUser));
- assertEquals(FileFighterDataException.getErrorMessagePrefix() + " Failed to delete FileSystemEntity with id " + fsItemId, ex.getMessage());
+ ex = assertThrows(FileSystemItemCouldNotBeDeletedException.class, () ->
+ fileSystemBusinessService.deleteFileSystemItemById(requestId, authenticatedUser));
+ assertEquals(FileSystemItemCouldNotBeDeletedException.getErrorMessagePrefix() + " FileSystemId was " + requestId, ex.getMessage());
}
@Test
- void getFolderContentsOfEntityWorks() {
- long fileSystemId0 = 420;
- long fileSystemId1 = 1234;
- long fileSystemId2 = 1231231234;
- long userId = 123123321;
-
- User authenticatedUser = User.builder().userId(userId).build();
-
- FileSystemEntity fileSystemEntity0 = FileSystemEntity.builder().visibleForUserIds(new long[]{userId}).build();
- FileSystemEntity fileSystemEntity1 = FileSystemEntity.builder().editableForUserIds(new long[]{userId}).build();
- FileSystemEntity fileSystemEntity2 = FileSystemEntity.builder().createdByUserId(userId).build();
-
- FileSystemEntity rootFolder = FileSystemEntity.builder().itemIds(new long[]{fileSystemId0, fileSystemId1, fileSystemId2}).build();
-
- when(fileSystemRepositoryMock.findByFileSystemId(fileSystemId0)).thenReturn(fileSystemEntity0);
- when(fileSystemRepositoryMock.findByFileSystemId(fileSystemId1)).thenReturn(fileSystemEntity1);
- when(fileSystemRepositoryMock.findByFileSystemId(fileSystemId2)).thenReturn(fileSystemEntity2);
-
- ArrayList fs0 = (ArrayList) fileSystemBusinessService.getFolderContentsOfEntityAndPermissions(rootFolder, authenticatedUser, true, false);
- ArrayList fs1 = (ArrayList) fileSystemBusinessService.getFolderContentsOfEntityAndPermissions(rootFolder, authenticatedUser, false, true);
- ArrayList fs2 = (ArrayList) fileSystemBusinessService.getFolderContentsOfEntityAndPermissions(rootFolder, authenticatedUser, true, true);
- ArrayList fs3 = (ArrayList) fileSystemBusinessService.getFolderContentsOfEntityAndPermissions(rootFolder, authenticatedUser, false, false);
-
- assertEquals(2, fs0.size());
- assertEquals(fileSystemEntity0, fs0.get(0));
- assertEquals(2, fs1.size());
- assertEquals(fileSystemEntity1, fs1.get(0));
- assertEquals(1, fs2.size());
- assertEquals(3, fs3.size());
- // why can't I compare 3 objects at once :(
- assertNotEquals(fs3.get(0), fs3.get(1));
- assertNotEquals(fs3.get(1), fs3.get(2));
- assertNotEquals(fs3.get(0), fs3.get(2));
+ void deleteFileSystemItemByIdWorksWithDeletableItemsOnly() {
+ long requestId = 420;
+ User authenticatedUser = User.builder().build();
+ FileSystemEntity entityFolderToDelete = FileSystemEntity.builder().fileSystemId(requestId).isFile(false).fileSystemId(FOLDER.getId()).itemIds(new long[]{123, 321, 1234}).build();
+ FileSystemEntity entity0 = FileSystemEntity.builder().isFile(true).typeId(TEXT.getId()).fileSystemId(321).build();
+ FileSystemEntity entity1 = FileSystemEntity.builder().isFile(true).typeId(TEXT.getId()).fileSystemId(123).build();
+ FileSystemEntity entity2 = FileSystemEntity.builder().isFile(false).typeId(FOLDER.getId()).fileSystemId(1234).build();
+ List contentsOfDirectoryToDelete = Arrays.asList(entity0, entity1, entity2);
+
+ FileSystemItem folderItem = FileSystemItem.builder().build();
+ FileSystemItem file0 = FileSystemItem.builder().build();
+ FileSystemItem file1 = FileSystemItem.builder().build();
+ FileSystemItem file2 = FileSystemItem.builder().build();
+ List dtoReturnList = Arrays.asList(folderItem, file0, file1, file2);
+
+ when(fileSystemRepositoryMock.findByFileSystemId(requestId)).thenReturn(entityFolderToDelete);
+ when(fileSystemHelperServiceMock.userIsAllowedToInteractWithFileSystemEntity(entityFolderToDelete, authenticatedUser, InteractionType.READ)).thenReturn(true);
+ when(fileSystemHelperServiceMock.userIsAllowedToInteractWithFileSystemEntity(entityFolderToDelete, authenticatedUser, InteractionType.DELETE)).thenReturn(true);
+ when(fileSystemHelperServiceMock.getFolderContentsOfEntityAndPermissions(entityFolderToDelete, authenticatedUser, false, false)).thenReturn(contentsOfDirectoryToDelete);
+ when(fileSystemHelperServiceMock.userIsAllowedToInteractWithFileSystemEntity(entity0, authenticatedUser, InteractionType.READ)).thenReturn(true);
+ when(fileSystemHelperServiceMock.userIsAllowedToInteractWithFileSystemEntity(entity0, authenticatedUser, InteractionType.DELETE)).thenReturn(true);
+ when(fileSystemHelperServiceMock.userIsAllowedToInteractWithFileSystemEntity(entity1, authenticatedUser, InteractionType.READ)).thenReturn(true);
+ when(fileSystemHelperServiceMock.userIsAllowedToInteractWithFileSystemEntity(entity1, authenticatedUser, InteractionType.DELETE)).thenReturn(true);
+ when(fileSystemHelperServiceMock.userIsAllowedToInteractWithFileSystemEntity(entity2, authenticatedUser, InteractionType.READ)).thenReturn(true);
+ when(fileSystemHelperServiceMock.userIsAllowedToInteractWithFileSystemEntity(entity2, authenticatedUser, InteractionType.DELETE)).thenReturn(true);
+
+ // create dtos.
+ when(fileSystemHelperServiceMock.createDTO(entityFolderToDelete, authenticatedUser, null)).thenReturn(folderItem);
+ when(fileSystemHelperServiceMock.createDTO(entity0, authenticatedUser, null)).thenReturn(file0);
+ when(fileSystemHelperServiceMock.createDTO(entity1, authenticatedUser, null)).thenReturn(file1);
+ when(fileSystemHelperServiceMock.createDTO(entity2, authenticatedUser, null)).thenReturn(file2);
+
+ // call function
+ List actual = fileSystemBusinessService.deleteFileSystemItemById(requestId, authenticatedUser);
+
+ // verify deletion
+ verify(fileSystemHelperServiceMock, times(4)).deleteAndUnbindFileSystemEntity(any());
+
+ // check for returns
+ assertEquals(dtoReturnList, actual);
}
@Test
- void sumUpAllPermissionsOfFileSystemEntitiesWorks() {
- FileSystemEntity fileSystemEntity0 = FileSystemEntity.builder().visibleForUserIds(new long[]{0, 2, 4}).visibleForGroupIds(new long[]{0, 2, 4}).editableForUserIds(new long[]{0, 2, 4}).editableFoGroupIds(new long[]{0, 2, 4}).build();
- FileSystemEntity fileSystemEntity1 = FileSystemEntity.builder().visibleForUserIds(new long[]{1, 2, 3, 4}).visibleForGroupIds(new long[]{1, 2, 3, 4}).editableForUserIds(new long[]{1, 2, 3, 4}).editableFoGroupIds(new long[]{1, 2, 3, 4}).build();
- FileSystemEntity fileSystemEntity2 = FileSystemEntity.builder().visibleForUserIds(new long[]{1, 3}).visibleForGroupIds(new long[]{1, 3}).editableForUserIds(new long[]{1, 3}).editableFoGroupIds(new long[]{1, 3}).build();
- FileSystemEntity fileSystemEntity3 = FileSystemEntity.builder().visibleForUserIds(new long[]{2, 4}).visibleForGroupIds(new long[]{2, 4}).editableForUserIds(new long[]{2, 4}).editableFoGroupIds(new long[]{2, 4}).build();
+ void deleteFileSystemItemByIdWorksWithInvisibleItemsOnly() {
+ long requestId = 420;
+ long userId = 1234;
+ long notUserId0 = 123898901;
+ long notUserId1 = 908137452;
+ User authenticatedUser = User.builder().userId(userId).groups(new Group[]{Group.FAMILY}).build();
+ FileSystemEntity entityFolderToDelete = FileSystemEntity.builder()
+ .visibleForGroupIds(new long[]{Group.FAMILY.getGroupId(), Group.ADMIN.getGroupId()})
+ .visibleForUserIds(new long[]{userId, notUserId0, notUserId1})
+ .fileSystemId(requestId)
+ .isFile(false)
+ .typeId(FOLDER.getId())
+ .itemIds(new long[]{123})
+ .build();
+ FileSystemEntity entity0 = FileSystemEntity.builder().isFile(true).typeId(TEXT.getId()).fileSystemId(321).build();
- FileSystemEntity parentFileSystemEntity = FileSystemEntity.builder().visibleForUserIds(new long[]{-10, -99, 9}).build();
- ArrayList fileSystemEntityArrayList = new ArrayList<>();
- fileSystemEntityArrayList.add(fileSystemEntity0);
- fileSystemEntityArrayList.add(fileSystemEntity1);
- fileSystemEntityArrayList.add(fileSystemEntity2);
- fileSystemEntityArrayList.add(fileSystemEntity3);
-
- FileSystemEntity actualFileSystemEntity = fileSystemBusinessService.sumUpAllPermissionsOfFileSystemEntities(parentFileSystemEntity, fileSystemEntityArrayList);
- assertEquals(5, actualFileSystemEntity.getVisibleForUserIds().length);
- assertEquals(5, actualFileSystemEntity.getVisibleForGroupIds().length);
- assertEquals(5, actualFileSystemEntity.getEditableForUserIds().length);
- assertEquals(5, actualFileSystemEntity.getEditableFoGroupIds().length);
- }
+ List contentsOfDirectoryToDelete = Collections.singletonList(entity0);
- @Test
- void deleteFileSystemItemByIdThrows() {
- long fsItemId = 12332123;
- long userId = 123123123;
- User authenticatedUser = User.builder().userId(userId).build();
- when(fileSystemRepositoryMock.findByFileSystemId(fsItemId)).thenReturn(null);
- FileSystemItemCouldNotBeDeletedException ex = assertThrows(FileSystemItemCouldNotBeDeletedException.class, () ->
- fileSystemBusinessService.deleteFileSystemItemById(fsItemId, authenticatedUser));
- assertEquals(FileSystemItemCouldNotBeDeletedException.getErrorMessagePrefix() + " FileSystemId was " + fsItemId, ex.getMessage());
+ FileSystemItem folderItem = FileSystemItem.builder().build();
+ FileSystemItem file0 = FileSystemItem.builder().build();
- FileSystemEntity foundEntity = FileSystemEntity.builder().build();
- when(fileSystemRepositoryMock.findByFileSystemId(fsItemId)).thenReturn(foundEntity);
- ex = assertThrows(FileSystemItemCouldNotBeDeletedException.class, () ->
- fileSystemBusinessService.deleteFileSystemItemById(fsItemId, authenticatedUser));
- assertEquals(FileSystemItemCouldNotBeDeletedException.getErrorMessagePrefix() + " FileSystemId was " + fsItemId, ex.getMessage());
-
- foundEntity = FileSystemEntity.builder().createdByUserId(userId).isFile(true).typeId(0).build();
- when(fileSystemRepositoryMock.findByFileSystemId(fsItemId)).thenReturn(foundEntity);
- when(fileSystemTypeRepositoryMock.findFileSystemTypeById(0)).thenReturn(FileSystemType.FOLDER);
- FileFighterDataException ex1 = assertThrows(FileFighterDataException.class, () ->
- fileSystemBusinessService.deleteFileSystemItemById(fsItemId, authenticatedUser));
- assertEquals(FileFighterDataException.getErrorMessagePrefix() + " FileType was wrong. " + foundEntity, ex1.getMessage());
-
- long folderContentId = 13287132;
- FileSystemEntity folderContentEntity = FileSystemEntity.builder().createdByUserId(userId).isFile(true).typeId(0).build();
- when(fileSystemRepositoryMock.findByFileSystemId(folderContentId)).thenReturn(folderContentEntity);
- foundEntity = FileSystemEntity.builder().typeId(0).isFile(false).createdByUserId(userId).itemIds(new long[]{folderContentId}).build();
- when(fileSystemRepositoryMock.findByFileSystemId(fsItemId)).thenReturn(foundEntity);
- ex1 = assertThrows(FileFighterDataException.class, () ->
- fileSystemBusinessService.deleteFileSystemItemById(fsItemId, authenticatedUser));
- assertEquals(FileFighterDataException.getErrorMessagePrefix() + " FileType was wrong. " + folderContentEntity, ex1.getMessage());
- }
+ when(fileSystemRepositoryMock.findByFileSystemId(requestId)).thenReturn(entityFolderToDelete);
+ when(fileSystemHelperServiceMock.userIsAllowedToInteractWithFileSystemEntity(entityFolderToDelete, authenticatedUser, InteractionType.READ)).thenReturn(true);
+ when(fileSystemHelperServiceMock.userIsAllowedToInteractWithFileSystemEntity(entityFolderToDelete, authenticatedUser, InteractionType.DELETE)).thenReturn(true);
+ when(fileSystemHelperServiceMock.getFolderContentsOfEntityAndPermissions(entityFolderToDelete, authenticatedUser, false, false)).thenReturn(contentsOfDirectoryToDelete);
+ when(fileSystemHelperServiceMock.userIsAllowedToInteractWithFileSystemEntity(entity0, authenticatedUser, InteractionType.READ)).thenReturn(false);
+ when(fileSystemHelperServiceMock.userIsAllowedToInteractWithFileSystemEntity(entity0, authenticatedUser, InteractionType.DELETE)).thenReturn(false);
- @Test
- void deleteFileSystemItemByIdWorksWithFile() {
- long fsItemId = 12332123;
- long userId = 243724328;
- User authenticatedUser = User.builder().userId(userId).build();
- FileSystemEntity foundEntity = FileSystemEntity.builder().fileSystemId(fsItemId).typeId(1).isFile(true).createdByUserId(userId).build();
- when(fileSystemRepositoryMock.findByFileSystemId(fsItemId)).thenReturn(foundEntity);
- when(fileSystemRepositoryMock.deleteByFileSystemId(fsItemId)).thenReturn(1L);
-
- fileSystemBusinessService.deleteFileSystemItemById(fsItemId, authenticatedUser);
- verify(fileSystemRepositoryMock, times(1)).deleteByFileSystemId(fsItemId);
- }
+ // create dtos.
+ when(fileSystemHelperServiceMock.createDTO(entityFolderToDelete, authenticatedUser, null)).thenReturn(folderItem);
+ when(fileSystemHelperServiceMock.createDTO(entity0, authenticatedUser, null)).thenReturn(file0);
- @Test
- void deleteFileSystemItemByIdWorksWithFolder() {
- long fsItemId = 12332123;
- long userId = 243724328;
- User authenticatedUser = User.builder().userId(userId).build();
- FileSystemEntity foundEntity = FileSystemEntity.builder().fileSystemId(fsItemId).typeId(0).isFile(false).createdByUserId(userId).build();
-
- when(fileSystemRepositoryMock.findByFileSystemId(fsItemId)).thenReturn(foundEntity);
- when(fileSystemTypeRepositoryMock.findFileSystemTypeById(0)).thenReturn(FileSystemType.FOLDER);
- when(fileSystemRepositoryMock.deleteByFileSystemId(fsItemId)).thenReturn(1L);
-
- fileSystemBusinessService.deleteFileSystemItemById(fsItemId, authenticatedUser);
-
- foundEntity = FileSystemEntity.builder().typeId(0).fileSystemId(fsItemId).isFile(false).createdByUserId(userId).itemIds(new long[0]).build();
- when(fileSystemRepositoryMock.findByFileSystemId(fsItemId)).thenReturn(foundEntity);
- fileSystemBusinessService.deleteFileSystemItemById(fsItemId, authenticatedUser);
- verify(fileSystemRepositoryMock, times(2)).deleteByFileSystemId(fsItemId);
- }
+ // call function
+ List deletedItems = fileSystemBusinessService.deleteFileSystemItemById(requestId, authenticatedUser);
- @Test
- void deleteFileSystemItemByIdWorksWithFolderWhenAllItemsCanBeDeleted() {
- long fsItemId = 12332123;
- long userId = 243724328;
- User authenticatedUser = User.builder().userId(userId).build();
- long itemId0 = 1233212;
- long itemId1 = 9872317;
- long itemId2 = 1923847;
- FileSystemEntity fileSystemEntity0 = FileSystemEntity.builder().isFile(false).typeId(0).createdByUserId(userId).fileSystemId(itemId0).build();
- FileSystemEntity fileSystemEntity1 = FileSystemEntity.builder().fileSystemId(itemId1).typeId(1).createdByUserId(userId).isFile(true).build();
- FileSystemEntity fileSystemEntity2 = FileSystemEntity.builder().fileSystemId(itemId2).typeId(1).createdByUserId(userId).isFile(true).build();
- FileSystemEntity foundEntity = FileSystemEntity.builder().typeId(0).isFile(false).fileSystemId(fsItemId).createdByUserId(userId).itemIds(new long[]{itemId0, itemId1, itemId2}).build();
-
- when(fileSystemTypeRepositoryMock.findFileSystemTypeById(0)).thenReturn(FileSystemType.FOLDER);
- when(fileSystemRepositoryMock.findByFileSystemId(fsItemId)).thenReturn(foundEntity);
- when(fileSystemRepositoryMock.findByFileSystemId(itemId0)).thenReturn(fileSystemEntity0);
- when(fileSystemRepositoryMock.findByFileSystemId(itemId1)).thenReturn(fileSystemEntity1);
- when(fileSystemRepositoryMock.findByFileSystemId(itemId2)).thenReturn(fileSystemEntity2);
-
- when(fileSystemRepositoryMock.deleteByFileSystemId(fsItemId)).thenReturn(1L);
- when(fileSystemRepositoryMock.deleteByFileSystemId(itemId0)).thenReturn(1L);
- when(fileSystemRepositoryMock.deleteByFileSystemId(itemId1)).thenReturn(1L);
- when(fileSystemRepositoryMock.deleteByFileSystemId(itemId2)).thenReturn(1L);
-
- fileSystemBusinessService.deleteFileSystemItemById(fsItemId, authenticatedUser);
-
- verify(fileSystemRepositoryMock, times(1)).deleteByFileSystemId(fsItemId);
- verify(fileSystemRepositoryMock, times(1)).deleteByFileSystemId(itemId0); // empty folder
- verify(fileSystemRepositoryMock, times(1)).deleteByFileSystemId(itemId1);
- verify(fileSystemRepositoryMock, times(1)).deleteByFileSystemId(itemId2);
- }
+ // verify change of parent
- @Test
- void deleteFileSystemItemByIdWorksWithFolderWhenSomeItemsCannotBeDeleted() {
- long fsItemId = 12332123;
- long userId = 243724328;
- long itemId0 = 1233212;
- long itemId1 = 9872317;
- long itemId2 = 1923847;
- long itemId3 = 9817232;
- User authenticatedUser = User.builder().userId(userId).build();
- FileSystemEntity foundEntity = FileSystemEntity.builder().typeId(0).isFile(false).createdByUserId(userId).itemIds(new long[]{itemId0, itemId1, itemId2, itemId3}).build();
- FileSystemEntity visibleEditableEmptyFolder = FileSystemEntity.builder().isFile(false).typeId(0).createdByUserId(userId).fileSystemId(itemId0).build();
- FileSystemEntity invisibleFile = FileSystemEntity.builder().fileSystemId(itemId1).isFile(true).build();
- FileSystemEntity visibleNonEditableFile = FileSystemEntity.builder().fileSystemId(itemId2).visibleForUserIds(new long[]{userId}).isFile(true).build();
- FileSystemEntity visibleEditableFile = FileSystemEntity.builder().fileSystemId(itemId3).createdByUserId(userId).isFile(true).build();
-
- when(fileSystemRepositoryMock.findByFileSystemId(fsItemId)).thenReturn(foundEntity);
- when(fileSystemTypeRepositoryMock.findFileSystemTypeById(0)).thenReturn(FileSystemType.FOLDER);
- when(fileSystemTypeRepositoryMock.findFileSystemTypeById(-1)).thenReturn(FileSystemType.UNDEFINED);
- when(fileSystemRepositoryMock.findByFileSystemId(itemId0)).thenReturn(visibleEditableEmptyFolder);
- when(fileSystemRepositoryMock.findByFileSystemId(itemId1)).thenReturn(invisibleFile);
- when(fileSystemRepositoryMock.findByFileSystemId(itemId2)).thenReturn(visibleNonEditableFile);
- when(fileSystemRepositoryMock.findByFileSystemId(itemId3)).thenReturn(visibleEditableFile);
- when(fileSystemRepositoryMock.deleteByFileSystemId(itemId0)).thenReturn(1L);
- when(fileSystemRepositoryMock.deleteByFileSystemId(itemId3)).thenReturn(1L);
-
- fileSystemBusinessService.deleteFileSystemItemById(fsItemId, authenticatedUser);
-
- // verify deleted entities.
- verify(fileSystemRepositoryMock, times(1)).deleteByFileSystemId(itemId0);
- verify(fileSystemRepositoryMock, times(1)).deleteByFileSystemId(itemId3);
-
- ArgumentCaptor updateArgumentCaptor = ArgumentCaptor.forClass(Update.class);
- verify(mongoTemplateMock, times(1)).findAndModify(any(), updateArgumentCaptor.capture(), any());
- assertEquals("{ \"$set\" : { \"itemIds\" : [ " + itemId1 + ", " + itemId2 + " ] } }", updateArgumentCaptor.getValue().toString()); // no better way to assert requested changes.
+
+ verify(fileSystemHelperServiceMock, times(1)).removeVisibilityRightsOfFileSystemEntityForUser(entityFolderToDelete, authenticatedUser);
+ assertEquals(0, deletedItems.size());
}
@Test
- void deleteFileSystemItemByIdWorksWithFolderOnlyInvisible() {
- long fsItemId = 12332123;
- long userId = 243724328;
- User authenticatedUser = User.builder().userId(userId).build();
- long itemId0 = 1233212;
- long itemId1 = 9872317;
- long itemId2 = 1923847;
- FileSystemEntity foundEntity = FileSystemEntity.builder().typeId(0).isFile(false).createdByUserId(userId).itemIds(new long[]{itemId0, itemId1, itemId2}).build(); // TODO: implement this edge case. (created by.)
- FileSystemEntity visibleEditableEmptyFolder = FileSystemEntity.builder().isFile(false).typeId(0).createdByUserId(userId).fileSystemId(itemId0).build();
- FileSystemEntity invisibleFile = FileSystemEntity.builder().fileSystemId(itemId1).isFile(true).visibleForUserIds(new long[]{userId - 1}).build();
- FileSystemEntity visibleEditableFile = FileSystemEntity.builder().fileSystemId(itemId2).createdByUserId(userId).isFile(true).build();
-
- when(fileSystemRepositoryMock.findByFileSystemId(fsItemId)).thenReturn(foundEntity);
- when(fileSystemTypeRepositoryMock.findFileSystemTypeById(0)).thenReturn(FileSystemType.FOLDER);
- when(fileSystemTypeRepositoryMock.findFileSystemTypeById(-1)).thenReturn(FileSystemType.UNDEFINED);
- when(fileSystemRepositoryMock.findByFileSystemId(itemId0)).thenReturn(visibleEditableEmptyFolder);
- when(fileSystemRepositoryMock.findByFileSystemId(itemId1)).thenReturn(invisibleFile);
- when(fileSystemRepositoryMock.findByFileSystemId(itemId2)).thenReturn(visibleEditableFile);
- when(fileSystemRepositoryMock.deleteByFileSystemId(itemId0)).thenReturn(1L);
- when(fileSystemRepositoryMock.deleteByFileSystemId(itemId2)).thenReturn(1L);
-
- fileSystemBusinessService.deleteFileSystemItemById(fsItemId, authenticatedUser);
-
- // verify deleted entities.
- verify(fileSystemRepositoryMock, times(1)).deleteByFileSystemId(itemId0);
- verify(fileSystemRepositoryMock, times(1)).deleteByFileSystemId(itemId2);
-
- ArgumentCaptor updateArgumentCaptor = ArgumentCaptor.forClass(Update.class);
- verify(mongoTemplateMock, times(1)).findAndModify(any(), updateArgumentCaptor.capture(), any());
- assertEquals("{ \"$set\" : { \"itemIds\" : [ " + itemId1 + " ], \"visibleForUserIds\" : [ " + (userId - 1) + " ], \"visibleForGroupIds\" : [ ], \"editableForUserIds\" : [ ], \"editableForGroupIds\" : [ ] } }", updateArgumentCaptor.getValue().toString()); // no better way to assert requested changes.
+ void deleteFileSystemItemByIdWorksWithNonDeletableItems() {
+ long requestId = 420;
+ long userId = 1234;
+ long notUserId0 = 123898901;
+ long notUserId1 = 908137452;
+ User authenticatedUser = User.builder().userId(userId).groups(new Group[]{Group.FAMILY}).build();
+ FileSystemEntity entityFolderToDelete = FileSystemEntity.builder()
+ .visibleForGroupIds(new long[]{Group.FAMILY.getGroupId(), Group.ADMIN.getGroupId()})
+ .visibleForUserIds(new long[]{userId, notUserId0, notUserId1})
+ .fileSystemId(requestId)
+ .isFile(false)
+ .typeId(FOLDER.getId())
+ .itemIds(new long[]{123})
+ .build();
+ FileSystemEntity entity0 = FileSystemEntity.builder().isFile(true).typeId(TEXT.getId()).fileSystemId(321).build();
+
+ List contentsOfDirectoryToDelete = Collections.singletonList(entity0);
+
+ FileSystemItem folderItem = FileSystemItem.builder().build();
+ FileSystemItem file0 = FileSystemItem.builder().build();
+
+ when(fileSystemRepositoryMock.findByFileSystemId(requestId)).thenReturn(entityFolderToDelete);
+ when(fileSystemHelperServiceMock.userIsAllowedToInteractWithFileSystemEntity(entityFolderToDelete, authenticatedUser, InteractionType.READ)).thenReturn(true);
+ when(fileSystemHelperServiceMock.userIsAllowedToInteractWithFileSystemEntity(entityFolderToDelete, authenticatedUser, InteractionType.DELETE)).thenReturn(true);
+ when(fileSystemHelperServiceMock.getFolderContentsOfEntityAndPermissions(entityFolderToDelete, authenticatedUser, false, false)).thenReturn(contentsOfDirectoryToDelete);
+ when(fileSystemHelperServiceMock.userIsAllowedToInteractWithFileSystemEntity(entity0, authenticatedUser, InteractionType.READ)).thenReturn(true);
+ when(fileSystemHelperServiceMock.userIsAllowedToInteractWithFileSystemEntity(entity0, authenticatedUser, InteractionType.DELETE)).thenReturn(false);
+
+ // create dtos.
+ when(fileSystemHelperServiceMock.createDTO(entityFolderToDelete, authenticatedUser, null)).thenReturn(folderItem);
+ when(fileSystemHelperServiceMock.createDTO(entity0, authenticatedUser, null)).thenReturn(file0);
+
+ // call function
+ List actual = fileSystemBusinessService.deleteFileSystemItemById(requestId, authenticatedUser);
+
+ // verify no deletion.
+ verify(fileSystemHelperServiceMock, times(0)).deleteAndUnbindFileSystemEntity(any());
+ assertTrue(actual.isEmpty());
}
@Test
@@ -385,169 +347,15 @@ void getFileSystemItemInfoWorks() {
long userId = 1234321;
String name = "Folder";
User dummyUser = User.builder().userId(userId).build();
- FileSystemEntity entity = FileSystemEntity.builder().name(name).createdByUserId(userId).build();
+ FileSystemEntity entity = FileSystemEntity.builder().name(name).lastUpdatedBy(userId).build();
+ FileSystemItem item = FileSystemItem.builder().build();
when(userBusinessServiceMock.getUserById(userId)).thenReturn(dummyUser);
when(fileSystemRepositoryMock.findByFileSystemId(id)).thenReturn(entity);
- FileSystemItem fileSystemItem = fileSystemBusinessService.getFileSystemItemInfo(id, dummyUser);
- assertEquals(name, fileSystemItem.getName());
- assertEquals(userId, fileSystemItem.getCreatedByUser().getUserId());
- assertNull(fileSystemItem.getPath());
- assertFalse(fileSystemItem.isShared());
- }
-
- @Test
- void removeTrailingWhiteSpaces() {
- String doesNotRemove0 = "/";
- String doesNotRemove1 = "/ugabuga";
- String doesRemove = "/uga/";
- String removed = "/uga";
-
-
- String actual0 = fileSystemBusinessService.removeTrailingBackSlashes(doesNotRemove0);
- assertEquals(doesNotRemove0, actual0);
-
- String actual1 = fileSystemBusinessService.removeTrailingBackSlashes(doesNotRemove1);
- assertEquals(doesNotRemove1, actual1);
-
- String actual2 = fileSystemBusinessService.removeTrailingBackSlashes(doesRemove);
- assertEquals(removed, actual2);
- }
-
- @Test
- void userIsAllowedToSeeFileSystemEntity() {
- long userId = 1232783672;
- User user = User.builder().userId(userId).build();
- FileSystemEntity fileSystemEntity = FileSystemEntity.builder().createdByUserId(userId).build();
-
- // user created fileSystemItem
- assertTrue(fileSystemBusinessService.userIsAllowedToSeeFileSystemEntity(fileSystemEntity, user));
-
- // user created containing folder
- fileSystemEntity.setCreatedByUserId(1203891230);
- fileSystemEntity.setOwnerIds(new long[]{userId});
- assertTrue(fileSystemBusinessService.userIsAllowedToSeeFileSystemEntity(fileSystemEntity, user));
-
- // user got it shared.
- fileSystemEntity = FileSystemEntity.builder().visibleForUserIds(new long[]{userId}).build();
- assertTrue(fileSystemBusinessService.userIsAllowedToSeeFileSystemEntity(fileSystemEntity, user));
-
- //user is in group
- user = User.builder().userId(123897123).groups(new Group[]{Group.ADMIN}).build();
- fileSystemEntity = FileSystemEntity.builder().fileSystemId(9872347).visibleForGroupIds(new long[]{1}).build();
- assertTrue(fileSystemBusinessService.userIsAllowedToSeeFileSystemEntity(fileSystemEntity, user));
-
- // user is not allowed.
- user = User.builder().userId(123).groups(new Group[]{Group.UNDEFINED}).build();
- fileSystemEntity = FileSystemEntity.builder().createdByUserId(321).visibleForGroupIds(new long[]{1}).build();
- assertFalse(fileSystemBusinessService.userIsAllowedToSeeFileSystemEntity(fileSystemEntity, user));
- }
-
- @Test
- void userIsAllowedToEditFileSystemEntity() {
- long userId = 1232783672;
- User user = User.builder().userId(userId).build();
- FileSystemEntity fileSystemEntity = FileSystemEntity.builder().createdByUserId(userId).build();
-
- // fileSystemEntity was created by runtime user.
- assertFalse(fileSystemBusinessService.userIsAllowedToEditFileSystemEntity(FileSystemEntity.builder().createdByUserId(RestConfiguration.RUNTIME_USER_ID).build(), user));
-
- // user created fileSystemItem
- assertTrue(fileSystemBusinessService.userIsAllowedToEditFileSystemEntity(fileSystemEntity, user));
+ when(fileSystemHelperServiceMock.userIsAllowedToInteractWithFileSystemEntity(entity, dummyUser, InteractionType.READ)).thenReturn(true);
+ when(fileSystemHelperServiceMock.createDTO(entity, dummyUser, null)).thenReturn(item);
- // user created containing folder
- fileSystemEntity.setCreatedByUserId(1203891230);
- fileSystemEntity.setOwnerIds(new long[]{userId});
- assertTrue(fileSystemBusinessService.userIsAllowedToEditFileSystemEntity(fileSystemEntity, user));
-
- // user got it shared.
- fileSystemEntity = FileSystemEntity.builder().editableForUserIds(new long[]{userId}).build();
- assertTrue(fileSystemBusinessService.userIsAllowedToEditFileSystemEntity(fileSystemEntity, user));
-
- //user is in group
- user = User.builder().userId(0).groups(new Group[]{Group.ADMIN}).build();
- fileSystemEntity = FileSystemEntity.builder().editableFoGroupIds(new long[]{1}).build();
- assertTrue(fileSystemBusinessService.userIsAllowedToEditFileSystemEntity(fileSystemEntity, user));
-
- // user is not allowed.
- user = User.builder().userId(123).groups(new Group[]{Group.UNDEFINED}).build();
- fileSystemEntity = FileSystemEntity.builder().createdByUserId(321).editableFoGroupIds(new long[]{1}).build();
- assertFalse(fileSystemBusinessService.userIsAllowedToEditFileSystemEntity(fileSystemEntity, user));
- }
-
- @Test
- void createDTOThrows() {
- long userId = 420;
- FileSystemEntity entity = FileSystemEntity.builder().createdByUserId(userId).build();
- User user = User.builder().build();
-
- when(userBusinessServiceMock.getUserById(userId)).thenThrow(UserNotFoundException.class);
-
- FileFighterDataException ex = assertThrows(FileFighterDataException.class, () ->
- fileSystemBusinessService.createDTO(entity, user, null));
- assertEquals(FileFighterDataException.getErrorMessagePrefix() + " Owner of a file could not be found.", ex.getMessage());
- }
-
- @Test
- void createDTOWorks() {
- long createdByUserId = 420L;
- String basePath = "/someTHING/somethingElse/";
- long[] items = new long[]{1, 2, 3};
- long fileSystemId = 123123;
- boolean isFile = true;
- long lastUpdated = 123123;
- String name = "SomeText.txt";
- double size = 123321;
- long typeId = -1;
-
- User authenticatedUser = User.builder().userId(createdByUserId - 1).build();
- User userThatCreatedFile = User.builder().userId(createdByUserId).build();
- FileSystemEntity fileSystemEntity = FileSystemEntity
- .builder()
- .createdByUserId(createdByUserId)
- .itemIds(items)
- .fileSystemId(fileSystemId)
- .isFile(isFile)
- .lastUpdated(lastUpdated)
- .name(name)
- .path("") // is empty because its a file.
- .size(size)
- .typeId(typeId)
- .build();
-
- when(userBusinessServiceMock.getUserById(createdByUserId)).thenReturn(userThatCreatedFile);
- when(fileSystemTypeRepositoryMock.findFileSystemTypeById(typeId)).thenReturn(FileSystemType.UNDEFINED);
-
- FileSystemItem actual = fileSystemBusinessService.createDTO(fileSystemEntity, authenticatedUser, basePath);
-
- assertEquals(createdByUserId, actual.getCreatedByUser().getUserId());
- assertEquals(fileSystemId, actual.getFileSystemId());
- assertEquals(lastUpdated, actual.getLastUpdated());
- assertEquals(name, actual.getName());
- assertEquals(size, actual.getSize());
- assertEquals(FileSystemType.UNDEFINED, actual.getType());
- assertEquals(basePath + name, actual.getPath());
- assertTrue(actual.isShared());
- }
-
- @Test
- void getTotalFileSizeThrows() {
- when(fileSystemRepositoryMock.findByPath("/")).thenReturn(null);
- FileFighterDataException ex = assertThrows(FileFighterDataException.class, fileSystemBusinessService::getTotalFileSize);
- assertEquals(FileFighterDataException.getErrorMessagePrefix() + " Couldn't find any Home directories!", ex.getMessage());
- }
-
- @Test
- void getTotalFileSizeWorks() {
- double size0 = 1.3;
- double size1 = 2.4;
- ArrayList entities = new ArrayList<>();
- entities.add(FileSystemEntity.builder().size(size0).build());
- entities.add(FileSystemEntity.builder().size(size1).build());
-
- when(fileSystemRepositoryMock.findByPath("/")).thenReturn(entities);
-
- double actualSize = fileSystemBusinessService.getTotalFileSize();
- assertEquals(size0 + size1, actualSize);
+ FileSystemItem fileSystemItem = fileSystemBusinessService.getFileSystemItemInfo(id, dummyUser);
+ assertEquals(item, fileSystemItem);
}
}
\ No newline at end of file
diff --git a/src/test/java/de/filefighter/rest/domain/filesystem/business/FileSystemHelperServiceUnitTest.java b/src/test/java/de/filefighter/rest/domain/filesystem/business/FileSystemHelperServiceUnitTest.java
new file mode 100644
index 00000000..b1ab7e0e
--- /dev/null
+++ b/src/test/java/de/filefighter/rest/domain/filesystem/business/FileSystemHelperServiceUnitTest.java
@@ -0,0 +1,345 @@
+package de.filefighter.rest.domain.filesystem.business;
+
+
+import de.filefighter.rest.configuration.RestConfiguration;
+import de.filefighter.rest.domain.common.exceptions.FileFighterDataException;
+import de.filefighter.rest.domain.filesystem.data.dto.FileSystemItem;
+import de.filefighter.rest.domain.filesystem.data.persistence.FileSystemEntity;
+import de.filefighter.rest.domain.filesystem.data.persistence.FileSystemRepository;
+import de.filefighter.rest.domain.filesystem.type.FileSystemType;
+import de.filefighter.rest.domain.filesystem.type.FileSystemTypeRepository;
+import de.filefighter.rest.domain.user.business.UserBusinessService;
+import de.filefighter.rest.domain.user.data.dto.User;
+import de.filefighter.rest.domain.user.exceptions.UserNotFoundException;
+import de.filefighter.rest.domain.user.group.Group;
+import org.junit.jupiter.api.Test;
+import org.mockito.ArgumentCaptor;
+import org.springframework.data.mongodb.core.MongoTemplate;
+import org.springframework.data.mongodb.core.query.Criteria;
+import org.springframework.data.mongodb.core.query.Query;
+import org.springframework.data.mongodb.core.query.Update;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import static de.filefighter.rest.domain.filesystem.business.FileSystemBusinessService.DELETION_FAILED_MSG;
+import static de.filefighter.rest.domain.filesystem.data.InteractionType.*;
+import static org.junit.jupiter.api.Assertions.*;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.*;
+
+class FileSystemHelperServiceUnitTest {
+
+ private final UserBusinessService userBusinessServiceMock = mock(UserBusinessService.class);
+ private final FileSystemRepository fileSystemRepositoryMock = mock(FileSystemRepository.class);
+ private final FileSystemTypeRepository fileSystemTypeRepositoryMock = mock(FileSystemTypeRepository.class);
+ private final MongoTemplate mongoTemplateMock = mock(MongoTemplate.class);
+
+ private final FileSystemHelperService fileSystemHelperService = new FileSystemHelperService(fileSystemRepositoryMock, fileSystemTypeRepositoryMock, userBusinessServiceMock, mongoTemplateMock);
+
+ @Test
+ void sumUpAllPermissionsOfFileSystemEntitiesWorks() {
+ FileSystemEntity fileSystemEntity0 = FileSystemEntity.builder().visibleForUserIds(new long[]{0, 2, 4}).visibleForGroupIds(new long[]{0, 2, 4}).editableForUserIds(new long[]{0, 2, 4}).editableFoGroupIds(new long[]{0, 2, 4}).build();
+ FileSystemEntity fileSystemEntity1 = FileSystemEntity.builder().visibleForUserIds(new long[]{1, 2, 3, 4}).visibleForGroupIds(new long[]{1, 2, 3, 4}).editableForUserIds(new long[]{1, 2, 3, 4}).editableFoGroupIds(new long[]{1, 2, 3, 4}).build();
+ FileSystemEntity fileSystemEntity2 = FileSystemEntity.builder().visibleForUserIds(new long[]{1, 3}).visibleForGroupIds(new long[]{1, 3}).editableForUserIds(new long[]{1, 3}).editableFoGroupIds(new long[]{1, 3}).build();
+ FileSystemEntity fileSystemEntity3 = FileSystemEntity.builder().visibleForUserIds(new long[]{2, 4}).visibleForGroupIds(new long[]{2, 4}).editableForUserIds(new long[]{2, 4}).editableFoGroupIds(new long[]{2, 4}).build();
+
+ FileSystemEntity parentFileSystemEntity = FileSystemEntity.builder().visibleForUserIds(new long[]{-10, -99, 9}).build();
+ ArrayList fileSystemEntityArrayList = new ArrayList<>();
+ fileSystemEntityArrayList.add(fileSystemEntity0);
+ fileSystemEntityArrayList.add(fileSystemEntity1);
+ fileSystemEntityArrayList.add(fileSystemEntity2);
+ fileSystemEntityArrayList.add(fileSystemEntity3);
+
+ FileSystemEntity actualFileSystemEntity = fileSystemHelperService.sumUpAllPermissionsOfFileSystemEntities(parentFileSystemEntity, fileSystemEntityArrayList);
+ assertEquals(5, actualFileSystemEntity.getVisibleForUserIds().length);
+ assertEquals(5, actualFileSystemEntity.getVisibleForGroupIds().length);
+ assertEquals(5, actualFileSystemEntity.getEditableForUserIds().length);
+ assertEquals(5, actualFileSystemEntity.getEditableFoGroupIds().length);
+ }
+
+ @Test
+ void getFolderContentsOfEntityThrows() {
+ long fileSystemId0 = 420;
+ long fileSystemId1 = 1234;
+
+ User authenticatedUser = User.builder().build();
+ FileSystemEntity rootFolder = FileSystemEntity.builder().itemIds(new long[]{fileSystemId0, fileSystemId1}).build();
+
+ when(fileSystemRepositoryMock.findByFileSystemId(fileSystemId0)).thenReturn(FileSystemEntity.builder().build());
+ when(fileSystemRepositoryMock.findByFileSystemId(fileSystemId1)).thenReturn(null);
+
+ FileFighterDataException ex = assertThrows(FileFighterDataException.class, () ->
+ fileSystemHelperService.getFolderContentsOfEntityAndPermissions(rootFolder, authenticatedUser, true, false));
+ assertEquals(FileFighterDataException.getErrorMessagePrefix() + " FolderContents expected fileSystemItem with id " + fileSystemId1 + " but was empty.", ex.getMessage());
+ }
+
+ @Test
+ void getFolderContentsOfEntityWorks() {
+ long fileSystemId0 = 420;
+ long fileSystemId1 = 1234;
+ long fileSystemId2 = 1231231234;
+ long userId = 123123321;
+
+ User authenticatedUser = User.builder().userId(userId).build();
+
+ FileSystemEntity fileSystemEntity0 = FileSystemEntity.builder().visibleForUserIds(new long[]{userId}).build();
+ FileSystemEntity fileSystemEntity1 = FileSystemEntity.builder().editableForUserIds(new long[]{userId}).build();
+ FileSystemEntity fileSystemEntity2 = FileSystemEntity.builder().ownerId(userId).build();
+
+ FileSystemEntity rootFolder = FileSystemEntity.builder().itemIds(new long[]{fileSystemId0, fileSystemId1, fileSystemId2}).build();
+
+ when(fileSystemRepositoryMock.findByFileSystemId(fileSystemId0)).thenReturn(fileSystemEntity0);
+ when(fileSystemRepositoryMock.findByFileSystemId(fileSystemId1)).thenReturn(fileSystemEntity1);
+ when(fileSystemRepositoryMock.findByFileSystemId(fileSystemId2)).thenReturn(fileSystemEntity2);
+
+ ArrayList fs0 = (ArrayList) fileSystemHelperService.getFolderContentsOfEntityAndPermissions(rootFolder, authenticatedUser, true, false);
+ ArrayList fs1 = (ArrayList) fileSystemHelperService.getFolderContentsOfEntityAndPermissions(rootFolder, authenticatedUser, false, true);
+ ArrayList fs2 = (ArrayList) fileSystemHelperService.getFolderContentsOfEntityAndPermissions(rootFolder, authenticatedUser, true, true);
+ ArrayList fs3 = (ArrayList) fileSystemHelperService.getFolderContentsOfEntityAndPermissions(rootFolder, authenticatedUser, false, false);
+
+ assertEquals(2, fs0.size());
+ assertEquals(fileSystemEntity0, fs0.get(0));
+ assertEquals(2, fs1.size());
+ assertEquals(fileSystemEntity1, fs1.get(0));
+ assertEquals(1, fs2.size());
+ assertEquals(3, fs3.size());
+ // why can't I compare 3 objects at once :(
+ assertNotEquals(fs3.get(0), fs3.get(1));
+ assertNotEquals(fs3.get(1), fs3.get(2));
+ assertNotEquals(fs3.get(0), fs3.get(2));
+ }
+
+ @Test
+ void removeTrailingWhiteSpaces() {
+ String doesNotRemove0 = "/";
+ String doesNotRemove1 = "/ugabuga";
+ String doesRemove = "/uga/";
+ String removed = "/uga";
+
+
+ String actual0 = fileSystemHelperService.removeTrailingBackSlashes(doesNotRemove0);
+ assertEquals(doesNotRemove0, actual0);
+
+ String actual1 = fileSystemHelperService.removeTrailingBackSlashes(doesNotRemove1);
+ assertEquals(doesNotRemove1, actual1);
+
+ String actual2 = fileSystemHelperService.removeTrailingBackSlashes(doesRemove);
+ assertEquals(removed, actual2);
+ }
+
+ @Test
+ void userIsAllowedToReadFileSystemEntity() {
+ long userId = 1232783672;
+ User user = User.builder().userId(userId).build();
+ FileSystemEntity fileSystemEntity = FileSystemEntity.builder().ownerId(userId).build();
+
+ // user created fileSystemItem
+ assertTrue(fileSystemHelperService.userIsAllowedToInteractWithFileSystemEntity(fileSystemEntity, user, READ));
+
+ // user created containing folder
+ fileSystemEntity.setLastUpdatedBy(1203891230);
+ assertTrue(fileSystemHelperService.userIsAllowedToInteractWithFileSystemEntity(fileSystemEntity, user, READ));
+
+ // user got it shared.
+ fileSystemEntity = FileSystemEntity.builder().visibleForUserIds(new long[]{userId}).build();
+ assertTrue(fileSystemHelperService.userIsAllowedToInteractWithFileSystemEntity(fileSystemEntity, user, READ));
+
+ //user is in group
+ user = User.builder().userId(123897123).groups(new Group[]{Group.ADMIN}).build();
+ fileSystemEntity = FileSystemEntity.builder().fileSystemId(9872347).visibleForGroupIds(new long[]{1}).build();
+ assertTrue(fileSystemHelperService.userIsAllowedToInteractWithFileSystemEntity(fileSystemEntity, user, READ));
+
+ // user is not allowed.
+ user = User.builder().userId(123).groups(new Group[]{Group.UNDEFINED}).build();
+ fileSystemEntity = FileSystemEntity.builder().lastUpdatedBy(321).visibleForGroupIds(new long[]{1}).build();
+ assertFalse(fileSystemHelperService.userIsAllowedToInteractWithFileSystemEntity(fileSystemEntity, user, READ));
+ }
+
+ @Test
+ void userIsAllowedToEditFileSystemEntity() {
+ long userId = 1232783672;
+ User user = User.builder().userId(userId).build();
+ FileSystemEntity fileSystemEntity = FileSystemEntity.builder().ownerId(userId).build();
+
+ // fileSystemEntity was created by runtime user.
+ assertTrue(fileSystemHelperService.userIsAllowedToInteractWithFileSystemEntity(FileSystemEntity.builder().lastUpdatedBy(RestConfiguration.RUNTIME_USER_ID).editableForUserIds(new long[]{userId}).build(), user, CHANGE));
+
+ assertFalse(fileSystemHelperService.userIsAllowedToInteractWithFileSystemEntity(FileSystemEntity.builder().lastUpdatedBy(RestConfiguration.RUNTIME_USER_ID).editableForUserIds(new long[]{userId}).build(), user, DELETE));
+
+ // user created fileSystemItem
+ assertTrue(fileSystemHelperService.userIsAllowedToInteractWithFileSystemEntity(fileSystemEntity, user, CHANGE));
+
+ // user created containing folder
+ fileSystemEntity.setLastUpdatedBy(1203891230);
+ assertTrue(fileSystemHelperService.userIsAllowedToInteractWithFileSystemEntity(fileSystemEntity, user, CHANGE));
+
+ // user got it shared.
+ fileSystemEntity = FileSystemEntity.builder().editableForUserIds(new long[]{userId}).build();
+ assertTrue(fileSystemHelperService.userIsAllowedToInteractWithFileSystemEntity(fileSystemEntity, user, CHANGE));
+
+ //user is in group
+ user = User.builder().userId(0).groups(new Group[]{Group.ADMIN}).build();
+ fileSystemEntity = FileSystemEntity.builder().editableFoGroupIds(new long[]{1}).build();
+ assertTrue(fileSystemHelperService.userIsAllowedToInteractWithFileSystemEntity(fileSystemEntity, user, CHANGE));
+
+ // user is not allowed.
+ user = User.builder().userId(123).groups(new Group[]{Group.UNDEFINED}).build();
+ fileSystemEntity = FileSystemEntity.builder().lastUpdatedBy(321).editableFoGroupIds(new long[]{1}).build();
+ assertFalse(fileSystemHelperService.userIsAllowedToInteractWithFileSystemEntity(fileSystemEntity, user, CHANGE));
+ }
+
+ @Test
+ void createDTOThrows() {
+ long userId = 420;
+ FileSystemEntity entity = FileSystemEntity.builder().lastUpdatedBy(userId).build();
+ User user = User.builder().build();
+
+ when(userBusinessServiceMock.getUserById(userId)).thenThrow(UserNotFoundException.class);
+
+ FileFighterDataException ex = assertThrows(FileFighterDataException.class, () ->
+ fileSystemHelperService.createDTO(entity, user, null));
+ assertEquals(FileFighterDataException.getErrorMessagePrefix() + " Owner or auther of last change could not be found.", ex.getMessage());
+ }
+
+ @Test
+ void createDTOWorks() {
+ long createdByUserId = 420L;
+ String basePath = "/someTHING/somethingElse/";
+ long[] items = new long[]{1, 2, 3};
+ long fileSystemId = 123123;
+ boolean isFile = true;
+ long lastUpdated = 123123;
+ String name = "SomeText.txt";
+ double size = 123321;
+ long typeId = -1;
+
+ User authenticatedUser = User.builder().userId(createdByUserId - 1).build();
+ User userThatCreatedFile = User.builder().userId(createdByUserId).build();
+ FileSystemEntity fileSystemEntity = FileSystemEntity
+ .builder()
+ .ownerId(createdByUserId)
+ .itemIds(items)
+ .fileSystemId(fileSystemId)
+ .isFile(isFile)
+ .lastUpdatedBy(createdByUserId)
+ .lastUpdated(lastUpdated)
+ .name(name)
+ .path("") // is empty because its a file.
+ .size(size)
+ .typeId(typeId)
+ .build();
+
+ when(userBusinessServiceMock.getUserById(createdByUserId)).thenReturn(userThatCreatedFile);
+ when(fileSystemTypeRepositoryMock.findFileSystemTypeById(typeId)).thenReturn(FileSystemType.UNDEFINED);
+
+ FileSystemItem actual = fileSystemHelperService.createDTO(fileSystemEntity, authenticatedUser, basePath);
+
+ assertEquals(createdByUserId, actual.getLastUpdatedBy().getUserId());
+ assertEquals(fileSystemId, actual.getFileSystemId());
+ assertEquals(lastUpdated, actual.getLastUpdated());
+ assertEquals(name, actual.getName());
+ assertEquals(size, actual.getSize());
+ assertEquals(FileSystemType.UNDEFINED, actual.getType());
+ assertEquals(basePath + name, actual.getPath());
+ assertTrue(actual.isShared());
+ }
+
+ @Test
+ void getTotalFileSizeThrows() {
+ when(fileSystemRepositoryMock.findByPath("/")).thenReturn(null);
+ FileFighterDataException ex = assertThrows(FileFighterDataException.class, fileSystemHelperService::getTotalFileSize);
+ assertEquals(FileFighterDataException.getErrorMessagePrefix() + " Couldn't find any Home directories!", ex.getMessage());
+ }
+
+ @Test
+ void deleteAndUnbindFileSystemEntityThrows() {
+ long fileSystemId = 420;
+ FileSystemEntity fileSystemEntity = FileSystemEntity.builder().fileSystemId(fileSystemId).build();
+
+ when(fileSystemRepositoryMock.deleteByFileSystemId(fileSystemId)).thenReturn(1234L);
+
+ FileFighterDataException ex = assertThrows(FileFighterDataException.class, () ->
+ fileSystemHelperService.deleteAndUnbindFileSystemEntity(fileSystemEntity));
+ assertEquals(FileFighterDataException.getErrorMessagePrefix() + " " + DELETION_FAILED_MSG + fileSystemId, ex.getMessage());
+ }
+
+ @SuppressWarnings("squid:S5778")
+ @Test
+ void recursivlyUpdateTimeStampsThrows() {
+ List entities = new ArrayList<>();
+ entities.add(FileSystemEntity.builder().build());
+ entities.add(FileSystemEntity.builder().build());
+ when(mongoTemplateMock.find(any(), eq(FileSystemEntity.class))).thenReturn(entities);
+
+ FileFighterDataException ex = assertThrows(FileFighterDataException.class, () ->
+ fileSystemHelperService.recursivlyUpdateTimeStamps(FileSystemEntity.builder().build(), User.builder().build(), 420));
+ assertEquals(FileFighterDataException.getErrorMessagePrefix() + " Found more than one parent entity for entity.", ex.getMessage());
+
+ when(mongoTemplateMock.find(any(), any())).thenReturn(new ArrayList<>());
+
+ ex = assertThrows(FileFighterDataException.class, () ->
+ fileSystemHelperService.recursivlyUpdateTimeStamps(FileSystemEntity.builder().fileSystemId(123123).isFile(true).path("/").build(), User.builder().build(), 420));
+ assertEquals(FileFighterDataException.getErrorMessagePrefix() + " Found no parent entity for a non root entity.", ex.getMessage());
+ }
+
+ @Test
+ void removeVisibilityRightsFromEntityWorks() {
+ long fsItemId = 123;
+ long userId = 123123;
+ long otherUserId = 120938;
+ long groupId = Group.FAMILY.getGroupId();
+ long otherGroupId = Group.ADMIN.getGroupId();
+ FileSystemEntity fileSystemEntity = FileSystemEntity.builder()
+ .fileSystemId(fsItemId)
+ .visibleForGroupIds(new long[]{groupId, otherGroupId})
+ .visibleForUserIds(new long[]{userId, otherUserId})
+ .build();
+ User authenticatedUser = User.builder()
+ .userId(userId)
+ .groups(new Group[]{Group.FAMILY})
+ .build();
+
+ // run it
+ fileSystemHelperService.removeVisibilityRightsOfFileSystemEntityForUser(fileSystemEntity, authenticatedUser);
+
+ // verify it
+ ArgumentCaptor updateArgumentCaptor = ArgumentCaptor.forClass(Update.class);
+ ArgumentCaptor queryArgumentCaptor = ArgumentCaptor.forClass(Query.class);
+ verify(mongoTemplateMock, times(1)).findAndModify(queryArgumentCaptor.capture(), updateArgumentCaptor.capture(), eq(FileSystemEntity.class));
+ assertEquals("Query: { \"fileSystemId\" : " + fsItemId + "}, Fields: {}, Sort: {}", queryArgumentCaptor.getValue().toString());
+ assertEquals("{ \"$set\" : { \"visibleForUserIds\" : [ " + otherUserId + " ], \"visibleForGroupIds\" : [ " + otherGroupId + " ] } }", updateArgumentCaptor.getValue().toString());
+ }
+
+ @Test
+ void recursivlyUpdateTimeStampsWorks() {
+ long fsItemId = 420;
+ long fsItemId2 = 1234;
+ ArrayList entities = new ArrayList<>();
+ entities.add(FileSystemEntity.builder().fileSystemId(fsItemId2).isFile(false).path("/").build());
+ ArrayList emptyList = new ArrayList<>();
+
+ when(mongoTemplateMock.find(eq(new Query().addCriteria(Criteria.where("itemIds").is(fsItemId))), eq(FileSystemEntity.class))).thenReturn(entities);
+ when(mongoTemplateMock.find(eq(new Query().addCriteria(Criteria.where("itemIds").is(fsItemId2))), eq(FileSystemEntity.class))).thenReturn(emptyList);
+
+ fileSystemHelperService.recursivlyUpdateTimeStamps(FileSystemEntity.builder().fileSystemId(fsItemId).build(), User.builder().build(), 420);
+
+ verify(mongoTemplateMock, times(2)).findAndModify(any(), any(), any());
+ }
+
+ @Test
+ void getTotalFileSizeWorks() {
+ double size0 = 1.3;
+ double size1 = 2.4;
+ ArrayList entities = new ArrayList<>();
+ entities.add(FileSystemEntity.builder().size(size0).build());
+ entities.add(FileSystemEntity.builder().size(size1).build());
+
+ when(fileSystemRepositoryMock.findByPath("/")).thenReturn(entities);
+
+ double actualSize = fileSystemHelperService.getTotalFileSize();
+ assertEquals(size0 + size1, actualSize);
+ }
+}
+
diff --git a/src/test/java/de/filefighter/rest/domain/filesystem/rest/FileSystemRestControllerUnitTest.java b/src/test/java/de/filefighter/rest/domain/filesystem/rest/FileSystemRestControllerUnitTest.java
index b6ac4584..8ed27925 100644
--- a/src/test/java/de/filefighter/rest/domain/filesystem/rest/FileSystemRestControllerUnitTest.java
+++ b/src/test/java/de/filefighter/rest/domain/filesystem/rest/FileSystemRestControllerUnitTest.java
@@ -2,19 +2,18 @@
import de.filefighter.rest.domain.filesystem.data.dto.FileSystemItem;
import de.filefighter.rest.domain.filesystem.data.dto.FileSystemItemUpdate;
-import de.filefighter.rest.rest.ServerResponse;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import java.util.ArrayList;
+import java.util.List;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import static org.springframework.http.HttpStatus.OK;
-import static org.springframework.http.HttpStatus.UNAUTHORIZED;
class FileSystemRestControllerUnitTest {
@@ -72,15 +71,14 @@ void searchFileOrFolderByName() {
@Test
void uploadFileOrFolder() {
FileSystemItem file = FileSystemItem.builder().build();
- ResponseEntity expectedModel = new ResponseEntity<>(file, OK);
+ FileSystemItemUpdate upload = FileSystemItemUpdate.builder().build();
+ String token = "sometoken";
+ ResponseEntity responseEntity = new ResponseEntity<>(file, OK);
- FileSystemItemUpdate fileSystemItemUpdate = FileSystemItemUpdate.builder().name("ugabuga").build();
- String token = "token";
+ when(fileSystemRestServiceMock.uploadFileSystemItemWithAccessToken(upload, token)).thenReturn(responseEntity);
- when(fileSystemRestServiceMock.uploadFileSystemItemWithAccessToken(fileSystemItemUpdate, token)).thenReturn(expectedModel);
-
- ResponseEntity actualModel = fileSystemRestController.uploadFileOrFolder(fileSystemItemUpdate, token);
- assertEquals(expectedModel, actualModel);
+ ResponseEntity actualModel = fileSystemRestController.uploadFileOrFolder(upload, token);
+ assertEquals(responseEntity, actualModel);
}
@Test
@@ -92,7 +90,7 @@ void updateExistingFileOrFolder() {
FileSystemItemUpdate fileSystemItemUpdate = FileSystemItemUpdate.builder().name("ugabuga").build();
String token = "token";
- when(fileSystemRestServiceMock.updatedFileSystemItemWithIdAndAccessToken(id, fileSystemItemUpdate, token)).thenReturn(expectedModel);
+ when(fileSystemRestServiceMock.updateFileSystemItemWithIdAndAccessToken(id, fileSystemItemUpdate, token)).thenReturn(expectedModel);
ResponseEntity actualModel = fileSystemRestController.updateExistingFileOrFolder(id, fileSystemItemUpdate, token);
assertEquals(expectedModel, actualModel);
@@ -100,15 +98,15 @@ void updateExistingFileOrFolder() {
@Test
void deleteFileOrFolder() {
- ServerResponse response = new ServerResponse(UNAUTHORIZED, "not authorized");
- ResponseEntity expectedModel = new ResponseEntity<>(response, OK);
+ ArrayList expectedItems = new ArrayList<>();
+ ResponseEntity> expectedModel = new ResponseEntity<>(expectedItems, OK);
long id = 420;
String token = "token";
when(fileSystemRestServiceMock.deleteFileSystemItemWithIdAndAccessToken(id, token)).thenReturn(expectedModel);
- ResponseEntity actualModel = fileSystemRestController.deleteFileOrFolder(id, token);
+ ResponseEntity> actualModel = fileSystemRestController.deleteFileOrFolder(id, token);
assertEquals(expectedModel, actualModel);
}
}
\ No newline at end of file
diff --git a/src/test/java/de/filefighter/rest/domain/health/business/SystemHealthBusinessServiceUnitTest.java b/src/test/java/de/filefighter/rest/domain/health/business/SystemHealthBusinessServiceUnitTest.java
index 245fe093..a09e272f 100644
--- a/src/test/java/de/filefighter/rest/domain/health/business/SystemHealthBusinessServiceUnitTest.java
+++ b/src/test/java/de/filefighter/rest/domain/health/business/SystemHealthBusinessServiceUnitTest.java
@@ -1,6 +1,6 @@
package de.filefighter.rest.domain.health.business;
-import de.filefighter.rest.domain.filesystem.business.FileSystemBusinessService;
+import de.filefighter.rest.domain.filesystem.business.FileSystemHelperService;
import de.filefighter.rest.domain.health.data.SystemHealth;
import de.filefighter.rest.domain.health.data.SystemHealth.DataIntegrity;
import de.filefighter.rest.domain.token.business.AccessTokenBusinessService;
@@ -20,7 +20,7 @@ class SystemHealthBusinessServiceUnitTest {
private final UserBusinessService userBusinessServiceMock = mock(UserBusinessService.class);
private final AccessTokenBusinessService accessTokenBusinessServiceMock = mock(AccessTokenBusinessService.class);
- private final FileSystemBusinessService fileSystemBusinessServiceMock = mock(FileSystemBusinessService.class);
+ private final FileSystemHelperService fileSystemBusinessServiceMock = mock(FileSystemHelperService.class);
private final Environment environmentMock = mock(Environment.class);
private SystemHealthBusinessService systemHealthBusinessService;
diff --git a/src/test/resources/ViewFolderContents.feature b/src/test/resources/ViewFolderContents.feature
index aec46df7..52e5022a 100644
--- a/src/test/resources/ViewFolderContents.feature
+++ b/src/test/resources/ViewFolderContents.feature
@@ -4,73 +4,89 @@ Feature: View Folder
Background:
Given database is empty
- And user 1234 exists
- And user 420 exists
+ And runtime user exists
+ And user with userId 1234 exists and has username "Richard", password "badPassword"
+ And user with userId 420 exists and has username "Nasir", password "AlsoBadPassword"
And accessToken with value "900000" exists for user 1234
- And fileSystemItem with the fileSystemId 42 exists, was created by user with userId 420 has the path "/bla" and name "bla"
- And fileSystemItem with the fileSystemId 72 exists, was created by user with userId 420 and has the name "wow.txt"
+ And accessToken with value "222222" exists for user 420
+ And user with userId 1234 has HomeFolder with Id 1234
+ And user with userId 420 has HomeFolder with Id 420
+ And fileSystemItem with the fileSystemId 42 exists, has owner with userId 1234 has the path "/bla" and name "bla"
+ And fileSystemItem with the fileSystemId 72 exists, has owner with userId 1234 and name "wow.txt"
And fileSystemItem with the fileSystemId 42 is a folder and contains the fileSystemId 72
Scenario: Successful interaction
- Given user with the userId 1234 is allowed to VIEW the fileSystemItem with the fileSystemId 42
- And user with the userId 1234 is allowed to VIEW the fileSystemItem with the fileSystemId 72
- When user with token "900000" wants to see the content of folder with path "/bla"
+ When user with token "900000" wants to see the content of folder with path "/Richard/bla"
+ Then response status code is 200
+ And the response contains the file with fileSystemId 72 and name "wow.txt"
+
+ Scenario: Successful interaction shared folder
+ # the folder
+ Given user with the userId 420 is allowed to VIEW the fileSystemItem with the fileSystemId 42
+ # the file
+ And user with the userId 420 is allowed to VIEW the fileSystemItem with the fileSystemId 72
+ When user with token "222222" wants to see the content of folder with path "/Richard/bla"
Then response status code is 200
And the response contains the file with fileSystemId 72 and name "wow.txt"
Scenario: Folder does not exist
- Given user with the userId 1234 is allowed to VIEW the fileSystemItem with the fileSystemId 42
- When user with token "900000" wants to see the content of folder with path "/bla/fasel"
+ When user with token "900000" wants to see the content of folder with path "/Richard/bla/fasel"
Then response status code is 400
And response contains key "message" and value "Folder does not exist, or you are not allowed to see the folder."
Scenario: insufficient authorization
- Given user 9877 exists
- And accessToken with value "2345678" exists for user 9877
- When user with token "2345678" wants to see the content of folder with path "/bla/fasel"
+ When user with token "222222" wants to see the content of folder with path "/Richard/bla"
Then response status code is 400
And response contains key "message" and value "Folder does not exist, or you are not allowed to see the folder."
- Scenario: shared folder (user)
- Given user 4321 exists
- And accessToken with value "123321123" exists for user 4321
- And user with the userId 4321 is allowed to VIEW the fileSystemItem with the fileSystemId 42
- When user with token "123321123" wants to see the content of folder with path "/bla"
- Then response status code is 200
- And the response contains an empty list for files and folders
-
- Scenario: shared folder and file (user)
- Given user 4321 exists
- And accessToken with value "123321123" exists for user 4321
- And user with the userId 4321 is allowed to VIEW the fileSystemItem with the fileSystemId 72
- And user with the userId 4321 is allowed to VIEW the fileSystemItem with the fileSystemId 42
- When user with token "123321123" wants to see the content of folder with path "/bla"
- Then response status code is 200
- And the response contains the file with fileSystemId 72 and name "wow.txt"
-
Scenario: shared folder (group)
- Given user 4321 exists
- And user with userId 4321 is in group with groupId 1
- And accessToken with value "123321123" exists for user 4321
+ And user with userId 420 is in group with groupId 1
And group with the groupId 1 is allowed to VIEW the fileSystemItem with the fileSystemId 42
- When user with token "123321123" wants to see the content of folder with path "/bla"
- Then response status code is 200
- And the response contains an empty list for files and folders
-
- Scenario: shared folder and file (group)
- Given user 4321 exists
- And user with userId 4321 is in group with groupId 1
- And accessToken with value "123321123" exists for user 4321
And group with the groupId 1 is allowed to VIEW the fileSystemItem with the fileSystemId 72
- And group with the groupId 1 is allowed to VIEW the fileSystemItem with the fileSystemId 42
- When user with token "123321123" wants to see the content of folder with path "/bla"
+ When user with token "222222" wants to see the content of folder with path "/Richard/bla"
Then response status code is 200
And the response contains the file with fileSystemId 72 and name "wow.txt"
Scenario: empty directory
- Given fileSystemItem with the fileSystemId 44 exists, was created by user with userId 420 has the path "/empty" and name "empty"
+ Given fileSystemItem with the fileSystemId 44 exists, has owner with userId 1234 has the path "/empty" and name "empty"
And fileSystemItem with the fileSystemId 44 is a folder
- And user with the userId 1234 is allowed to VIEW the fileSystemItem with the fileSystemId 44
- When user with token "900000" wants to see the content of folder with path "/empty"
+ When user with token "900000" wants to see the content of folder with path "/Richard/empty"
Then response status code is 200
And the response contains an empty list for files and folders
+
+ Scenario: root folder
+ When user with token "900000" wants to see the content of folder with path "/"
+ Then response status code is 200
+ And the response contains the folder with name "Richard"
+
+ Scenario: root folder shared
+ Given user with the userId 420 is allowed to VIEW the fileSystemItem with the fileSystemId 1234
+ When user with token "222222" wants to see the content of folder with path "/"
+ Then response status code is 200
+ And the response contains the folder with name "Richard"
+ And the response contains the folder with name "Nasir"
+
+ Scenario: nested shared folder
+ Given fileSystemItem with the fileSystemId 4 exists, has owner with userId 1234 has the path "/pläne" and name "pläne"
+ And fileSystemItem with the fileSystemId 5 exists, has owner with userId 1234 has the path "/pläne/städte" and name "städte"
+ And fileSystemItem with the fileSystemId 12 exists, has owner with userId 1234 has the path "/pläne/städte/jerusalem" and name "jerusalem"
+ And fileSystemItem with the fileSystemId 13 exists, has owner with userId 1234 and name "we_will_take.mp3"
+ And fileSystemItem with the fileSystemId 12 is a folder and contains the fileSystemId 13
+ And fileSystemItem with the fileSystemId 4 is a folder and contains the fileSystemId 5
+ And fileSystemItem with the fileSystemId 5 is a folder and contains the fileSystemId 12
+ And user with the userId 420 is allowed to VIEW the fileSystemItem with the fileSystemId 12
+ And user with the userId 420 is allowed to VIEW the fileSystemItem with the fileSystemId 13
+ # Use this is the crud permissions feature file.
+ #When user with token "222222" wants to see the content of folder with path "/Richard"
+ #Then response status code is 200
+ #And the response does not contains the file with fileSystemId 42 and name "bla"
+ #And the response contains the folder with fileSystemId 4 and name "pläne"
+ #When user with token "222222" wants to see the content of folder with path "/Richard/pläne"
+ #Then response status code is 200
+ #And the response contains the folder with fileSystemId 5 and name "städte"
+ #When user with token "222222" wants to see the content of folder with path "/Richard/pläne/städte"
+ #Then response status code is 200
+ #And the response contains the folder with fileSystemId 12 and name "jerusalem"
+ When user with token "222222" wants to see the content of folder with path "/Richard/pläne/städte/jerusalem"
+ Then response status code is 200
+ And the response contains the file with fileSystemId 13 and name "we_will_take.mp3"
diff --git a/src/test/resources/deleteFileSystemItems.feature b/src/test/resources/deleteFileSystemItems.feature
index 99225531..5b091f44 100644
--- a/src/test/resources/deleteFileSystemItems.feature
+++ b/src/test/resources/deleteFileSystemItems.feature
@@ -3,107 +3,76 @@ Feature: FileSystem Delete
Background:
Given database is empty
- And user 1234 exists
- And user 420 exists
+ And runtime user exists
+ And user with userId 1234 exists and has username "Richard", password "badPassword"
+ And user with userId 420 exists and has username "Nasir", password "AlsoBadPassword"
And accessToken with value "900000" exists for user 1234
- And fileSystemItem with the fileSystemId 42 exists, was created by user with userId 420 has the path "/bla" and name "bla"
+ And accessToken with value "222222" exists for user 420
+ And user with userId 1234 has HomeFolder with Id 1234
+ And user with userId 420 has HomeFolder with Id 420
+ And fileSystemItem with the fileSystemId 42 exists, has owner with userId 1234 has the path "/bla" and name "bla"
+ And fileSystemItem with the fileSystemId 72 exists, has owner with userId 1234 and name "wow.txt"
And fileSystemItem with the fileSystemId 42 is a folder and contains the fileSystemId 72
- And fileSystemItem with the fileSystemId 72 exists, was created by user with userId 420 and has the name "wow.txt"
+ And fileSystemItem with the fileSystemId 1234 is a folder and contains the fileSystemId 42
Scenario: File Deletion
- Given user with the userId 1234 is allowed to EDIT the fileSystemItem with the fileSystemId 72
- And user with the userId 1234 is allowed to VIEW the fileSystemItem with the fileSystemId 72
- And user with the userId 1234 is allowed to VIEW the fileSystemItem with the fileSystemId 42
- When user with token "900000" wants to see the content of folder with path "/bla"
+ When user with token "900000" wants to see the content of folder with path "/Richard/bla"
Then response status code is 200
And the response contains the file with fileSystemId 72 and name "wow.txt"
When user with token "900000" wants to delete the fileSystemItem with the fileSystemId 72
Then response status code is 200
- And response contains key "message" and value "Successfully deleted all requested FileSystemItems."
- When user with token "900000" wants to see the content of folder with path "/bla"
- And the response contains an empty list for files and folders
+ And the response contains the file with fileSystemId 72 and name "wow.txt"
+ When user with token "900000" wants to see the content of folder with path "/Richard/bla"
+ Then the response contains an empty list for files and folders
And response status code is 200
-
- Scenario: Folder and content Deletion
- Given user with the userId 1234 is allowed to EDIT the fileSystemItem with the fileSystemId 42
- And user with the userId 1234 is allowed to VIEW the fileSystemItem with the fileSystemId 42
- And user with the userId 1234 is allowed to EDIT the fileSystemItem with the fileSystemId 72
- And user with the userId 1234 is allowed to VIEW the fileSystemItem with the fileSystemId 72
- When user with token "900000" wants to delete the fileSystemItem with the fileSystemId 42
- Then response status code is 200
- When user with token "900000" wants to see the content of folder with path "/bla"
- Then response status code is 400
- And response contains key "message" and value "Folder does not exist, or you are not allowed to see the folder."
-
- Scenario: Folder and content Deletion with remaining content
- Given user with the userId 1234 is allowed to VIEW the fileSystemItem with the fileSystemId 42
- And user with the userId 1234 is allowed to EDIT the fileSystemItem with the fileSystemId 42
- And user with the userId 1234 is allowed to VIEW the fileSystemItem with the fileSystemId 72
- And user with the userId 1234 is allowed to EDIT the fileSystemItem with the fileSystemId 72
- And fileSystemItem with the fileSystemId 1080 exists, was created by user with userId 420 and has the name "IwillStay.txt"
- And user with the userId 1234 is allowed to VIEW the fileSystemItem with the fileSystemId 1080
- And fileSystemItem with the fileSystemId 42 is a folder and contains the fileSystemId 1080
- When user with token "900000" wants to delete the fileSystemItem with the fileSystemId 42
+ When user with token "900000" wants to get the info of fileSystemItem with the fileSystemId 42
Then response status code is 200
- And response contains key "message" and value "Not everything got deleted, because you are not allowed to edit some files."
- When user with token "900000" wants to see the content of folder with path "/bla"
- And the response does not contains the file with fileSystemId 72 and name "wow.txt"
- And the response contains the file with fileSystemId 1080 and name "IwillStay.txt"
+ And response contains a valid timestamp at key "lastUpdated".
+ And response contains the user with userId 1234 at key "lastUpdatedBy"
- Scenario: Folder and content Deletion with remaining content (invisible)
- And accessToken with value "2000000" exists for user 420
- Given user with the userId 1234 is allowed to EDIT the fileSystemItem with the fileSystemId 42
- Given user with the userId 1234 is allowed to VIEW the fileSystemItem with the fileSystemId 42
+ Scenario: Folder and content Deletion
When user with token "900000" wants to delete the fileSystemItem with the fileSystemId 42
Then response status code is 200
- # This sucks, because for the user everything got deleted. But the message doesnt say that because "NOT EVERYTHING GOT DELETED".
- And response contains key "message" and value "Not everything got deleted, because you are not allowed to edit some files."
- When user with token "900000" wants to see the content of folder with path "/bla"
+ And the response contains the file with fileSystemId 72 and name "wow.txt"
+ And the response contains the folder with fileSystemId 42 and name "bla"
+ When user with token "900000" wants to see the content of folder with path "/Richard/bla"
Then response status code is 400
And response contains key "message" and value "Folder does not exist, or you are not allowed to see the folder."
- When user with token "2000000" wants to see the content of folder with path "/bla"
- Then response status code is 200
- And the response contains the file with fileSystemId 72 and name "wow.txt"
Scenario: recursion
- Given fileSystemItem with the fileSystemId 0 exists, was created by user with userId 1234 has the path "/foo" and name "foo"
+ Given fileSystemItem with the fileSystemId 0 exists, has owner with userId 1234 has the path "/foo" and name "foo"
+ And fileSystemItem with the fileSystemId 1234 is a folder and contains the fileSystemId 0
And fileSystemItem with the fileSystemId 0 is a folder and contains the fileSystemId 1
- And fileSystemItem with the fileSystemId 1 exists, was created by user with userId 1234 has the path "/foo/bar" and name "bar"
+ And fileSystemItem with the fileSystemId 1 exists, has owner with userId 1234 has the path "/foo/bar" and name "bar"
And fileSystemItem with the fileSystemId 1 is a folder and contains the fileSystemId 2
- And fileSystemItem with the fileSystemId 2 exists, was created by user with userId 1234 and has the name "git.exe"
+ And fileSystemItem with the fileSystemId 2 exists, has owner with userId 1234 and name "git.exe"
When user with token "900000" wants to delete the fileSystemItem with the fileSystemId 0
Then response status code is 200
- And response contains key "message" and value "Successfully deleted all requested FileSystemItems."
- When user with token "900000" wants to see the content of folder with path "/foo/bar"
+ And the response contains the file with fileSystemId 2 and name "git.exe"
+ And the response contains the folder with fileSystemId 1 and name "bar"
+ And the response contains the folder with fileSystemId 0 and name "foo"
+ When user with token "900000" wants to see the content of folder with path "/Richard/foo/bar"
Then response status code is 400
And response contains key "message" and value "Folder does not exist, or you are not allowed to see the folder."
- When user with token "900000" wants to see the content of folder with path "/foo"
+ When user with token "900000" wants to see the content of folder with path "/Richard/foo"
Then response status code is 400
And response contains key "message" and value "Folder does not exist, or you are not allowed to see the folder."
-
- Scenario: recursion with remaining file
- Given fileSystemItem with the fileSystemId 0 exists, was created by user with userId 1234 has the path "/foo" and name "foo"
- And fileSystemItem with the fileSystemId 0 is a folder and contains the fileSystemId 1
- And fileSystemItem with the fileSystemId 1 exists, was created by user with userId 1234 has the path "/foo/bar" and name "bar"
- And fileSystemItem with the fileSystemId 1 is a folder and contains the fileSystemId 2
- And fileSystemItem with the fileSystemId 1 is a folder and contains the fileSystemId 3
- And fileSystemItem with the fileSystemId 2 exists, was created by user with userId 1234 and has the name "git.exe"
- And fileSystemItem with the fileSystemId 3 exists, was created by user with userId 420 and has the name "subversion.exe"
- And user with the userId 1234 is allowed to VIEW the fileSystemItem with the fileSystemId 3
- When user with token "900000" wants to delete the fileSystemItem with the fileSystemId 0
- Then response status code is 200
- And response contains key "message" and value "Not everything got deleted, because you are not allowed to edit some files."
- When user with token "900000" wants to see the content of folder with path "/foo/bar"
- Then response status code is 200
- And the response contains the file with fileSystemId 3 and name "subversion.exe"
- When user with token "900000" wants to see the content of folder with path "/foo"
+ When user with token "900000" wants to delete the fileSystemItem with the fileSystemId 42
Then response status code is 200
- And the response contains the folder with fileSystemId 1 and name "bar"
- And the response does not contains the file with fileSystemId 2 and name "git.exe"
+ When user with token "900000" wants to see the content of folder with path "/Richard/bla"
+ Then response status code is 400
+ And response contains key "message" and value "Folder does not exist, or you are not allowed to see the folder."
+ When user with token "900000" wants to get the info of fileSystemItem with the fileSystemId 72
+ Then response status code is 400
+ And response contains key "message" and value "FileSystemItem could not be found or you are not allowed to view it. FileSystemId was 72"
+ When user with token "900000" wants to see the content of folder with path "/Richard"
+ Then the response contains an empty list for files and folders
+ And response status code is 200
+
Scenario: insufficient authorization
- Given user with the userId 1234 is allowed to VIEW the fileSystemItem with the fileSystemId 42
- When user with token "900000" wants to delete the fileSystemItem with the fileSystemId 42
+ Given user with the userId 420 is allowed to VIEW the fileSystemItem with the fileSystemId 42
+ When user with token "222222" wants to delete the fileSystemItem with the fileSystemId 42
Then response status code is 400
And response contains key "message" and value "FileSystemEntity could not be deleted. FileSystemId was 42"
@@ -121,7 +90,6 @@ Feature: FileSystem Delete
Scenario: Folder was created by runtime user.
Given database is empty
- # If this fails check the runtime user id.
And fileSystemItem with the fileSystemId 0 exists, was created by user with userId 0 has the path "/" and name "HOME_kevin"
And user with userId 123123123 exists and has username "kevin", password "securePassword123"
And user with the userId 123123123 is allowed to VIEW the fileSystemItem with the fileSystemId 0
@@ -133,15 +101,17 @@ Feature: FileSystem Delete
Scenario: File was created by runtime user.
Given database is empty
+ And user with userId 123123123 has HomeFolder with Id 420
+ And fileSystemItem with the fileSystemId 420 is a folder and contains the fileSystemId 0
And user with userId 123123123 exists and has username "kevin", password "securePassword123"
- And user with the userId 123123123 is allowed to VIEW the fileSystemItem with the fileSystemId 2
- And user with the userId 123123123 is allowed to EDIT the fileSystemItem with the fileSystemId 2
And accessToken with value "token" exists for user 123123123
And fileSystemItem with the fileSystemId 0 exists, was created by user with userId 123123123 has the path "/foo" and name "foo"
And fileSystemItem with the fileSystemId 0 is a folder and contains the fileSystemId 1
And fileSystemItem with the fileSystemId 1 exists, was created by user with userId 123123123 has the path "/foo/bar" and name "bar"
And fileSystemItem with the fileSystemId 1 is a folder and contains the fileSystemId 2
And fileSystemItem with the fileSystemId 2 exists, was created by user with userId 0 and has the name "veryImportantDocumentDon'tDeleteMePls.exe"
+ And user with the userId 123123123 is allowed to VIEW the fileSystemItem with the fileSystemId 2
+ And user with the userId 123123123 is allowed to EDIT the fileSystemItem with the fileSystemId 2
When user with token "token" wants to delete the fileSystemItem with the fileSystemId 0
Then response status code is 200
- And response contains key "message" and value "Not everything got deleted, because you are not allowed to edit some files."
\ No newline at end of file
+ And the response contains an empty list for files and folders
\ No newline at end of file