From c7926adf3b65fefe33da561bfd9d79e64e79b3b5 Mon Sep 17 00:00:00 2001 From: open-schnick Date: Sun, 6 Dec 2020 11:42:33 +0100 Subject: [PATCH 01/50] WIP FF-218 Write Code for ShowContents --- .../business/FileSystemBusinessService.java | 37 ++++++++++++++++++- .../persistance/FileSystemRepository.java | 3 ++ .../rest/FileSystemRestService.java | 3 +- 3 files changed, 40 insertions(+), 3 deletions(-) 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 9dbcc70e..3310389b 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 @@ -3,21 +3,46 @@ import de.filefighter.rest.domain.filesystem.data.dto.File; import de.filefighter.rest.domain.filesystem.data.dto.Folder; import de.filefighter.rest.domain.filesystem.data.dto.FolderContents; +import de.filefighter.rest.domain.filesystem.data.persistance.FileSystemEntity; +import de.filefighter.rest.domain.filesystem.data.persistance.FileSystemRepository; import de.filefighter.rest.domain.filesystem.exceptions.FileSystemContentsNotAccessibleException; import de.filefighter.rest.domain.filesystem.type.FileSystemType; import de.filefighter.rest.domain.user.data.dto.User; import org.springframework.stereotype.Service; import java.time.Instant; +import java.util.ArrayList; @Service public class FileSystemBusinessService { - public FileSystemBusinessService() { + private final FileSystemRepository fileSystemRepository; + public FileSystemBusinessService(FileSystemRepository fileSystemRepository) { + + this.fileSystemRepository = fileSystemRepository; } - public static FolderContents getContentsOfFolder(String path, User authenticatedUser) { + // TODO: implement necessary files when a new user is created. + + // path is /username/folder + // in db only /folder but we know the username that created it. + // that way we know what contents to display if the same foldername exists twice. + + public FolderContents getContentsOfFolder(String path, User authenticatedUser) { + String pathToFind = this.removeTrailingBackSlashFromPath(path); + + ArrayList listOfFileSystemEntities = fileSystemRepository.findByPath(pathToFind); + if (listOfFileSystemEntities.isEmpty()) + throw new FileSystemContentsNotAccessibleException(); + + if (fileSystemEntity.isFile() || fileSystemEntity.getTypeId() != FileSystemType.FOLDER.getId()) + throw new FileSystemContentsNotAccessibleException(); + + if (!userIsAllowedToSeeFileSystemEntity(fileSystemEntity, authenticatedUser)) + throw new FileSystemContentsNotAccessibleException(); + + FolderContents folderContents; switch (path) { case "/": @@ -57,4 +82,12 @@ public static FolderContents getContentsOfFolder(String path, User authenticated } return folderContents; } + + public String removeTrailingBackSlashFromPath(String path) { + return null; + } + + public boolean userIsAllowedToSeeFileSystemEntity(FileSystemEntity entity, User user) { + return true; + } } diff --git a/src/main/java/de/filefighter/rest/domain/filesystem/data/persistance/FileSystemRepository.java b/src/main/java/de/filefighter/rest/domain/filesystem/data/persistance/FileSystemRepository.java index ca6cd2e2..84ba904b 100644 --- a/src/main/java/de/filefighter/rest/domain/filesystem/data/persistance/FileSystemRepository.java +++ b/src/main/java/de/filefighter/rest/domain/filesystem/data/persistance/FileSystemRepository.java @@ -3,7 +3,10 @@ import org.springframework.data.mongodb.repository.MongoRepository; import org.springframework.stereotype.Service; +import java.util.ArrayList; + @Service public interface FileSystemRepository extends MongoRepository { FileSystemEntity findByFileSystemId(long fileSystemId); + ArrayList findByPath(String path); } 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 f544df5d..0477f6ea 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 @@ -36,8 +36,9 @@ public ResponseEntity getContentsOfFolderByPathAndAccessToken(St String cleanValue = inputSanitizerService.sanitizeTokenValue(cleanHeader); AccessToken accessToken = accessTokenBusinessService.findAccessTokenByValue(cleanValue); User authenticatedUser = userAuthorizationService.authenticateUserWithAccessToken(accessToken); + String cleanPathString = InputSanitizerService.sanitizeString(path); - FolderContents folderContents = FileSystemBusinessService.getContentsOfFolder(path, authenticatedUser); + FolderContents folderContents = fileSystemBusinessService.getContentsOfFolder(cleanPathString, authenticatedUser); return new ResponseEntity<>(folderContents, HttpStatus.OK); } From 2a58b836a3b3fd277b5357880d82695a85768433 Mon Sep 17 00:00:00 2001 From: open-schnick Date: Wed, 9 Dec 2020 09:19:22 +0100 Subject: [PATCH 02/50] Added UserBusinessService.userWithUsernameDoesExist --- .../user/business/UserBusinessService.java | 31 +++++++------------ .../business/UserBusinessServiceUnitTest.java | 10 +++++- 2 files changed, 20 insertions(+), 21 deletions(-) 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 f2df352a..dfc05f89 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 @@ -11,8 +11,6 @@ import de.filefighter.rest.domain.user.exceptions.UserNotUpdatedException; import de.filefighter.rest.domain.user.group.GroupRepository; import de.filefighter.rest.domain.user.group.Groups; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Value; import org.springframework.data.mongodb.core.MongoTemplate; import org.springframework.data.mongodb.core.query.Criteria; @@ -34,10 +32,8 @@ public class UserBusinessService { private final GroupRepository groupRepository; private final MongoTemplate mongoTemplate; - private static final Logger LOG = LoggerFactory.getLogger(UserBusinessService.class); public static final int USER_ID_MAX = 99999999; - @Value("${filefighter.disable-password-check}") public boolean passwordCheckDisabled; @@ -89,17 +85,12 @@ public User findUserByUsername(String username) { } public void registerNewUser(UserRegisterForm newUser) { - // check username String username = newUser.getUsername(); - User user = null; - try { - user = this.findUserByUsername(newUser.getUsername()); - } catch (UserNotFoundException ignored) { - LOG.info("Username '{}' is free to use.", username); - } + if(!stringIsValid(username)) + throw new UserNotRegisteredException("Username was not valid."); - if (null != user) + if (this.userWithUsernameDoesExist(username)) throw new UserNotRegisteredException("Username already taken."); // check pws. @@ -149,6 +140,13 @@ public boolean passwordIsValid(String password) { return pattern.matcher(password).matches(); } + public boolean userWithUsernameDoesExist(String username){ + String lowercaseUsername = username.toLowerCase(); + + UserEntity entity = userRepository.findByLowercaseUsername(lowercaseUsername); + return entity != null; + } + public void updateUser(long userId, UserRegisterForm userToUpdate, User authenticatedUser) { if (null == userToUpdate) throw new UserNotUpdatedException("No updates specified."); @@ -231,14 +229,7 @@ private boolean updateUserName(Update update, String username) { if (!stringIsValid(username)) throw new UserNotUpdatedException("Wanted to change username, but username was not valid."); - User user = null; - try { - user = this.findUserByUsername(username); - } catch (UserNotFoundException ignored) { - LOG.info("Username '{}' is free to use.", username); - } - - if (null != user) + if (this.userWithUsernameDoesExist(username)) throw new UserNotUpdatedException("Username already taken."); update.set("username", username); diff --git a/src/test/java/de/filefighter/rest/domain/user/business/UserBusinessServiceUnitTest.java b/src/test/java/de/filefighter/rest/domain/user/business/UserBusinessServiceUnitTest.java index dbee6b53..5f319bb5 100644 --- a/src/test/java/de/filefighter/rest/domain/user/business/UserBusinessServiceUnitTest.java +++ b/src/test/java/de/filefighter/rest/domain/user/business/UserBusinessServiceUnitTest.java @@ -177,6 +177,7 @@ void passwordIsValidWorks() { @Test void registerNewUserThrows() { + String notValidUsername = null; String username = "ValidUserName"; String notValidPassword = "password"; String password = "validPassword1234"; @@ -190,11 +191,18 @@ void registerNewUserThrows() { .groupIds(groups) .build(); + // not valid. + userRegisterForm.setUsername(notValidUsername); + UserNotRegisteredException ex = assertThrows(UserNotRegisteredException.class, () -> + userBusinessService.registerNewUser(userRegisterForm)); + assertEquals("User could not be registered. Username was not valid.", ex.getMessage()); + // username taken + userRegisterForm.setUsername(username); when(userRepositoryMock.findByLowercaseUsername(username.toLowerCase())).thenReturn(UserEntity.builder().build()); when(userDtoServiceMock.createDto(any())).thenReturn(User.builder().build()); - UserNotRegisteredException ex = assertThrows(UserNotRegisteredException.class, () -> + ex = assertThrows(UserNotRegisteredException.class, () -> userBusinessService.registerNewUser(userRegisterForm)); assertEquals("User could not be registered. Username already taken.", ex.getMessage()); From 5564b1b1b212e322653b85e8c9e54a4922b0cdfc Mon Sep 17 00:00:00 2001 From: open-schnick Date: Fri, 11 Dec 2020 21:49:21 +0100 Subject: [PATCH 03/50] Renamed dto to DTO, removed PermissionSets from FileSystemItems. --- .../rest/configuration/PrepareDataBase.java | 20 +++- ...nterface.java => DTOServiceInterface.java} | 2 +- .../rest/domain/filesystem/data/dto/File.java | 7 +- .../filesystem/data/dto/FileSystemItem.java | 5 +- .../domain/filesystem/data/dto/Folder.java | 5 +- ...eSystemContentsNotAccessibleException.java | 4 + .../rest/FileSystemRestService.java | 2 +- .../business/AccessTokenBusinessService.java | 4 +- ...ervice.java => AccessTokenDTOService.java} | 6 +- .../business/UserAuthorizationService.java | 4 +- .../user/business/UserBusinessService.java | 24 ++-- ...serDtoService.java => UserDTOService.java} | 6 +- .../rest/cucumber/CrudPermissionSteps.java | 12 +- .../AccessTokenBusinessServiceUnitTest.java | 2 +- .../AccessTokenDtoServiceUnitTest.java | 4 +- .../UserAuthorizationServiceUnitTest.java | 2 +- .../business/UserBusinessServiceUnitTest.java | 2 +- .../user/business/UserDtoServiceUnitTest.java | 4 +- src/test/resources/ViewFolderContents.feature | 106 +++++++++--------- 19 files changed, 116 insertions(+), 105 deletions(-) rename src/main/java/de/filefighter/rest/domain/common/{DtoServiceInterface.java => DTOServiceInterface.java} (69%) rename src/main/java/de/filefighter/rest/domain/token/business/{AccessTokenDtoService.java => AccessTokenDTOService.java} (87%) rename src/main/java/de/filefighter/rest/domain/user/business/{UserDtoService.java => UserDTOService.java} (87%) diff --git a/src/main/java/de/filefighter/rest/configuration/PrepareDataBase.java b/src/main/java/de/filefighter/rest/configuration/PrepareDataBase.java index f56c559d..81f17390 100644 --- a/src/main/java/de/filefighter/rest/configuration/PrepareDataBase.java +++ b/src/main/java/de/filefighter/rest/configuration/PrepareDataBase.java @@ -142,22 +142,34 @@ CommandLineRunner initDataBaseDev(UserRepository userRepository, AccessTokenRepo .validUntil(Instant.now().getEpochSecond() + AccessTokenBusinessService.ACCESS_TOKEN_DURATION_IN_SECONDS) .build())); - LOG.info("Preloading default fsItems: {} {}.", + LOG.info("Preloading default fsItems: {} {} {}.", fileSystemRepository.save(FileSystemEntity.builder() .createdByUserId(0) .fileSystemId(0) .isFile(false) .path("/") - .itemIds(new long[]{1}) + .itemIds(new long[]{2}) .lastUpdated(Instant.now().getEpochSecond()) - .name("root") + .name("root_User") .size(420) .typeId(FileSystemType.FOLDER.getId()) .visibleForGroupIds(new long[]{-1, 0, 1}) .build()), fileSystemRepository.save(FileSystemEntity.builder() - .createdByUserId(0) + .createdByUserId(1) .fileSystemId(1) + .isFile(false) + .path("/") + .itemIds(new long[0]) + .lastUpdated(Instant.now().getEpochSecond()) + .name("root_User1") + .size(420) + .typeId(FileSystemType.FOLDER.getId()) + .visibleForGroupIds(new long[]{-1, 0, 1}) + .build()), + fileSystemRepository.save(FileSystemEntity.builder() + .createdByUserId(0) + .fileSystemId(2) .isFile(true) .lastUpdated(Instant.now().getEpochSecond()) .name("dummyFile.txt") diff --git a/src/main/java/de/filefighter/rest/domain/common/DtoServiceInterface.java b/src/main/java/de/filefighter/rest/domain/common/DTOServiceInterface.java similarity index 69% rename from src/main/java/de/filefighter/rest/domain/common/DtoServiceInterface.java rename to src/main/java/de/filefighter/rest/domain/common/DTOServiceInterface.java index 06605dbb..0896db98 100644 --- a/src/main/java/de/filefighter/rest/domain/common/DtoServiceInterface.java +++ b/src/main/java/de/filefighter/rest/domain/common/DTOServiceInterface.java @@ -1,6 +1,6 @@ package de.filefighter.rest.domain.common; -public interface DtoServiceInterface { +public interface DTOServiceInterface { D createDto(E entity); E findEntity(D dto); } diff --git a/src/main/java/de/filefighter/rest/domain/filesystem/data/dto/File.java b/src/main/java/de/filefighter/rest/domain/filesystem/data/dto/File.java index d4b5183c..84fa5f5b 100644 --- a/src/main/java/de/filefighter/rest/domain/filesystem/data/dto/File.java +++ b/src/main/java/de/filefighter/rest/domain/filesystem/data/dto/File.java @@ -1,13 +1,12 @@ package de.filefighter.rest.domain.filesystem.data.dto; import de.filefighter.rest.domain.filesystem.type.FileSystemType; -import de.filefighter.rest.domain.permission.data.dto.PermissionSet; -public class File extends FileSystemItem{ +public class File extends FileSystemItem { public File() { } - public File(long fileSystemId, String name, double size, long createdByUserId, long lastUpdated, FileSystemType type, PermissionSet permissionSet) { - super(fileSystemId, name, size, createdByUserId, lastUpdated, type, permissionSet); + public File(long fileSystemId, String name, double size, long createdByUserId, long lastUpdated, FileSystemType type) { + super(fileSystemId, name, size, createdByUserId, lastUpdated, type); } } \ No newline at end of file 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 43452a08..3f18f86d 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 @@ -1,7 +1,6 @@ package de.filefighter.rest.domain.filesystem.data.dto; import de.filefighter.rest.domain.filesystem.type.FileSystemType; -import de.filefighter.rest.domain.permission.data.dto.PermissionSet; import lombok.Getter; import lombok.Setter; @@ -14,18 +13,16 @@ public class FileSystemItem { private long createdByUserId; //uploadedBy private long lastUpdated; private FileSystemType type; - private PermissionSet permissionSet; protected FileSystemItem() { } - public FileSystemItem(long fileSystemId, String name, double size, long createdByUserId, long lastUpdated, FileSystemType type, PermissionSet permissionSet) { + public FileSystemItem(long fileSystemId, String name, double size, long createdByUserId, long lastUpdated, FileSystemType type) { this.fileSystemId = fileSystemId; this.name = name; this.size = size; this.createdByUserId = createdByUserId; this.lastUpdated = lastUpdated; this.type = type; - this.permissionSet = permissionSet; } } diff --git a/src/main/java/de/filefighter/rest/domain/filesystem/data/dto/Folder.java b/src/main/java/de/filefighter/rest/domain/filesystem/data/dto/Folder.java index af47726d..a700e6b7 100644 --- a/src/main/java/de/filefighter/rest/domain/filesystem/data/dto/Folder.java +++ b/src/main/java/de/filefighter/rest/domain/filesystem/data/dto/Folder.java @@ -1,7 +1,6 @@ package de.filefighter.rest.domain.filesystem.data.dto; import de.filefighter.rest.domain.filesystem.type.FileSystemType; -import de.filefighter.rest.domain.permission.data.dto.PermissionSet; public class Folder extends FileSystemItem { private String path; @@ -9,8 +8,8 @@ public class Folder extends FileSystemItem { public Folder() { } - public Folder(long id, String path, String name, double size, long createdByUserId, long lastUpdated, PermissionSet permissionSet) { - super(id, name, size, createdByUserId, lastUpdated, FileSystemType.FOLDER, permissionSet); + public Folder(long id, String path, String name, double size, long createdByUserId, long lastUpdated) { + super(id, name, size, createdByUserId, lastUpdated, FileSystemType.FOLDER); this.path = path; } diff --git a/src/main/java/de/filefighter/rest/domain/filesystem/exceptions/FileSystemContentsNotAccessibleException.java b/src/main/java/de/filefighter/rest/domain/filesystem/exceptions/FileSystemContentsNotAccessibleException.java index 389e6e95..a7d17554 100644 --- a/src/main/java/de/filefighter/rest/domain/filesystem/exceptions/FileSystemContentsNotAccessibleException.java +++ b/src/main/java/de/filefighter/rest/domain/filesystem/exceptions/FileSystemContentsNotAccessibleException.java @@ -5,4 +5,8 @@ public class FileSystemContentsNotAccessibleException extends RuntimeException { public FileSystemContentsNotAccessibleException() { super("Folder does not exist, or you are not allowed to see the folder."); } + + public FileSystemContentsNotAccessibleException(String reason) { + super("Folder contents could not be displayed. "+reason); + } } 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 0477f6ea..1efeb639 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 @@ -38,7 +38,7 @@ public ResponseEntity getContentsOfFolderByPathAndAccessToken(St User authenticatedUser = userAuthorizationService.authenticateUserWithAccessToken(accessToken); String cleanPathString = InputSanitizerService.sanitizeString(path); - FolderContents folderContents = fileSystemBusinessService.getContentsOfFolder(cleanPathString, authenticatedUser); + FolderContents folderContents = fileSystemBusinessService.getFolderContentsByPath(cleanPathString, authenticatedUser); return new ResponseEntity<>(folderContents, HttpStatus.OK); } diff --git a/src/main/java/de/filefighter/rest/domain/token/business/AccessTokenBusinessService.java b/src/main/java/de/filefighter/rest/domain/token/business/AccessTokenBusinessService.java index 918a019f..cba033a0 100644 --- a/src/main/java/de/filefighter/rest/domain/token/business/AccessTokenBusinessService.java +++ b/src/main/java/de/filefighter/rest/domain/token/business/AccessTokenBusinessService.java @@ -17,13 +17,13 @@ public class AccessTokenBusinessService { private final AccessTokenRepository accessTokenRepository; - private final AccessTokenDtoService accessTokenDtoService; + private final AccessTokenDTOService accessTokenDtoService; public static final long ACCESS_TOKEN_DURATION_IN_SECONDS = 3600L; public static final long ACCESS_TOKEN_SAFETY_MARGIN = 5L; private static final Logger LOG = LoggerFactory.getLogger(AccessTokenBusinessService.class); - public AccessTokenBusinessService(AccessTokenRepository accessTokenRepository, AccessTokenDtoService accessTokenDtoService) { + public AccessTokenBusinessService(AccessTokenRepository accessTokenRepository, AccessTokenDTOService accessTokenDtoService) { this.accessTokenRepository = accessTokenRepository; this.accessTokenDtoService = accessTokenDtoService; } diff --git a/src/main/java/de/filefighter/rest/domain/token/business/AccessTokenDtoService.java b/src/main/java/de/filefighter/rest/domain/token/business/AccessTokenDTOService.java similarity index 87% rename from src/main/java/de/filefighter/rest/domain/token/business/AccessTokenDtoService.java rename to src/main/java/de/filefighter/rest/domain/token/business/AccessTokenDTOService.java index 6a99629d..a86c26bb 100644 --- a/src/main/java/de/filefighter/rest/domain/token/business/AccessTokenDtoService.java +++ b/src/main/java/de/filefighter/rest/domain/token/business/AccessTokenDTOService.java @@ -1,6 +1,6 @@ package de.filefighter.rest.domain.token.business; -import de.filefighter.rest.domain.common.DtoServiceInterface; +import de.filefighter.rest.domain.common.DTOServiceInterface; import de.filefighter.rest.domain.token.data.dto.AccessToken; import de.filefighter.rest.domain.token.data.persistance.AccessTokenEntity; import de.filefighter.rest.domain.token.data.persistance.AccessTokenRepository; @@ -8,11 +8,11 @@ import org.springframework.stereotype.Service; @Service -public class AccessTokenDtoService implements DtoServiceInterface { +public class AccessTokenDTOService implements DTOServiceInterface { private final AccessTokenRepository accessTokenRepository; - public AccessTokenDtoService(AccessTokenRepository accessTokenRepository) { + public AccessTokenDTOService(AccessTokenRepository accessTokenRepository) { this.accessTokenRepository = accessTokenRepository; } diff --git a/src/main/java/de/filefighter/rest/domain/user/business/UserAuthorizationService.java b/src/main/java/de/filefighter/rest/domain/user/business/UserAuthorizationService.java index e771f3ae..0af9b2b0 100644 --- a/src/main/java/de/filefighter/rest/domain/user/business/UserAuthorizationService.java +++ b/src/main/java/de/filefighter/rest/domain/user/business/UserAuthorizationService.java @@ -19,11 +19,11 @@ public class UserAuthorizationService { private final UserRepository userRepository; - private final UserDtoService userDtoService; + private final UserDTOService userDtoService; private static final Logger LOG = LoggerFactory.getLogger(UserAuthorizationService.class); - public UserAuthorizationService(UserRepository userRepository, UserDtoService userDtoService) { + public UserAuthorizationService(UserRepository userRepository, UserDTOService userDtoService) { this.userRepository = userRepository; this.userDtoService = userDtoService; } 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 dfc05f89..d56bf7a9 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 @@ -28,7 +28,7 @@ public class UserBusinessService { private final UserRepository userRepository; - private final UserDtoService userDtoService; + private final UserDTOService userDtoService; private final GroupRepository groupRepository; private final MongoTemplate mongoTemplate; @@ -37,7 +37,7 @@ public class UserBusinessService { @Value("${filefighter.disable-password-check}") public boolean passwordCheckDisabled; - public UserBusinessService(UserRepository userRepository, UserDtoService userDtoService, GroupRepository groupRepository, MongoTemplate mongoTemplate) { + public UserBusinessService(UserRepository userRepository, UserDTOService userDtoService, GroupRepository groupRepository, MongoTemplate mongoTemplate) { this.userRepository = userRepository; this.userDtoService = userDtoService; this.groupRepository = groupRepository; @@ -75,9 +75,7 @@ public RefreshToken getRefreshTokenForUser(User user) { } public User findUserByUsername(String username) { - String lowercaseUsername = username.toLowerCase(); - - UserEntity entity = userRepository.findByLowercaseUsername(lowercaseUsername); + UserEntity entity = getUserWithUsername(username); if (null == entity) throw new UserNotFoundException("User with username '" + username + "' not found."); @@ -87,10 +85,10 @@ public User findUserByUsername(String username) { public void registerNewUser(UserRegisterForm newUser) { String username = newUser.getUsername(); - if(!stringIsValid(username)) + if (!stringIsValid(username)) throw new UserNotRegisteredException("Username was not valid."); - if (this.userWithUsernameDoesExist(username)) + if (null != this.getUserWithUsername(username)) throw new UserNotRegisteredException("Username already taken."); // check pws. @@ -140,11 +138,13 @@ public boolean passwordIsValid(String password) { return pattern.matcher(password).matches(); } - public boolean userWithUsernameDoesExist(String username){ + /** + * @param username username to find. + * @return null or the found user. + */ + public UserEntity getUserWithUsername(String username) { String lowercaseUsername = username.toLowerCase(); - - UserEntity entity = userRepository.findByLowercaseUsername(lowercaseUsername); - return entity != null; + return userRepository.findByLowercaseUsername(lowercaseUsername); } public void updateUser(long userId, UserRegisterForm userToUpdate, User authenticatedUser) { @@ -229,7 +229,7 @@ private boolean updateUserName(Update update, String username) { if (!stringIsValid(username)) throw new UserNotUpdatedException("Wanted to change username, but username was not valid."); - if (this.userWithUsernameDoesExist(username)) + if (null != getUserWithUsername(username)) throw new UserNotUpdatedException("Username already taken."); update.set("username", username); diff --git a/src/main/java/de/filefighter/rest/domain/user/business/UserDtoService.java b/src/main/java/de/filefighter/rest/domain/user/business/UserDTOService.java similarity index 87% rename from src/main/java/de/filefighter/rest/domain/user/business/UserDtoService.java rename to src/main/java/de/filefighter/rest/domain/user/business/UserDTOService.java index 54b2fc17..33283192 100644 --- a/src/main/java/de/filefighter/rest/domain/user/business/UserDtoService.java +++ b/src/main/java/de/filefighter/rest/domain/user/business/UserDTOService.java @@ -1,6 +1,6 @@ package de.filefighter.rest.domain.user.business; -import de.filefighter.rest.domain.common.DtoServiceInterface; +import de.filefighter.rest.domain.common.DTOServiceInterface; import de.filefighter.rest.domain.user.data.dto.User; import de.filefighter.rest.domain.user.data.persistance.UserEntity; import de.filefighter.rest.domain.user.data.persistance.UserRepository; @@ -9,12 +9,12 @@ import org.springframework.stereotype.Service; @Service -public class UserDtoService implements DtoServiceInterface { +public class UserDTOService implements DTOServiceInterface { private final GroupRepository groupRepository; private final UserRepository userRepository; - public UserDtoService(GroupRepository groupRepository, UserRepository userRepository) { + public UserDTOService(GroupRepository groupRepository, UserRepository userRepository) { this.groupRepository = groupRepository; this.userRepository = userRepository; } diff --git a/src/test/java/de/filefighter/rest/cucumber/CrudPermissionSteps.java b/src/test/java/de/filefighter/rest/cucumber/CrudPermissionSteps.java index d8bc96c8..cb7c1f6a 100644 --- a/src/test/java/de/filefighter/rest/cucumber/CrudPermissionSteps.java +++ b/src/test/java/de/filefighter/rest/cucumber/CrudPermissionSteps.java @@ -6,27 +6,27 @@ public class CrudPermissionSteps extends RestApplicationIntegrationTest { - @And("user {long} has permission of {string} for {string} with id {long}") + @And("user {long} has permission of {string} for {string} with fileSystemId {long}") public void userHasPermissionOfForWithIdId(long userId, String readOrWrite, String fileOrFolder, long fsItemId) { } - @When("user with token {string} wants to change permissions of {string} with id {long} for user with id {long} to {string}") + @When("user with token {string} wants to change permissions of {string} with fileSystemId {long} for user with id {long} to {string}") public void userWithTokenWantsToChangePermissionsOfWithIdIdForUserWithIdTo(String accessTokenValue, String fileOrFolder, long fsItemId, long userId, String newPermission) { } - @When("user with token {string} wants to remove permissions of {string} with id {long} for user {long}") + @When("user with token {string} wants to remove permissions of {string} with fileSystemId {long} for user {long}") public void userWithTokenWantsToRemovePermissionsOfWithIdIdForUser(String accessTokenValue, String fileOrFolder, long fsItemId, long userId) { } - @And("user with id {long} has no permission for {string} with id {long}") + @And("user with id {long} has no permission for {string} with fileSystemId {long}") public void userWithIdHasNoPermissionForWithIdId(long userId, String fileOrFolder, long fsItemId) { } - @And("user {long} has no permission for {string} with id {long}") + @And("user {long} has no permission for {string} with fileSystemId {long}") public void userHasNoPermissionForWithId(long userId, String fileOrFolder, long fsItemId) { } - @When("user with token {string} wants to give {string} permission for {string} with id {long} to user {long}") + @When("user with token {string} wants to give {string} permission for {string} with fileSystemId {long} to user {long}") public void userWithTokenWantsToAddPermissionsOfWithIdForUserFor(String accessTokenValue, String permission, String fileOrFolder, long fsItemId, long userId) { } diff --git a/src/test/java/de/filefighter/rest/domain/token/business/AccessTokenBusinessServiceUnitTest.java b/src/test/java/de/filefighter/rest/domain/token/business/AccessTokenBusinessServiceUnitTest.java index 0596669b..e52586c5 100644 --- a/src/test/java/de/filefighter/rest/domain/token/business/AccessTokenBusinessServiceUnitTest.java +++ b/src/test/java/de/filefighter/rest/domain/token/business/AccessTokenBusinessServiceUnitTest.java @@ -19,7 +19,7 @@ class AccessTokenBusinessServiceUnitTest { private final AccessTokenRepository accessTokenRepositoryMock = mock(AccessTokenRepository.class); - private final AccessTokenDtoService accessTokenDtoServiceMock = mock(AccessTokenDtoService.class); + private final AccessTokenDTOService accessTokenDtoServiceMock = mock(AccessTokenDTOService.class); private AccessTokenBusinessService accessTokenBusinessService; @BeforeEach diff --git a/src/test/java/de/filefighter/rest/domain/token/business/AccessTokenDtoServiceUnitTest.java b/src/test/java/de/filefighter/rest/domain/token/business/AccessTokenDtoServiceUnitTest.java index a244f0c0..44498ae9 100644 --- a/src/test/java/de/filefighter/rest/domain/token/business/AccessTokenDtoServiceUnitTest.java +++ b/src/test/java/de/filefighter/rest/domain/token/business/AccessTokenDtoServiceUnitTest.java @@ -15,11 +15,11 @@ class AccessTokenDtoServiceUnitTest { private final AccessTokenRepository accessTokenRepository = mock(AccessTokenRepository.class); - private AccessTokenDtoService accessTokenDtoService; + private AccessTokenDTOService accessTokenDtoService; @BeforeEach void setUp() { - accessTokenDtoService = new AccessTokenDtoService(accessTokenRepository); + accessTokenDtoService = new AccessTokenDTOService(accessTokenRepository); } @Test diff --git a/src/test/java/de/filefighter/rest/domain/user/business/UserAuthorizationServiceUnitTest.java b/src/test/java/de/filefighter/rest/domain/user/business/UserAuthorizationServiceUnitTest.java index 59af310e..39a399e4 100644 --- a/src/test/java/de/filefighter/rest/domain/user/business/UserAuthorizationServiceUnitTest.java +++ b/src/test/java/de/filefighter/rest/domain/user/business/UserAuthorizationServiceUnitTest.java @@ -17,7 +17,7 @@ class UserAuthorizationServiceUnitTest { private final UserRepository userRepositoryMock = mock(UserRepository.class); - private final UserDtoService userDtoServiceMock = mock(UserDtoService.class); + private final UserDTOService userDtoServiceMock = mock(UserDTOService.class); private final UserAuthorizationService userAuthorizationService = new UserAuthorizationService( userRepositoryMock, userDtoServiceMock); diff --git a/src/test/java/de/filefighter/rest/domain/user/business/UserBusinessServiceUnitTest.java b/src/test/java/de/filefighter/rest/domain/user/business/UserBusinessServiceUnitTest.java index 5f319bb5..c5857212 100644 --- a/src/test/java/de/filefighter/rest/domain/user/business/UserBusinessServiceUnitTest.java +++ b/src/test/java/de/filefighter/rest/domain/user/business/UserBusinessServiceUnitTest.java @@ -22,7 +22,7 @@ class UserBusinessServiceUnitTest { private final UserRepository userRepositoryMock = mock(UserRepository.class); - private final UserDtoService userDtoServiceMock = mock(UserDtoService.class); + private final UserDTOService userDtoServiceMock = mock(UserDTOService.class); private final GroupRepository groupRepositoryMock = mock(GroupRepository.class); private final MongoTemplate mongoTemplateMock = mock(MongoTemplate.class); private UserBusinessService userBusinessService; diff --git a/src/test/java/de/filefighter/rest/domain/user/business/UserDtoServiceUnitTest.java b/src/test/java/de/filefighter/rest/domain/user/business/UserDtoServiceUnitTest.java index e3baaf1a..3954a12a 100644 --- a/src/test/java/de/filefighter/rest/domain/user/business/UserDtoServiceUnitTest.java +++ b/src/test/java/de/filefighter/rest/domain/user/business/UserDtoServiceUnitTest.java @@ -18,11 +18,11 @@ class UserDtoServiceUnitTest { private final GroupRepository groupRepositoryMock = mock(GroupRepository.class); private final UserRepository userRepositoryMock = mock(UserRepository.class); - private UserDtoService userDtoService; + private UserDTOService userDtoService; @BeforeEach void setUp() { - userDtoService = new UserDtoService(groupRepositoryMock, userRepositoryMock); + userDtoService = new UserDTOService(groupRepositoryMock, userRepositoryMock); } @Test diff --git a/src/test/resources/ViewFolderContents.feature b/src/test/resources/ViewFolderContents.feature index 0feefe0a..12b64290 100644 --- a/src/test/resources/ViewFolderContents.feature +++ b/src/test/resources/ViewFolderContents.feature @@ -1,53 +1,53 @@ -#Feature: View Folder -# As a user -# I want to see the content of folders and navigate in them, so they can see and interact with their uploaded and shared files. -# -#Background: -# Given database is empty -# And user 1234 exists -# And user 1234 has access token "900000" -# And "folder" exists with id 42 and path "bla" -# And "file" exists with id 72 and path "bla/wow.txt" -# -# -#Scenario: Successful interaction -# Given user 1234 has permission of "view" for "folder" with id 42 -# And user 1234 has permission of "view" for "file" with id 72 -# When user with token "900000" wants to see the content of folder with path "bla" -# Then response status code is 200 -# And the response contains the file with id 72 and name "wow.txt" -# -# -#Scenario: Folder does not exist -# Given user 1234 has permission of "view" for "folder" with id 42 -# When user with token "900000" wants to see the content of folder with path "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 user 9877 has access token "2345678" -# When user with token "2345678" 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: shared file -# Given "folder" exists with id 43 and path "bla" -# And "file" exists with id 73 and path "bla/wow.txt" -# And user 1234 is owner of file or folder with id 42 -# And user 1234 is owner of file or folder with id 72 -# And user 1234 has permission of "view" for "folder" with id 43 -# And user 1234 has permission of "view" for "file" with id 73 -# When user with token "900000" wants to see the content of folder with path "bla" -# Then response status code is 200 -# And the response contains the file with id 72 and name "wow.txt" -# And the response contains the file with id 73 and name "wow.txt" -# -#Scenario: empty directory -# Given "folder" exists with id 44 and path "empty" -# And user 1234 has permission of "view" for "folder" with id 44 -# When user with token "900000" wants to see the content of folder with path "empty" -# Then response status code is 200 -# And the response contains an empty list for files and folders \ No newline at end of file +Feature: View Folder + As a user + I want to see the content of folders and navigate in them, so they can see and interact with their uploaded and shared files. + +Background: + Given database is empty + And user 1234 exists + And accessToken with value "900000" exists for user 1234 + And "folder" exists with fileSystemId 42 and path "bla" + And "file" exists with fileSystemId 72 and path "bla/wow.txt" + + +Scenario: Successful interaction + Given user 1234 has permission of "view" for "folder" with fileSystemId 42 + And user 1234 has permission of "view" for "file" with fileSystemId 72 + When user with token "900000" 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: Folder does not exist + Given user 1234 has permission of "view" for "folder" with fileSystemId 42 + When user with token "900000" wants to see the content of folder with path "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" + 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 file + Given "folder" exists with fileSystemId 43 and path "bla" + And "file" exists with fileSystemId 73 and path "bla/wow.txt" + And user 1234 is owner of file or folder with fileSystemId 42 + And user 1234 is owner of file or folder with fileSystemId 72 + And user 1234 has permission of "view" for "folder" with fileSystemId 43 + And user 1234 has permission of "view" for "file" with fileSystemId 73 + When user with token "900000" 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" + And the response contains the file with fileSystemId 73 and name "wow.txt" + +Scenario: empty directory + Given "folder" exists with fileSystemId 44 and path "empty" + And user 1234 has permission of "view" for "folder" with fileSystemId 44 + When user with token "900000" wants to see the content of folder with path "empty" + Then response status code is 200 + And the response contains an empty list for files and folders \ No newline at end of file From 88065c33a97934aa5c0e3c585783bdc26e4c0217 Mon Sep 17 00:00:00 2001 From: open-schnick Date: Fri, 11 Dec 2020 21:50:06 +0100 Subject: [PATCH 04/50] FF-218 Added main functions. --- .../business/FileSystemBusinessService.java | 125 +++++++++++------- .../business/FileSystemItemsDTOService.java | 41 ++++++ 2 files changed, 118 insertions(+), 48 deletions(-) create mode 100644 src/main/java/de/filefighter/rest/domain/filesystem/business/FileSystemItemsDTOService.java 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 3310389b..cf35aaf6 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,5 +1,6 @@ package de.filefighter.rest.domain.filesystem.business; +import de.filefighter.rest.domain.common.InputSanitizerService; import de.filefighter.rest.domain.filesystem.data.dto.File; import de.filefighter.rest.domain.filesystem.data.dto.Folder; import de.filefighter.rest.domain.filesystem.data.dto.FolderContents; @@ -7,87 +8,115 @@ import de.filefighter.rest.domain.filesystem.data.persistance.FileSystemRepository; import de.filefighter.rest.domain.filesystem.exceptions.FileSystemContentsNotAccessibleException; import de.filefighter.rest.domain.filesystem.type.FileSystemType; +import de.filefighter.rest.domain.user.business.UserBusinessService; import de.filefighter.rest.domain.user.data.dto.User; +import de.filefighter.rest.domain.user.data.persistance.UserEntity; +import de.filefighter.rest.rest.exceptions.FileFighterDataException; import org.springframework.stereotype.Service; -import java.time.Instant; import java.util.ArrayList; +import java.util.Arrays; @Service public class FileSystemBusinessService { + private final FileSystemItemsDTOService fileSystemItemsDTOService; private final FileSystemRepository fileSystemRepository; + private final UserBusinessService userBusinessService; - public FileSystemBusinessService(FileSystemRepository fileSystemRepository) { - + public FileSystemBusinessService(FileSystemItemsDTOService fileSystemItemsDTOService, FileSystemRepository fileSystemRepository, UserBusinessService userBusinessService) { + this.fileSystemItemsDTOService = fileSystemItemsDTOService; this.fileSystemRepository = fileSystemRepository; + this.userBusinessService = userBusinessService; } // TODO: implement necessary files when a new user is created. // path is /username/folder // in db only /folder but we know the username that created it. - // that way we know what contents to display if the same foldername exists twice. + // that way we know what contents to display if the same folderName exists twice. + + public FolderContents getFolderContentsByPath(String path, User authenticatedUser) { + String[] pathWithoutSlashes = path.split("/"); + + if (pathWithoutSlashes.length < 2) + throw new FileSystemContentsNotAccessibleException(); - public FolderContents getContentsOfFolder(String path, User authenticatedUser) { - String pathToFind = this.removeTrailingBackSlashFromPath(path); + if (!"".equals(pathWithoutSlashes[0])) + throw new FileSystemContentsNotAccessibleException("Path was in wrong format. Use a leading backslash."); + String username = pathWithoutSlashes[1]; + if (!InputSanitizerService.stringIsValid(username)) + throw new FileSystemContentsNotAccessibleException("Path was in wrong format. Username was not found in path."); + + UserEntity userEntityWithUsername = userBusinessService.getUserWithUsername(username); + if (null == userEntityWithUsername) + throw new FileSystemContentsNotAccessibleException("Username in path does not exist."); + + //TODO: is it a risk to use a user input as regex? + String pathToFind = path.split("/" + username)[1]; + pathToFind = removeTrailingBackSlashes(pathToFind); + + // find the folder with matching path. ArrayList listOfFileSystemEntities = fileSystemRepository.findByPath(pathToFind); if (listOfFileSystemEntities.isEmpty()) throw new FileSystemContentsNotAccessibleException(); - if (fileSystemEntity.isFile() || fileSystemEntity.getTypeId() != FileSystemType.FOLDER.getId()) - throw new FileSystemContentsNotAccessibleException(); + // remove all not accessible items. + listOfFileSystemEntities.removeIf(entity -> entity.isFile() || entity.getTypeId() != FileSystemType.FOLDER.getId() || userEntityWithUsername.getUserId() != entity.getCreatedByUserId() || !userIsAllowedToSeeFileSystemEntity(entity, authenticatedUser)); - if (!userIsAllowedToSeeFileSystemEntity(fileSystemEntity, authenticatedUser)) + if (listOfFileSystemEntities.isEmpty()) throw new FileSystemContentsNotAccessibleException(); + if (listOfFileSystemEntities.size() != 1) + throw new IllegalStateException("More than one folder was found with the path " + pathToFind + " and name " + username); + + // get the contents + FileSystemEntity fileSystemEntity = listOfFileSystemEntities.get(0); + return this.getFolderContentsByEntity(fileSystemEntity, authenticatedUser); + } + + public FolderContents getFolderContentsByEntity(FileSystemEntity fileSystemEntity, User authenticatedUser) { + long[] folderContentItemIds = fileSystemEntity.getItemIds(); - FolderContents folderContents; - switch (path) { - case "/": - folderContents = FolderContents.builder() - .files(new File[]{new File(0, "DummyFileInRoot.txt", 420, 0, Instant.now().getEpochSecond(), FileSystemType.TEXT, null)}) - .folders(new Folder[]{ - new Folder(1, "/bla", "bla", 12345, 0, Instant.now().getEpochSecond(), null), - new Folder(2, "/fasel", "fasel", 12345, 0, Instant.now().getEpochSecond(), null) - }) - .build(); - break; - case "/bla": - folderContents = FolderContents.builder() - .files(new File[]{ - new File(3, "DummyFileInBla.pdf", 42, 0, Instant.now().getEpochSecond(), FileSystemType.PDF, null), - new File(4, "DummyFileInBla1.jpg", 1234321, 0, Instant.now().getEpochSecond(), FileSystemType.PICTURE, null) - }) - .build(); - break; - case "/fasel": - folderContents = FolderContents.builder() - .files(new File[]{new File(5, "DummyFileInFasel.txt", 420, 0, Instant.now().getEpochSecond(), FileSystemType.TEXT, null)}) - .folders(new Folder[]{new Folder(6, "/fasel/johndoessecretchamber", "JohnDoesSecretChamber", 12345, 0, Instant.now().getEpochSecond(), null)}) - .build(); - break; - case "/fasel/johndoessecretchamber": - folderContents = FolderContents.builder() - .folders(new Folder[]{new Folder(7, "/fasel/johndoessecretchamber/empty", "Empty", 12345, 0, Instant.now().getEpochSecond(), null)}) - .build(); - break; - case "/fasel/johndoessecretchamber/empty": - folderContents = FolderContents.builder().build(); - break; - default: - throw new FileSystemContentsNotAccessibleException(); + ArrayList folders = new ArrayList<>(); + ArrayList files = new ArrayList<>(); + // check if the contents are visible. + for (long fileSystemId : folderContentItemIds) { + FileSystemEntity fileSystemEntityInFolder = fileSystemRepository.findByFileSystemId(fileSystemId); + + if (null == fileSystemEntityInFolder) + throw new FileFighterDataException("FolderContents expected fileSystemItem with id " + fileSystemEntity + " but was empty."); + + if (userIsAllowedToSeeFileSystemEntity(fileSystemEntityInFolder, authenticatedUser)) { + if (fileSystemEntityInFolder.isFile()) { + File file = fileSystemItemsDTOService.createFileDto(fileSystemEntityInFolder); + files.add(file); + } else { + Folder folder = fileSystemItemsDTOService.createFolderDto(fileSystemEntityInFolder); + folders.add(folder); + } + } } - return folderContents; + + return FolderContents.builder() + .files(files.toArray(new File[0])) + .folders(folders.toArray(new Folder[0])) + .build(); } - public String removeTrailingBackSlashFromPath(String path) { - return null; + private 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 boolean userIsAllowedToSeeFileSystemEntity(FileSystemEntity entity, User user) { + public boolean userIsAllowedToSeeFileSystemEntity(FileSystemEntity fileSystemEntity, User authenticatedUser) { return true; } } diff --git a/src/main/java/de/filefighter/rest/domain/filesystem/business/FileSystemItemsDTOService.java b/src/main/java/de/filefighter/rest/domain/filesystem/business/FileSystemItemsDTOService.java new file mode 100644 index 00000000..18678875 --- /dev/null +++ b/src/main/java/de/filefighter/rest/domain/filesystem/business/FileSystemItemsDTOService.java @@ -0,0 +1,41 @@ +package de.filefighter.rest.domain.filesystem.business; + +import de.filefighter.rest.domain.filesystem.data.dto.File; +import de.filefighter.rest.domain.filesystem.data.dto.Folder; +import de.filefighter.rest.domain.filesystem.data.persistance.FileSystemEntity; +import de.filefighter.rest.domain.filesystem.type.FileSystemType; +import de.filefighter.rest.domain.filesystem.type.FileSystemTypeRepository; +import org.springframework.stereotype.Service; + +@Service +public class FileSystemItemsDTOService { + + private final FileSystemTypeRepository fileSystemTypeRepository; + + public FileSystemItemsDTOService(FileSystemTypeRepository fileSystemTypeRepository) { + this.fileSystemTypeRepository = fileSystemTypeRepository; + } + + public File createFileDto(FileSystemEntity entity) { + FileSystemType fileSystemType = fileSystemTypeRepository.findFileSystemTypeById(entity.getTypeId()); + + return new File( + entity.getFileSystemId(), + entity.getName(), + entity.getSize(), + entity.getCreatedByUserId(), + entity.getLastUpdated(), + fileSystemType); + } + + public Folder createFolderDto(FileSystemEntity entity) { + return new Folder( + entity.getFileSystemId(), + entity.getPath(), + entity.getName(), + entity.getSize(), + entity.getCreatedByUserId(), + entity.getLastUpdated()); + } + +} From 19e61fbeaa0ed457e2b30b3d92177142dcf2d22f Mon Sep 17 00:00:00 2001 From: open-schnick Date: Fri, 11 Dec 2020 22:13:55 +0100 Subject: [PATCH 05/50] Added defaults to builder classes. --- .../data/persistance/FileSystemEntity.java | 15 ++++++++++----- .../domain/user/data/persistance/UserEntity.java | 3 ++- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/main/java/de/filefighter/rest/domain/filesystem/data/persistance/FileSystemEntity.java b/src/main/java/de/filefighter/rest/domain/filesystem/data/persistance/FileSystemEntity.java index bbae88f1..25554910 100644 --- a/src/main/java/de/filefighter/rest/domain/filesystem/data/persistance/FileSystemEntity.java +++ b/src/main/java/de/filefighter/rest/domain/filesystem/data/persistance/FileSystemEntity.java @@ -20,10 +20,15 @@ public class FileSystemEntity { private boolean isFile; private long createdByUserId; //uploadedBy private long lastUpdated; - private long[] visibleForGroupIds; - private long[] editableFoGroupIds; - private long[] visibleForUserIds; - private long[] editableForUserIds; - private long[] itemIds; + @Builder.Default + private long[] visibleForGroupIds = new long[0]; + @Builder.Default + private long[] editableFoGroupIds = new long[0]; + @Builder.Default + private long[] visibleForUserIds = new long[0]; + @Builder.Default + private long[] editableForUserIds = new long[0]; + @Builder.Default + private long[] itemIds = new long[0]; } diff --git a/src/main/java/de/filefighter/rest/domain/user/data/persistance/UserEntity.java b/src/main/java/de/filefighter/rest/domain/user/data/persistance/UserEntity.java index 50a6fe29..afb20a86 100644 --- a/src/main/java/de/filefighter/rest/domain/user/data/persistance/UserEntity.java +++ b/src/main/java/de/filefighter/rest/domain/user/data/persistance/UserEntity.java @@ -21,6 +21,7 @@ public class UserEntity { private String lowercaseUsername; // Redundancy for performance tradeoff. private String password; private String refreshToken; - private long[] groupIds; + @Builder.Default + private long[] groupIds = new long[0]; } From fffaf1b435e0425e3dc1a8c8751b82086cd8ee50 Mon Sep 17 00:00:00 2001 From: open-schnick Date: Fri, 11 Dec 2020 22:18:03 +0100 Subject: [PATCH 06/50] FF-218 Added FileSystemBusinessService.userIsAllowedToSeeFileSystemEntity --- .../rest/configuration/PrepareDataBase.java | 3 +-- .../business/FileSystemBusinessService.java | 24 +++++++++++++++++-- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/src/main/java/de/filefighter/rest/configuration/PrepareDataBase.java b/src/main/java/de/filefighter/rest/configuration/PrepareDataBase.java index 81f17390..f77f0298 100644 --- a/src/main/java/de/filefighter/rest/configuration/PrepareDataBase.java +++ b/src/main/java/de/filefighter/rest/configuration/PrepareDataBase.java @@ -153,14 +153,13 @@ CommandLineRunner initDataBaseDev(UserRepository userRepository, AccessTokenRepo .name("root_User") .size(420) .typeId(FileSystemType.FOLDER.getId()) - .visibleForGroupIds(new long[]{-1, 0, 1}) + .visibleForGroupIds(new long[]{0, 1}) .build()), fileSystemRepository.save(FileSystemEntity.builder() .createdByUserId(1) .fileSystemId(1) .isFile(false) .path("/") - .itemIds(new long[0]) .lastUpdated(Instant.now().getEpochSecond()) .name("root_User1") .size(420) 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 cf35aaf6..77bad70b 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 @@ -11,6 +11,7 @@ import de.filefighter.rest.domain.user.business.UserBusinessService; import de.filefighter.rest.domain.user.data.dto.User; import de.filefighter.rest.domain.user.data.persistance.UserEntity; +import de.filefighter.rest.domain.user.group.Groups; import de.filefighter.rest.rest.exceptions.FileFighterDataException; import org.springframework.stereotype.Service; @@ -51,7 +52,7 @@ public FolderContents getFolderContentsByPath(String path, User authenticatedUse UserEntity userEntityWithUsername = userBusinessService.getUserWithUsername(username); if (null == userEntityWithUsername) - throw new FileSystemContentsNotAccessibleException("Username in path does not exist."); + throw new FileSystemContentsNotAccessibleException(); //TODO: is it a risk to use a user input as regex? String pathToFind = path.split("/" + username)[1]; @@ -117,6 +118,25 @@ private String removeTrailingBackSlashes(String pathToFind) { } public boolean userIsAllowedToSeeFileSystemEntity(FileSystemEntity fileSystemEntity, User authenticatedUser) { - return true; + // user created the item + if (fileSystemEntity.getCreatedByUserId() == 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 (Groups group : authenticatedUser.getGroups()) { + for (long groupId : fileIsSharedToGroups) { + if (groupId == group.getGroupId()) + return true; + + } + } + return false; } } From 62e4dd21d495a9bfcdeba10838e5cebed0e6d868 Mon Sep 17 00:00:00 2001 From: open-schnick Date: Fri, 11 Dec 2020 22:35:14 +0100 Subject: [PATCH 07/50] commented out tests. --- src/test/resources/ViewFolderContents.feature | 106 +++++++++--------- 1 file changed, 53 insertions(+), 53 deletions(-) diff --git a/src/test/resources/ViewFolderContents.feature b/src/test/resources/ViewFolderContents.feature index 12b64290..00a260c8 100644 --- a/src/test/resources/ViewFolderContents.feature +++ b/src/test/resources/ViewFolderContents.feature @@ -1,53 +1,53 @@ -Feature: View Folder - As a user - I want to see the content of folders and navigate in them, so they can see and interact with their uploaded and shared files. - -Background: - Given database is empty - And user 1234 exists - And accessToken with value "900000" exists for user 1234 - And "folder" exists with fileSystemId 42 and path "bla" - And "file" exists with fileSystemId 72 and path "bla/wow.txt" - - -Scenario: Successful interaction - Given user 1234 has permission of "view" for "folder" with fileSystemId 42 - And user 1234 has permission of "view" for "file" with fileSystemId 72 - When user with token "900000" 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: Folder does not exist - Given user 1234 has permission of "view" for "folder" with fileSystemId 42 - When user with token "900000" wants to see the content of folder with path "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" - 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 file - Given "folder" exists with fileSystemId 43 and path "bla" - And "file" exists with fileSystemId 73 and path "bla/wow.txt" - And user 1234 is owner of file or folder with fileSystemId 42 - And user 1234 is owner of file or folder with fileSystemId 72 - And user 1234 has permission of "view" for "folder" with fileSystemId 43 - And user 1234 has permission of "view" for "file" with fileSystemId 73 - When user with token "900000" 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" - And the response contains the file with fileSystemId 73 and name "wow.txt" - -Scenario: empty directory - Given "folder" exists with fileSystemId 44 and path "empty" - And user 1234 has permission of "view" for "folder" with fileSystemId 44 - When user with token "900000" wants to see the content of folder with path "empty" - Then response status code is 200 - And the response contains an empty list for files and folders \ No newline at end of file +#Feature: View Folder +# As a user +# I want to see the content of folders and navigate in them, so they can see and interact with their uploaded and shared files. +# +#Background: +# Given database is empty +# And user 1234 exists +# And accessToken with value "900000" exists for user 1234 +# And "folder" exists with fileSystemId 42 and path "bla" +# And "file" exists with fileSystemId 72 and path "bla/wow.txt" +# +# +#Scenario: Successful interaction +# Given user 1234 has permission of "view" for "folder" with fileSystemId 42 +# And user 1234 has permission of "view" for "file" with fileSystemId 72 +# When user with token "900000" 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: Folder does not exist +# Given user 1234 has permission of "view" for "folder" with fileSystemId 42 +# When user with token "900000" wants to see the content of folder with path "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" +# 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 file +# Given "folder" exists with fileSystemId 43 and path "bla" +# And "file" exists with fileSystemId 73 and path "bla/wow.txt" +# And user 1234 is owner of file or folder with fileSystemId 42 +# And user 1234 is owner of file or folder with fileSystemId 72 +# And user 1234 has permission of "view" for "folder" with fileSystemId 43 +# And user 1234 has permission of "view" for "file" with fileSystemId 73 +# When user with token "900000" 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" +# And the response contains the file with fileSystemId 73 and name "wow.txt" +# +#Scenario: empty directory +# Given "folder" exists with fileSystemId 44 and path "empty" +# And user 1234 has permission of "view" for "folder" with fileSystemId 44 +# When user with token "900000" wants to see the content of folder with path "empty" +# Then response status code is 200 +# And the response contains an empty list for files and folders \ No newline at end of file From 76e651f5b41d7218ddbcaad52657a1f5714607e5 Mon Sep 17 00:00:00 2001 From: open-schnick Date: Sun, 13 Dec 2020 23:05:43 +0100 Subject: [PATCH 08/50] Works but i need to rework the dto structure --- .../rest/configuration/PrepareDataBase.java | 2 +- .../business/FileSystemBusinessService.java | 43 ++++++++++--------- 2 files changed, 24 insertions(+), 21 deletions(-) diff --git a/src/main/java/de/filefighter/rest/configuration/PrepareDataBase.java b/src/main/java/de/filefighter/rest/configuration/PrepareDataBase.java index f77f0298..9199df5c 100644 --- a/src/main/java/de/filefighter/rest/configuration/PrepareDataBase.java +++ b/src/main/java/de/filefighter/rest/configuration/PrepareDataBase.java @@ -125,7 +125,7 @@ CommandLineRunner initDataBaseDev(UserRepository userRepository, AccessTokenRepo .lowercaseUsername("user1") .password("12345") .refreshToken("rft") - .groupIds(new long[]{-1}) + .groupIds(new long[]{0}) .build())); LOG.info("Preloading default tokens: {} {}", 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 77bad70b..3b4d6fdb 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 @@ -13,11 +13,13 @@ import de.filefighter.rest.domain.user.data.persistance.UserEntity; import de.filefighter.rest.domain.user.group.Groups; import de.filefighter.rest.rest.exceptions.FileFighterDataException; +import lombok.extern.log4j.Log4j2; import org.springframework.stereotype.Service; import java.util.ArrayList; import java.util.Arrays; +@Log4j2 @Service public class FileSystemBusinessService { @@ -64,39 +66,40 @@ public FolderContents getFolderContentsByPath(String path, User authenticatedUse throw new FileSystemContentsNotAccessibleException(); // remove all not accessible items. - listOfFileSystemEntities.removeIf(entity -> entity.isFile() || entity.getTypeId() != FileSystemType.FOLDER.getId() || userEntityWithUsername.getUserId() != entity.getCreatedByUserId() || !userIsAllowedToSeeFileSystemEntity(entity, authenticatedUser)); + listOfFileSystemEntities.removeIf(entity -> entity.isFile() || entity.getTypeId() != FileSystemType.FOLDER.getId() || !userIsAllowedToSeeFileSystemEntity(entity, authenticatedUser)); if (listOfFileSystemEntities.isEmpty()) throw new FileSystemContentsNotAccessibleException(); - if (listOfFileSystemEntities.size() != 1) - throw new IllegalStateException("More than one folder was found with the path " + pathToFind + " and name " + username); + // now only own or shared folders are left. + log.info("Found {} folders for path {}.", listOfFileSystemEntities.size(), pathToFind); // get the contents - FileSystemEntity fileSystemEntity = listOfFileSystemEntities.get(0); - return this.getFolderContentsByEntity(fileSystemEntity, authenticatedUser); + return this.getFolderContentsByEntity(listOfFileSystemEntities, authenticatedUser); } - public FolderContents getFolderContentsByEntity(FileSystemEntity fileSystemEntity, User authenticatedUser) { - long[] folderContentItemIds = fileSystemEntity.getItemIds(); - + public FolderContents getFolderContentsByEntity(ArrayList fileSystemEntities, User authenticatedUser) { ArrayList folders = new ArrayList<>(); ArrayList files = new ArrayList<>(); - // check if the contents are visible. - for (long fileSystemId : folderContentItemIds) { - FileSystemEntity fileSystemEntityInFolder = fileSystemRepository.findByFileSystemId(fileSystemId); + for (FileSystemEntity fileSystemEntity : fileSystemEntities) { + long[] folderContentItemIds = fileSystemEntity.getItemIds(); + + // check if the contents are visible. + for (long fileSystemId : folderContentItemIds) { + FileSystemEntity fileSystemEntityInFolder = fileSystemRepository.findByFileSystemId(fileSystemId); - if (null == fileSystemEntityInFolder) - throw new FileFighterDataException("FolderContents expected fileSystemItem with id " + fileSystemEntity + " but was empty."); + if (null == fileSystemEntityInFolder) + throw new FileFighterDataException("FolderContents expected fileSystemItem with id " + fileSystemEntities + " but was empty."); - if (userIsAllowedToSeeFileSystemEntity(fileSystemEntityInFolder, authenticatedUser)) { - if (fileSystemEntityInFolder.isFile()) { - File file = fileSystemItemsDTOService.createFileDto(fileSystemEntityInFolder); - files.add(file); - } else { - Folder folder = fileSystemItemsDTOService.createFolderDto(fileSystemEntityInFolder); - folders.add(folder); + if (userIsAllowedToSeeFileSystemEntity(fileSystemEntityInFolder, authenticatedUser)) { + if (fileSystemEntityInFolder.isFile()) { + File file = fileSystemItemsDTOService.createFileDto(fileSystemEntityInFolder); + files.add(file); + } else { + Folder folder = fileSystemItemsDTOService.createFolderDto(fileSystemEntityInFolder); + folders.add(folder); + } } } } From b42a454a0702bd28b5480cd40dfbf5f30a894913 Mon Sep 17 00:00:00 2001 From: open-schnick Date: Mon, 14 Dec 2020 00:47:22 +0100 Subject: [PATCH 09/50] FF-218 Should work now. Needs testing. --- .../rest/configuration/PrepareDataBase.java | 6 +- .../business/FileSystemBusinessService.java | 83 ++++++++----------- .../business/FileSystemItemsDTOService.java | 41 --------- .../rest/domain/filesystem/data/dto/File.java | 12 --- .../filesystem/data/dto/FileSystemItem.java | 22 ++--- .../domain/filesystem/data/dto/Folder.java | 23 ----- .../filesystem/data/dto/FolderContents.java | 11 --- .../rest/FileSystemRestController.java | 5 +- .../rest/FileSystemRestService.java | 9 +- .../rest/FileSystemRestServiceInterface.java | 5 +- .../FileSystemRestControllerUnitTest.java | 28 ++++--- 11 files changed, 72 insertions(+), 173 deletions(-) delete mode 100644 src/main/java/de/filefighter/rest/domain/filesystem/business/FileSystemItemsDTOService.java delete mode 100644 src/main/java/de/filefighter/rest/domain/filesystem/data/dto/File.java delete mode 100644 src/main/java/de/filefighter/rest/domain/filesystem/data/dto/Folder.java delete mode 100644 src/main/java/de/filefighter/rest/domain/filesystem/data/dto/FolderContents.java diff --git a/src/main/java/de/filefighter/rest/configuration/PrepareDataBase.java b/src/main/java/de/filefighter/rest/configuration/PrepareDataBase.java index 9199df5c..7b8dfa59 100644 --- a/src/main/java/de/filefighter/rest/configuration/PrepareDataBase.java +++ b/src/main/java/de/filefighter/rest/configuration/PrepareDataBase.java @@ -21,8 +21,8 @@ @Configuration public class PrepareDataBase { - private static final String MESSAGE_ON_SUCCESS = " was successful."; - private static final String MESSAGE_ON_FAILURE = " failed."; + private static final String MESSAGE_ON_SUCCESS = "was successful."; + private static final String MESSAGE_ON_FAILURE = "failed."; @Value("${server.port}") int serverPort; @@ -178,7 +178,7 @@ CommandLineRunner initDataBaseDev(UserRepository userRepository, AccessTokenRepo .visibleForGroupIds(new long[]{0}) .build())); - LOG.info("Inserting FileSystemItems {}", (fileSystemRepository.findAll().size() == 2 ? MESSAGE_ON_SUCCESS : MESSAGE_ON_FAILURE)); + LOG.info("Inserting FileSystemItems {}", (fileSystemRepository.findAll().size() == 3 ? MESSAGE_ON_SUCCESS : MESSAGE_ON_FAILURE)); LOG.info("Inserting token {}", (accessTokenRepository.findAll().size() == 2 ? MESSAGE_ON_SUCCESS : MESSAGE_ON_FAILURE)); LOG.info("Inserting Users {}", (userRepository.findAll().size() == 2 ? MESSAGE_ON_SUCCESS : MESSAGE_ON_FAILURE)); }; 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 3b4d6fdb..d66ed935 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,16 +1,14 @@ package de.filefighter.rest.domain.filesystem.business; import de.filefighter.rest.domain.common.InputSanitizerService; -import de.filefighter.rest.domain.filesystem.data.dto.File; -import de.filefighter.rest.domain.filesystem.data.dto.Folder; -import de.filefighter.rest.domain.filesystem.data.dto.FolderContents; +import de.filefighter.rest.domain.filesystem.data.dto.FileSystemItem; import de.filefighter.rest.domain.filesystem.data.persistance.FileSystemEntity; import de.filefighter.rest.domain.filesystem.data.persistance.FileSystemRepository; import de.filefighter.rest.domain.filesystem.exceptions.FileSystemContentsNotAccessibleException; 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.persistance.UserEntity; import de.filefighter.rest.domain.user.group.Groups; import de.filefighter.rest.rest.exceptions.FileFighterDataException; import lombok.extern.log4j.Log4j2; @@ -23,42 +21,31 @@ @Service public class FileSystemBusinessService { - private final FileSystemItemsDTOService fileSystemItemsDTOService; private final FileSystemRepository fileSystemRepository; private final UserBusinessService userBusinessService; + private final FileSystemTypeRepository fileSystemTypeRepository; - public FileSystemBusinessService(FileSystemItemsDTOService fileSystemItemsDTOService, FileSystemRepository fileSystemRepository, UserBusinessService userBusinessService) { - this.fileSystemItemsDTOService = fileSystemItemsDTOService; + public FileSystemBusinessService(FileSystemRepository fileSystemRepository, UserBusinessService userBusinessService, FileSystemTypeRepository fileSystemTypeRepository) { this.fileSystemRepository = fileSystemRepository; this.userBusinessService = userBusinessService; + this.fileSystemTypeRepository = fileSystemTypeRepository; } // TODO: implement necessary files when a new user is created. - // path is /username/folder - // in db only /folder but we know the username that created it. - // that way we know what contents to display if the same folderName exists twice. + public ArrayList getFolderContentsByPath(String path, User authenticatedUser) { + if (!InputSanitizerService.stringIsValid(path)) + throw new FileSystemContentsNotAccessibleException("Path was not valid."); - public FolderContents getFolderContentsByPath(String path, User authenticatedUser) { String[] pathWithoutSlashes = path.split("/"); - if (pathWithoutSlashes.length < 2) - throw new FileSystemContentsNotAccessibleException(); + if (!path.equals("/") && pathWithoutSlashes.length < 1) + throw new FileSystemContentsNotAccessibleException("Path was in wrong format."); - if (!"".equals(pathWithoutSlashes[0])) + if (!path.equals("/") && !"".equals(pathWithoutSlashes[0])) throw new FileSystemContentsNotAccessibleException("Path was in wrong format. Use a leading backslash."); - String username = pathWithoutSlashes[1]; - if (!InputSanitizerService.stringIsValid(username)) - throw new FileSystemContentsNotAccessibleException("Path was in wrong format. Username was not found in path."); - - UserEntity userEntityWithUsername = userBusinessService.getUserWithUsername(username); - if (null == userEntityWithUsername) - throw new FileSystemContentsNotAccessibleException(); - - //TODO: is it a risk to use a user input as regex? - String pathToFind = path.split("/" + username)[1]; - pathToFind = removeTrailingBackSlashes(pathToFind); + String pathToFind = removeTrailingBackSlashes(path); // find the folder with matching path. ArrayList listOfFileSystemEntities = fileSystemRepository.findByPath(pathToFind); @@ -72,17 +59,9 @@ public FolderContents getFolderContentsByPath(String path, User authenticatedUse throw new FileSystemContentsNotAccessibleException(); // now only own or shared folders are left. - log.info("Found {} folders for path {}.", listOfFileSystemEntities.size(), pathToFind); - - // get the contents - return this.getFolderContentsByEntity(listOfFileSystemEntities, authenticatedUser); - } + ArrayList fileSystemItems = new ArrayList<>(listOfFileSystemEntities.size()); - public FolderContents getFolderContentsByEntity(ArrayList fileSystemEntities, User authenticatedUser) { - ArrayList folders = new ArrayList<>(); - ArrayList files = new ArrayList<>(); - - for (FileSystemEntity fileSystemEntity : fileSystemEntities) { + for (FileSystemEntity fileSystemEntity : listOfFileSystemEntities) { long[] folderContentItemIds = fileSystemEntity.getItemIds(); // check if the contents are visible. @@ -90,24 +69,15 @@ public FolderContents getFolderContentsByEntity(ArrayList file FileSystemEntity fileSystemEntityInFolder = fileSystemRepository.findByFileSystemId(fileSystemId); if (null == fileSystemEntityInFolder) - throw new FileFighterDataException("FolderContents expected fileSystemItem with id " + fileSystemEntities + " but was empty."); + throw new FileFighterDataException("FolderContents expected fileSystemItem with id " + listOfFileSystemEntities + " but was empty."); if (userIsAllowedToSeeFileSystemEntity(fileSystemEntityInFolder, authenticatedUser)) { - if (fileSystemEntityInFolder.isFile()) { - File file = fileSystemItemsDTOService.createFileDto(fileSystemEntityInFolder); - files.add(file); - } else { - Folder folder = fileSystemItemsDTOService.createFolderDto(fileSystemEntityInFolder); - folders.add(folder); - } + fileSystemItems.add(this.createDTO(fileSystemEntityInFolder, authenticatedUser, pathToFind)); } } } - return FolderContents.builder() - .files(files.toArray(new File[0])) - .folders(folders.toArray(new Folder[0])) - .build(); + return fileSystemItems; } private String removeTrailingBackSlashes(String pathToFind) { @@ -142,4 +112,23 @@ public boolean userIsAllowedToSeeFileSystemEntity(FileSystemEntity fileSystemEnt } return false; } + + public FileSystemItem createDTO(FileSystemEntity fileSystemEntity, User authenticatedUser, String basePath) { + User ownerOfFileSystemItem = userBusinessService.getUserById(fileSystemEntity.getCreatedByUserId()); + if (null == ownerOfFileSystemItem) + throw new FileFighterDataException("Owner of File/Folder does not exist."); + + boolean isShared = ownerOfFileSystemItem.getUserId() != authenticatedUser.getUserId(); + + return FileSystemItem.builder() + .createdByUserId(fileSystemEntity.getCreatedByUserId()) + .fileSystemId(fileSystemEntity.getFileSystemId()) + .lastUpdated(fileSystemEntity.getLastUpdated()) + .name(fileSystemEntity.getName()) + .size(fileSystemEntity.getSize()) + .type(fileSystemTypeRepository.findFileSystemTypeById(fileSystemEntity.getTypeId())) + .path(basePath + fileSystemEntity.getName()) + .isShared(isShared) + .build(); + } } diff --git a/src/main/java/de/filefighter/rest/domain/filesystem/business/FileSystemItemsDTOService.java b/src/main/java/de/filefighter/rest/domain/filesystem/business/FileSystemItemsDTOService.java deleted file mode 100644 index 18678875..00000000 --- a/src/main/java/de/filefighter/rest/domain/filesystem/business/FileSystemItemsDTOService.java +++ /dev/null @@ -1,41 +0,0 @@ -package de.filefighter.rest.domain.filesystem.business; - -import de.filefighter.rest.domain.filesystem.data.dto.File; -import de.filefighter.rest.domain.filesystem.data.dto.Folder; -import de.filefighter.rest.domain.filesystem.data.persistance.FileSystemEntity; -import de.filefighter.rest.domain.filesystem.type.FileSystemType; -import de.filefighter.rest.domain.filesystem.type.FileSystemTypeRepository; -import org.springframework.stereotype.Service; - -@Service -public class FileSystemItemsDTOService { - - private final FileSystemTypeRepository fileSystemTypeRepository; - - public FileSystemItemsDTOService(FileSystemTypeRepository fileSystemTypeRepository) { - this.fileSystemTypeRepository = fileSystemTypeRepository; - } - - public File createFileDto(FileSystemEntity entity) { - FileSystemType fileSystemType = fileSystemTypeRepository.findFileSystemTypeById(entity.getTypeId()); - - return new File( - entity.getFileSystemId(), - entity.getName(), - entity.getSize(), - entity.getCreatedByUserId(), - entity.getLastUpdated(), - fileSystemType); - } - - public Folder createFolderDto(FileSystemEntity entity) { - return new Folder( - entity.getFileSystemId(), - entity.getPath(), - entity.getName(), - entity.getSize(), - entity.getCreatedByUserId(), - entity.getLastUpdated()); - } - -} diff --git a/src/main/java/de/filefighter/rest/domain/filesystem/data/dto/File.java b/src/main/java/de/filefighter/rest/domain/filesystem/data/dto/File.java deleted file mode 100644 index 84fa5f5b..00000000 --- a/src/main/java/de/filefighter/rest/domain/filesystem/data/dto/File.java +++ /dev/null @@ -1,12 +0,0 @@ -package de.filefighter.rest.domain.filesystem.data.dto; - -import de.filefighter.rest.domain.filesystem.type.FileSystemType; - -public class File extends FileSystemItem { - public File() { - } - - public File(long fileSystemId, String name, double size, long createdByUserId, long lastUpdated, FileSystemType type) { - super(fileSystemId, name, size, createdByUserId, lastUpdated, type); - } -} \ No newline at end of file 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 3f18f86d..797262c1 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 @@ -1,28 +1,20 @@ package de.filefighter.rest.domain.filesystem.data.dto; import de.filefighter.rest.domain.filesystem.type.FileSystemType; -import lombok.Getter; -import lombok.Setter; +import lombok.Builder; +import lombok.Data; -@Getter -@Setter +@Builder +@Data public class FileSystemItem { + private long fileSystemId; + private String path; private String name; + private boolean isShared; private double size; private long createdByUserId; //uploadedBy private long lastUpdated; private FileSystemType type; - protected FileSystemItem() { - } - - public FileSystemItem(long fileSystemId, String name, double size, long createdByUserId, long lastUpdated, FileSystemType type) { - this.fileSystemId = fileSystemId; - this.name = name; - this.size = size; - this.createdByUserId = createdByUserId; - this.lastUpdated = lastUpdated; - this.type = type; - } } diff --git a/src/main/java/de/filefighter/rest/domain/filesystem/data/dto/Folder.java b/src/main/java/de/filefighter/rest/domain/filesystem/data/dto/Folder.java deleted file mode 100644 index a700e6b7..00000000 --- a/src/main/java/de/filefighter/rest/domain/filesystem/data/dto/Folder.java +++ /dev/null @@ -1,23 +0,0 @@ -package de.filefighter.rest.domain.filesystem.data.dto; - -import de.filefighter.rest.domain.filesystem.type.FileSystemType; - -public class Folder extends FileSystemItem { - private String path; - - public Folder() { - } - - public Folder(long id, String path, String name, double size, long createdByUserId, long lastUpdated) { - super(id, name, size, createdByUserId, lastUpdated, FileSystemType.FOLDER); - this.path = path; - } - - public String getPath() { - return path; - } - - public void setPath(String path) { - this.path = path; - } -} diff --git a/src/main/java/de/filefighter/rest/domain/filesystem/data/dto/FolderContents.java b/src/main/java/de/filefighter/rest/domain/filesystem/data/dto/FolderContents.java deleted file mode 100644 index 153821da..00000000 --- a/src/main/java/de/filefighter/rest/domain/filesystem/data/dto/FolderContents.java +++ /dev/null @@ -1,11 +0,0 @@ -package de.filefighter.rest.domain.filesystem.data.dto; - -import lombok.Builder; -import lombok.Getter; - -@Getter -@Builder -public class FolderContents { - private final Folder[] folders; - private final File[] files; -} 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 056efec8..48788bde 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,7 +2,6 @@ import de.filefighter.rest.domain.filesystem.data.dto.FileSystemItem; import de.filefighter.rest.domain.filesystem.data.dto.FileSystemItemUpdate; -import de.filefighter.rest.domain.filesystem.data.dto.FolderContents; import de.filefighter.rest.rest.ServerResponse; import io.swagger.annotations.Api; import org.slf4j.Logger; @@ -10,6 +9,8 @@ import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; +import java.util.ArrayList; + import static de.filefighter.rest.configuration.RestConfiguration.*; @RestController @@ -26,7 +27,7 @@ public FileSystemRestController(FileSystemRestServiceInterface fileSystemRestSer } @GetMapping(FS_BASE_URI + "contents") - public ResponseEntity getContentsOfFolder( + public ResponseEntity> getContentsOfFolder( @RequestHeader(value = FS_PATH_HEADER, defaultValue = "/") String path, @RequestHeader(value = "Authorization", defaultValue = AUTHORIZATION_BEARER_PREFIX + "token") String 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 1efeb639..af659d01 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 @@ -5,7 +5,6 @@ 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.filesystem.data.dto.FolderContents; import de.filefighter.rest.domain.token.business.AccessTokenBusinessService; import de.filefighter.rest.domain.token.data.dto.AccessToken; import de.filefighter.rest.domain.user.business.UserAuthorizationService; @@ -15,6 +14,8 @@ import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Service; +import java.util.ArrayList; + @Service public class FileSystemRestService implements FileSystemRestServiceInterface { @@ -31,15 +32,15 @@ public FileSystemRestService(UserAuthorizationService userAuthorizationService, } @Override - public ResponseEntity getContentsOfFolderByPathAndAccessToken(String path, String accessTokenValue) { + public ResponseEntity> getContentsOfFolderByPathAndAccessToken(String path, String accessTokenValue) { String cleanHeader = inputSanitizerService.sanitizeRequestHeader(RestConfiguration.AUTHORIZATION_BEARER_PREFIX, accessTokenValue); String cleanValue = inputSanitizerService.sanitizeTokenValue(cleanHeader); AccessToken accessToken = accessTokenBusinessService.findAccessTokenByValue(cleanValue); User authenticatedUser = userAuthorizationService.authenticateUserWithAccessToken(accessToken); String cleanPathString = InputSanitizerService.sanitizeString(path); - FolderContents folderContents = fileSystemBusinessService.getFolderContentsByPath(cleanPathString, authenticatedUser); - return new ResponseEntity<>(folderContents, HttpStatus.OK); + ArrayList fileSystemItems = fileSystemBusinessService.getFolderContentsByPath(cleanPathString, authenticatedUser); + return new ResponseEntity<>(fileSystemItems, HttpStatus.OK); } @Override 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 0dc3345f..b868aa7e 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,12 +2,13 @@ import de.filefighter.rest.domain.filesystem.data.dto.FileSystemItem; import de.filefighter.rest.domain.filesystem.data.dto.FileSystemItemUpdate; -import de.filefighter.rest.domain.filesystem.data.dto.FolderContents; import de.filefighter.rest.rest.ServerResponse; import org.springframework.http.ResponseEntity; +import java.util.ArrayList; + public interface FileSystemRestServiceInterface { - ResponseEntity getContentsOfFolderByPathAndAccessToken(String path, String accessToken); + ResponseEntity> getContentsOfFolderByPathAndAccessToken(String path, String accessToken); ResponseEntity getInfoAboutFileOrFolderByIdAndAccessToken(long fsItemId, String accessToken); ResponseEntity findFileOrFolderByNameAndAccessToken(String name, String accessToken); ResponseEntity uploadFileSystemItemWithAccessToken(FileSystemItemUpdate fileSystemItemUpdate, String accessToken); 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 cd28e3e8..b6ac4584 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 @@ -1,11 +1,15 @@ package de.filefighter.rest.domain.filesystem.rest; -import de.filefighter.rest.domain.filesystem.data.dto.*; +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 static org.junit.jupiter.api.Assertions.assertEquals; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -24,24 +28,22 @@ void setUp() { @Test void getContentsOfFolder() { - Folder dummyFolder = new Folder(); - File dummyFile = new File(); - ResponseEntity expectedModel = new ResponseEntity<>(FolderContents.builder() - .files(new File[]{dummyFile}) - .folders(new Folder[]{dummyFolder}).build(), OK); + ArrayList itemArrayList = new ArrayList<>(); + itemArrayList.add(FileSystemItem.builder().build()); - String path= "/root/data.txt"; + ResponseEntity> expectedModel = new ResponseEntity<>(itemArrayList, HttpStatus.OK); + String path = "/username/data.txt"; String token = "token"; when(fileSystemRestServiceMock.getContentsOfFolderByPathAndAccessToken(path, token)).thenReturn(expectedModel); - ResponseEntity actualModel = fileSystemRestController.getContentsOfFolder(path, token); - assertEquals(expectedModel, actualModel); + ResponseEntity> actualModel = fileSystemRestController.getContentsOfFolder(path, token); + assertEquals(itemArrayList, actualModel.getBody()); } @Test void getFileOrFolderInfo() { - File file = new File(); + FileSystemItem file = FileSystemItem.builder().build(); ResponseEntity expectedModel = new ResponseEntity<>(file, OK); long id = 420; @@ -55,7 +57,7 @@ void getFileOrFolderInfo() { @Test void searchFileOrFolderByName() { - File file = new File(); + FileSystemItem file = FileSystemItem.builder().build(); ResponseEntity expectedModel = new ResponseEntity<>(file, OK); String name = "randomFile.exe"; @@ -69,7 +71,7 @@ void searchFileOrFolderByName() { @Test void uploadFileOrFolder() { - File file = new File(); + FileSystemItem file = FileSystemItem.builder().build(); ResponseEntity expectedModel = new ResponseEntity<>(file, OK); FileSystemItemUpdate fileSystemItemUpdate = FileSystemItemUpdate.builder().name("ugabuga").build(); @@ -83,7 +85,7 @@ void uploadFileOrFolder() { @Test void updateExistingFileOrFolder() { - File file = new File(); + FileSystemItem file = FileSystemItem.builder().build(); ResponseEntity expectedModel = new ResponseEntity<>(file, OK); long id = 420L; From 00f8e81df927b498351b991f2966dfa138e9977d Mon Sep 17 00:00:00 2001 From: open-schnick Date: Mon, 14 Dec 2020 00:55:33 +0100 Subject: [PATCH 10/50] Fixed Merge Import Problems --- .../rest/configuration/PrepareDataBase.java | 12 ++++++------ .../business/FileSystemBusinessService.java | 4 ++-- .../user/business/UserAuthorizationService.java | 4 ++-- .../domain/user/business/UserBusinessService.java | 4 ++-- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/main/java/de/filefighter/rest/configuration/PrepareDataBase.java b/src/main/java/de/filefighter/rest/configuration/PrepareDataBase.java index 7b8dfa59..231f7365 100644 --- a/src/main/java/de/filefighter/rest/configuration/PrepareDataBase.java +++ b/src/main/java/de/filefighter/rest/configuration/PrepareDataBase.java @@ -1,13 +1,13 @@ package de.filefighter.rest.configuration; -import de.filefighter.rest.domain.filesystem.data.persistance.FileSystemEntity; -import de.filefighter.rest.domain.filesystem.data.persistance.FileSystemRepository; +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.token.business.AccessTokenBusinessService; -import de.filefighter.rest.domain.token.data.persistance.AccessTokenEntity; -import de.filefighter.rest.domain.token.data.persistance.AccessTokenRepository; -import de.filefighter.rest.domain.user.data.persistance.UserEntity; -import de.filefighter.rest.domain.user.data.persistance.UserRepository; +import de.filefighter.rest.domain.token.data.persistence.AccessTokenEntity; +import de.filefighter.rest.domain.token.data.persistence.AccessTokenRepository; +import de.filefighter.rest.domain.user.data.persistence.UserEntity; +import de.filefighter.rest.domain.user.data.persistence.UserRepository; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Value; 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 d66ed935..d96f8157 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 @@ -2,8 +2,8 @@ import de.filefighter.rest.domain.common.InputSanitizerService; import de.filefighter.rest.domain.filesystem.data.dto.FileSystemItem; -import de.filefighter.rest.domain.filesystem.data.persistance.FileSystemEntity; -import de.filefighter.rest.domain.filesystem.data.persistance.FileSystemRepository; +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.type.FileSystemType; import de.filefighter.rest.domain.filesystem.type.FileSystemTypeRepository; diff --git a/src/main/java/de/filefighter/rest/domain/user/business/UserAuthorizationService.java b/src/main/java/de/filefighter/rest/domain/user/business/UserAuthorizationService.java index e34cf3d1..75580651 100644 --- a/src/main/java/de/filefighter/rest/domain/user/business/UserAuthorizationService.java +++ b/src/main/java/de/filefighter/rest/domain/user/business/UserAuthorizationService.java @@ -3,8 +3,8 @@ import de.filefighter.rest.domain.common.InputSanitizerService; import de.filefighter.rest.domain.token.data.dto.AccessToken; import de.filefighter.rest.domain.user.data.dto.User; -import de.filefighter.rest.domain.user.data.persistance.UserEntity; -import de.filefighter.rest.domain.user.data.persistance.UserRepository; +import de.filefighter.rest.domain.user.data.persistence.UserEntity; +import de.filefighter.rest.domain.user.data.persistence.UserRepository; import de.filefighter.rest.domain.user.exceptions.UserNotAuthenticatedException; import de.filefighter.rest.domain.user.group.Groups; import de.filefighter.rest.rest.exceptions.RequestDidntMeetFormalRequirementsException; 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 d56bf7a9..a726a935 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 @@ -4,8 +4,8 @@ import de.filefighter.rest.domain.token.data.dto.RefreshToken; import de.filefighter.rest.domain.user.data.dto.User; import de.filefighter.rest.domain.user.data.dto.UserRegisterForm; -import de.filefighter.rest.domain.user.data.persistance.UserEntity; -import de.filefighter.rest.domain.user.data.persistance.UserRepository; +import de.filefighter.rest.domain.user.data.persistence.UserEntity; +import de.filefighter.rest.domain.user.data.persistence.UserRepository; import de.filefighter.rest.domain.user.exceptions.UserNotFoundException; import de.filefighter.rest.domain.user.exceptions.UserNotRegisteredException; import de.filefighter.rest.domain.user.exceptions.UserNotUpdatedException; From 444250073d3c505d78eecb1a180d78535955a217 Mon Sep 17 00:00:00 2001 From: open-schnick Date: Mon, 14 Dec 2020 00:56:27 +0100 Subject: [PATCH 11/50] Fixed Merge Annotation Problem --- .../rest/configuration/PrepareDataBase.java | 32 +++++++++---------- 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/src/main/java/de/filefighter/rest/configuration/PrepareDataBase.java b/src/main/java/de/filefighter/rest/configuration/PrepareDataBase.java index 231f7365..2cf1b74a 100644 --- a/src/main/java/de/filefighter/rest/configuration/PrepareDataBase.java +++ b/src/main/java/de/filefighter/rest/configuration/PrepareDataBase.java @@ -8,8 +8,7 @@ import de.filefighter.rest.domain.token.data.persistence.AccessTokenRepository; import de.filefighter.rest.domain.user.data.persistence.UserEntity; import de.filefighter.rest.domain.user.data.persistence.UserRepository; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import lombok.extern.log4j.Log4j2; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.CommandLineRunner; import org.springframework.context.annotation.Bean; @@ -18,6 +17,7 @@ import java.time.Instant; +@Log4j2 @Configuration public class PrepareDataBase { @@ -33,8 +33,6 @@ public class PrepareDataBase { @Value("${filefighter.date}") String date; - private static final Logger LOG = LoggerFactory.getLogger(PrepareDataBase.class); - @Bean @Profile({"dev", "prod"}) CommandLineRunner veryImportantFileFighterStartScript() { @@ -62,11 +60,11 @@ CommandLineRunner veryImportantFileFighterStartScript() { @Bean CommandLineRunner cleanDataBase(UserRepository userRepository, FileSystemRepository fileSystemRepository, AccessTokenRepository accessTokenRepository) { return args -> { - LOG.info("Starting with clean user collection."); + log.info("Starting with clean user collection."); userRepository.deleteAll(); - LOG.info("Starting with clean fileSystem collection."); + log.info("Starting with clean fileSystem collection."); fileSystemRepository.deleteAll(); - LOG.info("Starting with clean accessToken collection."); + log.info("Starting with clean accessToken collection."); accessTokenRepository.deleteAll(); }; } @@ -75,7 +73,7 @@ CommandLineRunner cleanDataBase(UserRepository userRepository, FileSystemReposit @Profile("prod") CommandLineRunner initDataBaseProd(UserRepository userRepository, FileSystemRepository fileSystemRepository) { return args -> { - LOG.info("Preloading default admin user: {}.", userRepository.save(UserEntity + log.info("Preloading default admin user: {}.", userRepository.save(UserEntity .builder() .userId(0L) .username("Admin") @@ -85,7 +83,7 @@ CommandLineRunner initDataBaseProd(UserRepository userRepository, FileSystemRepo .groupIds(new long[]{0, 1}) .build())); - LOG.info("Preloading default fsStructure: {}.", fileSystemRepository.save(FileSystemEntity + log.info("Preloading default fsStructure: {}.", fileSystemRepository.save(FileSystemEntity .builder() .createdByUserId(0) .fileSystemId(0) @@ -99,8 +97,8 @@ CommandLineRunner initDataBaseProd(UserRepository userRepository, FileSystemRepo .visibleForGroupIds(new long[]{-1, 0, 1}) .build())); - LOG.info("Inserting Users {}", (userRepository.findAll().size() == 1 ? MESSAGE_ON_SUCCESS : MESSAGE_ON_FAILURE)); - LOG.info("Inserting fsItems {}", (fileSystemRepository.findAll().size() == 1 ? MESSAGE_ON_SUCCESS : MESSAGE_ON_FAILURE)); + log.info("Inserting Users {}", (userRepository.findAll().size() == 1 ? MESSAGE_ON_SUCCESS : MESSAGE_ON_FAILURE)); + log.info("Inserting fsItems {}", (fileSystemRepository.findAll().size() == 1 ? MESSAGE_ON_SUCCESS : MESSAGE_ON_FAILURE)); }; } @@ -108,7 +106,7 @@ CommandLineRunner initDataBaseProd(UserRepository userRepository, FileSystemRepo @Profile("dev") CommandLineRunner initDataBaseDev(UserRepository userRepository, AccessTokenRepository accessTokenRepository, FileSystemRepository fileSystemRepository) { return args -> { - LOG.info("Preloading default users: {} {}.", + log.info("Preloading default users: {} {}.", userRepository.save(UserEntity .builder() .userId(0) @@ -128,7 +126,7 @@ CommandLineRunner initDataBaseDev(UserRepository userRepository, AccessTokenRepo .groupIds(new long[]{0}) .build())); - LOG.info("Preloading default tokens: {} {}", + log.info("Preloading default tokens: {} {}", accessTokenRepository.save(AccessTokenEntity .builder() .userId(0) @@ -142,7 +140,7 @@ CommandLineRunner initDataBaseDev(UserRepository userRepository, AccessTokenRepo .validUntil(Instant.now().getEpochSecond() + AccessTokenBusinessService.ACCESS_TOKEN_DURATION_IN_SECONDS) .build())); - LOG.info("Preloading default fsItems: {} {} {}.", + log.info("Preloading default fsItems: {} {} {}.", fileSystemRepository.save(FileSystemEntity.builder() .createdByUserId(0) .fileSystemId(0) @@ -178,9 +176,9 @@ CommandLineRunner initDataBaseDev(UserRepository userRepository, AccessTokenRepo .visibleForGroupIds(new long[]{0}) .build())); - LOG.info("Inserting FileSystemItems {}", (fileSystemRepository.findAll().size() == 3 ? MESSAGE_ON_SUCCESS : MESSAGE_ON_FAILURE)); - LOG.info("Inserting token {}", (accessTokenRepository.findAll().size() == 2 ? MESSAGE_ON_SUCCESS : MESSAGE_ON_FAILURE)); - LOG.info("Inserting Users {}", (userRepository.findAll().size() == 2 ? MESSAGE_ON_SUCCESS : MESSAGE_ON_FAILURE)); + log.info("Inserting FileSystemItems {}", (fileSystemRepository.findAll().size() == 3 ? MESSAGE_ON_SUCCESS : MESSAGE_ON_FAILURE)); + log.info("Inserting token {}", (accessTokenRepository.findAll().size() == 2 ? MESSAGE_ON_SUCCESS : MESSAGE_ON_FAILURE)); + log.info("Inserting Users {}", (userRepository.findAll().size() == 2 ? MESSAGE_ON_SUCCESS : MESSAGE_ON_FAILURE)); }; } } \ No newline at end of file From 714efa73932c975c2d064bded9e748acf6d56fc4 Mon Sep 17 00:00:00 2001 From: open-schnick Date: Mon, 14 Dec 2020 01:03:41 +0100 Subject: [PATCH 12/50] Added missing @Data --- .../filefighter/rest/domain/health/data/SystemHealth.java | 6 ++---- .../rest/domain/user/data/persistence/UserEntity.java | 8 ++------ 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/src/main/java/de/filefighter/rest/domain/health/data/SystemHealth.java b/src/main/java/de/filefighter/rest/domain/health/data/SystemHealth.java index 2a6b21fa..62728cd1 100644 --- a/src/main/java/de/filefighter/rest/domain/health/data/SystemHealth.java +++ b/src/main/java/de/filefighter/rest/domain/health/data/SystemHealth.java @@ -1,14 +1,12 @@ package de.filefighter.rest.domain.health.data; -import lombok.Builder; -import lombok.Getter; +import lombok.Data; /** * This class is a representation of the json model. */ -@Getter -@Builder +@Data public class SystemHealth { private final long uptimeInSeconds; private final long userCount; diff --git a/src/main/java/de/filefighter/rest/domain/user/data/persistence/UserEntity.java b/src/main/java/de/filefighter/rest/domain/user/data/persistence/UserEntity.java index e11a50e8..572e53ff 100644 --- a/src/main/java/de/filefighter/rest/domain/user/data/persistence/UserEntity.java +++ b/src/main/java/de/filefighter/rest/domain/user/data/persistence/UserEntity.java @@ -1,17 +1,13 @@ package de.filefighter.rest.domain.user.data.persistence; import lombok.Builder; -import lombok.Getter; -import lombok.Setter; -import lombok.ToString; +import lombok.Data; import org.springframework.data.mongodb.core.mapping.Document; import org.springframework.data.mongodb.core.mapping.MongoId; @Document(collection = "user") -@Getter -@ToString +@Data @Builder -@Setter public class UserEntity { @MongoId From bcc695be98fafa5c63e9cb1eb4f7b6cf117fcc2c Mon Sep 17 00:00:00 2001 From: open-schnick Date: Mon, 14 Dec 2020 01:06:41 +0100 Subject: [PATCH 13/50] Added missing @Builder --- .../de/filefighter/rest/domain/health/data/SystemHealth.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/de/filefighter/rest/domain/health/data/SystemHealth.java b/src/main/java/de/filefighter/rest/domain/health/data/SystemHealth.java index 62728cd1..d63ce362 100644 --- a/src/main/java/de/filefighter/rest/domain/health/data/SystemHealth.java +++ b/src/main/java/de/filefighter/rest/domain/health/data/SystemHealth.java @@ -1,5 +1,6 @@ package de.filefighter.rest.domain.health.data; +import lombok.Builder; import lombok.Data; /** @@ -7,6 +8,7 @@ */ @Data +@Builder public class SystemHealth { private final long uptimeInSeconds; private final long userCount; From 61a06c8d99db319068b8208514944f31cd24ecee Mon Sep 17 00:00:00 2001 From: open-schnick Date: Mon, 14 Dec 2020 01:35:27 +0100 Subject: [PATCH 14/50] Added missing DummyFile. --- .../rest/configuration/PrepareDataBase.java | 38 ++++++++++++------- 1 file changed, 25 insertions(+), 13 deletions(-) diff --git a/src/main/java/de/filefighter/rest/configuration/PrepareDataBase.java b/src/main/java/de/filefighter/rest/configuration/PrepareDataBase.java index 2cf1b74a..22985613 100644 --- a/src/main/java/de/filefighter/rest/configuration/PrepareDataBase.java +++ b/src/main/java/de/filefighter/rest/configuration/PrepareDataBase.java @@ -83,19 +83,31 @@ CommandLineRunner initDataBaseProd(UserRepository userRepository, FileSystemRepo .groupIds(new long[]{0, 1}) .build())); - log.info("Preloading default fsStructure: {}.", fileSystemRepository.save(FileSystemEntity - .builder() - .createdByUserId(0) - .fileSystemId(0) - .isFile(false) - .path("/") - .itemIds(new long[0]) - .lastUpdated(Instant.now().getEpochSecond()) - .name("root") - .size(0) - .typeId(FileSystemType.FOLDER.getId()) - .visibleForGroupIds(new long[]{-1, 0, 1}) - .build())); + log.info("Preloading default fsStructure: {} {}.", fileSystemRepository.save(FileSystemEntity + .builder() + .createdByUserId(0) + .fileSystemId(0) + .isFile(false) + .path("/") + .itemIds(new long[0]) + .lastUpdated(Instant.now().getEpochSecond()) + .name("root") + .size(0) + .typeId(FileSystemType.FOLDER.getId()) + .visibleForGroupIds(new long[]{-1, 0, 1}) + .itemIds(new long[]{1}) + .build()), + fileSystemRepository.save(FileSystemEntity.builder() + .createdByUserId(0) + .fileSystemId(1) + .isFile(true) + .lastUpdated(Instant.now().getEpochSecond()) + .name("dummyFile.txt") + .size(420) + .typeId(FileSystemType.TEXT.getId()) + .editableFoGroupIds(new long[]{0}) + .visibleForGroupIds(new long[]{0}) + .build())); log.info("Inserting Users {}", (userRepository.findAll().size() == 1 ? MESSAGE_ON_SUCCESS : MESSAGE_ON_FAILURE)); log.info("Inserting fsItems {}", (fileSystemRepository.findAll().size() == 1 ? MESSAGE_ON_SUCCESS : MESSAGE_ON_FAILURE)); From 96cc38140ceec08276e3995c6ebbe5755f43f116 Mon Sep 17 00:00:00 2001 From: open-schnick Date: Thu, 17 Dec 2020 00:55:32 +0100 Subject: [PATCH 15/50] Added Cors for local dev purposes only. --- .../rest/configuration/CorsConfig.java | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 src/main/java/de/filefighter/rest/configuration/CorsConfig.java diff --git a/src/main/java/de/filefighter/rest/configuration/CorsConfig.java b/src/main/java/de/filefighter/rest/configuration/CorsConfig.java new file mode 100644 index 00000000..6b52831c --- /dev/null +++ b/src/main/java/de/filefighter/rest/configuration/CorsConfig.java @@ -0,0 +1,28 @@ +package de.filefighter.rest.configuration; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Profile; +import org.springframework.web.cors.CorsConfiguration; +import org.springframework.web.cors.UrlBasedCorsConfigurationSource; +import org.springframework.web.filter.CorsFilter; + +import java.util.ArrayList; + +@Configuration +public class CorsConfig { + + // Cors again. For local testing only. + @Bean + @Profile("dev") + public CorsFilter corsFilter(){ + final CorsConfiguration config = new CorsConfiguration().applyPermitDefaultValues(); + ArrayList allowedOrigins = new ArrayList<>(); + allowedOrigins.add("*"); + config.setAllowedOrigins(allowedOrigins); + + final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); + source.registerCorsConfiguration("/**", config); + return new CorsFilter(source); + } +} From 882aa75c0fd64acedb6e9b9fe27449a39e4ba7d4 Mon Sep 17 00:00:00 2001 From: open-schnick Date: Thu, 17 Dec 2020 00:55:56 +0100 Subject: [PATCH 16/50] Cleanup --- .../de/filefighter/rest/configuration/RestConfiguration.java | 2 +- .../domain/filesystem/business/FileSystemBusinessService.java | 3 ++- .../rest/domain/filesystem/rest/FileSystemRestService.java | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/main/java/de/filefighter/rest/configuration/RestConfiguration.java b/src/main/java/de/filefighter/rest/configuration/RestConfiguration.java index 31a5096f..eb239a69 100644 --- a/src/main/java/de/filefighter/rest/configuration/RestConfiguration.java +++ b/src/main/java/de/filefighter/rest/configuration/RestConfiguration.java @@ -12,6 +12,6 @@ public class RestConfiguration { public static final String DEFAULT_ERROR_URI = "/error"; private RestConfiguration(){ - // Cannot be inst + // Cannot be instantiated. } } \ No newline at end of file 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 d96f8157..033b527f 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 @@ -16,6 +16,7 @@ import java.util.ArrayList; import java.util.Arrays; +import java.util.List; @Log4j2 @Service @@ -33,7 +34,7 @@ public FileSystemBusinessService(FileSystemRepository fileSystemRepository, User // TODO: implement necessary files when a new user is created. - public ArrayList getFolderContentsByPath(String path, User authenticatedUser) { + public List getFolderContentsByPath(String path, User authenticatedUser) { if (!InputSanitizerService.stringIsValid(path)) throw new FileSystemContentsNotAccessibleException("Path was not valid."); 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 af659d01..2c17a50e 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 @@ -39,7 +39,7 @@ public ResponseEntity> getContentsOfFolderByPathAndAcc User authenticatedUser = userAuthorizationService.authenticateUserWithAccessToken(accessToken); String cleanPathString = InputSanitizerService.sanitizeString(path); - ArrayList fileSystemItems = fileSystemBusinessService.getFolderContentsByPath(cleanPathString, authenticatedUser); + ArrayList fileSystemItems = (ArrayList) fileSystemBusinessService.getFolderContentsByPath(cleanPathString, authenticatedUser); return new ResponseEntity<>(fileSystemItems, HttpStatus.OK); } From cfb718dc2e65c1207df58b5cbe8b830405c8981b Mon Sep 17 00:00:00 2001 From: open-schnick Date: Thu, 17 Dec 2020 13:14:07 +0100 Subject: [PATCH 17/50] Added more @Builder.default --- .../rest/domain/filesystem/data/dto/FileSystemItem.java | 3 ++- .../filesystem/data/persistence/FileSystemEntity.java | 3 ++- .../rest/domain/token/data/dto/AccessToken.java | 3 ++- .../domain/token/data/persistence/AccessTokenEntity.java | 3 ++- .../de/filefighter/rest/domain/user/data/dto/User.java | 7 +++++-- .../rest/domain/user/data/dto/UserRegisterForm.java | 3 ++- 6 files changed, 15 insertions(+), 7 deletions(-) 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 797262c1..c0b9f015 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 @@ -8,7 +8,8 @@ @Data public class FileSystemItem { - private long fileSystemId; + @Builder.Default + private long fileSystemId = -1; private String path; private String name; private boolean isShared; 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 11c3c84f..67297e17 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 @@ -12,7 +12,8 @@ public class FileSystemEntity { @MongoId private String mongoId; - private long fileSystemId; + @Builder.Default + private long fileSystemId = -1; private String name; private String path; private long typeId; diff --git a/src/main/java/de/filefighter/rest/domain/token/data/dto/AccessToken.java b/src/main/java/de/filefighter/rest/domain/token/data/dto/AccessToken.java index 8e20d3ad..55798453 100644 --- a/src/main/java/de/filefighter/rest/domain/token/data/dto/AccessToken.java +++ b/src/main/java/de/filefighter/rest/domain/token/data/dto/AccessToken.java @@ -7,6 +7,7 @@ @Builder public class AccessToken { private String tokenValue; - private long userId; + @Builder.Default + private long userId = -1; private long validUntil; } diff --git a/src/main/java/de/filefighter/rest/domain/token/data/persistence/AccessTokenEntity.java b/src/main/java/de/filefighter/rest/domain/token/data/persistence/AccessTokenEntity.java index c306adcf..c5626519 100644 --- a/src/main/java/de/filefighter/rest/domain/token/data/persistence/AccessTokenEntity.java +++ b/src/main/java/de/filefighter/rest/domain/token/data/persistence/AccessTokenEntity.java @@ -13,7 +13,8 @@ public class AccessTokenEntity { @MongoId private String mongoId; private String value; - private long userId; + @Builder.Default + private long userId = -1; private long validUntil; } \ No newline at end of file diff --git a/src/main/java/de/filefighter/rest/domain/user/data/dto/User.java b/src/main/java/de/filefighter/rest/domain/user/data/dto/User.java index 18c421ea..891d7e06 100644 --- a/src/main/java/de/filefighter/rest/domain/user/data/dto/User.java +++ b/src/main/java/de/filefighter/rest/domain/user/data/dto/User.java @@ -1,4 +1,5 @@ package de.filefighter.rest.domain.user.data.dto; + import de.filefighter.rest.domain.user.group.Groups; import lombok.Builder; import lombok.Data; @@ -7,9 +8,11 @@ @Data @Builder public class User { - private long userId; + @Builder.Default + private long userId = -1; private String username; - private Groups[] groups; + @Builder.Default + private Groups[] groups = new Groups[0]; public User(long userId, String username, Groups... groups) { this.userId = userId; diff --git a/src/main/java/de/filefighter/rest/domain/user/data/dto/UserRegisterForm.java b/src/main/java/de/filefighter/rest/domain/user/data/dto/UserRegisterForm.java index 713e83b8..622594bf 100644 --- a/src/main/java/de/filefighter/rest/domain/user/data/dto/UserRegisterForm.java +++ b/src/main/java/de/filefighter/rest/domain/user/data/dto/UserRegisterForm.java @@ -11,7 +11,8 @@ public class UserRegisterForm { private String username; private String password; private String confirmationPassword; - private long[] groupIds; + @Builder.Default + private long[] groupIds = new long[0]; @Override public String toString() { From 7812180963b81bf4e023e61bc3c7c0c9da21d4e5 Mon Sep 17 00:00:00 2001 From: open-schnick Date: Thu, 17 Dec 2020 13:15:34 +0100 Subject: [PATCH 18/50] Fixed Test, Wrote UnitTests (1/2) --- .../business/FileSystemBusinessService.java | 11 +- .../user/business/UserBusinessService.java | 2 +- .../FileSystemBusinessServiceUnitTest.java | 125 ++++++++++++++++++ .../business/UserBusinessServiceUnitTest.java | 3 +- 4 files changed, 135 insertions(+), 6 deletions(-) create mode 100644 src/test/java/de/filefighter/rest/domain/filesystem/business/FileSystemBusinessServiceUnitTest.java 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 033b527f..f25f854c 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 @@ -33,7 +33,6 @@ public FileSystemBusinessService(FileSystemRepository fileSystemRepository, User } // TODO: implement necessary files when a new user is created. - public List getFolderContentsByPath(String path, User authenticatedUser) { if (!InputSanitizerService.stringIsValid(path)) throw new FileSystemContentsNotAccessibleException("Path was not valid."); @@ -60,7 +59,11 @@ public List getFolderContentsByPath(String path, User authentica throw new FileSystemContentsNotAccessibleException(); // now only own or shared folders are left. - ArrayList fileSystemItems = new ArrayList<>(listOfFileSystemEntities.size()); + return getFolderContentsOfEntity(listOfFileSystemEntities, authenticatedUser, pathToFind); + } + + public List getFolderContentsOfEntity(List listOfFileSystemEntities, User authenticatedUser, String pathToFind){ + List fileSystemItems = new ArrayList<>(); for (FileSystemEntity fileSystemEntity : listOfFileSystemEntities) { long[] folderContentItemIds = fileSystemEntity.getItemIds(); @@ -73,7 +76,7 @@ public List getFolderContentsByPath(String path, User authentica throw new FileFighterDataException("FolderContents expected fileSystemItem with id " + listOfFileSystemEntities + " but was empty."); if (userIsAllowedToSeeFileSystemEntity(fileSystemEntityInFolder, authenticatedUser)) { - fileSystemItems.add(this.createDTO(fileSystemEntityInFolder, authenticatedUser, pathToFind)); + fileSystemItems.add(this.createDTO(fileSystemEntityInFolder, authenticatedUser, pathToFind + "/")); } } } @@ -81,7 +84,7 @@ public List getFolderContentsByPath(String path, User authentica return fileSystemItems; } - private String removeTrailingBackSlashes(String pathToFind) { + public String removeTrailingBackSlashes(String pathToFind) { char[] chars = pathToFind.toCharArray(); // for the case of "/" if (chars.length != 1 && chars[chars.length - 1] == '/') { 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 a726a935..fcaafb4d 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 @@ -183,7 +183,7 @@ public void updateUser(long userId, UserRegisterForm userToUpdate, User authenti } private boolean updateGroups(Update newUpdate, long[] groupIds, boolean authenticatedUserIsAdmin) { - if (null != groupIds) { + if (null != groupIds && groupIds.length != 0) { try { for (Groups group : groupRepository.getGroupsByIds(groupIds)) { if (group == Groups.ADMIN && !authenticatedUserIsAdmin) 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 new file mode 100644 index 00000000..7d73b78c --- /dev/null +++ b/src/test/java/de/filefighter/rest/domain/filesystem/business/FileSystemBusinessServiceUnitTest.java @@ -0,0 +1,125 @@ +package de.filefighter.rest.domain.filesystem.business; + +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.group.Groups; +import de.filefighter.rest.rest.exceptions.FileFighterDataException; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +class FileSystemBusinessServiceUnitTest { + + private final FileSystemRepository fileSystemRepository = mock(FileSystemRepository.class); + private final UserBusinessService userBusinessService = mock(UserBusinessService.class); + private final FileSystemTypeRepository fileSystemTypeRepository = mock(FileSystemTypeRepository.class); + private final FileSystemBusinessService fileSystemBusinessService = new FileSystemBusinessService(fileSystemRepository, userBusinessService, fileSystemTypeRepository); + + @Test + void getFolderContentsByPath() { + } + + @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 got it shared. + fileSystemEntity = FileSystemEntity.builder().visibleForUserIds(new long[]{userId}).build(); + assertTrue(fileSystemBusinessService.userIsAllowedToSeeFileSystemEntity(fileSystemEntity, user)); + + //user is in group + user = User.builder().groups(new Groups[]{Groups.ADMIN}).build(); + fileSystemEntity = FileSystemEntity.builder().visibleForGroupIds(new long[]{1}).build(); + assertTrue(fileSystemBusinessService.userIsAllowedToSeeFileSystemEntity(fileSystemEntity, user)); + + // user is not allowed. + user = User.builder().groups(new Groups[]{Groups.UNDEFINED}).build(); + fileSystemEntity = FileSystemEntity.builder().visibleForGroupIds(new long[]{1}).build(); + assertFalse(fileSystemBusinessService.userIsAllowedToSeeFileSystemEntity(fileSystemEntity, user)); + } + + @Test + void createDTOThrows() { + long userId = 420L; + FileSystemEntity fileSystemEntity = FileSystemEntity.builder().createdByUserId(userId).build(); + + when(userBusinessService.getUserById(userId)).thenReturn(null); + + FileFighterDataException ex = assertThrows(FileFighterDataException.class, () -> + fileSystemBusinessService.createDTO(fileSystemEntity, null, "/")); + + assertEquals("Internal Error occurred. Owner of File/Folder does not exist.", 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(userBusinessService.getUserById(createdByUserId)).thenReturn(userThatCreatedFile); + when(fileSystemTypeRepository.findFileSystemTypeById(typeId)).thenReturn(FileSystemType.UNDEFINED); + + FileSystemItem actual = fileSystemBusinessService.createDTO(fileSystemEntity, authenticatedUser, basePath); + + assertEquals(createdByUserId, actual.getCreatedByUserId()); + 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()); + } +} \ No newline at end of file diff --git a/src/test/java/de/filefighter/rest/domain/user/business/UserBusinessServiceUnitTest.java b/src/test/java/de/filefighter/rest/domain/user/business/UserBusinessServiceUnitTest.java index 116a99c5..414a8f94 100644 --- a/src/test/java/de/filefighter/rest/domain/user/business/UserBusinessServiceUnitTest.java +++ b/src/test/java/de/filefighter/rest/domain/user/business/UserBusinessServiceUnitTest.java @@ -283,8 +283,9 @@ void updateUserThrows() { assertEquals("User could not get updated. No updates specified.", ex.getMessage()); UserRegisterForm userRegisterForm1 = UserRegisterForm.builder().build(); + User authenticatedUser1 = User.builder().groups(null).build(); ex = assertThrows(UserNotUpdatedException.class, () -> - userBusinessService.updateUser(userId, userRegisterForm1, authenticatedUser)); + userBusinessService.updateUser(userId, userRegisterForm1, authenticatedUser1)); assertEquals("User could not get updated. Authenticated User is not allowed.", ex.getMessage()); authenticatedUser.setGroups(new Groups[]{Groups.UNDEFINED}); From 64ab9f281d1e61e57ac2f38d28f3130d4cd235ec Mon Sep 17 00:00:00 2001 From: open-schnick Date: Thu, 17 Dec 2020 14:32:09 +0100 Subject: [PATCH 19/50] Fixed Test, Wrote UnitTests (2/2) --- .../business/FileSystemBusinessService.java | 13 +-- .../FileSystemBusinessServiceUnitTest.java | 95 ++++++++++++++++++- 2 files changed, 101 insertions(+), 7 deletions(-) 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 f25f854c..6083996f 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 @@ -39,7 +39,7 @@ public List getFolderContentsByPath(String path, User authentica String[] pathWithoutSlashes = path.split("/"); - if (!path.equals("/") && pathWithoutSlashes.length < 1) + if (!path.equals("/") && pathWithoutSlashes.length < 2) throw new FileSystemContentsNotAccessibleException("Path was in wrong format."); if (!path.equals("/") && !"".equals(pathWithoutSlashes[0])) @@ -49,7 +49,7 @@ public List getFolderContentsByPath(String path, User authentica // find the folder with matching path. ArrayList listOfFileSystemEntities = fileSystemRepository.findByPath(pathToFind); - if (listOfFileSystemEntities.isEmpty()) + if (null == listOfFileSystemEntities) // does return null and not a empty collection. throw new FileSystemContentsNotAccessibleException(); // remove all not accessible items. @@ -59,10 +59,10 @@ public List getFolderContentsByPath(String path, User authentica throw new FileSystemContentsNotAccessibleException(); // now only own or shared folders are left. - return getFolderContentsOfEntity(listOfFileSystemEntities, authenticatedUser, pathToFind); + return getFolderContentsOfEntities(listOfFileSystemEntities, authenticatedUser, pathToFind); } - public List getFolderContentsOfEntity(List listOfFileSystemEntities, User authenticatedUser, String pathToFind){ + public List getFolderContentsOfEntities(List listOfFileSystemEntities, User authenticatedUser, String pathToFind) { List fileSystemItems = new ArrayList<>(); for (FileSystemEntity fileSystemEntity : listOfFileSystemEntities) { @@ -73,10 +73,11 @@ public List getFolderContentsOfEntity(List lis FileSystemEntity fileSystemEntityInFolder = fileSystemRepository.findByFileSystemId(fileSystemId); if (null == fileSystemEntityInFolder) - throw new FileFighterDataException("FolderContents expected fileSystemItem with id " + listOfFileSystemEntities + " but was empty."); + throw new FileFighterDataException("FolderContents expected fileSystemItem with id " + fileSystemId + " but was empty."); if (userIsAllowedToSeeFileSystemEntity(fileSystemEntityInFolder, authenticatedUser)) { - fileSystemItems.add(this.createDTO(fileSystemEntityInFolder, authenticatedUser, pathToFind + "/")); + String pathWithTrailingSlash = pathToFind.equals("/") ? pathToFind : pathToFind + "/"; + fileSystemItems.add(this.createDTO(fileSystemEntityInFolder, authenticatedUser, pathWithTrailingSlash)); } } } 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 7d73b78c..6e8a02ad 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 @@ -3,6 +3,7 @@ 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.type.FileSystemType; import de.filefighter.rest.domain.filesystem.type.FileSystemTypeRepository; import de.filefighter.rest.domain.user.business.UserBusinessService; @@ -11,6 +12,8 @@ import de.filefighter.rest.rest.exceptions.FileFighterDataException; import org.junit.jupiter.api.Test; +import java.util.ArrayList; + import static org.junit.jupiter.api.Assertions.*; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -23,7 +26,97 @@ class FileSystemBusinessServiceUnitTest { private final FileSystemBusinessService fileSystemBusinessService = new FileSystemBusinessService(fileSystemRepository, userBusinessService, fileSystemTypeRepository); @Test - void getFolderContentsByPath() { + void getFolderContentsByPathThrows() { + String notValid = ""; + String wrongFormat = "asd"; + String wrongFormat1 = "as/d"; + String validPath = "/uga/uga/as/sasda/sassasd"; + + User dummyUser = User.builder().userId(0).build(); + + FileSystemContentsNotAccessibleException ex = assertThrows(FileSystemContentsNotAccessibleException.class, () -> + fileSystemBusinessService.getFolderContentsByPath(notValid, dummyUser)); + assertEquals("Folder contents could not be displayed. Path was not valid.", ex.getMessage()); + + ex = assertThrows(FileSystemContentsNotAccessibleException.class, () -> + fileSystemBusinessService.getFolderContentsByPath(wrongFormat, dummyUser)); + assertEquals("Folder contents could not be displayed. Path was in wrong format.", ex.getMessage()); + + ex = assertThrows(FileSystemContentsNotAccessibleException.class, () -> + fileSystemBusinessService.getFolderContentsByPath(wrongFormat1, dummyUser)); + assertEquals("Folder contents could not be displayed. Path was in wrong format. Use a leading backslash.", ex.getMessage()); + + when(fileSystemRepository.findByPath(validPath)).thenReturn(null); + + ex = assertThrows(FileSystemContentsNotAccessibleException.class, () -> + fileSystemBusinessService.getFolderContentsByPath(validPath, dummyUser)); + assertEquals("Folder does not exist, or you are not allowed to see the folder.", ex.getMessage()); + + 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()); + + when(fileSystemRepository.findByPath(validPath)).thenReturn(fileSystemEntityArrayList); + + ex = assertThrows(FileSystemContentsNotAccessibleException.class, () -> + fileSystemBusinessService.getFolderContentsByPath(validPath, dummyUser)); + assertEquals("Folder does not exist, or you are not allowed to see the folder.", ex.getMessage()); + } + + @Test + void getFolderContentsByPathWorks() { + String path = "/uga/buga/buga"; + String pathToRequest = path+"/"; + long userId = 420; + long fileIdInFolder = 123; + User user = User.builder().userId(userId).build(); + FileSystemEntity foundFolder = FileSystemEntity.builder().createdByUserId(userId).itemIds(new long[]{fileIdInFolder}).build(); + ArrayList entities = new ArrayList<>(); + entities.add(foundFolder); + + when(fileSystemRepository.findByPath(path)).thenReturn(entities); + when(fileSystemRepository.findByFileSystemId(fileIdInFolder)).thenReturn(FileSystemEntity.builder().createdByUserId(userId).build()); + when(userBusinessService.getUserById(userId)).thenReturn(User.builder().build()); + + ArrayList fileSystemItems = (ArrayList) fileSystemBusinessService.getFolderContentsByPath(pathToRequest, user); + assertEquals(1, fileSystemItems.size()); + } + + @Test + void getFolderContentsOfEntityThrows() { + long fileSystemId = 420; + + User authenticatedUser = User.builder().build(); + FileSystemEntity foundFolder = FileSystemEntity.builder().itemIds(new long[]{fileSystemId}).build(); + ArrayList arrayList = new ArrayList<>(); + arrayList.add(foundFolder); + + when(fileSystemRepository.findByFileSystemId(fileSystemId)).thenReturn(null); + + FileFighterDataException ex = assertThrows(FileFighterDataException.class, () -> + fileSystemBusinessService.getFolderContentsOfEntities(arrayList, authenticatedUser, "/")); + assertEquals("Internal Error occurred. FolderContents expected fileSystemItem with id " + fileSystemId + " but was empty.", ex.getMessage()); + } + + @Test + void getFolderContentsOfEntityWorks() { + long userId = 420; + User authenticatedUser = User.builder().userId(userId).build(); + FileSystemEntity foundFolder = FileSystemEntity.builder().itemIds(new long[]{0, 1, 2, 3, 4}).build(); + ArrayList arrayList = new ArrayList<>(); + arrayList.add(foundFolder); + + FileSystemEntity dummyEntity = FileSystemEntity.builder().createdByUserId(userId).build(); + when(fileSystemRepository.findByFileSystemId(0)).thenReturn(dummyEntity); + when(fileSystemRepository.findByFileSystemId(1)).thenReturn(dummyEntity); + when(fileSystemRepository.findByFileSystemId(2)).thenReturn(dummyEntity); + when(fileSystemRepository.findByFileSystemId(3)).thenReturn(dummyEntity); + when(fileSystemRepository.findByFileSystemId(4)).thenReturn(FileSystemEntity.builder().createdByUserId(userId+1).build()); + when(userBusinessService.getUserById(userId)).thenReturn(User.builder().userId(userId).build()); + + ArrayList actual = (ArrayList) fileSystemBusinessService.getFolderContentsOfEntities(arrayList, authenticatedUser, "/"); + assertEquals(4, actual.size()); } @Test From b93945c50db1468576c97f5d3eac9d51fa860805 Mon Sep 17 00:00:00 2001 From: open-schnick Date: Thu, 17 Dec 2020 14:57:54 +0100 Subject: [PATCH 20/50] Added createBasicFilesForNewUser --- .../business/FileSystemBusinessService.java | 32 ++++++++++++++++++- .../user/business/UserBusinessService.java | 4 +-- .../domain/user/rest/UserRestService.java | 9 ++++-- 3 files changed, 40 insertions(+), 5 deletions(-) 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 6083996f..cd0a63d8 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 @@ -9,11 +9,14 @@ 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.group.Groups; import de.filefighter.rest.rest.exceptions.FileFighterDataException; import lombok.extern.log4j.Log4j2; import org.springframework.stereotype.Service; +import java.security.SecureRandom; +import java.time.Instant; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -22,6 +25,7 @@ @Service public class FileSystemBusinessService { + private static final int FILE_SYSTEM_ID_MAX = 99999999; private final FileSystemRepository fileSystemRepository; private final UserBusinessService userBusinessService; private final FileSystemTypeRepository fileSystemTypeRepository; @@ -32,7 +36,6 @@ public FileSystemBusinessService(FileSystemRepository fileSystemRepository, User this.fileSystemTypeRepository = fileSystemTypeRepository; } - // TODO: implement necessary files when a new user is created. public List getFolderContentsByPath(String path, User authenticatedUser) { if (!InputSanitizerService.stringIsValid(path)) throw new FileSystemContentsNotAccessibleException("Path was not valid."); @@ -136,4 +139,31 @@ public FileSystemItem createDTO(FileSystemEntity fileSystemEntity, User authenti .isShared(isShared) .build(); } + + public void createBasicFilesForNewUser(UserEntity registeredUserEntity) { + fileSystemRepository.save(FileSystemEntity + .builder() + .createdByUserId(registeredUserEntity.getUserId()) + .typeId(0) + .isFile(false) + .name("root_" + registeredUserEntity.getUsername()) + .path("/") + .lastUpdated(Instant.now().getEpochSecond()) + .fileSystemId(generateRandomFileSystemId()) + .build()); + } + + public long generateRandomFileSystemId() { + long possibleFileSystemId = 0L; + boolean possibleFileSystemIdIsFree = false; + + while (!possibleFileSystemIdIsFree) { + possibleFileSystemId = new SecureRandom().nextInt(FileSystemBusinessService.FILE_SYSTEM_ID_MAX); + FileSystemEntity fileSystemEntity = fileSystemRepository.findByFileSystemId(possibleFileSystemId); + if (null == fileSystemEntity && possibleFileSystemId > 0) + possibleFileSystemIdIsFree = true; + } + + return possibleFileSystemId; + } } 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 fcaafb4d..73155222 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 @@ -82,7 +82,7 @@ public User findUserByUsername(String username) { return userDtoService.createDto(entity); } - public void registerNewUser(UserRegisterForm newUser) { + public UserEntity registerNewUser(UserRegisterForm newUser) { String username = newUser.getUsername(); if (!stringIsValid(username)) @@ -121,7 +121,7 @@ public void registerNewUser(UserRegisterForm newUser) { } //create new user. - userRepository.save(UserEntity.builder() + return userRepository.save(UserEntity.builder() .lowercaseUsername(username.toLowerCase()) .username(username) .password(password) 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 12b5d663..50dde960 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,6 +1,7 @@ package de.filefighter.rest.domain.user.rest; import de.filefighter.rest.domain.common.InputSanitizerService; +import de.filefighter.rest.domain.filesystem.business.FileSystemBusinessService; 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; @@ -8,6 +9,7 @@ import de.filefighter.rest.domain.user.business.UserBusinessService; import de.filefighter.rest.domain.user.data.dto.User; import de.filefighter.rest.domain.user.data.dto.UserRegisterForm; +import de.filefighter.rest.domain.user.data.persistence.UserEntity; import de.filefighter.rest.rest.ServerResponse; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -25,12 +27,14 @@ public class UserRestService implements UserRestServiceInterface { private final UserAuthorizationService userAuthorizationService; private final AccessTokenBusinessService accessTokenBusinessService; private final InputSanitizerService inputSanitizerService; + private final FileSystemBusinessService fileSystemBusinessService; - public UserRestService(UserBusinessService userBusinessService, UserAuthorizationService userAuthorizationService, AccessTokenBusinessService accessTokenBusinessService, InputSanitizerService inputSanitizerService) { + public UserRestService(UserBusinessService userBusinessService, UserAuthorizationService userAuthorizationService, AccessTokenBusinessService accessTokenBusinessService, InputSanitizerService inputSanitizerService, FileSystemBusinessService fileSystemBusinessService) { this.userBusinessService = userBusinessService; this.userAuthorizationService = userAuthorizationService; this.accessTokenBusinessService = accessTokenBusinessService; this.inputSanitizerService = inputSanitizerService; + this.fileSystemBusinessService = fileSystemBusinessService; } @Override @@ -82,7 +86,8 @@ public ResponseEntity registerNewUserWithAccessToken(UserRegiste AccessToken validAccessToken = accessTokenBusinessService.findAccessTokenByValue(sanitizedTokenString); userAuthorizationService.authenticateUserWithAccessTokenAndGroup(validAccessToken, ADMIN); - userBusinessService.registerNewUser(newUser); + UserEntity registeredUserEntity = userBusinessService.registerNewUser(newUser); + fileSystemBusinessService.createBasicFilesForNewUser(registeredUserEntity); return new ResponseEntity<>(new ServerResponse(HttpStatus.CREATED, "User successfully created."), HttpStatus.CREATED); } From 8580bec2dea972d84fd4a692f0ae6d1390e26555 Mon Sep 17 00:00:00 2001 From: open-schnick Date: Sat, 19 Dec 2020 15:16:06 +0100 Subject: [PATCH 21/50] Updated Sonar Hostname --- README.md | 12 ++++++------ settings.xml | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 69d11308..99fc8a12 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,11 @@ # RestApi -Backend REST API for FileFighter
+Backend REST API for FileFighter ![Docker Release](https://img.shields.io/github/v/release/filefighter/restapi?color=dark-green&label=Stable%20Version&logo=docker&style=for-the-badge) -![Docker Pulls](https://img.shields.io/docker/pulls/filefighter/rest?logo=docker&style=for-the-badge)
-[![Quality Gate Status](http://filefighter.ddns.net:9000/api/project_badges/measure?project=de.filefighter%3Arest&metric=alert_status)](http://filefighter.ddns.net:9000/dashboard?id=de.filefighter%3Arest) -[![Coverage](http://filefighter.ddns.net:9000/api/project_badges/measure?project=de.filefighter%3Arest&metric=coverage)](http://filefighter.ddns.net:9000/dashboard?id=de.filefighter%3Arest) -[![Lines of Code](http://filefighter.ddns.net:9000/api/project_badges/measure?project=de.filefighter%3Arest&metric=ncloc)](http://filefighter.ddns.net:9000/dashboard?id=de.filefighter%3Arest) -[![Security Rating](http://filefighter.ddns.net:9000/api/project_badges/measure?project=de.filefighter%3Arest&metric=security_rating)](http://filefighter.ddns.net:9000/dashboard?id=de.filefighter%3Arest)
+![Docker Pulls](https://img.shields.io/docker/pulls/filefighter/rest?logo=docker&style=for-the-badge) +[![Quality Gate Status](http://sonar.filefighter.de/api/project_badges/measure?project=de.filefighter%3Arest&metric=alert_status)](http://sonar.filefighter.de/dashboard?id=de.filefighter%3Arest) +[![Coverage](http://sonar.filefighter.de/api/project_badges/measure?project=de.filefighter%3Arest&metric=coverage)](http://sonar.filefighter.de/dashboard?id=de.filefighter%3Arest) +[![Lines of Code](http://sonar.filefighter.de/api/project_badges/measure?project=de.filefighter%3Arest&metric=ncloc)](http://sonar.filefighter.de/dashboard?id=de.filefighter%3Arest) +[![Security Rating](http://sonar.filefighter.de/api/project_badges/measure?project=de.filefighter%3Arest&metric=security_rating)](http://sonar.filefighter.de/dashboard?id=de.filefighter%3Arest) ![Latest Release](https://github.com/FileFighter/RestApi/workflows/Latest%20Release/badge.svg) ![Stable Release](https://github.com/FileFighter/RestApi/workflows/Stable%20Release/badge.svg) ![Tests](https://github.com/FileFighter/RestApi/workflows/Tests/badge.svg) diff --git a/settings.xml b/settings.xml index 9ee4fb86..ce580f9a 100644 --- a/settings.xml +++ b/settings.xml @@ -10,7 +10,7 @@ - http://filefighter.ddns.net:9000 + http://sonar.filefighter.de ${env.SONAR_LOGIN} ${env.SONAR_PASSWORD} From 5ead455e8f642e87de04cf1345086f5e04395034 Mon Sep 17 00:00:00 2001 From: open-schnick Date: Sat, 19 Dec 2020 15:20:15 +0100 Subject: [PATCH 22/50] Implemented Changes requested by @qvalentin --- .../rest/configuration/CorsConfig.java | 11 +++++++++- .../business/FileSystemBusinessService.java | 22 ++++++------------- 2 files changed, 17 insertions(+), 16 deletions(-) diff --git a/src/main/java/de/filefighter/rest/configuration/CorsConfig.java b/src/main/java/de/filefighter/rest/configuration/CorsConfig.java index 6b52831c..bb571f4a 100644 --- a/src/main/java/de/filefighter/rest/configuration/CorsConfig.java +++ b/src/main/java/de/filefighter/rest/configuration/CorsConfig.java @@ -15,12 +15,21 @@ public class CorsConfig { // Cors again. For local testing only. @Bean @Profile("dev") - public CorsFilter corsFilter(){ + public CorsFilter corsFilter() { final CorsConfiguration config = new CorsConfiguration().applyPermitDefaultValues(); ArrayList allowedOrigins = new ArrayList<>(); allowedOrigins.add("*"); config.setAllowedOrigins(allowedOrigins); + ArrayList allowedMethods = new ArrayList<>(); + allowedMethods.add("HEAD"); + allowedMethods.add("GET"); + allowedMethods.add("POST"); + allowedMethods.add("PUT"); + allowedMethods.add("DELETE"); + allowedMethods.add("OPTIONS"); + config.setAllowedMethods(allowedMethods); + final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); source.registerCorsConfiguration("/**", config); return new CorsFilter(source); 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 cd0a63d8..f6ca39d9 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 @@ -15,7 +15,6 @@ import lombok.extern.log4j.Log4j2; import org.springframework.stereotype.Service; -import java.security.SecureRandom; import java.time.Instant; import java.util.ArrayList; import java.util.Arrays; @@ -25,7 +24,6 @@ @Service public class FileSystemBusinessService { - private static final int FILE_SYSTEM_ID_MAX = 99999999; private final FileSystemRepository fileSystemRepository; private final UserBusinessService userBusinessService; private final FileSystemTypeRepository fileSystemTypeRepository; @@ -146,24 +144,18 @@ public void createBasicFilesForNewUser(UserEntity registeredUserEntity) { .createdByUserId(registeredUserEntity.getUserId()) .typeId(0) .isFile(false) - .name("root_" + registeredUserEntity.getUsername()) + .name("HOME_" + registeredUserEntity.getUsername()) .path("/") .lastUpdated(Instant.now().getEpochSecond()) - .fileSystemId(generateRandomFileSystemId()) + .fileSystemId(generateNextFileSystemId()) .build()); } - public long generateRandomFileSystemId() { - long possibleFileSystemId = 0L; - boolean possibleFileSystemIdIsFree = false; - - while (!possibleFileSystemIdIsFree) { - possibleFileSystemId = new SecureRandom().nextInt(FileSystemBusinessService.FILE_SYSTEM_ID_MAX); - FileSystemEntity fileSystemEntity = fileSystemRepository.findByFileSystemId(possibleFileSystemId); - if (null == fileSystemEntity && possibleFileSystemId > 0) - possibleFileSystemIdIsFree = true; - } + public long getFileSystemEntityCount() { + return fileSystemRepository.count(); + } - return possibleFileSystemId; + public long generateNextFileSystemId() { + return getFileSystemEntityCount() + 1; } } From 77bd8a996ddbe4baa6ffdfdb337875f096786999 Mon Sep 17 00:00:00 2001 From: open-schnick Date: Sat, 19 Dec 2020 15:28:45 +0100 Subject: [PATCH 23/50] Ignored Stupid CodeSmells --- .../rest/configuration/PrepareDataBase.java | 25 ++++++++++--------- .../business/FileSystemBusinessService.java | 2 +- .../data/dto/request/PermissionRecipient.java | 11 +++----- .../rest/RestApplicationIntegrationTest.java | 2 +- 4 files changed, 19 insertions(+), 21 deletions(-) diff --git a/src/main/java/de/filefighter/rest/configuration/PrepareDataBase.java b/src/main/java/de/filefighter/rest/configuration/PrepareDataBase.java index 22985613..d1b83ee3 100644 --- a/src/main/java/de/filefighter/rest/configuration/PrepareDataBase.java +++ b/src/main/java/de/filefighter/rest/configuration/PrepareDataBase.java @@ -33,6 +33,7 @@ public class PrepareDataBase { @Value("${filefighter.date}") String date; + @SuppressWarnings("squid:S106") @Bean @Profile({"dev", "prod"}) CommandLineRunner veryImportantFileFighterStartScript() { @@ -40,17 +41,17 @@ CommandLineRunner veryImportantFileFighterStartScript() { System.out.println(); System.out.println("-------------------------------< REST API >-------------------------------"); System.out.println(); - System.out.println(" _____ _ _ _____ _ _ _ "); - System.out.println(" | ___| (_) | | ___ | ___| (_) __ _ | |__ | |_ ___ _ __ "); + System.out.println(" _____ _ _ _____ _ _ _"); + System.out.println(" | ___| (_) | | ___ | ___| (_) __ _ | |__ | |_ ___ _ __"); System.out.println(" | |_ | | | | / _ \\ | |_ | | / _ | | '_ \\ | __| / _ \\ | '__|"); - System.out.println(" | _| | | | | | __/ | _| | | | (_| | | | | | | |_ | __/ | | "); - System.out.println(" |_| |_| |_| \\___| |_| |_| \\__, | |_| |_| \\__| \\___| |_| "); - System.out.println(" |___/ "); - System.out.println(" Version v" + version + " Last updated at " + date + " "); - System.out.println(" Developed by Gimleux, Valentin, Open-Schnick. "); - System.out.println(" Development Blog: https://filefighter.github.io "); - System.out.println(" The code can be found at: https://www.github.com/filefighter "); - System.out.println(" Running on http://localhost:" + serverPort); + System.out.println(" | _| | | | | | __/ | _| | | | (_| | | | | | | |_ | __/ | |"); + System.out.println(" |_| |_| |_| \\___| |_| |_| \\__, | |_| |_| \\__| \\___| |_|"); + System.out.println(" |___/"); + System.out.println(" Version v" + version + " Last updated at " + date + ""); + System.out.println(" Developed by Gimleux, Valentin, Open-Schnick."); + System.out.println(" Development Blog: https://blog.filefighter.de"); + System.out.println(" The code can be found at: https://www.github.com/filefighter"); + System.out.println(" Running on http://localhost:" + serverPort); System.out.println(); System.out.println("-------------------------------< REST API >-------------------------------"); System.out.println(); @@ -160,7 +161,7 @@ CommandLineRunner initDataBaseDev(UserRepository userRepository, AccessTokenRepo .path("/") .itemIds(new long[]{2}) .lastUpdated(Instant.now().getEpochSecond()) - .name("root_User") + .name("HOME_User") .size(420) .typeId(FileSystemType.FOLDER.getId()) .visibleForGroupIds(new long[]{0, 1}) @@ -171,7 +172,7 @@ CommandLineRunner initDataBaseDev(UserRepository userRepository, AccessTokenRepo .isFile(false) .path("/") .lastUpdated(Instant.now().getEpochSecond()) - .name("root_User1") + .name("HOME_User1") .size(420) .typeId(FileSystemType.FOLDER.getId()) .visibleForGroupIds(new long[]{-1, 0, 1}) 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 f6ca39d9..ede584aa 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 @@ -77,7 +77,7 @@ public List getFolderContentsOfEntities(List l throw new FileFighterDataException("FolderContents expected fileSystemItem with id " + fileSystemId + " but was empty."); if (userIsAllowedToSeeFileSystemEntity(fileSystemEntityInFolder, authenticatedUser)) { - String pathWithTrailingSlash = pathToFind.equals("/") ? pathToFind : pathToFind + "/"; + String pathWithTrailingSlash = pathToFind.equals("/") ? pathToFind : pathToFind + "/"; //NOSONAR fileSystemItems.add(this.createDTO(fileSystemEntityInFolder, authenticatedUser, pathWithTrailingSlash)); } } diff --git a/src/main/java/de/filefighter/rest/domain/permission/data/dto/request/PermissionRecipient.java b/src/main/java/de/filefighter/rest/domain/permission/data/dto/request/PermissionRecipient.java index a0ed4055..de1c6377 100644 --- a/src/main/java/de/filefighter/rest/domain/permission/data/dto/request/PermissionRecipient.java +++ b/src/main/java/de/filefighter/rest/domain/permission/data/dto/request/PermissionRecipient.java @@ -5,12 +5,9 @@ @Getter @ToString -public class PermissionRecipient{ - private final PermissionRecipientType permissionRecipientType; - private final long userOrGroupId; +public class PermissionRecipient { + + private PermissionRecipientType permissionRecipientType; + private long userOrGroupId; - private PermissionRecipient(PermissionRecipientType permissionRecipientType, long userOrGroupId) { - this.permissionRecipientType = permissionRecipientType; - this.userOrGroupId = userOrGroupId; - } } \ No newline at end of file diff --git a/src/test/java/de/filefighter/rest/RestApplicationIntegrationTest.java b/src/test/java/de/filefighter/rest/RestApplicationIntegrationTest.java index ba17cd09..36d3778a 100644 --- a/src/test/java/de/filefighter/rest/RestApplicationIntegrationTest.java +++ b/src/test/java/de/filefighter/rest/RestApplicationIntegrationTest.java @@ -24,7 +24,7 @@ import static org.assertj.core.api.Assertions.assertThat; -@SuppressWarnings("SameParameterValue") +@SuppressWarnings({"SameParameterValue", "squid:S5786"}) // public on test class. @ActiveProfiles("test") @SpringBootTest(classes = RestApplication.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) public class RestApplicationIntegrationTest { From 27202eb4bc71da005b5fa59506f786a3405accfb Mon Sep 17 00:00:00 2001 From: open-schnick Date: Sat, 19 Dec 2020 15:44:58 +0100 Subject: [PATCH 24/50] Added TotalFileSize To SystemHealth --- .../business/FileSystemBusinessService.java | 12 +++++ .../business/SystemHealthBusinessService.java | 16 +++--- .../rest/domain/health/data/SystemHealth.java | 1 + .../FileSystemBusinessServiceUnitTest.java | 49 +++++++++++++------ .../SystemHealthBusinessServiceUnitTest.java | 7 ++- 5 files changed, 64 insertions(+), 21 deletions(-) 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 ede584aa..67125399 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 @@ -151,6 +151,18 @@ public void createBasicFilesForNewUser(UserEntity registeredUserEntity) { .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(); } 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 0674fea6..3fbe96e4 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,5 +1,6 @@ package de.filefighter.rest.domain.health.business; +import de.filefighter.rest.domain.filesystem.business.FileSystemBusinessService; 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; @@ -14,25 +15,28 @@ public class SystemHealthBusinessService { private final UserBusinessService userBusinessService; private final AccessTokenBusinessService accessTokenBusinessService; + private final FileSystemBusinessService fileSystemBusinessService; private final long serverStartedAt; private DataIntegrity cachedIntegrity = DataIntegrity.STABLE; @Value("${filefighter.version}") String version; - public SystemHealthBusinessService(UserBusinessService userBusinessService, AccessTokenBusinessService accessTokenBusinessService) { + public SystemHealthBusinessService(UserBusinessService userBusinessService, AccessTokenBusinessService accessTokenBusinessService, FileSystemBusinessService fileSystemBusinessService) { this.userBusinessService = userBusinessService; this.accessTokenBusinessService = accessTokenBusinessService; + this.fileSystemBusinessService = fileSystemBusinessService; this.serverStartedAt = this.getCurrentEpochSeconds(); } - public SystemHealth getCurrentSystemHealthInfo(){ + public SystemHealth getCurrentSystemHealthInfo() { long currentEpoch = getCurrentEpochSeconds(); return SystemHealth.builder() .uptimeInSeconds(currentEpoch - serverStartedAt) .userCount(userBusinessService.getUserCount()) + .usedStorageInMb(fileSystemBusinessService.getTotalFileSize()) .dataIntegrity(calculateDataIntegrity()) - .version("v"+this.version) + .version("v" + this.version) .build(); } @@ -41,19 +45,19 @@ private DataIntegrity calculateDataIntegrity() { long accessTokenCount = accessTokenBusinessService.getAccessTokenCount(); // Risk / Unstable Cases. - if(userCount < accessTokenCount){ + if (userCount < accessTokenCount) { this.triggerIntegrityChange(DataIntegrity.POSSIBLE_RISK); } return cachedIntegrity; } - public long getCurrentEpochSeconds(){ + public long getCurrentEpochSeconds() { return Instant.now().getEpochSecond(); } public void triggerIntegrityChange(DataIntegrity integrity) { - if(cachedIntegrity.getCode() < integrity.getCode()){ + if (cachedIntegrity.getCode() < integrity.getCode()) { this.cachedIntegrity = integrity; } } diff --git a/src/main/java/de/filefighter/rest/domain/health/data/SystemHealth.java b/src/main/java/de/filefighter/rest/domain/health/data/SystemHealth.java index d63ce362..23af01a7 100644 --- a/src/main/java/de/filefighter/rest/domain/health/data/SystemHealth.java +++ b/src/main/java/de/filefighter/rest/domain/health/data/SystemHealth.java @@ -12,6 +12,7 @@ public class SystemHealth { private final long uptimeInSeconds; private final long userCount; + private final double usedStorageInMb; private final DataIntegrity dataIntegrity; private final String version; 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 6e8a02ad..9d32165c 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 @@ -20,10 +20,10 @@ class FileSystemBusinessServiceUnitTest { - private final FileSystemRepository fileSystemRepository = mock(FileSystemRepository.class); + private final FileSystemRepository fileSystemRepositoryMock = mock(FileSystemRepository.class); private final UserBusinessService userBusinessService = mock(UserBusinessService.class); private final FileSystemTypeRepository fileSystemTypeRepository = mock(FileSystemTypeRepository.class); - private final FileSystemBusinessService fileSystemBusinessService = new FileSystemBusinessService(fileSystemRepository, userBusinessService, fileSystemTypeRepository); + private final FileSystemBusinessService fileSystemBusinessService = new FileSystemBusinessService(fileSystemRepositoryMock, userBusinessService, fileSystemTypeRepository); @Test void getFolderContentsByPathThrows() { @@ -46,7 +46,7 @@ void getFolderContentsByPathThrows() { fileSystemBusinessService.getFolderContentsByPath(wrongFormat1, dummyUser)); assertEquals("Folder contents could not be displayed. Path was in wrong format. Use a leading backslash.", ex.getMessage()); - when(fileSystemRepository.findByPath(validPath)).thenReturn(null); + when(fileSystemRepositoryMock.findByPath(validPath)).thenReturn(null); ex = assertThrows(FileSystemContentsNotAccessibleException.class, () -> fileSystemBusinessService.getFolderContentsByPath(validPath, dummyUser)); @@ -57,7 +57,7 @@ void getFolderContentsByPathThrows() { fileSystemEntityArrayList.add(FileSystemEntity.builder().isFile(false).typeId(-1).build()); fileSystemEntityArrayList.add(FileSystemEntity.builder().createdByUserId(420).build()); - when(fileSystemRepository.findByPath(validPath)).thenReturn(fileSystemEntityArrayList); + when(fileSystemRepositoryMock.findByPath(validPath)).thenReturn(fileSystemEntityArrayList); ex = assertThrows(FileSystemContentsNotAccessibleException.class, () -> fileSystemBusinessService.getFolderContentsByPath(validPath, dummyUser)); @@ -67,7 +67,7 @@ void getFolderContentsByPathThrows() { @Test void getFolderContentsByPathWorks() { String path = "/uga/buga/buga"; - String pathToRequest = path+"/"; + String pathToRequest = path + "/"; long userId = 420; long fileIdInFolder = 123; User user = User.builder().userId(userId).build(); @@ -75,8 +75,8 @@ void getFolderContentsByPathWorks() { ArrayList entities = new ArrayList<>(); entities.add(foundFolder); - when(fileSystemRepository.findByPath(path)).thenReturn(entities); - when(fileSystemRepository.findByFileSystemId(fileIdInFolder)).thenReturn(FileSystemEntity.builder().createdByUserId(userId).build()); + when(fileSystemRepositoryMock.findByPath(path)).thenReturn(entities); + when(fileSystemRepositoryMock.findByFileSystemId(fileIdInFolder)).thenReturn(FileSystemEntity.builder().createdByUserId(userId).build()); when(userBusinessService.getUserById(userId)).thenReturn(User.builder().build()); ArrayList fileSystemItems = (ArrayList) fileSystemBusinessService.getFolderContentsByPath(pathToRequest, user); @@ -92,7 +92,7 @@ void getFolderContentsOfEntityThrows() { ArrayList arrayList = new ArrayList<>(); arrayList.add(foundFolder); - when(fileSystemRepository.findByFileSystemId(fileSystemId)).thenReturn(null); + when(fileSystemRepositoryMock.findByFileSystemId(fileSystemId)).thenReturn(null); FileFighterDataException ex = assertThrows(FileFighterDataException.class, () -> fileSystemBusinessService.getFolderContentsOfEntities(arrayList, authenticatedUser, "/")); @@ -101,18 +101,18 @@ void getFolderContentsOfEntityThrows() { @Test void getFolderContentsOfEntityWorks() { - long userId = 420; + long userId = 420; User authenticatedUser = User.builder().userId(userId).build(); FileSystemEntity foundFolder = FileSystemEntity.builder().itemIds(new long[]{0, 1, 2, 3, 4}).build(); ArrayList arrayList = new ArrayList<>(); arrayList.add(foundFolder); FileSystemEntity dummyEntity = FileSystemEntity.builder().createdByUserId(userId).build(); - when(fileSystemRepository.findByFileSystemId(0)).thenReturn(dummyEntity); - when(fileSystemRepository.findByFileSystemId(1)).thenReturn(dummyEntity); - when(fileSystemRepository.findByFileSystemId(2)).thenReturn(dummyEntity); - when(fileSystemRepository.findByFileSystemId(3)).thenReturn(dummyEntity); - when(fileSystemRepository.findByFileSystemId(4)).thenReturn(FileSystemEntity.builder().createdByUserId(userId+1).build()); + when(fileSystemRepositoryMock.findByFileSystemId(0)).thenReturn(dummyEntity); + when(fileSystemRepositoryMock.findByFileSystemId(1)).thenReturn(dummyEntity); + when(fileSystemRepositoryMock.findByFileSystemId(2)).thenReturn(dummyEntity); + when(fileSystemRepositoryMock.findByFileSystemId(3)).thenReturn(dummyEntity); + when(fileSystemRepositoryMock.findByFileSystemId(4)).thenReturn(FileSystemEntity.builder().createdByUserId(userId + 1).build()); when(userBusinessService.getUserById(userId)).thenReturn(User.builder().userId(userId).build()); ArrayList actual = (ArrayList) fileSystemBusinessService.getFolderContentsOfEntities(arrayList, authenticatedUser, "/"); @@ -215,4 +215,25 @@ void createDTOWorks() { assertEquals(basePath + name, actual.getPath()); assertTrue(actual.isShared()); } + + @Test + void getTotalFileSizeThrows() { + when(fileSystemRepositoryMock.findByPath("/")).thenReturn(null); + FileFighterDataException ex = assertThrows(FileFighterDataException.class, fileSystemBusinessService::getTotalFileSize); + assertEquals("Internal Error occurred. 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); + } } \ 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 0a4b6835..8e5d346c 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,5 +1,6 @@ package de.filefighter.rest.domain.health.business; +import de.filefighter.rest.domain.filesystem.business.FileSystemBusinessService; 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; @@ -18,22 +19,26 @@ class SystemHealthBusinessServiceUnitTest { private final UserBusinessService userBusinessServiceMock = mock(UserBusinessService.class); private final AccessTokenBusinessService accessTokenBusinessServiceMock = mock(AccessTokenBusinessService.class); + private final FileSystemBusinessService fileSystemBusinessService = mock(FileSystemBusinessService.class); private SystemHealthBusinessService systemHealthBusinessService; @BeforeEach void setUp() { - systemHealthBusinessService = new SystemHealthBusinessService(userBusinessServiceMock, accessTokenBusinessServiceMock); + systemHealthBusinessService = new SystemHealthBusinessService(userBusinessServiceMock, accessTokenBusinessServiceMock, fileSystemBusinessService); } @Test void getCurrentSystemHealthInfo() { long expectedUserCount = 420; + double expectedSize = 1234.532; when(userBusinessServiceMock.getUserCount()).thenReturn(expectedUserCount); + when(fileSystemBusinessService.getTotalFileSize()).thenReturn(expectedSize); SystemHealth systemHealth = systemHealthBusinessService.getCurrentSystemHealthInfo(); assertTrue(systemHealth.getUptimeInSeconds() >= 0); + assertEquals(expectedSize, systemHealth.getUsedStorageInMb()); assertEquals(expectedUserCount, systemHealth.getUserCount()); } From 13dcca0cd9f39ecf5c14c2277770a370af2fd37f Mon Sep 17 00:00:00 2001 From: open-schnick Date: Sat, 19 Dec 2020 15:48:59 +0100 Subject: [PATCH 25/50] Sonar needs to access over https --- settings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/settings.xml b/settings.xml index ce580f9a..c23661b4 100644 --- a/settings.xml +++ b/settings.xml @@ -10,7 +10,7 @@ - http://sonar.filefighter.de + https://sonar.filefighter.de ${env.SONAR_LOGIN} ${env.SONAR_PASSWORD} From ef5b06b54d35c70af73ee65766e96d15470159cb Mon Sep 17 00:00:00 2001 From: qvalentin Date: Sat, 19 Dec 2020 16:57:35 +0100 Subject: [PATCH 26/50] added import of ssl cert for reaching sonar --- .github/workflows/tests.yml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 19168685..44610421 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -26,7 +26,12 @@ jobs: docker start FileFighterDB - name: Run Tests and update Sonar - run: mvn clean verify sonar:sonar -s ./settings.xml + run: | + echo ${{ secrets.SSL_CERT }} > filefighter.de_ssl_certificate.cer + yes yes | keytool -import -alias filefighterde -file filefighter.de_ssl_certificate.cer -storetype JKS -keystore $JAVA_HOME/lib/security/cacerts -storepass ${{ secrets.STOREPASS }} + mvn clean verify sonar:sonar -s ./settings.xml + rm filefighter.de_ssl_certificate.cer + keytool -delete -alias filefighterde -keystore $JAVA_HOME/lib/security/cacerts -storepass ${{ secrets.STOREPASS }} env: SONAR_LOGIN: ${{ secrets.SONAR_LOGIN }} SONAR_PASSWORD: ${{ secrets.SONAR_PASSWORD }} From 1564a07e8b85b4c8b0ff0b4d89b545c5642fb17c Mon Sep 17 00:00:00 2001 From: qvalentin Date: Sat, 19 Dec 2020 17:01:06 +0100 Subject: [PATCH 27/50] also trigger workflow when workflow config is changed --- .github/workflows/tests.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 44610421..c684b72f 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -6,6 +6,7 @@ on: paths: - 'src/**' - 'pom.xml' + - '.github/workflows/tests.yml' jobs: Run_all_tests: From 9b78a8cceea36f050dc8dc6388df9387b30089cc Mon Sep 17 00:00:00 2001 From: qvalentin Date: Sat, 19 Dec 2020 17:03:14 +0100 Subject: [PATCH 28/50] bad echo? --- .github/workflows/tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index c684b72f..24e7dc2d 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -28,7 +28,7 @@ jobs: - name: Run Tests and update Sonar run: | - echo ${{ secrets.SSL_CERT }} > filefighter.de_ssl_certificate.cer + echo "${{ secrets.SSL_CERT }}" > filefighter.de_ssl_certificate.cer yes yes | keytool -import -alias filefighterde -file filefighter.de_ssl_certificate.cer -storetype JKS -keystore $JAVA_HOME/lib/security/cacerts -storepass ${{ secrets.STOREPASS }} mvn clean verify sonar:sonar -s ./settings.xml rm filefighter.de_ssl_certificate.cer From 2539776008912208a9bb97f47e1621a0bb5b1506 Mon Sep 17 00:00:00 2001 From: qvalentin Date: Sat, 19 Dec 2020 17:11:27 +0100 Subject: [PATCH 29/50] changed passowrd --- .github/workflows/tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 24e7dc2d..b8963b90 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -29,7 +29,7 @@ jobs: name: Run Tests and update Sonar run: | echo "${{ secrets.SSL_CERT }}" > filefighter.de_ssl_certificate.cer - yes yes | keytool -import -alias filefighterde -file filefighter.de_ssl_certificate.cer -storetype JKS -keystore $JAVA_HOME/lib/security/cacerts -storepass ${{ secrets.STOREPASS }} + yes yes | keytool -import -alias filefighterde -file filefighter.de_ssl_certificate.cer -storetype JKS -keystore $JAVA_HOME/lib/security/cacerts -storepass "${{ secrets.STOREPASS }}" mvn clean verify sonar:sonar -s ./settings.xml rm filefighter.de_ssl_certificate.cer keytool -delete -alias filefighterde -keystore $JAVA_HOME/lib/security/cacerts -storepass ${{ secrets.STOREPASS }} From 733cba23960f25586c1036a6692fa94559eb9158 Mon Sep 17 00:00:00 2001 From: qvalentin Date: Sat, 19 Dec 2020 17:12:51 +0100 Subject: [PATCH 30/50] changed passowrd --- .github/workflows/tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index b8963b90..0374dccf 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -26,7 +26,7 @@ jobs: docker create -p 27017:27017 --name FileFighterDB mongo:latest docker start FileFighterDB - - name: Run Tests and update Sonar + name: Run Tests and update Sonar (import cert first) run: | echo "${{ secrets.SSL_CERT }}" > filefighter.de_ssl_certificate.cer yes yes | keytool -import -alias filefighterde -file filefighter.de_ssl_certificate.cer -storetype JKS -keystore $JAVA_HOME/lib/security/cacerts -storepass "${{ secrets.STOREPASS }}" From a3912c3df472fb15c24bdff9a240d7b16673aac7 Mon Sep 17 00:00:00 2001 From: qvalentin Date: Sat, 19 Dec 2020 17:14:10 +0100 Subject: [PATCH 31/50] use default password --- .github/workflows/tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 0374dccf..acbe70a9 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -29,7 +29,7 @@ jobs: name: Run Tests and update Sonar (import cert first) run: | echo "${{ secrets.SSL_CERT }}" > filefighter.de_ssl_certificate.cer - yes yes | keytool -import -alias filefighterde -file filefighter.de_ssl_certificate.cer -storetype JKS -keystore $JAVA_HOME/lib/security/cacerts -storepass "${{ secrets.STOREPASS }}" + yes yes | keytool -import -alias filefighterde -file filefighter.de_ssl_certificate.cer -storetype JKS -keystore $JAVA_HOME/lib/security/cacerts -storepass changeit mvn clean verify sonar:sonar -s ./settings.xml rm filefighter.de_ssl_certificate.cer keytool -delete -alias filefighterde -keystore $JAVA_HOME/lib/security/cacerts -storepass ${{ secrets.STOREPASS }} From 99482f397f0ad6af0f9907319fde260c742610fe Mon Sep 17 00:00:00 2001 From: qvalentin Date: Sat, 19 Dec 2020 17:18:16 +0100 Subject: [PATCH 32/50] why did i take the password 'changeit' literally --- .github/workflows/tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index acbe70a9..0850ea6d 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -32,7 +32,7 @@ jobs: yes yes | keytool -import -alias filefighterde -file filefighter.de_ssl_certificate.cer -storetype JKS -keystore $JAVA_HOME/lib/security/cacerts -storepass changeit mvn clean verify sonar:sonar -s ./settings.xml rm filefighter.de_ssl_certificate.cer - keytool -delete -alias filefighterde -keystore $JAVA_HOME/lib/security/cacerts -storepass ${{ secrets.STOREPASS }} + keytool -delete -alias filefighterde -keystore $JAVA_HOME/lib/security/cacerts -storepass changeit env: SONAR_LOGIN: ${{ secrets.SONAR_LOGIN }} SONAR_PASSWORD: ${{ secrets.SONAR_PASSWORD }} From 2d6bd99a0bd967a7924adfd81893f99b8296d635 Mon Sep 17 00:00:00 2001 From: qvalentin Date: Sat, 19 Dec 2020 17:57:48 +0100 Subject: [PATCH 33/50] debug --- .github/workflows/tests.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 0850ea6d..2c52cd42 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -28,6 +28,8 @@ jobs: - name: Run Tests and update Sonar (import cert first) run: | + whoami + echo $JAVA_HOME echo "${{ secrets.SSL_CERT }}" > filefighter.de_ssl_certificate.cer yes yes | keytool -import -alias filefighterde -file filefighter.de_ssl_certificate.cer -storetype JKS -keystore $JAVA_HOME/lib/security/cacerts -storepass changeit mvn clean verify sonar:sonar -s ./settings.xml From 56407414327dbb48657e59ef4c5a936d4376af31 Mon Sep 17 00:00:00 2001 From: qvalentin Date: Sat, 19 Dec 2020 18:02:12 +0100 Subject: [PATCH 34/50] remove debug --- .github/workflows/tests.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 2c52cd42..0850ea6d 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -28,8 +28,6 @@ jobs: - name: Run Tests and update Sonar (import cert first) run: | - whoami - echo $JAVA_HOME echo "${{ secrets.SSL_CERT }}" > filefighter.de_ssl_certificate.cer yes yes | keytool -import -alias filefighterde -file filefighter.de_ssl_certificate.cer -storetype JKS -keystore $JAVA_HOME/lib/security/cacerts -storepass changeit mvn clean verify sonar:sonar -s ./settings.xml From 62b0b4691b1f5abc2047f88b98fb1471413525cf Mon Sep 17 00:00:00 2001 From: qvalentin Date: Sat, 19 Dec 2020 18:16:37 +0100 Subject: [PATCH 35/50] added SONAR_SCANNER_OPTS --- .github/workflows/tests.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 0850ea6d..58633900 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -30,6 +30,7 @@ jobs: run: | echo "${{ secrets.SSL_CERT }}" > filefighter.de_ssl_certificate.cer yes yes | keytool -import -alias filefighterde -file filefighter.de_ssl_certificate.cer -storetype JKS -keystore $JAVA_HOME/lib/security/cacerts -storepass changeit + export SONAR_SCANNER_OPTS="-Djavax.net.ssl.trustStore=/opt/hostedtoolcache/jdk/11.0.8/x64/lib/security/cacerts -Djavax.net.ssl.keyStore=/opt/hostedtoolcache/jdk/11.0.8/x64/lib/security/cacerts" mvn clean verify sonar:sonar -s ./settings.xml rm filefighter.de_ssl_certificate.cer keytool -delete -alias filefighterde -keystore $JAVA_HOME/lib/security/cacerts -storepass changeit From 0247bcc309d78b78f7546104bdbe20bbb5e7bc1f Mon Sep 17 00:00:00 2001 From: qvalentin Date: Sat, 19 Dec 2020 18:18:03 +0100 Subject: [PATCH 36/50] ups wrong repo --- .github/workflows/tests.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 58633900..0850ea6d 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -30,7 +30,6 @@ jobs: run: | echo "${{ secrets.SSL_CERT }}" > filefighter.de_ssl_certificate.cer yes yes | keytool -import -alias filefighterde -file filefighter.de_ssl_certificate.cer -storetype JKS -keystore $JAVA_HOME/lib/security/cacerts -storepass changeit - export SONAR_SCANNER_OPTS="-Djavax.net.ssl.trustStore=/opt/hostedtoolcache/jdk/11.0.8/x64/lib/security/cacerts -Djavax.net.ssl.keyStore=/opt/hostedtoolcache/jdk/11.0.8/x64/lib/security/cacerts" mvn clean verify sonar:sonar -s ./settings.xml rm filefighter.de_ssl_certificate.cer keytool -delete -alias filefighterde -keystore $JAVA_HOME/lib/security/cacerts -storepass changeit From 259e6c2e87bbeba1f80177170a56ed237dfdad5e Mon Sep 17 00:00:00 2001 From: qvalentin Date: Sat, 19 Dec 2020 20:45:46 +0100 Subject: [PATCH 37/50] trying https --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 99fc8a12..f6387805 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ Backend REST API for FileFighter ![Docker Release](https://img.shields.io/github/v/release/filefighter/restapi?color=dark-green&label=Stable%20Version&logo=docker&style=for-the-badge) ![Docker Pulls](https://img.shields.io/docker/pulls/filefighter/rest?logo=docker&style=for-the-badge) [![Quality Gate Status](http://sonar.filefighter.de/api/project_badges/measure?project=de.filefighter%3Arest&metric=alert_status)](http://sonar.filefighter.de/dashboard?id=de.filefighter%3Arest) -[![Coverage](http://sonar.filefighter.de/api/project_badges/measure?project=de.filefighter%3Arest&metric=coverage)](http://sonar.filefighter.de/dashboard?id=de.filefighter%3Arest) +[![Coverage](https://sonar.filefighter.de/api/project_badges/measure?project=de.filefighter%3Arest&metric=coverage)](http://sonar.filefighter.de/dashboard?id=de.filefighter%3Arest) [![Lines of Code](http://sonar.filefighter.de/api/project_badges/measure?project=de.filefighter%3Arest&metric=ncloc)](http://sonar.filefighter.de/dashboard?id=de.filefighter%3Arest) [![Security Rating](http://sonar.filefighter.de/api/project_badges/measure?project=de.filefighter%3Arest&metric=security_rating)](http://sonar.filefighter.de/dashboard?id=de.filefighter%3Arest) ![Latest Release](https://github.com/FileFighter/RestApi/workflows/Latest%20Release/badge.svg) From f28cb5cd41a8807e35934151c77e046e4a8f2a69 Mon Sep 17 00:00:00 2001 From: qvalentin Date: Sat, 19 Dec 2020 20:48:09 +0100 Subject: [PATCH 38/50] everything https --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index f6387805..9dfd9e3a 100644 --- a/README.md +++ b/README.md @@ -2,10 +2,10 @@ Backend REST API for FileFighter ![Docker Release](https://img.shields.io/github/v/release/filefighter/restapi?color=dark-green&label=Stable%20Version&logo=docker&style=for-the-badge) ![Docker Pulls](https://img.shields.io/docker/pulls/filefighter/rest?logo=docker&style=for-the-badge) -[![Quality Gate Status](http://sonar.filefighter.de/api/project_badges/measure?project=de.filefighter%3Arest&metric=alert_status)](http://sonar.filefighter.de/dashboard?id=de.filefighter%3Arest) +[![Quality Gate Status](https://sonar.filefighter.de/api/project_badges/measure?project=de.filefighter%3Arest&metric=alert_status)](http://sonar.filefighter.de/dashboard?id=de.filefighter%3Arest) [![Coverage](https://sonar.filefighter.de/api/project_badges/measure?project=de.filefighter%3Arest&metric=coverage)](http://sonar.filefighter.de/dashboard?id=de.filefighter%3Arest) -[![Lines of Code](http://sonar.filefighter.de/api/project_badges/measure?project=de.filefighter%3Arest&metric=ncloc)](http://sonar.filefighter.de/dashboard?id=de.filefighter%3Arest) -[![Security Rating](http://sonar.filefighter.de/api/project_badges/measure?project=de.filefighter%3Arest&metric=security_rating)](http://sonar.filefighter.de/dashboard?id=de.filefighter%3Arest) +[![Lines of Code](https://sonar.filefighter.de/api/project_badges/measure?project=de.filefighter%3Arest&metric=ncloc)](http://sonar.filefighter.de/dashboard?id=de.filefighter%3Arest) +[![Security Rating](https://sonar.filefighter.de/api/project_badges/measure?project=de.filefighter%3Arest&metric=security_rating)](http://sonar.filefighter.de/dashboard?id=de.filefighter%3Arest) ![Latest Release](https://github.com/FileFighter/RestApi/workflows/Latest%20Release/badge.svg) ![Stable Release](https://github.com/FileFighter/RestApi/workflows/Stable%20Release/badge.svg) ![Tests](https://github.com/FileFighter/RestApi/workflows/Tests/badge.svg) From 2276a02aeef90319d3a8ab42ee12c1b6625700d2 Mon Sep 17 00:00:00 2001 From: qvalentin Date: Sat, 19 Dec 2020 20:53:14 +0100 Subject: [PATCH 39/50] made it use http for the links --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 9dfd9e3a..c9634ccf 100644 --- a/README.md +++ b/README.md @@ -2,10 +2,10 @@ Backend REST API for FileFighter ![Docker Release](https://img.shields.io/github/v/release/filefighter/restapi?color=dark-green&label=Stable%20Version&logo=docker&style=for-the-badge) ![Docker Pulls](https://img.shields.io/docker/pulls/filefighter/rest?logo=docker&style=for-the-badge) -[![Quality Gate Status](https://sonar.filefighter.de/api/project_badges/measure?project=de.filefighter%3Arest&metric=alert_status)](http://sonar.filefighter.de/dashboard?id=de.filefighter%3Arest) -[![Coverage](https://sonar.filefighter.de/api/project_badges/measure?project=de.filefighter%3Arest&metric=coverage)](http://sonar.filefighter.de/dashboard?id=de.filefighter%3Arest) -[![Lines of Code](https://sonar.filefighter.de/api/project_badges/measure?project=de.filefighter%3Arest&metric=ncloc)](http://sonar.filefighter.de/dashboard?id=de.filefighter%3Arest) -[![Security Rating](https://sonar.filefighter.de/api/project_badges/measure?project=de.filefighter%3Arest&metric=security_rating)](http://sonar.filefighter.de/dashboard?id=de.filefighter%3Arest) +[![Quality Gate Status](https://sonar.filefighter.de/api/project_badges/measure?project=de.filefighter%3Arest&metric=alert_status)](https://sonar.filefighter.de/dashboard?id=de.filefighter%3Arest) +[![Coverage](https://sonar.filefighter.de/api/project_badges/measure?project=de.filefighter%3Arest&metric=coverage)](https://sonar.filefighter.de/dashboard?id=de.filefighter%3Arest) +[![Lines of Code](https://sonar.filefighter.de/api/project_badges/measure?project=de.filefighter%3Arest&metric=ncloc)](https://sonar.filefighter.de/dashboard?id=de.filefighter%3Arest) +[![Security Rating](https://sonar.filefighter.de/api/project_badges/measure?project=de.filefighter%3Arest&metric=security_rating)](https://sonar.filefighter.de/dashboard?id=de.filefighter%3Arest) ![Latest Release](https://github.com/FileFighter/RestApi/workflows/Latest%20Release/badge.svg) ![Stable Release](https://github.com/FileFighter/RestApi/workflows/Stable%20Release/badge.svg) ![Tests](https://github.com/FileFighter/RestApi/workflows/Tests/badge.svg) From ef76b5285da841e99a5f3c5441adc58f38dfff89 Mon Sep 17 00:00:00 2001 From: qvalentin Date: Sat, 19 Dec 2020 21:00:53 +0100 Subject: [PATCH 40/50] added test image --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index c9634ccf..47f892f6 100644 --- a/README.md +++ b/README.md @@ -9,3 +9,6 @@ Backend REST API for FileFighter ![Latest Release](https://github.com/FileFighter/RestApi/workflows/Latest%20Release/badge.svg) ![Stable Release](https://github.com/FileFighter/RestApi/workflows/Stable%20Release/badge.svg) ![Tests](https://github.com/FileFighter/RestApi/workflows/Tests/badge.svg) + + +![Test](https://sonar.filefighter.de/images/logo.svg?v=6.6) From 5f0421a71e782f0f4876a5df7cb3599d628ed702 Mon Sep 17 00:00:00 2001 From: qvalentin Date: Sat, 19 Dec 2020 21:02:20 +0100 Subject: [PATCH 41/50] undo changes --- README.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/README.md b/README.md index 47f892f6..c9634ccf 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,3 @@ Backend REST API for FileFighter ![Latest Release](https://github.com/FileFighter/RestApi/workflows/Latest%20Release/badge.svg) ![Stable Release](https://github.com/FileFighter/RestApi/workflows/Stable%20Release/badge.svg) ![Tests](https://github.com/FileFighter/RestApi/workflows/Tests/badge.svg) - - -![Test](https://sonar.filefighter.de/images/logo.svg?v=6.6) From 8a2edbf0244411188a9341ac90e458c78a9a7d3b Mon Sep 17 00:00:00 2001 From: open-schnick Date: Sun, 20 Dec 2020 00:47:56 +0100 Subject: [PATCH 42/50] Refactored Steps and Feature File. --- .../rest/cucumber/CommonCucumberSteps.java | 20 +++- .../rest/cucumber/CrudPermissionSteps.java | 26 ++--- src/test/resources/ViewFolderContents.feature | 106 +++++++++--------- 3 files changed, 79 insertions(+), 73 deletions(-) diff --git a/src/test/java/de/filefighter/rest/cucumber/CommonCucumberSteps.java b/src/test/java/de/filefighter/rest/cucumber/CommonCucumberSteps.java index 575268c0..a656e78e 100644 --- a/src/test/java/de/filefighter/rest/cucumber/CommonCucumberSteps.java +++ b/src/test/java/de/filefighter/rest/cucumber/CommonCucumberSteps.java @@ -20,7 +20,6 @@ import org.springframework.data.mongodb.core.query.Update; import java.io.IOException; -import java.util.Arrays; import static org.junit.jupiter.api.Assertions.*; @@ -90,7 +89,19 @@ public void userWithIdIsInGroupWithId(long userId, long groupId) { mongoTemplate.findAndModify(query, newUpdate, UserEntity.class); } - // This step almost needs a unit test. + @And("fileSystemItem with the fileSystemId {long} exists and has the path {string}") + public void fileSystemItemWithTheFileSystemIdExistsAndHasThePath(long fileSystemId, String path) { + } + + @And("fileSystemItem with the fileSystemId {long} exists and has the name {string}") + public void fileSystemItemWithTheFileSystemIdExistsAndHasTheName(long fileSystemId, String name) { + } + + @And("fileSystemItem with the fileSystemId {long} is a folder and contains the fileSystemId {long}") + public void fileSystemItemWithTheFileSystemIdIsAFolderAndContainsTheFileSystemId(long fileSystemIdFolder, long fileSystemId) { + } + + /* This step almost needs a unit test. @Given("{string} exists with fileSystemId {long} and path {string}") public void fileOrFolderExistsWithIdAndPath(String fileOrFolder, long fsItemId, String path) { String[] names = path.split("/"); @@ -141,9 +152,9 @@ public void fileOrFolderExistsWithIdAndPath(String fileOrFolder, long fsItemId, } } } - } + }*/ - @And("user {long} is owner of file or folder with fileSystemId {long}") + @And("user with userId {long} is owner of file or folder with fileSystemId {long}") public void userIsOwnerOfFileOrFolderWithId(long userId, long fsItemId) { FileSystemEntity fileSystemEntity = fileSystemRepository.findByFileSystemId(fsItemId); @@ -188,4 +199,5 @@ public void responseContainsKeyAndADifferentValueThan(String key, String differe assertNotEquals(differentValue, actualValue); } + } diff --git a/src/test/java/de/filefighter/rest/cucumber/CrudPermissionSteps.java b/src/test/java/de/filefighter/rest/cucumber/CrudPermissionSteps.java index cb7c1f6a..c25b0179 100644 --- a/src/test/java/de/filefighter/rest/cucumber/CrudPermissionSteps.java +++ b/src/test/java/de/filefighter/rest/cucumber/CrudPermissionSteps.java @@ -2,32 +2,26 @@ import de.filefighter.rest.RestApplicationIntegrationTest; import io.cucumber.java.en.And; -import io.cucumber.java.en.When; public class CrudPermissionSteps extends RestApplicationIntegrationTest { - @And("user {long} has permission of {string} for {string} with fileSystemId {long}") - public void userHasPermissionOfForWithIdId(long userId, String readOrWrite, String fileOrFolder, long fsItemId) { - } + @And("group with the groupId {long} is allowed to VIEW the fileSystemItem with the fileSystemId {long}") + public void groupWithTheGroupIdIsAllowedToViewTheFileSystemItemWithTheFileSystemId(long groupId, long fileSystemId) { - @When("user with token {string} wants to change permissions of {string} with fileSystemId {long} for user with id {long} to {string}") - public void userWithTokenWantsToChangePermissionsOfWithIdIdForUserWithIdTo(String accessTokenValue, String fileOrFolder, long fsItemId, long userId, String newPermission) { } - @When("user with token {string} wants to remove permissions of {string} with fileSystemId {long} for user {long}") - public void userWithTokenWantsToRemovePermissionsOfWithIdIdForUser(String accessTokenValue, String fileOrFolder, long fsItemId, long userId) { - } + @And("group with the groupId {long} is allowed to EDIT the fileSystemItem with the fileSystemId {long}") + public void groupWithTheGroupIdIsAllowedToEditTheFileSystemItemWithTheFileSystemId(long groupId, long fileSystemId) { - @And("user with id {long} has no permission for {string} with fileSystemId {long}") - public void userWithIdHasNoPermissionForWithIdId(long userId, String fileOrFolder, long fsItemId) { } - @And("user {long} has no permission for {string} with fileSystemId {long}") - public void userHasNoPermissionForWithId(long userId, String fileOrFolder, long fsItemId) { - } + @And("user with the userId {long} is allowed to VIEW the fileSystemItem with the fileSystemId {long}") + public void userWithTheUserIdIsAllowedToViewTheFileSystemItemWithTheFileSystemId(long userId, long fileSystemId) { - @When("user with token {string} wants to give {string} permission for {string} with fileSystemId {long} to user {long}") - public void userWithTokenWantsToAddPermissionsOfWithIdForUserFor(String accessTokenValue, String permission, String fileOrFolder, long fsItemId, long userId) { } + @And("user with the userId {long} is allowed to EDIT the fileSystemItem with the fileSystemId {long}") + public void userWithTheUserIdIsAllowedToEditTheFileSystemItemWithTheFileSystemId(long userId, long fileSystemId) { + + } } diff --git a/src/test/resources/ViewFolderContents.feature b/src/test/resources/ViewFolderContents.feature index 00a260c8..d4a5cbbf 100644 --- a/src/test/resources/ViewFolderContents.feature +++ b/src/test/resources/ViewFolderContents.feature @@ -1,53 +1,53 @@ -#Feature: View Folder -# As a user -# I want to see the content of folders and navigate in them, so they can see and interact with their uploaded and shared files. -# -#Background: -# Given database is empty -# And user 1234 exists -# And accessToken with value "900000" exists for user 1234 -# And "folder" exists with fileSystemId 42 and path "bla" -# And "file" exists with fileSystemId 72 and path "bla/wow.txt" -# -# -#Scenario: Successful interaction -# Given user 1234 has permission of "view" for "folder" with fileSystemId 42 -# And user 1234 has permission of "view" for "file" with fileSystemId 72 -# When user with token "900000" 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: Folder does not exist -# Given user 1234 has permission of "view" for "folder" with fileSystemId 42 -# When user with token "900000" wants to see the content of folder with path "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" -# 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 file -# Given "folder" exists with fileSystemId 43 and path "bla" -# And "file" exists with fileSystemId 73 and path "bla/wow.txt" -# And user 1234 is owner of file or folder with fileSystemId 42 -# And user 1234 is owner of file or folder with fileSystemId 72 -# And user 1234 has permission of "view" for "folder" with fileSystemId 43 -# And user 1234 has permission of "view" for "file" with fileSystemId 73 -# When user with token "900000" 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" -# And the response contains the file with fileSystemId 73 and name "wow.txt" -# -#Scenario: empty directory -# Given "folder" exists with fileSystemId 44 and path "empty" -# And user 1234 has permission of "view" for "folder" with fileSystemId 44 -# When user with token "900000" wants to see the content of folder with path "empty" -# Then response status code is 200 -# And the response contains an empty list for files and folders \ No newline at end of file +Feature: View Folder + As a user + I want to see the content of folders and navigate in them, so they can see and interact with their uploaded and shared files. + + Background: + Given database is empty + And user 1234 exists + And accessToken with value "900000" exists for user 1234 + And fileSystemItem with the fileSystemId 42 exists and has the path "/bla" + And fileSystemItem with the fileSystemId 72 exists and has the 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" + 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" + 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 + And response contains key "message" and value "Folder does not exist, or you are not allowed to see the folder." + + Scenario: shared folder + 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 73 + 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 + 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 73 + 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: empty directory + Given fileSystemItem with the fileSystemId 44 exists and has the path "/empty" + 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" + Then response status code is 200 + And the response contains an empty list for files and folders \ No newline at end of file From 3645bbf8acd7872e02a9e5ec65b7780a6bdf0855 Mon Sep 17 00:00:00 2001 From: qvalentin Date: Sun, 20 Dec 2020 09:50:12 +0100 Subject: [PATCH 43/50] no https for badges images --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index c9634ccf..93cd6a58 100644 --- a/README.md +++ b/README.md @@ -2,10 +2,10 @@ Backend REST API for FileFighter ![Docker Release](https://img.shields.io/github/v/release/filefighter/restapi?color=dark-green&label=Stable%20Version&logo=docker&style=for-the-badge) ![Docker Pulls](https://img.shields.io/docker/pulls/filefighter/rest?logo=docker&style=for-the-badge) -[![Quality Gate Status](https://sonar.filefighter.de/api/project_badges/measure?project=de.filefighter%3Arest&metric=alert_status)](https://sonar.filefighter.de/dashboard?id=de.filefighter%3Arest) -[![Coverage](https://sonar.filefighter.de/api/project_badges/measure?project=de.filefighter%3Arest&metric=coverage)](https://sonar.filefighter.de/dashboard?id=de.filefighter%3Arest) -[![Lines of Code](https://sonar.filefighter.de/api/project_badges/measure?project=de.filefighter%3Arest&metric=ncloc)](https://sonar.filefighter.de/dashboard?id=de.filefighter%3Arest) -[![Security Rating](https://sonar.filefighter.de/api/project_badges/measure?project=de.filefighter%3Arest&metric=security_rating)](https://sonar.filefighter.de/dashboard?id=de.filefighter%3Arest) +[![Quality Gate Status](http://sonar.filefighter.de/api/project_badges/measure?project=de.filefighter%3Arest&metric=alert_status)](https://sonar.filefighter.de/dashboard?id=de.filefighter%3Arest) +[![Coverage](http://sonar.filefighter.de/api/project_badges/measure?project=de.filefighter%3Arest&metric=coverage)](https://sonar.filefighter.de/dashboard?id=de.filefighter%3Arest) +[![Lines of Code](http://sonar.filefighter.de/api/project_badges/measure?project=de.filefighter%3Arest&metric=ncloc)](https://sonar.filefighter.de/dashboard?id=de.filefighter%3Arest) +[![Security Rating](http://sonar.filefighter.de/api/project_badges/measure?project=de.filefighter%3Arest&metric=security_rating)](https://sonar.filefighter.de/dashboard?id=de.filefighter%3Arest) ![Latest Release](https://github.com/FileFighter/RestApi/workflows/Latest%20Release/badge.svg) ![Stable Release](https://github.com/FileFighter/RestApi/workflows/Stable%20Release/badge.svg) ![Tests](https://github.com/FileFighter/RestApi/workflows/Tests/badge.svg) From cf2981fb335780935df137e065b1d4811539a553 Mon Sep 17 00:00:00 2001 From: open-schnick Date: Sun, 20 Dec 2020 14:22:20 +0100 Subject: [PATCH 44/50] Added same scenario but with groups --- src/test/resources/ViewFolderContents.feature | 23 +++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/src/test/resources/ViewFolderContents.feature b/src/test/resources/ViewFolderContents.feature index d4a5cbbf..c9fa3671 100644 --- a/src/test/resources/ViewFolderContents.feature +++ b/src/test/resources/ViewFolderContents.feature @@ -28,7 +28,7 @@ Feature: View Folder And accessToken with value "2345678" exists for user 9877 And response contains key "message" and value "Folder does not exist, or you are not allowed to see the folder." - Scenario: shared 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 73 @@ -36,7 +36,7 @@ Feature: View Folder Then response status code is 200 And the response contains an empty list for files and folders - Scenario: shared folder and file + 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 73 @@ -45,6 +45,25 @@ Feature: View Folder 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 group with the groupId 1 is allowed to VIEW the fileSystemItem with the fileSystemId 73 + 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 73 + 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 the file with fileSystemId 72 and name "wow.txt" + Scenario: empty directory Given fileSystemItem with the fileSystemId 44 exists and has the path "/empty" And user with the userId 1234 is allowed to VIEW the fileSystemItem with the fileSystemId 44 From 5667bb32f7155c6976006aefc6a4854a2c846416 Mon Sep 17 00:00:00 2001 From: open-schnick Date: Sun, 20 Dec 2020 16:05:58 +0100 Subject: [PATCH 45/50] Added Steps, Fixed the feature. --- .../rest/cucumber/CommonCucumberSteps.java | 82 +++++-------------- .../rest/cucumber/CrudPermissionSteps.java | 25 ++++++ .../cucumber/ViewFolderContentsSteps.java | 45 +++++++++- src/test/resources/ViewFolderContents.feature | 17 ++-- 4 files changed, 99 insertions(+), 70 deletions(-) diff --git a/src/test/java/de/filefighter/rest/cucumber/CommonCucumberSteps.java b/src/test/java/de/filefighter/rest/cucumber/CommonCucumberSteps.java index a656e78e..78583eb8 100644 --- a/src/test/java/de/filefighter/rest/cucumber/CommonCucumberSteps.java +++ b/src/test/java/de/filefighter/rest/cucumber/CommonCucumberSteps.java @@ -31,6 +31,9 @@ public class CommonCucumberSteps extends RestApplicationIntegrationTest { private final FileSystemRepository fileSystemRepository; private final ObjectMapper objectMapper; + @Autowired + MongoTemplate mongoTemplate; + @Autowired public CommonCucumberSteps(UserRepository userRepository, AccessTokenRepository accessTokenRepository, FileSystemRepository fileSystemRepository) { this.userRepository = userRepository; @@ -77,9 +80,6 @@ public void userWithIdExistsAndHasUsernamePassword(long userId, String username, .build())); } - @Autowired - MongoTemplate mongoTemplate; - @And("user with userId {long} is in group with groupId {long}") public void userWithIdIsInGroupWithId(long userId, long groupId) { Query query = new Query(); @@ -89,70 +89,32 @@ public void userWithIdIsInGroupWithId(long userId, long groupId) { mongoTemplate.findAndModify(query, newUpdate, UserEntity.class); } - @And("fileSystemItem with the fileSystemId {long} exists and has the path {string}") - public void fileSystemItemWithTheFileSystemIdExistsAndHasThePath(long fileSystemId, String path) { + @And("fileSystemItem with the fileSystemId {long} exists, was created by user with userId {long} and has the path {string}") + public void fileSystemItemWithTheFileSystemIdExistsAndHasThePath(long fileSystemId, long userId, String path) { + fileSystemRepository.save(FileSystemEntity.builder() + .path(path) + .createdByUserId(userId) + .fileSystemId(fileSystemId) + .build()); } - @And("fileSystemItem with the fileSystemId {long} exists and has the name {string}") - public void fileSystemItemWithTheFileSystemIdExistsAndHasTheName(long fileSystemId, String name) { + @And("fileSystemItem with the fileSystemId {long} exists, was created by user with userId {long} and has the name {string}") + public void fileSystemItemWithTheFileSystemIdExistsAndHasTheName(long fileSystemId, long userId, String name) { + fileSystemRepository.save(FileSystemEntity.builder() + .name(name) + .createdByUserId(userId) + .fileSystemId(fileSystemId) + .build()); } @And("fileSystemItem with the fileSystemId {long} is a folder and contains the fileSystemId {long}") public void fileSystemItemWithTheFileSystemIdIsAFolderAndContainsTheFileSystemId(long fileSystemIdFolder, long fileSystemId) { - } - - /* This step almost needs a unit test. - @Given("{string} exists with fileSystemId {long} and path {string}") - public void fileOrFolderExistsWithIdAndPath(String fileOrFolder, long fsItemId, String path) { - String[] names = path.split("/"); - StringBuilder completeFilePath = new StringBuilder("/"); - - System.out.println(Arrays.toString(names)); - - // build root dir. - fileSystemRepository.save(FileSystemEntity - .builder() - .isFile(false) - .path(completeFilePath.toString()) - .build()); - + Query query = new Query(); + Update newUpdate = new Update().set("itemIds", new long[]{fileSystemId}); + query.addCriteria(Criteria.where("fileSystemId").is(fileSystemIdFolder)); - // build all files and folders. - for (int i = 0; i < names.length; i++) { - if (!names[i].isEmpty() && !names[i].isBlank()) { - boolean isLastOne = i == names.length - 1; - if (!isLastOne) { - //is obviously a folder. - completeFilePath.append(names[i]).append("/"); - fileSystemRepository.save(FileSystemEntity - .builder() - .isFile(false) - .path(completeFilePath.toString()) - .build()); - System.out.println("folder: " + completeFilePath.toString()); - } else { - System.out.println("last one: " + names[i]); - if (fileOrFolder.equals("file")) { - fileSystemRepository.save(FileSystemEntity - .builder() - .isFile(true) - .fileSystemId(fsItemId) - .build()); - } else if (fileOrFolder.equals("folder")) { - completeFilePath.append(names[i]).append("/"); - fileSystemRepository.save(FileSystemEntity - .builder() - .isFile(false) - .fileSystemId(fsItemId) - .path(completeFilePath.toString()) - .build()); - } else { - throw new IllegalArgumentException("Found not valid string for FileOrFolder in Steps file."); - } - } - } - } - }*/ + mongoTemplate.findAndModify(query, newUpdate, FileSystemEntity.class); + } @And("user with userId {long} is owner of file or folder with fileSystemId {long}") public void userIsOwnerOfFileOrFolderWithId(long userId, long fsItemId) { diff --git a/src/test/java/de/filefighter/rest/cucumber/CrudPermissionSteps.java b/src/test/java/de/filefighter/rest/cucumber/CrudPermissionSteps.java index c25b0179..9dafbdce 100644 --- a/src/test/java/de/filefighter/rest/cucumber/CrudPermissionSteps.java +++ b/src/test/java/de/filefighter/rest/cucumber/CrudPermissionSteps.java @@ -1,27 +1,52 @@ package de.filefighter.rest.cucumber; import de.filefighter.rest.RestApplicationIntegrationTest; +import de.filefighter.rest.domain.filesystem.data.persistence.FileSystemEntity; import io.cucumber.java.en.And; +import org.springframework.beans.factory.annotation.Autowired; +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; public class CrudPermissionSteps extends RestApplicationIntegrationTest { + @Autowired + MongoTemplate mongoTemplate; + @And("group with the groupId {long} is allowed to VIEW the fileSystemItem with the fileSystemId {long}") public void groupWithTheGroupIdIsAllowedToViewTheFileSystemItemWithTheFileSystemId(long groupId, long fileSystemId) { + Query query = new Query(); + Update newUpdate = new Update().set("visibleForGroupIds", new long[]{groupId}); + query.addCriteria(Criteria.where("fileSystemId").is(fileSystemId)); + mongoTemplate.findAndModify(query, newUpdate, FileSystemEntity.class); } @And("group with the groupId {long} is allowed to EDIT the fileSystemItem with the fileSystemId {long}") public void groupWithTheGroupIdIsAllowedToEditTheFileSystemItemWithTheFileSystemId(long groupId, long fileSystemId) { + Query query = new Query(); + Update newUpdate = new Update().set("editableForGroupIds", new long[]{groupId}); + query.addCriteria(Criteria.where("fileSystemId").is(fileSystemId)); + mongoTemplate.findAndModify(query, newUpdate, FileSystemEntity.class); } @And("user with the userId {long} is allowed to VIEW the fileSystemItem with the fileSystemId {long}") public void userWithTheUserIdIsAllowedToViewTheFileSystemItemWithTheFileSystemId(long userId, long fileSystemId) { + Query query = new Query(); + Update newUpdate = new Update().set("visibleForUserIds", new long[]{userId}); + query.addCriteria(Criteria.where("fileSystemId").is(fileSystemId)); + mongoTemplate.findAndModify(query, newUpdate, FileSystemEntity.class); } @And("user with the userId {long} is allowed to EDIT the fileSystemItem with the fileSystemId {long}") public void userWithTheUserIdIsAllowedToEditTheFileSystemItemWithTheFileSystemId(long userId, long fileSystemId) { + Query query = new Query(); + Update newUpdate = new Update().set("editableForUserIds", new long[]{userId}); + query.addCriteria(Criteria.where("fileSystemId").is(fileSystemId)); + mongoTemplate.findAndModify(query, newUpdate, FileSystemEntity.class); } } diff --git a/src/test/java/de/filefighter/rest/cucumber/ViewFolderContentsSteps.java b/src/test/java/de/filefighter/rest/cucumber/ViewFolderContentsSteps.java index decd45d2..9b3983b0 100644 --- a/src/test/java/de/filefighter/rest/cucumber/ViewFolderContentsSteps.java +++ b/src/test/java/de/filefighter/rest/cucumber/ViewFolderContentsSteps.java @@ -1,20 +1,61 @@ package de.filefighter.rest.cucumber; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ArrayNode; import de.filefighter.rest.RestApplicationIntegrationTest; import io.cucumber.java.en.And; import io.cucumber.java.en.When; +import org.springframework.http.HttpMethod; + +import java.util.HashMap; + +import static de.filefighter.rest.configuration.RestConfiguration.*; +import static org.junit.Assert.assertTrue; public class ViewFolderContentsSteps extends RestApplicationIntegrationTest { + private final ObjectMapper objectMapper; + + public ViewFolderContentsSteps(ObjectMapper objectMapper) { + this.objectMapper = objectMapper; + } + @When("user with token {string} wants to see the content of folder with path {string}") public void userWithTokenWantsToSeeTheContentOfFolderWithPath(String accessTokenValue, String path) { + String authHeaderString = AUTHORIZATION_BEARER_PREFIX + accessTokenValue; + String url = BASE_API_URI + FS_BASE_URI + "contents"; + + HashMap header = new HashMap<>(); + header.put("Authorization", authHeaderString); + header.put(FS_PATH_HEADER, path); + + executeRestApiCall(HttpMethod.GET, url, header); } @And("the response contains the file with fileSystemId {long} and name {string}") - public void theResponseContainsTheFileWithIdAndName(long fsItemId , String name) { + public void theResponseContainsTheFileWithIdAndName(long fsItemId, 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("fileSystemId").asLong() == fsItemId && + node.get("name").asText().equals(name) && + node.get("type").asText().equals("FOLDER")) + found = true; + } + assertTrue(found); } @And("the response contains an empty list for files and folders") - public void theResponseContainsAnEmptyListForFilesAndFolders() { + public void theResponseContainsAnEmptyListForFilesAndFolders() throws JsonProcessingException { + ArrayNode rootNode = (ArrayNode) objectMapper.readTree(latestResponse.getBody()); + if (!rootNode.isContainerNode()) + throw new AssertionError("Response was not an Array or empty."); + + assertTrue(rootNode.isEmpty()); } } diff --git a/src/test/resources/ViewFolderContents.feature b/src/test/resources/ViewFolderContents.feature index c9fa3671..9dbe5956 100644 --- a/src/test/resources/ViewFolderContents.feature +++ b/src/test/resources/ViewFolderContents.feature @@ -5,9 +5,10 @@ Feature: View Folder Background: Given database is empty And user 1234 exists + And user 420 exists And accessToken with value "900000" exists for user 1234 - And fileSystemItem with the fileSystemId 42 exists and has the path "/bla" - And fileSystemItem with the fileSystemId 72 exists and has the name "wow.txt" + And fileSystemItem with the fileSystemId 42 exists, was created by user with userId 420 and has the path "/bla" + 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 42 is a folder and contains the fileSystemId 72 Scenario: Successful interaction @@ -31,7 +32,7 @@ Feature: View 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 73 + 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 @@ -39,7 +40,7 @@ Feature: View Folder 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 73 + 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 @@ -49,7 +50,7 @@ Feature: View Folder 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 73 + 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 @@ -58,15 +59,15 @@ Feature: View Folder 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 73 + 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" 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 and has the path "/empty" + Given fileSystemItem with the fileSystemId 44 exists, was created by user with userId 420 and has the path "/empty" 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 "/empty" Then response status code is 200 And the response contains an empty list for files and folders \ No newline at end of file From f0e9733852957d3a1d62a33132189758423fde8a Mon Sep 17 00:00:00 2001 From: open-schnick Date: Sun, 20 Dec 2020 16:06:12 +0100 Subject: [PATCH 46/50] Small fixes. --- .../filesystem/business/FileSystemBusinessService.java | 8 ++++---- .../filesystem/data/persistence/FileSystemEntity.java | 3 ++- 2 files changed, 6 insertions(+), 5 deletions(-) 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 67125399..cf8fc3c7 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 @@ -77,7 +77,7 @@ public List getFolderContentsOfEntities(List l throw new FileFighterDataException("FolderContents expected fileSystemItem with id " + fileSystemId + " but was empty."); if (userIsAllowedToSeeFileSystemEntity(fileSystemEntityInFolder, authenticatedUser)) { - String pathWithTrailingSlash = pathToFind.equals("/") ? pathToFind : pathToFind + "/"; //NOSONAR + String pathWithTrailingSlash = pathToFind.equals("/") ? pathToFind : (pathToFind + "/"); //NOSONAR fileSystemItems.add(this.createDTO(fileSystemEntityInFolder, authenticatedUser, pathWithTrailingSlash)); } } @@ -121,10 +121,10 @@ public boolean userIsAllowedToSeeFileSystemEntity(FileSystemEntity fileSystemEnt public FileSystemItem createDTO(FileSystemEntity fileSystemEntity, User authenticatedUser, String basePath) { User ownerOfFileSystemItem = userBusinessService.getUserById(fileSystemEntity.getCreatedByUserId()); - if (null == ownerOfFileSystemItem) - throw new FileFighterDataException("Owner of File/Folder does not exist."); boolean isShared = ownerOfFileSystemItem.getUserId() != authenticatedUser.getUserId(); + FileSystemType type = fileSystemTypeRepository.findFileSystemTypeById(fileSystemEntity.getTypeId()); + boolean isAFolder = type == FileSystemType.FOLDER && !fileSystemEntity.isFile(); return FileSystemItem.builder() .createdByUserId(fileSystemEntity.getCreatedByUserId()) @@ -132,7 +132,7 @@ public FileSystemItem createDTO(FileSystemEntity fileSystemEntity, User authenti .lastUpdated(fileSystemEntity.getLastUpdated()) .name(fileSystemEntity.getName()) .size(fileSystemEntity.getSize()) - .type(fileSystemTypeRepository.findFileSystemTypeById(fileSystemEntity.getTypeId())) + .type(isAFolder ? FileSystemType.FOLDER : type) .path(basePath + fileSystemEntity.getName()) .isShared(isShared) .build(); 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 67297e17..2449e812 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 @@ -19,7 +19,8 @@ public class FileSystemEntity { private long typeId; private double size; private boolean isFile; - private long createdByUserId; //uploadedBy + @Builder.Default + private long createdByUserId = -1; //uploadedBy private long lastUpdated; @Builder.Default private long[] visibleForGroupIds = new long[0]; From 47e3dee0a01a1fda1f73aa68c6b416e864239704 Mon Sep 17 00:00:00 2001 From: open-schnick Date: Sun, 20 Dec 2020 16:18:13 +0100 Subject: [PATCH 47/50] Fixed Tests --- .../rest/cucumber/ViewFolderContentsSteps.java | 2 ++ .../FileSystemBusinessServiceUnitTest.java | 17 ++--------------- 2 files changed, 4 insertions(+), 15 deletions(-) diff --git a/src/test/java/de/filefighter/rest/cucumber/ViewFolderContentsSteps.java b/src/test/java/de/filefighter/rest/cucumber/ViewFolderContentsSteps.java index 9b3983b0..6d24c1e6 100644 --- a/src/test/java/de/filefighter/rest/cucumber/ViewFolderContentsSteps.java +++ b/src/test/java/de/filefighter/rest/cucumber/ViewFolderContentsSteps.java @@ -7,6 +7,7 @@ import de.filefighter.rest.RestApplicationIntegrationTest; import io.cucumber.java.en.And; import io.cucumber.java.en.When; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpMethod; import java.util.HashMap; @@ -18,6 +19,7 @@ public class ViewFolderContentsSteps extends RestApplicationIntegrationTest { private final ObjectMapper objectMapper; + @Autowired public ViewFolderContentsSteps(ObjectMapper objectMapper) { this.objectMapper = objectMapper; } 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 9d32165c..665347ab 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 @@ -156,24 +156,11 @@ void userIsAllowedToSeeFileSystemEntity() { assertTrue(fileSystemBusinessService.userIsAllowedToSeeFileSystemEntity(fileSystemEntity, user)); // user is not allowed. - user = User.builder().groups(new Groups[]{Groups.UNDEFINED}).build(); - fileSystemEntity = FileSystemEntity.builder().visibleForGroupIds(new long[]{1}).build(); + user = User.builder().userId(123).groups(new Groups[]{Groups.UNDEFINED}).build(); + fileSystemEntity = FileSystemEntity.builder().createdByUserId(321).visibleForGroupIds(new long[]{1}).build(); assertFalse(fileSystemBusinessService.userIsAllowedToSeeFileSystemEntity(fileSystemEntity, user)); } - @Test - void createDTOThrows() { - long userId = 420L; - FileSystemEntity fileSystemEntity = FileSystemEntity.builder().createdByUserId(userId).build(); - - when(userBusinessService.getUserById(userId)).thenReturn(null); - - FileFighterDataException ex = assertThrows(FileFighterDataException.class, () -> - fileSystemBusinessService.createDTO(fileSystemEntity, null, "/")); - - assertEquals("Internal Error occurred. Owner of File/Folder does not exist.", ex.getMessage()); - } - @Test void createDTOWorks() { long createdByUserId = 420L; From 9f35a6d57a928615ae8a8b4ec36fe1802d12464d Mon Sep 17 00:00:00 2001 From: open-schnick Date: Sun, 20 Dec 2020 16:18:35 +0100 Subject: [PATCH 48/50] Bumped Up Version to -> 0.0.6 --- pom.xml | 4 +--- src/main/resources/application.properties | 4 ++-- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/pom.xml b/pom.xml index ad458098..a6b32ea8 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ de.filefighter rest - 0.0.5 + 0.0.6 RestApi RestApi for FileFighter @@ -180,10 +180,8 @@ - *FileSystemRestService *PermissionRestService - *FileSystemBusinessService diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 0621d1b6..3ba536ef 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -7,6 +7,6 @@ spring.data.mongodb.database=filefighter spring.data.mongodb.host=localhost spring.data.mongodb.port=27017 #-------------------Custom------------------ -filefighter.version=0.0.5 -filefighter.date=21.11.2020 +filefighter.version=0.0.6 +filefighter.date=20.12.2020 filefighter.disable-password-check=false From c2983c0a8553a45baec552c026cabaf6e5599f32 Mon Sep 17 00:00:00 2001 From: qvalentin Date: Mon, 21 Dec 2020 10:36:03 +0100 Subject: [PATCH 49/50] added .run to gitingore --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 549e00a2..579bf3e9 100644 --- a/.gitignore +++ b/.gitignore @@ -31,3 +31,5 @@ build/ ### VS Code ### .vscode/ + +.run/ From a8c7dbec48e214fa7e2f663a7aed62f86b68c068 Mon Sep 17 00:00:00 2001 From: open-schnick Date: Mon, 21 Dec 2020 16:36:36 +0100 Subject: [PATCH 50/50] Revert Changes, set default profile to "test" while running tests, added stage spring profile --- .gitignore | 4 +--- .../java/de/filefighter/rest/configuration/CorsConfig.java | 3 +-- .../de/filefighter/rest/cucumber/CucumberIntegrationTest.java | 4 ++-- 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/.gitignore b/.gitignore index 579bf3e9..5eac309e 100644 --- a/.gitignore +++ b/.gitignore @@ -30,6 +30,4 @@ build/ !**/src/test/**/build/ ### VS Code ### -.vscode/ - -.run/ +.vscode/ \ 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 bb571f4a..7b79d99e 100644 --- a/src/main/java/de/filefighter/rest/configuration/CorsConfig.java +++ b/src/main/java/de/filefighter/rest/configuration/CorsConfig.java @@ -12,9 +12,8 @@ @Configuration public class CorsConfig { - // Cors again. For local testing only. @Bean - @Profile("dev") + @Profile({"dev","stage"}) public CorsFilter corsFilter() { final CorsConfiguration config = new CorsConfiguration().applyPermitDefaultValues(); ArrayList allowedOrigins = new ArrayList<>(); diff --git a/src/test/java/de/filefighter/rest/cucumber/CucumberIntegrationTest.java b/src/test/java/de/filefighter/rest/cucumber/CucumberIntegrationTest.java index 63b94ed5..2b215509 100644 --- a/src/test/java/de/filefighter/rest/cucumber/CucumberIntegrationTest.java +++ b/src/test/java/de/filefighter/rest/cucumber/CucumberIntegrationTest.java @@ -1,16 +1,16 @@ package de.filefighter.rest.cucumber; -import de.filefighter.rest.RestApplicationIntegrationTest; import io.cucumber.junit.Cucumber; import io.cucumber.junit.CucumberOptions; import io.cucumber.spring.CucumberContextConfiguration; import org.junit.runner.RunWith; import org.springframework.boot.test.context.SpringBootTest; - +import org.springframework.test.context.ActiveProfiles; @RunWith(Cucumber.class) @CucumberOptions(features = "src/test/resources") @CucumberContextConfiguration +@ActiveProfiles("test") @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) public class CucumberIntegrationTest { } \ No newline at end of file