diff --git a/datasafe-business/src/test/java/de/adorsys/datasafe/business/impl/e2e/SchemeDelegationIT.java b/datasafe-business/src/test/java/de/adorsys/datasafe/business/impl/e2e/SchemeDelegationIT.java index 9b4d05dde..846c11ea1 100644 --- a/datasafe-business/src/test/java/de/adorsys/datasafe/business/impl/e2e/SchemeDelegationIT.java +++ b/datasafe-business/src/test/java/de/adorsys/datasafe/business/impl/e2e/SchemeDelegationIT.java @@ -1,4 +1,7 @@ package de.adorsys.datasafe.business.impl.e2e; + +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; import de.adorsys.datasafe.business.impl.service.DaggerDefaultDatasafeServices; import de.adorsys.datasafe.business.impl.service.DefaultDatasafeServices; import de.adorsys.datasafe.directory.impl.profile.config.DefaultDFSConfig; @@ -6,101 +9,143 @@ import de.adorsys.datasafe.encrypiton.api.types.UserIDAuth; import de.adorsys.datasafe.storage.api.SchemeDelegatingStorage; import de.adorsys.datasafe.storage.api.StorageService; +import de.adorsys.datasafe.storage.impl.db.DatabaseConnectionRegistry; +import de.adorsys.datasafe.storage.impl.db.DatabaseCredentials; +import de.adorsys.datasafe.storage.impl.db.DatabaseStorageService; import de.adorsys.datasafe.storage.impl.fs.FileSystemStorageService; import de.adorsys.datasafe.teststorage.WithStorageProvider; import de.adorsys.datasafe.types.api.actions.WriteRequest; import de.adorsys.datasafe.types.api.resource.AbsoluteLocation; import de.adorsys.datasafe.types.api.resource.BasePrivateResource; +import de.adorsys.datasafe.types.api.resource.ResolvedResource; import de.adorsys.datasafe.types.api.resource.Uri; +import de.adorsys.datasafe.types.api.types.ReadStorePassword; +import de.adorsys.datasafe.types.api.utils.ReadKeyPasswordTestFactory; import lombok.SneakyThrows; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.io.TempDir; -import org.testcontainers.shaded.com.google.common.collect.ImmutableMap; import java.io.OutputStream; +import java.net.URI; import java.nio.file.Files; import java.nio.file.Path; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import static de.adorsys.datasafe.types.api.global.PathEncryptionId.AES_SIV; import static org.assertj.core.api.Assertions.assertThat; -class SchemeDelegationTest extends WithStorageProvider { +class SchemeDelegationWithDbTest extends WithStorageProvider { + + private static final Set ALLOWED_TABLES = ImmutableSet.of("users", "private_profiles", "public_profiles"); private Path fsPath; - private Uri minioPath; - private StorageService minio; - private StorageService filesystem; + private StorageService db; private DefaultDatasafeServices datasafeServices; @BeforeEach void initialize(@TempDir Path tempDir) { - WithStorageProvider.StorageDescriptor minioDescriptor = minio(); this.fsPath = tempDir; - this.minio = minioDescriptor.getStorageService().get(); - this.filesystem = new FileSystemStorageService(tempDir); - this.minioPath = minioDescriptor.getLocation(); + StorageService filesystem = new FileSystemStorageService(tempDir); + this.db = new DatabaseStorageService(ALLOWED_TABLES, new DatabaseConnectionRegistry( + uri -> uri.location().getWrapped().getScheme() + ":" + uri.location().getPath().split("/")[1], + ImmutableMap.of("jdbc://localhost:9999", new DatabaseCredentials("sa", "sa"))) + ); + StorageService multiDfs = new SchemeDelegatingStorage( ImmutableMap.of( - "s3", minio, - "file", filesystem + "file", filesystem, + "jdbc", db ) ); this.datasafeServices = DaggerDefaultDatasafeServices .builder() - .config(new ProfilesOnFsDataOnMinio(minioPath, tempDir)) + .config(new ProfilesOnDbDataOnFs(tempDir.toUri(), URI.create("jdbc://localhost:9999/h2:mem:test/"))) .storage(multiDfs) .build(); } @Test @SneakyThrows - void testProfileOnFsDataOnMinioWorks() { - UserIDAuth userJohn = new UserIDAuth("john", "doe"); + void testProfileOnDbDataOnFsWorks() { + UserIDAuth userJohn = new UserIDAuth("john", ReadKeyPasswordTestFactory.getForString("doe")); - // John's profile will be saved to filesystem + // John's profile will be saved to Database datasafeServices.userProfile().registerUsingDefaults(userJohn); - // But this data - it will be saved to minio + // But this data - it will be saved to FS try (OutputStream os = datasafeServices.privateService().write(WriteRequest.forDefaultPrivate(userJohn, "file.txt"))) { os.write("Hello".getBytes()); } - // Profiles are on FS - assertThat(Files.walk(fsPath)) - .extracting(it -> fsPath.relativize(it)) - .extracting(Path::toString) - .containsExactlyInAnyOrder("", "public-john", "private-john"); - // File and keystore/pub keys are on minio - assertThat(minio.list(new AbsoluteLocation<>(BasePrivateResource.forPrivate(minioPath.resolve(""))))) - .extracting(it -> minioPath.relativize(it.location())) - .extracting(it -> it.asURI().toString()) - .contains("users/john/private/keystore", "users/john/public/pubkeys") - .anyMatch(it -> it.startsWith("users/john/private/files/")) - .hasSize(3); + // Profiles are on DB + assertThat(listDb("jdbc://localhost:9999/h2:mem:test/private_profiles/")) + .containsExactly("jdbc://localhost:9999/h2:mem:test/private_profiles/john"); + assertThat(listDb("jdbc://localhost:9999/h2:mem:test/public_profiles/")) + .containsExactly("jdbc://localhost:9999/h2:mem:test/public_profiles/john"); + + Path path = fsPath.resolve(new Uri("users/john/private/files/").resolve(AES_SIV.asUriRoot()).asString()); + Path encryptedFile = walk(path).get(1); + // File and keystore/pub keys are on FS + assertThat(walk(fsPath)) + .extracting(it -> fsPath.toUri().relativize(it.toUri())) + .extracting(URI::toString) + .containsExactlyInAnyOrder( + "", + "users/", + "users/john/", + "users/john/public/", + "users/john/public/pubkeys", + "users/john/private/", + "users/john/private/keystore", + "users/john/private/files/", + "users/john/private/files/SIV/", + fsPath.toUri().relativize(encryptedFile.toUri()).toString() + ); + } + + @SneakyThrows + private List walk(Path at) { + try (Stream ls = Files.walk(at)) { + return ls.collect(Collectors.toList()); + } + } + + private List listDb(String path) { + try (Stream> stream = db.list(BasePrivateResource.forAbsolutePrivate(URI.create(path)))){ + return stream.map(it -> it.location().asURI().toString()).collect(Collectors.toList()); + } } - static class ProfilesOnFsDataOnMinio extends DefaultDFSConfig { + static class ProfilesOnDbDataOnFs extends DefaultDFSConfig { - private final Path profilesPath; + private final Uri profilesPath; - ProfilesOnFsDataOnMinio(Uri minioBucketPath, Path profilesPath) { - super(minioBucketPath, "PAZZWORT"); - this.profilesPath = profilesPath; + ProfilesOnDbDataOnFs(URI fsPath, URI profilesPath) { + super(fsPath, new ReadStorePassword("PAZZWORT")); + this.profilesPath = new Uri(profilesPath); } @Override public AbsoluteLocation publicProfile(UserID forUser) { return new AbsoluteLocation<>( - BasePrivateResource.forPrivate(profilesPath.resolve("public-" + forUser.getValue()).toUri()) + BasePrivateResource.forPrivate( + profilesPath.resolve("public_profiles/").resolve(forUser.getValue()) + ) ); } @Override public AbsoluteLocation privateProfile(UserID forUser) { return new AbsoluteLocation<>( - BasePrivateResource.forPrivate(profilesPath.resolve("private-" + forUser.getValue()).toUri()) + BasePrivateResource.forPrivate( + profilesPath.resolve("private_profiles/").resolve(forUser.getValue()) + ) ); } }