diff --git a/SECURITY.WHITEPAPER.md b/SECURITY.WHITEPAPER.md index 81b319f6d..4de1f62d1 100644 --- a/SECURITY.WHITEPAPER.md +++ b/SECURITY.WHITEPAPER.md @@ -23,6 +23,59 @@ CMS Encryption: * [RSAES-PKCS1-v1_5](#RSAES-PKCS1-v1_5) - key derivation algorithm for shared files (use public key); * [SHA256withRSA](#SHA256withRSA) - for public keys. +## ECC Update + +With the latest release, Datasafe has transitioned from RSA to Elliptic Curve Cryptography (ECC) to enhance security and performance. This section details the new ECC implementation: + +#### Encryption and Signing + +- **Encryption Algorithm**: ECDH (Elliptic Curve Diffie-Hellman) with curve `secp256r1`. +- **Signing Algorithm**: SHA256withECDSA (Elliptic Curve Digital Signature Algorithm) with curve `secp256r1`. + +#### Benefits of ECC + +- **Security**: ECC offers stronger security per bit compared to RSA, making it more resistant to cryptographic attacks. +- **Performance**: ECC algorithms generally require less computational power and are faster. +- **Key Size**: ECC achieves comparable security to RSA with much smaller key sizes (256 bits for ECC vs. 2048 bits for RSA), resulting in reduced storage and transmission requirements. + +#### Implementation Details +
+Dynamically choosing between RSA and ECC + +```java +private RecipientInfoGenerator getRecipientInfoGenerator(PublicKeyIDWithPublicKey keyWithId, KeyPair senderKeyPair) { + if ("RSA".equals(keyWithId.getPublicKey().getAlgorithm())) { + return new JceKeyTransRecipientInfoGenerator(keyWithId.getKeyID().getValue().getBytes(), keyWithId.getPublicKey()); + } + if (Set.of("ECDH", "EC").contains(keyWithId.getPublicKey().getAlgorithm())) { + return getJceKeyAgreeRecipientInfoGenerator(senderKeyPair, keyWithId); + } + return null; +} +``` +in the updated implementation, the getRecipientInfoGenerator method dynamically chooses between RSA and ECC based on the algorithm associated with the public key. For ECC, it uses ECDH for encryption and SHA256withECDSA for signing. + +
+ +## Release Notes + +##### ECC Integration + +#### Added +- **Elliptic Curve Cryptography (ECC)**: + - Implemented ECC for improved security and performance. + - Encryption Algorithm: ECDH (Elliptic Curve Diffie-Hellman) with curve `secp256r1`. + - Signing Algorithm: SHA256withECDSA (Elliptic Curve Digital Signature Algorithm) with curve `secp256r1`. + +#### Changed +- **Encryption and Signing**: + - Transitioned from RSA to ECC, enhancing security and reducing key sizes. + +#### Improved +- **Security**: + - ECC offers stronger security per bit compared to RSA. +- **Key Size Reduction**: + - ECC achieves comparable security to RSA with much smaller key sizes, reducing storage and transmission requirements. ## General information Datasafe is a flexible encryption library. It uses different encryption algorithms. They can be configured by client application. Under the hood Datasafe uses BouncyCastle library to perform encryption. diff --git a/datasafe-examples/datasafe-examples-multidfs/pom.xml b/datasafe-examples/datasafe-examples-multidfs/pom.xml index 6bf92ae34..080424400 100644 --- a/datasafe-examples/datasafe-examples-multidfs/pom.xml +++ b/datasafe-examples/datasafe-examples-multidfs/pom.xml @@ -27,6 +27,18 @@ testcontainers test + + com.fasterxml.jackson.core + jackson-annotations + ${jackson.version} + test + + + com.fasterxml.jackson.core + jackson-databind + ${jackson.version} + test + org.junit.jupiter junit-jupiter-api diff --git a/datasafe-examples/datasafe-examples-versioned-s3/pom.xml b/datasafe-examples/datasafe-examples-versioned-s3/pom.xml index a9944fdbb..1a4322bf1 100644 --- a/datasafe-examples/datasafe-examples-versioned-s3/pom.xml +++ b/datasafe-examples/datasafe-examples-versioned-s3/pom.xml @@ -27,6 +27,18 @@ testcontainers test + + com.fasterxml.jackson.core + jackson-annotations + ${jackson.version} + test + + + com.fasterxml.jackson.core + jackson-databind + ${jackson.version} + test + org.junit.jupiter junit-jupiter-api diff --git a/datasafe-rest-impl/pom.xml b/datasafe-rest-impl/pom.xml index 6b181cf12..9fef3c6e9 100644 --- a/datasafe-rest-impl/pom.xml +++ b/datasafe-rest-impl/pom.xml @@ -13,14 +13,14 @@ Spring Boot DataSafe Application - 3.1.2 + 3.3.1 2.9.2 0.12.4 3.0.0 2.2.4 1.6.0 - 3.0.2 2.3.0 + true @@ -82,12 +82,12 @@ ${spring-boot.version} true - - jakarta.validation - jakarta.validation-api - ${jakarta.validation-api.version} + org.springframework.boot + spring-boot-starter-validation + ${spring-boot.version} + io.jsonwebtoken jjwt-api @@ -103,6 +103,12 @@ io.jsonwebtoken jjwt-jackson ${jjwt.version} + + + com.fasterxml.jackson.core + jackson-databind + + runtime diff --git a/datasafe-rest-impl/src/main/java/de/adorsys/datasafe/rest/impl/DatasafeRestApplication.java b/datasafe-rest-impl/src/main/java/de/adorsys/datasafe/rest/impl/DatasafeRestApplication.java index bdb527dc8..3212355da 100644 --- a/datasafe-rest-impl/src/main/java/de/adorsys/datasafe/rest/impl/DatasafeRestApplication.java +++ b/datasafe-rest-impl/src/main/java/de/adorsys/datasafe/rest/impl/DatasafeRestApplication.java @@ -3,10 +3,9 @@ import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; -import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration; import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration; -@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class, DataSourceTransactionManagerAutoConfiguration.class, HibernateJpaAutoConfiguration.class}) +@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class, HibernateJpaAutoConfiguration.class}) public class DatasafeRestApplication { public static void main(String[] args) { diff --git a/datasafe-rest-impl/src/main/java/de/adorsys/datasafe/rest/impl/config/MvcConfig.java b/datasafe-rest-impl/src/main/java/de/adorsys/datasafe/rest/impl/config/MvcConfig.java index a0696d97a..c88c09d56 100644 --- a/datasafe-rest-impl/src/main/java/de/adorsys/datasafe/rest/impl/config/MvcConfig.java +++ b/datasafe-rest-impl/src/main/java/de/adorsys/datasafe/rest/impl/config/MvcConfig.java @@ -6,12 +6,12 @@ import org.springframework.lang.NonNull; import org.springframework.util.StringUtils; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; -import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Slf4j @Configuration @RequiredArgsConstructor -public class MvcConfig extends WebMvcConfigurationSupport { +public class MvcConfig implements WebMvcConfigurer { private final DatasafeProperties datasafeProperties; diff --git a/datasafe-rest-impl/src/main/java/de/adorsys/datasafe/rest/impl/controller/AuthenticateController.java b/datasafe-rest-impl/src/main/java/de/adorsys/datasafe/rest/impl/controller/AuthenticateController.java index 59f79c43c..a876601d8 100644 --- a/datasafe-rest-impl/src/main/java/de/adorsys/datasafe/rest/impl/controller/AuthenticateController.java +++ b/datasafe-rest-impl/src/main/java/de/adorsys/datasafe/rest/impl/controller/AuthenticateController.java @@ -15,6 +15,7 @@ import org.springframework.security.core.Authentication; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.userdetails.User; +import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; @@ -31,7 +32,7 @@ public class AuthenticateController { private final AuthenticationManager authenticationManager; @PostMapping(SecurityConstants.AUTH_LOGIN_URL) - public void authenticate(@RequestBody UserDTO credentialsDTO, HttpServletResponse response) { + public void authenticate(@RequestBody @Validated UserDTO credentialsDTO, HttpServletResponse response) { String username = credentialsDTO.getUserName(); String password = credentialsDTO.getPassword(); UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(username, password); diff --git a/datasafe-rest-impl/src/main/java/de/adorsys/datasafe/rest/impl/controller/DocumentController.java b/datasafe-rest-impl/src/main/java/de/adorsys/datasafe/rest/impl/controller/DocumentController.java index 5aa758bd8..77cfb19ab 100644 --- a/datasafe-rest-impl/src/main/java/de/adorsys/datasafe/rest/impl/controller/DocumentController.java +++ b/datasafe-rest-impl/src/main/java/de/adorsys/datasafe/rest/impl/controller/DocumentController.java @@ -11,6 +11,8 @@ import de.adorsys.datasafe.types.api.resource.PrivateResource; import de.adorsys.datasafe.types.api.resource.StorageIdentifier; import jakarta.servlet.http.HttpServletResponse; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; import lombok.RequiredArgsConstructor; import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; @@ -49,11 +51,16 @@ public class DocumentController { */ @SneakyThrows @GetMapping(value = "/document/{*path}", produces = APPLICATION_OCTET_STREAM_VALUE) - public void readDocument(@RequestHeader String user, - @RequestHeader String password, + public void readDocument(@RequestHeader @NotBlank String user, + @RequestHeader @NotBlank String password, @RequestHeader(defaultValue = StorageIdentifier.DEFAULT_ID) String storageId, - @PathVariable String path, + @PathVariable @NotBlank String path, HttpServletResponse response) { + // Validate and sanitize path + if (path.contains("..")) { + throw new IllegalArgumentException("Invalid path"); + } + UserIDAuth userIDAuth = new UserIDAuth(new UserID(user), ReadKeyPasswordHelper.getForString(password)); ReadRequest request = ReadRequest.forPrivate(userIDAuth, new StorageIdentifier(storageId), path); @@ -72,11 +79,16 @@ public void readDocument(@RequestHeader String user, */ @SneakyThrows @PutMapping(value = "/document/{*path}", consumes = MULTIPART_FORM_DATA_VALUE) - public void writeDocument(@RequestHeader String user, - @RequestHeader String password, + public void writeDocument(@RequestHeader @NotBlank String user, + @RequestHeader @NotBlank String password, @RequestHeader(defaultValue = StorageIdentifier.DEFAULT_ID) String storageId, @PathVariable String path, - @RequestParam("file") MultipartFile file) { + @RequestParam("file") @NotNull MultipartFile file) { + // Validate and sanitize path + if (path.contains("..")) { + throw new IllegalArgumentException("Invalid path"); + } + UserIDAuth userIDAuth = new UserIDAuth(new UserID(user), ReadKeyPasswordHelper.getForString(password)); WriteRequest request = WriteRequest.forPrivate(userIDAuth, new StorageIdentifier(storageId), path); @@ -91,14 +103,20 @@ public void writeDocument(@RequestHeader String user, * lists files in user's private space. */ @GetMapping("/documents/{*path}") - public List listDocuments(@RequestHeader String user, - @RequestHeader String password, + public List listDocuments(@RequestHeader @NotBlank String user, + @RequestHeader @NotBlank String password, @RequestHeader(defaultValue = StorageIdentifier.DEFAULT_ID) String storageId, @PathVariable(required = false) String path) { UserIDAuth userIDAuth = new UserIDAuth(new UserID(user), ReadKeyPasswordHelper.getForString(password)); path = Optional.ofNullable(path) .map(it -> it.replaceAll("^\\.$", "")) .orElse("./"); + + // Validate and sanitize path + if (path.contains("..")) { + throw new IllegalArgumentException("Invalid path"); + } + try { List documentList = datasafeService.privateService().list( ListRequest.forPrivate(userIDAuth, new StorageIdentifier(storageId), path)) @@ -115,10 +133,16 @@ public List listDocuments(@RequestHeader String user, * deletes files from user's private space. */ @DeleteMapping("/document/{*path}") - public void removeDocument(@RequestHeader String user, - @RequestHeader String password, + public void removeDocument(@RequestHeader @NotBlank String user, + @RequestHeader @NotBlank String password, @RequestHeader(defaultValue = StorageIdentifier.DEFAULT_ID) String storageId, - @PathVariable String path) { + @PathVariable @NotBlank String path) { + + // Validate and sanitize path + if (path.contains("..")) { + throw new IllegalArgumentException("Invalid path"); + } + UserIDAuth userIDAuth = new UserIDAuth(new UserID(user), ReadKeyPasswordHelper.getForString(password)); RemoveRequest request = RemoveRequest.forPrivate(userIDAuth, new StorageIdentifier(storageId), path); diff --git a/datasafe-rest-impl/src/main/java/de/adorsys/datasafe/rest/impl/controller/InboxController.java b/datasafe-rest-impl/src/main/java/de/adorsys/datasafe/rest/impl/controller/InboxController.java index 71df87cca..75c5b76d1 100644 --- a/datasafe-rest-impl/src/main/java/de/adorsys/datasafe/rest/impl/controller/InboxController.java +++ b/datasafe-rest-impl/src/main/java/de/adorsys/datasafe/rest/impl/controller/InboxController.java @@ -11,6 +11,7 @@ import de.adorsys.datasafe.types.api.resource.BasePrivateResource; import de.adorsys.datasafe.types.api.resource.PrivateResource; import jakarta.servlet.http.HttpServletResponse; +import jakarta.validation.constraints.NotBlank; import lombok.RequiredArgsConstructor; import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; @@ -28,7 +29,6 @@ import java.io.InputStream; import java.io.OutputStream; import java.util.List; -import java.util.Optional; import java.util.Set; import java.util.stream.Collectors; @@ -52,10 +52,10 @@ public class InboxController { */ @SneakyThrows @PutMapping(value = "/inbox/document/{*path}", consumes = MULTIPART_FORM_DATA_VALUE) - public void writeToInbox(@RequestHeader String user, - @RequestHeader String password, - @RequestHeader Set recipients, - @PathVariable String path, + public void writeToInbox(@RequestHeader @NotBlank String user, + @RequestHeader @NotBlank String password, + @RequestHeader Set<@NotBlank String> recipients, + @PathVariable @NotBlank String path, @RequestParam("file") MultipartFile file) { UserIDAuth fromUser = new UserIDAuth(new UserID(user), ReadKeyPasswordHelper.getForString(password)); Set toUsers = recipients.stream().map(UserID::new).collect(Collectors.toSet()); @@ -72,9 +72,9 @@ public void writeToInbox(@RequestHeader String user, */ @SneakyThrows @GetMapping(value = "/inbox/document/{*path}", produces = APPLICATION_OCTET_STREAM_VALUE) - public void readFromInbox(@RequestHeader String user, - @RequestHeader String password, - @PathVariable String path, + public void readFromInbox(@RequestHeader @NotBlank String user, + @RequestHeader @NotBlank String password, + @PathVariable @NotBlank String path, HttpServletResponse response) { path = path.replaceAll("^/", ""); UserIDAuth userIDAuth = new UserIDAuth(new UserID(user), ReadKeyPasswordHelper.getForString(password)); @@ -93,9 +93,9 @@ public void readFromInbox(@RequestHeader String user, * Deletes file from users' INBOX. */ @DeleteMapping("/inbox/document/{*path}") - public void deleteFromInbox(@RequestHeader String user, - @RequestHeader String password, - @PathVariable String path) { + public void deleteFromInbox(@RequestHeader @NotBlank String user, + @RequestHeader @NotBlank String password, + @PathVariable @NotBlank String path) { path = path.replaceAll("^/", ""); UserIDAuth userIDAuth = new UserIDAuth(new UserID(user), ReadKeyPasswordHelper.getForString(password)); PrivateResource resource = BasePrivateResource.forPrivate(path); @@ -108,8 +108,8 @@ public void deleteFromInbox(@RequestHeader String user, * list files in users' INBOX. */ @GetMapping(value = "/inbox/documents/{*path}", produces = APPLICATION_JSON_VALUE) - public List listInbox(@RequestHeader String user, - @RequestHeader String password, + public List listInbox(@RequestHeader @NotBlank String user, + @RequestHeader @NotBlank String password, @PathVariable(required = false) String path) { path = path.replaceAll("^/", ""); UserIDAuth userIDAuth = new UserIDAuth(new UserID(user), ReadKeyPasswordHelper.getForString(password)); diff --git a/datasafe-rest-impl/src/main/java/de/adorsys/datasafe/rest/impl/controller/UserController.java b/datasafe-rest-impl/src/main/java/de/adorsys/datasafe/rest/impl/controller/UserController.java index 5d78aece9..d9f616d73 100644 --- a/datasafe-rest-impl/src/main/java/de/adorsys/datasafe/rest/impl/controller/UserController.java +++ b/datasafe-rest-impl/src/main/java/de/adorsys/datasafe/rest/impl/controller/UserController.java @@ -14,6 +14,7 @@ import de.adorsys.datasafe.rest.impl.exceptions.UserExistsException; import de.adorsys.datasafe.types.api.resource.StorageIdentifier; import de.adorsys.datasafe.types.api.types.ReadKeyPassword; +import jakarta.validation.constraints.NotBlank; import lombok.RequiredArgsConstructor; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.DeleteMapping; @@ -61,8 +62,8 @@ public void createUser(@Validated @RequestBody UserDTO userDTO) { } @PostMapping("/password") - public void changePassword(@RequestHeader String user, - @RequestHeader String password, + public void changePassword(@RequestHeader @NotBlank String user, + @RequestHeader @NotBlank String password, @Validated @RequestBody NewPasswordDTO newPassword) { ReadKeyPassword readKeyPassword = ReadKeyPasswordHelper.getForString(password); UserIDAuth auth = new UserIDAuth(new UserID(user), readKeyPassword); @@ -70,24 +71,24 @@ public void changePassword(@RequestHeader String user, } @GetMapping("/publicProfile") - public UserPublicProfileDTO getPublicProfile(@RequestHeader String user, - @RequestHeader String password) { + public UserPublicProfileDTO getPublicProfile(@RequestHeader @NotBlank String user, + @RequestHeader @NotBlank String password) { ReadKeyPassword readKeyPassword = ReadKeyPasswordHelper.getForString(password); UserIDAuth auth = new UserIDAuth(new UserID(user), readKeyPassword); return UserPublicProfileDTO.from(dataSafeService.userProfile().publicProfile(auth.getUserID())); } @GetMapping("/privateProfile") - public UserPrivateProfileDTO getPrivateProfile(@RequestHeader String user, - @RequestHeader String password) { + public UserPrivateProfileDTO getPrivateProfile(@RequestHeader @NotBlank String user, + @RequestHeader @NotBlank String password) { ReadKeyPassword readKeyPassword = ReadKeyPasswordHelper.getForString(password); UserIDAuth auth = new UserIDAuth(new UserID(user), readKeyPassword); return UserPrivateProfileDTO.from(dataSafeService.userProfile().privateProfile(auth)); } @PostMapping("/publicProfile") - public void updatePublicProfile(@RequestHeader String user, - @RequestHeader String password, + public void updatePublicProfile(@RequestHeader @NotBlank String user, + @RequestHeader @NotBlank String password, @Validated @RequestBody UserPublicProfileDTO profileDto) { ReadKeyPassword readKeyPassword = ReadKeyPasswordHelper.getForString(password); UserIDAuth auth = new UserIDAuth(new UserID(user), readKeyPassword); @@ -95,8 +96,8 @@ public void updatePublicProfile(@RequestHeader String user, } @PostMapping("/privateProfile") - public void updatePrivateProfile(@RequestHeader String user, - @RequestHeader String password, + public void updatePrivateProfile(@RequestHeader @NotBlank String user, + @RequestHeader @NotBlank String password, @Validated @RequestBody UserPrivateProfileDTO profileDto) { ReadKeyPassword readKeyPassword = ReadKeyPasswordHelper.getForString(password); UserIDAuth auth = new UserIDAuth(new UserID(user), readKeyPassword); @@ -104,8 +105,8 @@ public void updatePrivateProfile(@RequestHeader String user, } @PostMapping("/storages") - public void addStorageCredentials(@RequestHeader String user, - @RequestHeader String password, + public void addStorageCredentials(@RequestHeader @NotBlank String user, + @RequestHeader @NotBlank String password, @Validated @RequestBody StorageCredsDTO creds) { ReadKeyPassword readKeyPassword = ReadKeyPasswordHelper.getForString(password); UserIDAuth auth = new UserIDAuth(new UserID(user), readKeyPassword); @@ -117,9 +118,9 @@ public void addStorageCredentials(@RequestHeader String user, } @DeleteMapping("/storages") - public void removeStorageCredentials(@RequestHeader String user, - @RequestHeader String password, - @RequestHeader String storageId) { + public void removeStorageCredentials(@RequestHeader @NotBlank String user, + @RequestHeader @NotBlank String password, + @RequestHeader @NotBlank String storageId) { ReadKeyPassword readKeyPassword = ReadKeyPasswordHelper.getForString(password); UserIDAuth auth = new UserIDAuth(new UserID(user), readKeyPassword); dataSafeService.userProfile().deregisterStorageCredentials(auth, new StorageIdentifier(storageId)); @@ -132,8 +133,8 @@ public void removeStorageCredentials(@RequestHeader String user, * @param password user password. */ @DeleteMapping - public void deleteUser(@RequestHeader String user, - @RequestHeader String password) { + public void deleteUser(@RequestHeader @NotBlank String user, + @RequestHeader @NotBlank String password) { UserIDAuth auth = new UserIDAuth(new UserID(user), ReadKeyPasswordHelper.getForString(password)); if (!dataSafeService.userProfile().userExists(auth.getUserID())) { throw new UserDoesNotExistsException("user '" + auth.getUserID().getValue() + "' does not exists"); diff --git a/datasafe-rest-impl/src/main/java/de/adorsys/datasafe/rest/impl/controller/VersionController.java b/datasafe-rest-impl/src/main/java/de/adorsys/datasafe/rest/impl/controller/VersionController.java index 7ce0f2383..e59c21975 100644 --- a/datasafe-rest-impl/src/main/java/de/adorsys/datasafe/rest/impl/controller/VersionController.java +++ b/datasafe-rest-impl/src/main/java/de/adorsys/datasafe/rest/impl/controller/VersionController.java @@ -15,6 +15,7 @@ import de.adorsys.datasafe.types.api.resource.StorageIdentifier; import de.adorsys.datasafe.types.api.resource.Versioned; import jakarta.servlet.http.HttpServletResponse; +import jakarta.validation.constraints.NotBlank; import lombok.RequiredArgsConstructor; import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; @@ -49,10 +50,10 @@ public class VersionController { * lists latest versions of files in user's private space. */ @GetMapping(value = "/versioned/{*path}", produces = APPLICATION_JSON_VALUE) - public List listVersionedDocuments(@RequestHeader String user, - @RequestHeader String password, + public List listVersionedDocuments(@RequestHeader @NotBlank String user, + @RequestHeader @NotBlank String password, @RequestHeader(defaultValue = StorageIdentifier.DEFAULT_ID) String storageId, - @PathVariable(required = false) String path) { + @PathVariable(required = false) String path) { UserIDAuth userIDAuth = new UserIDAuth(new UserID(user), ReadKeyPasswordHelper.getForString(password)); path = path.replaceAll("^/", ""); try { @@ -73,10 +74,10 @@ public List listVersionedDocuments(@RequestHeader String user, */ @SneakyThrows @GetMapping(value = "/versioned/{*path}", produces = APPLICATION_OCTET_STREAM_VALUE) - public void readVersionedDocument(@RequestHeader String user, - @RequestHeader String password, + public void readVersionedDocument(@RequestHeader @NotBlank String user, + @RequestHeader @NotBlank String password, @RequestHeader(defaultValue = StorageIdentifier.DEFAULT_ID) String storageId, - @PathVariable String path, + @PathVariable @NotBlank String path, HttpServletResponse response) { path = path.replaceAll("^/", ""); UserIDAuth userIDAuth = new UserIDAuth(new UserID(user), ReadKeyPasswordHelper.getForString(password)); @@ -97,10 +98,10 @@ public void readVersionedDocument(@RequestHeader String user, */ @SneakyThrows @PutMapping(value = "/versioned/{*path}", consumes = MULTIPART_FORM_DATA_VALUE) - public void writeVersionedDocument(@RequestHeader String user, - @RequestHeader String password, + public void writeVersionedDocument(@RequestHeader @NotBlank String user, + @RequestHeader @NotBlank String password, @RequestHeader(defaultValue = StorageIdentifier.DEFAULT_ID) String storageId, - @PathVariable String path, + @PathVariable @NotBlank String path, @RequestParam("file") MultipartFile file) { path = path.replaceAll("^/", ""); UserIDAuth userIDAuth = new UserIDAuth(new UserID(user), ReadKeyPasswordHelper.getForString(password)); @@ -117,10 +118,10 @@ public void writeVersionedDocument(@RequestHeader String user, * deletes latest version of file from user's private space. */ @DeleteMapping("/versioned/{*path}") - public void deleteVersionedDocument(@RequestHeader String user, - @RequestHeader String password, + public void deleteVersionedDocument(@RequestHeader @NotBlank String user, + @RequestHeader @NotBlank String password, @RequestHeader(defaultValue = StorageIdentifier.DEFAULT_ID) String storageId, - @PathVariable String path) { + @PathVariable @NotBlank String path) { path = path.replaceAll("^/", ""); UserIDAuth userIDAuth = new UserIDAuth(new UserID(user), ReadKeyPasswordHelper.getForString(password)); RemoveRequest request = @@ -133,8 +134,8 @@ public void deleteVersionedDocument(@RequestHeader String user, * list of file versions. */ @GetMapping(value = "/versions/list/{*path}", produces = APPLICATION_JSON_VALUE) - public List versionsOf(@RequestHeader String user, - @RequestHeader String password, + public List versionsOf(@RequestHeader @NotBlank String user, + @RequestHeader @NotBlank String password, @RequestHeader(defaultValue = StorageIdentifier.DEFAULT_ID) String storageId, @PathVariable(required = false) String path) { UserIDAuth userIDAuth = new UserIDAuth(new UserID(user), ReadKeyPasswordHelper.getForString(password)); diff --git a/datasafe-simple-adapter/datasafe-simple-adapter-impl/src/test/java/de/adorsys/datasafe/simple/adapter/impl/CleanupDbTest.java b/datasafe-simple-adapter/datasafe-simple-adapter-impl/src/test/java/de/adorsys/datasafe/simple/adapter/impl/CleanupDbIT.java similarity index 98% rename from datasafe-simple-adapter/datasafe-simple-adapter-impl/src/test/java/de/adorsys/datasafe/simple/adapter/impl/CleanupDbTest.java rename to datasafe-simple-adapter/datasafe-simple-adapter-impl/src/test/java/de/adorsys/datasafe/simple/adapter/impl/CleanupDbIT.java index 45cce5494..54f5c50dd 100644 --- a/datasafe-simple-adapter/datasafe-simple-adapter-impl/src/test/java/de/adorsys/datasafe/simple/adapter/impl/CleanupDbTest.java +++ b/datasafe-simple-adapter/datasafe-simple-adapter-impl/src/test/java/de/adorsys/datasafe/simple/adapter/impl/CleanupDbIT.java @@ -20,7 +20,7 @@ import static org.assertj.core.api.Assertions.assertThat; -class CleanupDbTest extends WithStorageProvider { +class CleanupDbIT extends WithStorageProvider { private SimpleDatasafeService simpleDatasafeService; private DFSCredentials dfsCredentials; diff --git a/datasafe-simple-adapter/datasafe-simple-adapter-impl/src/test/java/de/adorsys/datasafe/simple/adapter/impl/DFSRelativeToRootProfileTest.java b/datasafe-simple-adapter/datasafe-simple-adapter-impl/src/test/java/de/adorsys/datasafe/simple/adapter/impl/DFSRelativeToRootProfileIT.java similarity index 97% rename from datasafe-simple-adapter/datasafe-simple-adapter-impl/src/test/java/de/adorsys/datasafe/simple/adapter/impl/DFSRelativeToRootProfileTest.java rename to datasafe-simple-adapter/datasafe-simple-adapter-impl/src/test/java/de/adorsys/datasafe/simple/adapter/impl/DFSRelativeToRootProfileIT.java index 4833e6bcd..1f3a06d66 100644 --- a/datasafe-simple-adapter/datasafe-simple-adapter-impl/src/test/java/de/adorsys/datasafe/simple/adapter/impl/DFSRelativeToRootProfileTest.java +++ b/datasafe-simple-adapter/datasafe-simple-adapter-impl/src/test/java/de/adorsys/datasafe/simple/adapter/impl/DFSRelativeToRootProfileIT.java @@ -22,7 +22,7 @@ import static org.assertj.core.api.Assertions.assertThat; -class DFSRelativeToRootProfileTest extends WithStorageProvider { +class DFSRelativeToRootProfileIT extends WithStorageProvider { private SimpleDatasafeService simpleDatasafeService; private UserIDAuth userIDAuth; diff --git a/datasafe-simple-adapter/datasafe-simple-adapter-impl/src/test/java/de/adorsys/datasafe/simple/adapter/impl/SimpleAdapterFeatureTest.java b/datasafe-simple-adapter/datasafe-simple-adapter-impl/src/test/java/de/adorsys/datasafe/simple/adapter/impl/SimpleAdapterFeatureTest.java index 9d5d34527..d1d33c51b 100644 --- a/datasafe-simple-adapter/datasafe-simple-adapter-impl/src/test/java/de/adorsys/datasafe/simple/adapter/impl/SimpleAdapterFeatureTest.java +++ b/datasafe-simple-adapter/datasafe-simple-adapter-impl/src/test/java/de/adorsys/datasafe/simple/adapter/impl/SimpleAdapterFeatureTest.java @@ -39,7 +39,7 @@ @Slf4j class SimpleAdapterFeatureTest extends BaseMockitoTest { - + private UserIDAuth userIDAuth = new UserIDAuth(new UserID("peter"), ReadKeyPasswordTestFactory.getForString("password")); private String content = "content of document"; private String path = "a/b/c.txt"; diff --git a/datasafe-simple-adapter/datasafe-simple-adapter-impl/src/test/java/de/adorsys/datasafe/simple/adapter/impl/SimpleDatasafeAdapterTest.java b/datasafe-simple-adapter/datasafe-simple-adapter-impl/src/test/java/de/adorsys/datasafe/simple/adapter/impl/SimpleDatasafeAdapterIT.java similarity index 99% rename from datasafe-simple-adapter/datasafe-simple-adapter-impl/src/test/java/de/adorsys/datasafe/simple/adapter/impl/SimpleDatasafeAdapterTest.java rename to datasafe-simple-adapter/datasafe-simple-adapter-impl/src/test/java/de/adorsys/datasafe/simple/adapter/impl/SimpleDatasafeAdapterIT.java index 8e425ea3c..f7581b729 100644 --- a/datasafe-simple-adapter/datasafe-simple-adapter-impl/src/test/java/de/adorsys/datasafe/simple/adapter/impl/SimpleDatasafeAdapterTest.java +++ b/datasafe-simple-adapter/datasafe-simple-adapter-impl/src/test/java/de/adorsys/datasafe/simple/adapter/impl/SimpleDatasafeAdapterIT.java @@ -42,7 +42,7 @@ import static org.junit.jupiter.api.Assertions.*; @Slf4j -class SimpleDatasafeAdapterTest extends WithStorageProvider { +class SimpleDatasafeAdapterIT extends WithStorageProvider { private SimpleDatasafeService simpleDatasafeService; private UserIDAuth userIDAuth; diff --git a/datasafe-simple-adapter/datasafe-simple-adapter-spring/pom.xml b/datasafe-simple-adapter/datasafe-simple-adapter-spring/pom.xml index 853af91b2..bef17150f 100644 --- a/datasafe-simple-adapter/datasafe-simple-adapter-spring/pom.xml +++ b/datasafe-simple-adapter/datasafe-simple-adapter-spring/pom.xml @@ -11,6 +11,12 @@ datasafe-simple-adapter-spring + + 6.1.10 + 3.3.1 + 2.2 + + org.springframework.boot @@ -85,7 +91,7 @@ org.yaml snakeyaml - 2.1 + ${snakeyaml.version} org.junit.jupiter @@ -129,6 +135,11 @@ test-jar test + + com.fasterxml.jackson.core + jackson-databind + ${jackson.version} + jakarta.annotation jakarta.annotation-api diff --git a/datasafe-storage/datasafe-storage-impl-db/pom.xml b/datasafe-storage/datasafe-storage-impl-db/pom.xml index e408805e0..db5401c52 100644 --- a/datasafe-storage/datasafe-storage-impl-db/pom.xml +++ b/datasafe-storage/datasafe-storage-impl-db/pom.xml @@ -11,6 +11,10 @@ datasafe-storage-impl-db + + 6.1.10 + + de.adorsys @@ -26,6 +30,7 @@ org.springframework spring-jdbc + ${spring.framework.version} com.zaxxer diff --git a/datasafe-storage/datasafe-storage-impl-s3/pom.xml b/datasafe-storage/datasafe-storage-impl-s3/pom.xml index 9e846aa3c..752e2c734 100644 --- a/datasafe-storage/datasafe-storage-impl-s3/pom.xml +++ b/datasafe-storage/datasafe-storage-impl-s3/pom.xml @@ -72,6 +72,18 @@ testcontainers test + + com.fasterxml.jackson.core + jackson-annotations + ${jackson.version} + test + + + com.fasterxml.jackson.core + jackson-databind + ${jackson.version} + test + org.junit.jupiter junit-jupiter-api diff --git a/datasafe-test-storages/pom.xml b/datasafe-test-storages/pom.xml index 185516284..0544657a2 100644 --- a/datasafe-test-storages/pom.xml +++ b/datasafe-test-storages/pom.xml @@ -28,6 +28,18 @@ testcontainers compile + + com.fasterxml.jackson.core + jackson-annotations + ${jackson.version} + compile + + + com.fasterxml.jackson.core + jackson-databind + ${jackson.version} + compile + de.adorsys datasafe-storage-api diff --git a/datasafe-types-api/src/main/java/de/adorsys/datasafe/types/api/resource/BasePrivateResource.java b/datasafe-types-api/src/main/java/de/adorsys/datasafe/types/api/resource/BasePrivateResource.java index 954cb636f..97d6dd870 100644 --- a/datasafe-types-api/src/main/java/de/adorsys/datasafe/types/api/resource/BasePrivateResource.java +++ b/datasafe-types-api/src/main/java/de/adorsys/datasafe/types/api/resource/BasePrivateResource.java @@ -27,7 +27,6 @@ private BasePrivateResource() { this.encryptedPath = EMPTY_URI; } - // TODO: Hide it public BasePrivateResource(Uri containerUri) { this.container = containerUri; this.decryptedPath = EMPTY_URI;