From 2a81c54d435aee43ab347861be7911fb0305e067 Mon Sep 17 00:00:00 2001 From: Esta Nagy Date: Tue, 21 Mar 2023 19:33:12 +0100 Subject: [PATCH] Reduce the amount of converter injections in controllers (#514) - Reimplements the way converters are injected into beans using converter registries - Simplifies controller implementations by using new base controller classes - Merges backup models into a single version per entity type (cert/key/secret) - Updates affected test cases Resolves #506 {minor} Signed-off-by: Esta Nagy --- build.gradle | 5 +- .../lowkeyvault/context/ApiVersionAware.java | 25 +++ .../CertificateConverterConfiguration.java | 59 ++++++ .../context/KeyConverterConfiguration.java | 57 ++++++ .../context/SecretConverterConfiguration.java | 45 +++++ .../VaultBackupManagementController.java | 8 +- .../controller/VaultManagementController.java | 181 +++++------------- .../common/BaseBackupRestoreController.java | 68 +++---- .../common/BaseCertificateController.java | 73 +++++++ .../controller/common/BaseKeyController.java | 70 +++++++ .../common/BaseSecretController.java | 48 +++++ .../common/CommonCertificateController.java | 116 +++-------- .../CommonCertificatePolicyController.java | 56 ++---- .../CommonKeyBackupRestoreController.java | 79 ++++---- .../common/CommonKeyController.java | 90 +++------ .../common/CommonKeyCryptoController.java | 36 +--- .../CommonSecretBackupRestoreController.java | 45 +++-- .../common/CommonSecretController.java | 75 +++----- .../common/GenericEntityController.java | 123 +++++++----- .../controller/common/PaginationContext.java | 58 ++++++ .../v7_2/KeyBackupRestoreController.java | 43 ++--- .../controller/v7_2/KeyController.java | 12 +- .../controller/v7_2/KeyCryptoController.java | 12 +- .../v7_2/SecretBackupRestoreController.java | 12 +- .../controller/v7_2/SecretController.java | 13 +- .../v7_3/CertificateController.java | 15 +- .../v7_3/CertificatePolicyController.java | 13 +- .../v7_3/KeyBackupRestoreController.java | 57 ++---- .../controller/v7_3/KeyController.java | 12 +- .../controller/v7_3/KeyCryptoController.java | 12 +- .../controller/v7_3/KeyPolicyController.java | 40 ++-- .../v7_3/SecretBackupRestoreController.java | 14 +- .../controller/v7_3/SecretController.java | 13 +- .../{ => common}/AliasAwareConverter.java | 6 +- .../common/ApiVersionAwareConverter.java | 8 + .../mapper/common/BackupConverter.java | 16 +- .../common/BaseEntityConverterRegistry.java | 74 +++++++ ...java => BasePropertiesModelConverter.java} | 7 +- .../common/EntityConverterRegistry.java | 40 ++++ .../mapper/common/RecoveryAwareConverter.java | 4 +- .../CertificateConverterRegistry.java | 85 ++++++++ .../common/registry/KeyConverterRegistry.java | 60 ++++++ .../registry/SecretConverterRegistry.java | 29 +++ .../key/KeyEntityToV72BackupConverter.java | 35 +++- .../KeyEntityToV72KeyItemModelConverter.java | 27 ++- ...tityToV72KeyVersionItemModelConverter.java | 16 +- .../key/KeyEntityToV72ModelConverter.java | 23 ++- ...eyEntityToV72PropertiesModelConverter.java | 30 ++- .../SecretEntityToV72BackupConverter.java | 49 +++++ .../SecretEntityToV72ModelConverter.java | 25 ++- ...etEntityToV72PropertiesModelConverter.java | 29 ++- ...etEntityToV72SecretItemModelConverter.java | 28 ++- ...yToV72SecretVersionItemModelConverter.java | 12 +- ...ficateEntityToV73PolicyModelConverter.java | 11 +- ...ityToV73CertificateItemModelConverter.java | 27 ++- ...3CertificateVersionItemModelConverter.java | 14 +- ...tityToV73IssuancePolicyModelConverter.java | 14 +- .../CertificateEntityToV73ModelConverter.java | 30 +-- ...ingCertificateOperationModelConverter.java | 25 ++- ...ficateEntityToV73PolicyModelConverter.java | 16 +- ...teEntityToV73PropertiesModelConverter.java | 28 ++- ...timeActionsPolicyToV73ModelConverter.java} | 36 ++-- .../KeyRotationPolicyToV73ModelConverter.java | 25 ++- ...tationPolicyV73ModelToEntityConverter.java | 42 ++-- .../common/backup/CertificateBackupList.java | 28 +++ .../backup/CertificateBackupListItem.java | 15 ++ .../common/backup/CertificateBackupModel.java | 25 +++ .../key => common/backup}/KeyBackupList.java | 18 +- .../backup}/KeyBackupListItem.java | 3 +- .../key => common/backup}/KeyBackupModel.java | 11 +- .../backup}/SecretBackupList.java | 2 +- .../backup}/SecretBackupListItem.java | 3 +- .../backup}/SecretBackupModel.java | 3 +- ...zer.java => Base64ZipKeyDeserializer.java} | 8 +- .../json/util/Base64ZipKeySerializer.java | 15 ++ .../util/Base64ZipSecretDeserializer.java | 2 +- .../json/util/Base64ZipSecretSerializer.java | 2 +- .../util/Base64ZipV72KeyDeserializer.java | 20 -- .../json/util/Base64ZipV72KeySerializer.java | 15 -- .../json/util/Base64ZipV73KeySerializer.java | 15 -- .../model/management/VaultBackupModel.java | 4 +- .../model/v7_2/key/KeyBackupModel.java | 28 --- .../SecretEntityToV72BackupConverter.java | 28 --- .../model/v7_3/key/KeyBackupList.java | 22 --- .../v7_3/key/KeyRotationPolicyModel.java | 4 + .../CertificateBackingEntityGenerator.java | 85 ++++++++ .../impl/CertificateVaultFakeImpl.java | 18 +- .../impl/KeyVaultCertificateEntity.java | 49 +---- .../service/common/BaseVaultEntity.java | 9 +- .../common/impl/BaseVaultFakeImpl.java | 16 +- .../lowkeyvault/service/key/KeyVaultFake.java | 17 +- .../key/impl/KeyCreateDetailedInput.java | 103 ++++++++++ .../service/key/impl/KeyImportInput.java | 108 +++++++++++ .../service/key/impl/KeyVaultFakeImpl.java | 76 ++++---- .../secret/ReadOnlyKeyVaultSecretEntity.java | 3 +- .../service/secret/SecretVaultFake.java | 10 +- .../secret/impl/SecretCreateInput.java | 109 +++++++++++ .../secret/impl/SecretVaultFakeImpl.java | 39 ++-- .../template/backup/VaultImporter.java | 8 +- .../controller/VaultBackupConfiguration.java | 35 ++-- ...upManagementControllerIntegrationTest.java | 4 +- ...ackupRestoreControllerIntegrationTest.java | 33 ++-- .../controller/v7_2/KeyControllerTest.java | 44 ++--- .../v7_2/KeyCryptoControllerTest.java | 35 ++-- ...ackupRestoreControllerIntegrationTest.java | 32 ++-- .../controller/v7_2/SecretControllerTest.java | 42 ++-- .../v7_3/CertificateControllerTest.java | 45 +---- .../v7_3/CertificatePolicyControllerTest.java | 30 +-- ...ackupRestoreControllerIntegrationTest.java | 39 ++-- .../controller/v7_3/KeyControllerTest.java | 71 ++++--- .../v7_3/KeyCryptoControllerTest.java | 36 ++-- .../v7_3/KeyPolicyControllerTest.java | 50 ++--- ...ackupRestoreControllerIntegrationTest.java | 32 ++-- .../controller/v7_3/SecretControllerTest.java | 51 ++--- ...yEntityToV72KeyItemModelConverterTest.java | 10 +- ...ToV72KeyVersionItemModelConverterTest.java | 10 +- .../key/KeyEntityToV72ModelConverterTest.java | 10 +- ...tityToV72PropertiesModelConverterTest.java | 19 +- .../SecretEntityToV72ModelConverterTest.java | 10 +- ...tityToV72PropertiesModelConverterTest.java | 18 +- ...tityToV72SecretItemModelConverterTest.java | 10 +- ...72SecretVersionItemModelConverterTest.java | 10 +- ...oV73CertificateItemModelConverterTest.java | 24 ++- ...tificateVersionItemModelConverterTest.java | 12 +- ...ToV73IssuancePolicyModelConverterTest.java | 18 ++ ...ityToV73ModelConverterIntegrationTest.java | 9 +- ...tificateEntityToV73ModelConverterTest.java | 26 +-- ...perationModelConverterIntegrationTest.java | 19 +- ...teEntityToV73PolicyModelConverterTest.java | 23 ++- ...tityToV73PropertiesModelConverterTest.java | 18 ++ ...ActionsPolicyToV73ModelConverterTest.java} | 8 +- ...RotationPolicyToV73ModelConverterTest.java | 16 +- ...onPolicyV73ModelToEntityConverterTest.java | 50 +++-- ...java => Base64ZipKeyDeserializerTest.java} | 10 +- ...SerializerDeserializerIntegrationTest.java | 6 +- ...t.java => Base64ZipKeySerializerTest.java} | 8 +- ...SerializerDeserializerIntegrationTest.java | 6 +- .../util/Base64ZipV72KeyDeserializerTest.java | 49 ----- .../util/Base64ZipV73KeySerializerTest.java | 48 ----- .../KeyEntityToV72BackupConverterTest.java | 10 +- .../SecretEntityToV72BackupConverterTest.java | 6 + ...VaultCertificateEntityIntegrationTest.java | 6 +- .../key/impl/KeyVaultFakeImplTest.java | 109 ++++++++--- .../secret/impl/SecretVaultFakeImplTest.java | 125 ++++++++++-- 144 files changed, 2933 insertions(+), 1726 deletions(-) create mode 100644 lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/context/ApiVersionAware.java create mode 100644 lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/context/CertificateConverterConfiguration.java create mode 100644 lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/context/KeyConverterConfiguration.java create mode 100644 lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/context/SecretConverterConfiguration.java create mode 100644 lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/controller/common/BaseCertificateController.java create mode 100644 lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/controller/common/BaseKeyController.java create mode 100644 lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/controller/common/BaseSecretController.java create mode 100644 lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/controller/common/PaginationContext.java rename lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/{ => common}/AliasAwareConverter.java (59%) create mode 100644 lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/common/ApiVersionAwareConverter.java create mode 100644 lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/common/BaseEntityConverterRegistry.java rename lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/common/{BaseEntityToV72PropertiesModelConverter.java => BasePropertiesModelConverter.java} (67%) create mode 100644 lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/common/EntityConverterRegistry.java create mode 100644 lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/common/registry/CertificateConverterRegistry.java create mode 100644 lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/common/registry/KeyConverterRegistry.java create mode 100644 lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/common/registry/SecretConverterRegistry.java create mode 100644 lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/v7_2/secret/SecretEntityToV72BackupConverter.java rename lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/v7_3/certificate/{LifetimeActionsPolicyToV73ModelConverter.java => CertificateLifetimeActionsPolicyToV73ModelConverter.java} (59%) create mode 100644 lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/model/common/backup/CertificateBackupList.java create mode 100644 lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/model/common/backup/CertificateBackupListItem.java create mode 100644 lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/model/common/backup/CertificateBackupModel.java rename lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/model/{v7_2/key => common/backup}/KeyBackupList.java (50%) rename lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/model/{v7_2/key => common/backup}/KeyBackupListItem.java (82%) rename lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/model/{v7_3/key => common/backup}/KeyBackupModel.java (74%) rename lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/model/{v7_2/secret => common/backup}/SecretBackupList.java (92%) rename lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/model/{v7_2/secret => common/backup}/SecretBackupListItem.java (79%) rename lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/model/{v7_2/secret => common/backup}/SecretBackupModel.java (87%) rename lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/model/json/util/{Base64ZipV73KeyDeserializer.java => Base64ZipKeyDeserializer.java} (52%) create mode 100644 lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/model/json/util/Base64ZipKeySerializer.java delete mode 100644 lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/model/json/util/Base64ZipV72KeyDeserializer.java delete mode 100644 lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/model/json/util/Base64ZipV72KeySerializer.java delete mode 100644 lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/model/json/util/Base64ZipV73KeySerializer.java delete mode 100644 lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/model/v7_2/key/KeyBackupModel.java delete mode 100644 lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/model/v7_2/secret/SecretEntityToV72BackupConverter.java delete mode 100644 lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/model/v7_3/key/KeyBackupList.java create mode 100644 lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/service/certificate/impl/CertificateBackingEntityGenerator.java create mode 100644 lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/service/key/impl/KeyCreateDetailedInput.java create mode 100644 lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/service/key/impl/KeyImportInput.java create mode 100644 lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/service/secret/impl/SecretCreateInput.java create mode 100644 lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/mapper/v7_3/certificate/CertificateEntityToV73IssuancePolicyModelConverterTest.java create mode 100644 lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/mapper/v7_3/certificate/CertificateEntityToV73PropertiesModelConverterTest.java rename lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/mapper/v7_3/certificate/{LifetimeActionsPolicyToV73ModelConverterTest.java => CertificateLifetimeActionsPolicyToV73ModelConverterTest.java} (78%) rename lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/model/json/util/{Base64ZipV73KeyDeserializerTest.java => Base64ZipKeyDeserializerTest.java} (82%) rename lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/model/json/util/{Base64ZipV72KeySerializerTest.java => Base64ZipKeySerializerTest.java} (83%) delete mode 100644 lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/model/json/util/Base64ZipV72KeyDeserializerTest.java delete mode 100644 lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/model/json/util/Base64ZipV73KeySerializerTest.java diff --git a/build.gradle b/build.gradle index 27b6f506..28523b6a 100644 --- a/build.gradle +++ b/build.gradle @@ -134,8 +134,9 @@ configure(subprojects.findAll({ 'com.github.nagyesta.lowkeyvault.service.exception.NotFoundException', 'com.github.nagyesta.lowkeyvault.service.exception.CryptoException', 'com.github.nagyesta.lowkeyvault.exception.VaultNotFoundException', - //until Cert features are implemented - 'com.github.nagyesta.lowkeyvault.model.v7_3.certificate.DeletedKeyVaultCertificateItemModel' + //until Certificate backup features are implemented + 'com.github.nagyesta.lowkeyvault.model.common.backup.CertificateBackupModel', + 'com.github.nagyesta.lowkeyvault.model.common.backup.CertificateBackupList' ] } } diff --git a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/context/ApiVersionAware.java b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/context/ApiVersionAware.java new file mode 100644 index 00000000..b8616f33 --- /dev/null +++ b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/context/ApiVersionAware.java @@ -0,0 +1,25 @@ +package com.github.nagyesta.lowkeyvault.context; + +import com.github.nagyesta.lowkeyvault.model.common.ApiConstants; + +import java.util.Set; +import java.util.SortedSet; +import java.util.TreeSet; + +public interface ApiVersionAware { + + /** + * Supported API version collection containing only 7.2. + */ + SortedSet V7_2 = new TreeSet<>(Set.of(ApiConstants.V_7_2)); + /** + * Supported API version collection containing only 7.3. + */ + SortedSet V7_3 = new TreeSet<>(Set.of(ApiConstants.V_7_3)); + /** + * Supported API version collection containing both 7.2 and 7.3. + */ + SortedSet V7_2_AND_V7_3 = new TreeSet<>(Set.of(ApiConstants.V_7_2, ApiConstants.V_7_3)); + + SortedSet supportedVersions(); +} diff --git a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/context/CertificateConverterConfiguration.java b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/context/CertificateConverterConfiguration.java new file mode 100644 index 00000000..3741edec --- /dev/null +++ b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/context/CertificateConverterConfiguration.java @@ -0,0 +1,59 @@ +package com.github.nagyesta.lowkeyvault.context; + +import com.github.nagyesta.lowkeyvault.mapper.common.registry.CertificateConverterRegistry; +import com.github.nagyesta.lowkeyvault.mapper.v7_3.certificate.*; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.DependsOn; + +@Configuration +public class CertificateConverterConfiguration { + + @Bean + public CertificateConverterRegistry certificateConverterRegistry() { + return new CertificateConverterRegistry(); + } + + @Bean + public CertificateEntityToV73PropertiesModelConverter certificatePropertiesConverter() { + return new CertificateEntityToV73PropertiesModelConverter(certificateConverterRegistry()); + } + + @Bean + @DependsOn("certificatePropertiesConverter") + public CertificateEntityToV73ModelConverter certificateModelConverter() { + return new CertificateEntityToV73ModelConverter(certificateConverterRegistry()); + } + + @Bean + @DependsOn("certificatePropertiesConverter") + public CertificateEntityToV73CertificateItemModelConverter certificateItemConverter() { + return new CertificateEntityToV73CertificateItemModelConverter(certificateConverterRegistry()); + } + + @Bean + @DependsOn("certificatePropertiesConverter") + public CertificateEntityToV73CertificateVersionItemModelConverter certificateVersionedItemConverter() { + return new CertificateEntityToV73CertificateVersionItemModelConverter(certificateConverterRegistry()); + } + + @Bean + public CertificateEntityToV73PolicyModelConverter certificatePolicyConverter() { + return new CertificateEntityToV73PolicyModelConverter(certificateConverterRegistry()); + } + + @Bean + public CertificateEntityToV73IssuancePolicyModelConverter certificateIssuancePolicyConverter() { + return new CertificateEntityToV73IssuancePolicyModelConverter(certificateConverterRegistry()); + } + + @Bean + public CertificateEntityToV73PendingCertificateOperationModelConverter certificatePendingOperationConverter() { + return new CertificateEntityToV73PendingCertificateOperationModelConverter(certificateConverterRegistry()); + } + + @Bean + public CertificateLifetimeActionsPolicyToV73ModelConverter certificateLifetimeActionConverter() { + return new CertificateLifetimeActionsPolicyToV73ModelConverter(certificateConverterRegistry()); + } +} diff --git a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/context/KeyConverterConfiguration.java b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/context/KeyConverterConfiguration.java new file mode 100644 index 00000000..f368b469 --- /dev/null +++ b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/context/KeyConverterConfiguration.java @@ -0,0 +1,57 @@ +package com.github.nagyesta.lowkeyvault.context; + +import com.github.nagyesta.lowkeyvault.mapper.common.registry.KeyConverterRegistry; +import com.github.nagyesta.lowkeyvault.mapper.v7_2.key.*; +import com.github.nagyesta.lowkeyvault.mapper.v7_3.key.KeyRotationPolicyToV73ModelConverter; +import com.github.nagyesta.lowkeyvault.mapper.v7_3.key.KeyRotationPolicyV73ModelToEntityConverter; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.DependsOn; + +@Configuration +public class KeyConverterConfiguration { + + @Bean + public KeyConverterRegistry keyConverterRegistry() { + return new KeyConverterRegistry(); + } + + @Bean + public KeyEntityToV72PropertiesModelConverter keyPropertiesConverter() { + return new KeyEntityToV72PropertiesModelConverter(keyConverterRegistry()); + } + + @Bean + @DependsOn("keyPropertiesConverter") + public KeyEntityToV72ModelConverter keyModelConverter() { + return new KeyEntityToV72ModelConverter(keyConverterRegistry()); + } + + @Bean + @DependsOn("keyPropertiesConverter") + public KeyEntityToV72KeyItemModelConverter keyItemConverter() { + return new KeyEntityToV72KeyItemModelConverter(keyConverterRegistry()); + } + + @Bean + @DependsOn("keyPropertiesConverter") + public KeyEntityToV72KeyVersionItemModelConverter keyVersionedItemConverter() { + return new KeyEntityToV72KeyVersionItemModelConverter(keyConverterRegistry()); + } + + @Bean + @DependsOn("keyPropertiesConverter") + public KeyEntityToV72BackupConverter keyBackupConverter() { + return new KeyEntityToV72BackupConverter(keyConverterRegistry()); + } + + @Bean + public KeyRotationPolicyToV73ModelConverter keyRotationPolicyModelConverter() { + return new KeyRotationPolicyToV73ModelConverter(keyConverterRegistry()); + } + + @Bean + public KeyRotationPolicyV73ModelToEntityConverter keyRotationPolicyEntityConverter() { + return new KeyRotationPolicyV73ModelToEntityConverter(keyConverterRegistry()); + } +} diff --git a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/context/SecretConverterConfiguration.java b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/context/SecretConverterConfiguration.java new file mode 100644 index 00000000..658cba46 --- /dev/null +++ b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/context/SecretConverterConfiguration.java @@ -0,0 +1,45 @@ +package com.github.nagyesta.lowkeyvault.context; + +import com.github.nagyesta.lowkeyvault.mapper.common.registry.SecretConverterRegistry; +import com.github.nagyesta.lowkeyvault.mapper.v7_2.secret.*; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.DependsOn; + +@Configuration +public class SecretConverterConfiguration { + + @Bean + public SecretConverterRegistry secretConverterRegistry() { + return new SecretConverterRegistry(); + } + + @Bean + public SecretEntityToV72PropertiesModelConverter secretPropertiesConverter() { + return new SecretEntityToV72PropertiesModelConverter(secretConverterRegistry()); + } + + @Bean + @DependsOn("secretPropertiesConverter") + public SecretEntityToV72ModelConverter secretModelConverter() { + return new SecretEntityToV72ModelConverter(secretConverterRegistry()); + } + + @Bean + @DependsOn("secretPropertiesConverter") + public SecretEntityToV72SecretItemModelConverter secretItemConverter() { + return new SecretEntityToV72SecretItemModelConverter(secretConverterRegistry()); + } + + @Bean + @DependsOn("secretPropertiesConverter") + public SecretEntityToV72SecretVersionItemModelConverter secretVersionedItemConverter() { + return new SecretEntityToV72SecretVersionItemModelConverter(secretConverterRegistry()); + } + + @Bean + @DependsOn("secretPropertiesConverter") + public SecretEntityToV72BackupConverter secretBackupConverter() { + return new SecretEntityToV72BackupConverter(secretConverterRegistry()); + } +} diff --git a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/controller/VaultBackupManagementController.java b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/controller/VaultBackupManagementController.java index c83b857b..7c7ab5f8 100644 --- a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/controller/VaultBackupManagementController.java +++ b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/controller/VaultBackupManagementController.java @@ -3,13 +3,13 @@ import com.github.nagyesta.lowkeyvault.controller.v7_3.KeyBackupRestoreController; import com.github.nagyesta.lowkeyvault.controller.v7_3.SecretBackupRestoreController; import com.github.nagyesta.lowkeyvault.model.common.ErrorModel; +import com.github.nagyesta.lowkeyvault.model.common.backup.KeyBackupList; +import com.github.nagyesta.lowkeyvault.model.common.backup.KeyBackupModel; +import com.github.nagyesta.lowkeyvault.model.common.backup.SecretBackupList; +import com.github.nagyesta.lowkeyvault.model.common.backup.SecretBackupModel; import com.github.nagyesta.lowkeyvault.model.management.VaultBackupListModel; import com.github.nagyesta.lowkeyvault.model.management.VaultBackupModel; import com.github.nagyesta.lowkeyvault.model.management.VaultModel; -import com.github.nagyesta.lowkeyvault.model.v7_2.secret.SecretBackupList; -import com.github.nagyesta.lowkeyvault.model.v7_2.secret.SecretBackupModel; -import com.github.nagyesta.lowkeyvault.model.v7_3.key.KeyBackupList; -import com.github.nagyesta.lowkeyvault.model.v7_3.key.KeyBackupModel; import com.github.nagyesta.lowkeyvault.service.exception.NotFoundException; import com.github.nagyesta.lowkeyvault.service.key.ReadOnlyKeyVaultKeyEntity; import com.github.nagyesta.lowkeyvault.service.key.id.VersionedKeyEntityId; diff --git a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/controller/VaultManagementController.java b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/controller/VaultManagementController.java index dda603bb..96b33478 100644 --- a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/controller/VaultManagementController.java +++ b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/controller/VaultManagementController.java @@ -16,7 +16,6 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; -import org.springframework.util.MimeTypeUtils; import org.springframework.web.bind.annotation.*; import javax.validation.Valid; @@ -25,12 +24,13 @@ import java.util.stream.Collectors; import static com.github.nagyesta.lowkeyvault.openapi.Examples.*; +import static org.springframework.util.MimeTypeUtils.APPLICATION_JSON_VALUE; @Slf4j @RestController @RequestMapping(value = "/management/vault", - consumes = MimeTypeUtils.APPLICATION_JSON_VALUE, - produces = MimeTypeUtils.APPLICATION_JSON_VALUE) + consumes = APPLICATION_JSON_VALUE, + produces = APPLICATION_JSON_VALUE) public class VaultManagementController extends ErrorHandlingAwareController { private final VaultService vaultService; @@ -48,29 +48,15 @@ public VaultManagementController(@NonNull final VaultService vaultService, summary = "Create a vault", responses = { @ApiResponse(responseCode = "200", description = "Operation completed", - content = @Content( - mediaType = MimeTypeUtils.APPLICATION_JSON_VALUE, - schema = @Schema(implementation = VaultModel.class) - )), + content = @Content(mediaType = APPLICATION_JSON_VALUE, schema = @Schema(implementation = VaultModel.class))), @ApiResponse(responseCode = "404", description = "Vault not found", - content = @Content( - mediaType = MimeTypeUtils.APPLICATION_JSON_VALUE, - schema = @Schema(implementation = ErrorModel.class) - )), + content = @Content(mediaType = APPLICATION_JSON_VALUE, schema = @Schema(implementation = ErrorModel.class))), @ApiResponse(responseCode = "400", description = "Validation Failure", - content = @Content( - mediaType = MimeTypeUtils.APPLICATION_JSON_VALUE, - schema = @Schema(implementation = ErrorModel.class) - )), + content = @Content(mediaType = APPLICATION_JSON_VALUE, schema = @Schema(implementation = ErrorModel.class))), @ApiResponse(responseCode = "500", description = "Internal error", - content = @Content( - mediaType = MimeTypeUtils.APPLICATION_JSON_VALUE, - schema = @Schema(implementation = ErrorModel.class) - ))}, + content = @Content(mediaType = APPLICATION_JSON_VALUE, schema = @Schema(implementation = ErrorModel.class)))}, requestBody = @RequestBody( - content = @Content( - mediaType = MimeTypeUtils.APPLICATION_JSON_VALUE, - schema = @Schema(implementation = VaultModel.class)))) + content = @Content(mediaType = APPLICATION_JSON_VALUE, schema = @Schema(implementation = VaultModel.class)))) @PostMapping public ResponseEntity createVault(@Valid @org.springframework.web.bind.annotation.RequestBody final VaultModel model) { log.info("Received request to create vault with uri: {}, recovery level: {}, recoverable days: {}", @@ -84,15 +70,11 @@ public ResponseEntity createVault(@Valid @org.springframework.web.bi summary = "List active vaults", responses = { @ApiResponse(responseCode = "200", description = "Operation completed (result in response body)", - content = @Content( - mediaType = MimeTypeUtils.APPLICATION_JSON_VALUE, + content = @Content(mediaType = APPLICATION_JSON_VALUE, array = @ArraySchema(schema = @Schema(implementation = VaultModel.class)))), @ApiResponse(responseCode = "500", description = "Internal error", - content = @Content( - mediaType = MimeTypeUtils.APPLICATION_JSON_VALUE, - schema = @Schema(implementation = ErrorModel.class) - ))}, - requestBody = @RequestBody(content = @Content(mediaType = MimeTypeUtils.APPLICATION_JSON_VALUE))) + content = @Content(mediaType = APPLICATION_JSON_VALUE, schema = @Schema(implementation = ErrorModel.class)))}, + requestBody = @RequestBody(content = @Content(mediaType = APPLICATION_JSON_VALUE))) @GetMapping public ResponseEntity> listVaults() { log.info("Received request to list vaults."); @@ -107,15 +89,11 @@ public ResponseEntity> listVaults() { summary = "List deleted vaults", responses = { @ApiResponse(responseCode = "200", description = "Operation completed (result in response body)", - content = @Content( - mediaType = MimeTypeUtils.APPLICATION_JSON_VALUE, + content = @Content(mediaType = APPLICATION_JSON_VALUE, array = @ArraySchema(schema = @Schema(implementation = VaultModel.class)))), @ApiResponse(responseCode = "500", description = "Internal error", - content = @Content( - mediaType = MimeTypeUtils.APPLICATION_JSON_VALUE, - schema = @Schema(implementation = ErrorModel.class) - ))}, - requestBody = @RequestBody(content = @Content(mediaType = MimeTypeUtils.APPLICATION_JSON_VALUE))) + content = @Content(mediaType = APPLICATION_JSON_VALUE, schema = @Schema(implementation = ErrorModel.class)))}, + requestBody = @RequestBody(content = @Content(mediaType = APPLICATION_JSON_VALUE))) @GetMapping("/deleted") public ResponseEntity> listDeletedVaults() { log.info("Received request to list deleted vaults."); @@ -130,30 +108,17 @@ public ResponseEntity> listDeletedVaults() { summary = "Delete a vault", responses = { @ApiResponse(responseCode = "200", description = "Operation completed (result in response body)", - content = @Content( - mediaType = MimeTypeUtils.APPLICATION_JSON_VALUE, - schema = @Schema( - implementation = Boolean.class, - description = "True if the operation changed anything.") - )), + content = @Content(mediaType = APPLICATION_JSON_VALUE, schema = @Schema(implementation = Boolean.class, + description = "True if the operation changed something."))), @ApiResponse(responseCode = "404", description = "Vault not found", - content = @Content( - mediaType = MimeTypeUtils.APPLICATION_JSON_VALUE, - schema = @Schema(implementation = ErrorModel.class) - )), + content = @Content(mediaType = APPLICATION_JSON_VALUE, schema = @Schema(implementation = ErrorModel.class))), @ApiResponse(responseCode = "400", description = "Validation Failure", - content = @Content( - mediaType = MimeTypeUtils.APPLICATION_JSON_VALUE, - schema = @Schema(implementation = ErrorModel.class) - )), + content = @Content(mediaType = APPLICATION_JSON_VALUE, schema = @Schema(implementation = ErrorModel.class))), @ApiResponse(responseCode = "500", description = "Internal error", - content = @Content( - mediaType = MimeTypeUtils.APPLICATION_JSON_VALUE, - schema = @Schema(implementation = ErrorModel.class) - ))}, + content = @Content(mediaType = APPLICATION_JSON_VALUE, schema = @Schema(implementation = ErrorModel.class)))}, parameters = { @Parameter(name = "baseUri", example = BASE_URI, description = "The base URI of the vault we want delete.")}, - requestBody = @RequestBody(content = @Content(mediaType = MimeTypeUtils.APPLICATION_JSON_VALUE))) + requestBody = @RequestBody(content = @Content(mediaType = APPLICATION_JSON_VALUE))) @DeleteMapping public ResponseEntity deleteVault(@RequestParam final URI baseUri) { log.info("Received request to delete vault with uri: {}", baseUri); @@ -164,28 +129,16 @@ public ResponseEntity deleteVault(@RequestParam final URI baseUri) { summary = "Recover a deleted vault", responses = { @ApiResponse(responseCode = "200", description = "Operation completed", - content = @Content( - mediaType = MimeTypeUtils.APPLICATION_JSON_VALUE, - schema = @Schema(implementation = VaultModel.class) - )), + content = @Content(mediaType = APPLICATION_JSON_VALUE, schema = @Schema(implementation = VaultModel.class))), @ApiResponse(responseCode = "404", description = "Vault not found", - content = @Content( - mediaType = MimeTypeUtils.APPLICATION_JSON_VALUE, - schema = @Schema(implementation = ErrorModel.class) - )), + content = @Content(mediaType = APPLICATION_JSON_VALUE, schema = @Schema(implementation = ErrorModel.class))), @ApiResponse(responseCode = "400", description = "Validation Failure", - content = @Content( - mediaType = MimeTypeUtils.APPLICATION_JSON_VALUE, - schema = @Schema(implementation = ErrorModel.class) - )), + content = @Content(mediaType = APPLICATION_JSON_VALUE, schema = @Schema(implementation = ErrorModel.class))), @ApiResponse(responseCode = "500", description = "Internal error", - content = @Content( - mediaType = MimeTypeUtils.APPLICATION_JSON_VALUE, - schema = @Schema(implementation = ErrorModel.class) - ))}, + content = @Content(mediaType = APPLICATION_JSON_VALUE, schema = @Schema(implementation = ErrorModel.class)))}, parameters = { @Parameter(name = "baseUri", example = BASE_URI, description = "The base URI of the vault we want to recover.")}, - requestBody = @RequestBody(content = @Content(mediaType = MimeTypeUtils.APPLICATION_JSON_VALUE))) + requestBody = @RequestBody(content = @Content(mediaType = APPLICATION_JSON_VALUE))) @PutMapping("/recover") public ResponseEntity recoverVault(@RequestParam final URI baseUri) { log.info("Received request to recover deleted vault with uri: {}", baseUri); @@ -198,30 +151,17 @@ public ResponseEntity recoverVault(@RequestParam final URI baseUri) summary = "Purge a deleted vault", responses = { @ApiResponse(responseCode = "200", description = "Operation completed (result in response body)", - content = @Content( - mediaType = MimeTypeUtils.APPLICATION_JSON_VALUE, - schema = @Schema( - implementation = Boolean.class, - description = "True if the operation changed anything.") - )), + content = @Content(mediaType = APPLICATION_JSON_VALUE, schema = @Schema(implementation = Boolean.class, + description = "True if the operation changed something."))), @ApiResponse(responseCode = "404", description = "Vault not found", - content = @Content( - mediaType = MimeTypeUtils.APPLICATION_JSON_VALUE, - schema = @Schema(implementation = ErrorModel.class) - )), + content = @Content(mediaType = APPLICATION_JSON_VALUE, schema = @Schema(implementation = ErrorModel.class))), @ApiResponse(responseCode = "400", description = "Validation Failure", - content = @Content( - mediaType = MimeTypeUtils.APPLICATION_JSON_VALUE, - schema = @Schema(implementation = ErrorModel.class) - )), + content = @Content(mediaType = APPLICATION_JSON_VALUE, schema = @Schema(implementation = ErrorModel.class))), @ApiResponse(responseCode = "500", description = "Internal error", - content = @Content( - mediaType = MimeTypeUtils.APPLICATION_JSON_VALUE, - schema = @Schema(implementation = ErrorModel.class) - ))}, + content = @Content(mediaType = APPLICATION_JSON_VALUE, schema = @Schema(implementation = ErrorModel.class)))}, parameters = { @Parameter(name = "baseUri", example = BASE_URI, description = "The base URI of the vault we want to purge.")}, - requestBody = @RequestBody(content = @Content(mediaType = MimeTypeUtils.APPLICATION_JSON_VALUE))) + requestBody = @RequestBody(content = @Content(mediaType = APPLICATION_JSON_VALUE))) @DeleteMapping("/purge") public ResponseEntity purgeVault(@RequestParam final URI baseUri) { log.info("Received request to purge deleted vault with uri: {}", baseUri); @@ -232,25 +172,13 @@ public ResponseEntity purgeVault(@RequestParam final URI baseUri) { summary = "Update aliases of a vault", responses = { @ApiResponse(responseCode = "200", description = "Operation completed (result in response body)", - content = @Content( - mediaType = MimeTypeUtils.APPLICATION_JSON_VALUE, - schema = @Schema(implementation = VaultModel.class) - )), + content = @Content(mediaType = APPLICATION_JSON_VALUE, schema = @Schema(implementation = VaultModel.class))), @ApiResponse(responseCode = "404", description = "Vault not found", - content = @Content( - mediaType = MimeTypeUtils.APPLICATION_JSON_VALUE, - schema = @Schema(implementation = ErrorModel.class) - )), + content = @Content(mediaType = APPLICATION_JSON_VALUE, schema = @Schema(implementation = ErrorModel.class))), @ApiResponse(responseCode = "400", description = "Validation Failure", - content = @Content( - mediaType = MimeTypeUtils.APPLICATION_JSON_VALUE, - schema = @Schema(implementation = ErrorModel.class) - )), + content = @Content(mediaType = APPLICATION_JSON_VALUE, schema = @Schema(implementation = ErrorModel.class))), @ApiResponse(responseCode = "500", description = "Internal error", - content = @Content( - mediaType = MimeTypeUtils.APPLICATION_JSON_VALUE, - schema = @Schema(implementation = ErrorModel.class) - ))}, + content = @Content(mediaType = APPLICATION_JSON_VALUE, schema = @Schema(implementation = ErrorModel.class)))}, parameters = { @Parameter(name = "baseUri", example = BASE_URI, description = "The base URI of the vault we want to update."), @@ -258,7 +186,7 @@ public ResponseEntity purgeVault(@RequestParam final URI baseUri) { description = "The base URI we want to add to the aliases of the vault.", required = false), @Parameter(name = "remove", example = ALIAS2, description = "The base URI we want to remove from the aliases of the vault.", required = false)}, - requestBody = @RequestBody(content = @Content(mediaType = MimeTypeUtils.APPLICATION_JSON_VALUE))) + requestBody = @RequestBody(content = @Content(mediaType = APPLICATION_JSON_VALUE))) @PatchMapping("/alias") public ResponseEntity aliasUpdate(@RequestParam final URI baseUri, @RequestParam(required = false) final URI add, @@ -272,24 +200,16 @@ public ResponseEntity aliasUpdate(@RequestParam final URI baseUri, summary = "Time shift for ALL vaults", responses = { @ApiResponse(responseCode = "204", description = "Successful Operation", - content = @Content( - mediaType = MimeTypeUtils.APPLICATION_JSON_VALUE - )), + content = @Content(mediaType = APPLICATION_JSON_VALUE)), @ApiResponse(responseCode = "400", description = "Validation Failure", - content = @Content( - mediaType = MimeTypeUtils.APPLICATION_JSON_VALUE, - schema = @Schema(implementation = ErrorModel.class) - )), + content = @Content(mediaType = APPLICATION_JSON_VALUE, schema = @Schema(implementation = ErrorModel.class))), @ApiResponse(responseCode = "500", description = "Internal error", - content = @Content( - mediaType = MimeTypeUtils.APPLICATION_JSON_VALUE, - schema = @Schema(implementation = ErrorModel.class) - ))}, + content = @Content(mediaType = APPLICATION_JSON_VALUE, schema = @Schema(implementation = ErrorModel.class)))}, parameters = { @Parameter(name = "seconds", example = ONE, description = "The number of seconds we want to shift."), @Parameter(name = "regenerateCertificates", example = FALSE, description = "Whether we allow regeneration of certificates to let their validity match the new time-frame.")}, - requestBody = @RequestBody(content = @Content(mediaType = MimeTypeUtils.APPLICATION_JSON_VALUE))) + requestBody = @RequestBody(content = @Content(mediaType = APPLICATION_JSON_VALUE))) @PutMapping(value = "/time/all", params = {"seconds"}) public ResponseEntity timeShiftAll( @RequestParam final int seconds, @@ -304,30 +224,19 @@ public ResponseEntity timeShiftAll( summary = "Time shift for a single vault", responses = { @ApiResponse(responseCode = "204", description = "Successful Operation", - content = @Content( - mediaType = MimeTypeUtils.APPLICATION_JSON_VALUE - )), + content = @Content(mediaType = APPLICATION_JSON_VALUE)), @ApiResponse(responseCode = "404", description = "Vault not found", - content = @Content( - mediaType = MimeTypeUtils.APPLICATION_JSON_VALUE, - schema = @Schema(implementation = ErrorModel.class) - )), + content = @Content(mediaType = APPLICATION_JSON_VALUE, schema = @Schema(implementation = ErrorModel.class))), @ApiResponse(responseCode = "400", description = "Validation Failure", - content = @Content( - mediaType = MimeTypeUtils.APPLICATION_JSON_VALUE, - schema = @Schema(implementation = ErrorModel.class) - )), + content = @Content(mediaType = APPLICATION_JSON_VALUE, schema = @Schema(implementation = ErrorModel.class))), @ApiResponse(responseCode = "500", description = "Internal error", - content = @Content( - mediaType = MimeTypeUtils.APPLICATION_JSON_VALUE, - schema = @Schema(implementation = ErrorModel.class) - ))}, + content = @Content(mediaType = APPLICATION_JSON_VALUE, schema = @Schema(implementation = ErrorModel.class)))}, parameters = { @Parameter(name = "seconds", example = ONE, description = "The number of seconds we want to shift."), @Parameter(name = "baseUri", example = BASE_URI, description = "The base URI of the vault we want to shift."), @Parameter(name = "regenerateCertificates", example = FALSE, description = "Whether we allow regeneration of certificates to let their validity match the new time-frame.")}, - requestBody = @RequestBody(content = @Content(mediaType = MimeTypeUtils.APPLICATION_JSON_VALUE))) + requestBody = @RequestBody(content = @Content(mediaType = APPLICATION_JSON_VALUE))) @PutMapping(value = "/time", params = {"baseUri", "seconds"}) public ResponseEntity timeShiftSingle( @RequestParam final URI baseUri, @RequestParam final int seconds, diff --git a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/controller/common/BaseBackupRestoreController.java b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/controller/common/BaseBackupRestoreController.java index a9a27d64..dcc595ac 100644 --- a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/controller/common/BaseBackupRestoreController.java +++ b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/controller/common/BaseBackupRestoreController.java @@ -1,6 +1,6 @@ package com.github.nagyesta.lowkeyvault.controller.common; -import com.github.nagyesta.lowkeyvault.mapper.common.BackupConverter; +import com.github.nagyesta.lowkeyvault.mapper.common.BaseEntityConverterRegistry; import com.github.nagyesta.lowkeyvault.mapper.common.RecoveryAwareConverter; import com.github.nagyesta.lowkeyvault.model.v7_2.BasePropertiesModel; import com.github.nagyesta.lowkeyvault.model.v7_2.common.BaseBackupListItem; @@ -10,16 +10,13 @@ import com.github.nagyesta.lowkeyvault.service.common.BaseVaultEntity; import com.github.nagyesta.lowkeyvault.service.common.BaseVaultFake; import com.github.nagyesta.lowkeyvault.service.common.ReadOnlyVersionedEntityMultiMap; -import com.github.nagyesta.lowkeyvault.service.common.impl.KeyVaultBaseEntity; import com.github.nagyesta.lowkeyvault.service.vault.VaultFake; import com.github.nagyesta.lowkeyvault.service.vault.VaultService; -import lombok.NonNull; +import org.springframework.lang.NonNull; import org.springframework.util.Assert; import java.net.URI; import java.util.List; -import java.util.Map; -import java.util.Objects; import java.util.Optional; import java.util.function.Function; import java.util.stream.Collectors; @@ -27,34 +24,36 @@ /** * The base implementation of the backup/restore controllers. * - * @param The type of the entity id (not versioned). - * @param The versioned entity id type. + * @param The type of the key (not versioned). + * @param The versioned key type. * @param The entity type. * @param The entity model type. * @param The deleted entity model type. - * @param

The type of the properties model. - * @param The type of the list item representing one entity version in the backup model. - * @param The wrapper type of the list in the backup model. - * @param The type of the backup model. + * @param The item model type. + * @param The deleted item model type. * @param The model converter, converting entities to entity models. - * @param The converter, converting entities to list items of the backup models. + * @param The item converter, converting version item entities to item models. + * @param The versioned item converter, converting version item entities to item models. * @param The fake type holding the entities. + * @param The type of the PropertiesModel. + * @param The list item type of the backup lists. + * @param The type of the backup list. + * @param The type of the backup model. + * @param The ConverterRegistry used for conversions. */ -public abstract class BaseBackupRestoreController, M, DM extends M, - P extends BasePropertiesModel, BLI extends BaseBackupListItem

, BL extends BackupListContainer, - B extends BaseBackupModel, BC extends BackupConverter, MC extends RecoveryAwareConverter, - S extends BaseVaultFake> extends BaseEntityReadController { - - private final MC modelConverter; - private final BC backupConverter; - - protected BaseBackupRestoreController(@NonNull final MC modelConverter, - @NonNull final BC backupConverter, - @org.springframework.lang.NonNull final VaultService vaultService, - @org.springframework.lang.NonNull final Function toEntityVault) { - super(vaultService, toEntityVault); - this.modelConverter = modelConverter; - this.backupConverter = backupConverter; +public abstract class BaseBackupRestoreController, + M, DM extends M, I, DI extends I, MC extends RecoveryAwareConverter, + IC extends RecoveryAwareConverter, VIC extends RecoveryAwareConverter, + S extends BaseVaultFake, PM extends BasePropertiesModel, + BLI extends BaseBackupListItem, BL extends BackupListContainer, + B extends BaseBackupModel, + R extends BaseEntityConverterRegistry> + extends GenericEntityController { + + protected BaseBackupRestoreController(@NonNull final R registry, + @NonNull final VaultService vaultService, + @NonNull final Function toEntityVault) { + super(registry, vaultService, toEntityVault); } protected M restoreEntity(final B backupModel) { @@ -69,28 +68,17 @@ protected M restoreEntity(final B backupModel) { }); final V latestVersionOfEntity = vault.getEntities().getLatestVersionOfEntity(entityId); final E readOnlyEntity = vault.getEntities().getReadOnlyEntity(latestVersionOfEntity); - return modelConverter.convert(readOnlyEntity, baseUri); + return registry().modelConverter(apiVersion()).convert(readOnlyEntity, baseUri); } protected abstract void restoreVersion(S vault, V versionedEntityId, BLI entityVersion); - protected void updateCommonFields(final BLI entityVersion, final KeyVaultBaseEntity entity) { - final P attributes = entityVersion.getAttributes(); - entity.setTags(Objects.requireNonNullElse(entityVersion.getTags(), Map.of())); - entity.setExpiry(attributes.getExpiresOn()); - entity.setEnabled(attributes.isEnabled()); - entity.setNotBefore(attributes.getNotBefore()); - entity.setManaged(entityVersion.isManaged()); - entity.setCreatedOn(attributes.getCreatedOn()); - entity.setUpdatedOn(attributes.getUpdatedOn()); - } - protected B backupEntity(final K entityId) { final ReadOnlyVersionedEntityMultiMap entities = getVaultByUri(entityId.vault()) .getEntities(); final List list = entities.getVersions(entityId).stream() .map(version -> getEntityByNameAndVersion(entityId.vault(), entityId.id(), version)) - .map(backupConverter::convert) + .map(registry().backupConverter(apiVersion())::convert) .collect(Collectors.toUnmodifiableList()); return wrapBackup(list); } diff --git a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/controller/common/BaseCertificateController.java b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/controller/common/BaseCertificateController.java new file mode 100644 index 00000000..520f6fee --- /dev/null +++ b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/controller/common/BaseCertificateController.java @@ -0,0 +1,73 @@ +package com.github.nagyesta.lowkeyvault.controller.common; + +import com.github.nagyesta.lowkeyvault.mapper.common.registry.CertificateConverterRegistry; +import com.github.nagyesta.lowkeyvault.mapper.v7_3.certificate.CertificateEntityToV73CertificateItemModelConverter; +import com.github.nagyesta.lowkeyvault.mapper.v7_3.certificate.CertificateEntityToV73CertificateVersionItemModelConverter; +import com.github.nagyesta.lowkeyvault.mapper.v7_3.certificate.CertificateEntityToV73ModelConverter; +import com.github.nagyesta.lowkeyvault.model.common.backup.CertificateBackupList; +import com.github.nagyesta.lowkeyvault.model.common.backup.CertificateBackupListItem; +import com.github.nagyesta.lowkeyvault.model.common.backup.CertificateBackupModel; +import com.github.nagyesta.lowkeyvault.model.v7_3.certificate.*; +import com.github.nagyesta.lowkeyvault.service.certificate.CertificateVaultFake; +import com.github.nagyesta.lowkeyvault.service.certificate.ReadOnlyKeyVaultCertificateEntity; +import com.github.nagyesta.lowkeyvault.service.certificate.id.CertificateEntityId; +import com.github.nagyesta.lowkeyvault.service.certificate.id.VersionedCertificateEntityId; +import com.github.nagyesta.lowkeyvault.service.vault.VaultFake; +import com.github.nagyesta.lowkeyvault.service.vault.VaultService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.lang.NonNull; + +import java.net.URI; +import java.util.Optional; + +@Slf4j +public abstract class BaseCertificateController extends GenericEntityController { + + /** + * Default parameter value for including the pending certificates. + */ + protected static final String TRUE = "true"; + /** + * Parameter name for including the pending certificates. + */ + protected static final String INCLUDE_PENDING_PARAM = "includePending"; + + protected BaseCertificateController( + @NonNull final CertificateConverterRegistry registry, + @NonNull final VaultService vaultService) { + super(registry, vaultService, VaultFake::certificateVaultFake); + } + + @Override + protected KeyVaultCertificateModel getModelById( + final CertificateVaultFake entityVaultFake, + final VersionedCertificateEntityId entityId, + final URI baseUri, + final boolean includeDisabled) { + final KeyVaultCertificateModel model = super.getModelById(entityVaultFake, entityId, baseUri, includeDisabled); + populateLifetimeActions(entityVaultFake, entityId, model.getPolicy()); + return model; + } + + @Override + protected DeletedKeyVaultCertificateModel getDeletedModelById( + final CertificateVaultFake entityVaultFake, + final VersionedCertificateEntityId entityId, + final URI baseUri, + final boolean includeDisabled) { + final DeletedKeyVaultCertificateModel model = super.getDeletedModelById(entityVaultFake, entityId, baseUri, includeDisabled); + populateLifetimeActions(entityVaultFake, entityId, model.getPolicy()); + return model; + } + + protected void populateLifetimeActions( + final CertificateVaultFake vaultFake, final VersionedCertificateEntityId entityId, final CertificatePolicyModel model) { + Optional.ofNullable(vaultFake.lifetimeActionPolicy(entityId)) + .map(registry().lifetimeActionConverters(apiVersion())::convert) + .ifPresent(model::setLifetimeActions); + } +} diff --git a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/controller/common/BaseKeyController.java b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/controller/common/BaseKeyController.java new file mode 100644 index 00000000..90a92fc6 --- /dev/null +++ b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/controller/common/BaseKeyController.java @@ -0,0 +1,70 @@ +package com.github.nagyesta.lowkeyvault.controller.common; + +import com.github.nagyesta.lowkeyvault.mapper.common.registry.KeyConverterRegistry; +import com.github.nagyesta.lowkeyvault.mapper.v7_2.key.KeyEntityToV72KeyItemModelConverter; +import com.github.nagyesta.lowkeyvault.mapper.v7_2.key.KeyEntityToV72KeyVersionItemModelConverter; +import com.github.nagyesta.lowkeyvault.mapper.v7_2.key.KeyEntityToV72ModelConverter; +import com.github.nagyesta.lowkeyvault.model.common.backup.KeyBackupList; +import com.github.nagyesta.lowkeyvault.model.common.backup.KeyBackupListItem; +import com.github.nagyesta.lowkeyvault.model.common.backup.KeyBackupModel; +import com.github.nagyesta.lowkeyvault.model.v7_2.BasePropertiesUpdateModel; +import com.github.nagyesta.lowkeyvault.model.v7_2.key.*; +import com.github.nagyesta.lowkeyvault.model.v7_2.key.request.CreateKeyRequest; +import com.github.nagyesta.lowkeyvault.model.v7_2.key.request.ImportKeyRequest; +import com.github.nagyesta.lowkeyvault.service.key.KeyVaultFake; +import com.github.nagyesta.lowkeyvault.service.key.ReadOnlyKeyVaultKeyEntity; +import com.github.nagyesta.lowkeyvault.service.key.id.KeyEntityId; +import com.github.nagyesta.lowkeyvault.service.key.id.VersionedKeyEntityId; +import com.github.nagyesta.lowkeyvault.service.key.impl.KeyCreateDetailedInput; +import com.github.nagyesta.lowkeyvault.service.key.impl.KeyImportInput; +import com.github.nagyesta.lowkeyvault.service.vault.VaultFake; +import com.github.nagyesta.lowkeyvault.service.vault.VaultService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.lang.NonNull; + +import java.util.Objects; + +@Slf4j +public abstract class BaseKeyController extends GenericEntityController { + + protected BaseKeyController(@NonNull final KeyConverterRegistry registry, + @NonNull final VaultService vaultService) { + super(registry, vaultService, VaultFake::keyVaultFake); + } + + protected VersionedKeyEntityId createKeyWithAttributes( + final KeyVaultFake keyVaultFake, final String keyName, final CreateKeyRequest request) { + final KeyPropertiesModel properties = Objects.requireNonNullElse(request.getProperties(), new KeyPropertiesModel()); + //no need to set managed property as this endpoint cannot create managed entities by definition + return keyVaultFake.createKeyVersion(keyName, KeyCreateDetailedInput.builder() + .key(request.toKeyCreationInput()) + .keyOperations(request.getKeyOperations()) + .tags(request.getTags()) + .expiresOn(properties.getExpiresOn()) + .notBefore(properties.getNotBefore()) + .enabled(properties.isEnabled()) + .hsm(request.getKeyType().isHsm()) + .managed(false) + .build()); + } + + protected VersionedKeyEntityId importKeyWithAttributes( + final KeyVaultFake keyVaultFake, final String keyName, final ImportKeyRequest request) { + final BasePropertiesUpdateModel properties = Objects + .requireNonNullElse(request.getProperties(), new BasePropertiesUpdateModel()); + return keyVaultFake.importKeyVersion(keyName, KeyImportInput.builder() + .key(request.getKey()) + .hsm(request.getHsm()) + .tags(request.getTags()) + .enabled(properties.getEnabled()) + .expiresOn(properties.getExpiresOn()) + .notBefore(properties.getNotBefore()) + .createdOn(null) + .updatedOn(null) + .managed(false) + .build()); + } +} diff --git a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/controller/common/BaseSecretController.java b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/controller/common/BaseSecretController.java new file mode 100644 index 00000000..7d32a053 --- /dev/null +++ b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/controller/common/BaseSecretController.java @@ -0,0 +1,48 @@ +package com.github.nagyesta.lowkeyvault.controller.common; + +import com.github.nagyesta.lowkeyvault.mapper.common.registry.SecretConverterRegistry; +import com.github.nagyesta.lowkeyvault.mapper.v7_2.secret.SecretEntityToV72ModelConverter; +import com.github.nagyesta.lowkeyvault.mapper.v7_2.secret.SecretEntityToV72SecretItemModelConverter; +import com.github.nagyesta.lowkeyvault.mapper.v7_2.secret.SecretEntityToV72SecretVersionItemModelConverter; +import com.github.nagyesta.lowkeyvault.model.common.backup.SecretBackupList; +import com.github.nagyesta.lowkeyvault.model.common.backup.SecretBackupListItem; +import com.github.nagyesta.lowkeyvault.model.common.backup.SecretBackupModel; +import com.github.nagyesta.lowkeyvault.model.v7_2.secret.*; +import com.github.nagyesta.lowkeyvault.model.v7_2.secret.request.CreateSecretRequest; +import com.github.nagyesta.lowkeyvault.service.secret.ReadOnlyKeyVaultSecretEntity; +import com.github.nagyesta.lowkeyvault.service.secret.SecretVaultFake; +import com.github.nagyesta.lowkeyvault.service.secret.id.SecretEntityId; +import com.github.nagyesta.lowkeyvault.service.secret.id.VersionedSecretEntityId; +import com.github.nagyesta.lowkeyvault.service.secret.impl.SecretCreateInput; +import com.github.nagyesta.lowkeyvault.service.vault.VaultFake; +import com.github.nagyesta.lowkeyvault.service.vault.VaultService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.lang.NonNull; + +import java.util.Objects; + +@Slf4j +public abstract class BaseSecretController extends GenericEntityController { + + protected BaseSecretController(@NonNull final SecretConverterRegistry registry, @NonNull final VaultService vaultService) { + super(registry, vaultService, VaultFake::secretVaultFake); + } + + protected VersionedSecretEntityId createSecretWithAttributes( + final SecretVaultFake secretVaultFake, final String secretName, final CreateSecretRequest request) { + final SecretPropertiesModel properties = Objects.requireNonNullElse(request.getProperties(), new SecretPropertiesModel()); + return secretVaultFake.createSecretVersion(secretName, SecretCreateInput.builder() + .value(request.getValue()) + .contentType(request.getContentType()) + .tags(request.getTags()) + .expiresOn(properties.getExpiresOn()) + .notBefore(properties.getNotBefore()) + .enabled(properties.isEnabled()) + .managed(false) + .build()); + } +} diff --git a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/controller/common/CommonCertificateController.java b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/controller/common/CommonCertificateController.java index ab7f9b74..b11da9f6 100644 --- a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/controller/common/CommonCertificateController.java +++ b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/controller/common/CommonCertificateController.java @@ -1,13 +1,12 @@ package com.github.nagyesta.lowkeyvault.controller.common; -import com.github.nagyesta.lowkeyvault.mapper.v7_3.certificate.*; +import com.github.nagyesta.lowkeyvault.mapper.common.registry.CertificateConverterRegistry; import com.github.nagyesta.lowkeyvault.model.common.KeyVaultItemListModel; import com.github.nagyesta.lowkeyvault.model.v7_3.certificate.*; import com.github.nagyesta.lowkeyvault.service.certificate.CertificateVaultFake; import com.github.nagyesta.lowkeyvault.service.certificate.ReadOnlyKeyVaultCertificateEntity; import com.github.nagyesta.lowkeyvault.service.certificate.id.CertificateEntityId; import com.github.nagyesta.lowkeyvault.service.certificate.id.VersionedCertificateEntityId; -import com.github.nagyesta.lowkeyvault.service.vault.VaultFake; import com.github.nagyesta.lowkeyvault.service.vault.VaultService; import lombok.extern.slf4j.Slf4j; import org.springframework.http.ResponseEntity; @@ -17,38 +16,18 @@ import javax.validation.Valid; import javax.validation.constraints.Pattern; import java.net.URI; -import java.util.Optional; +import java.util.Map; import static com.github.nagyesta.lowkeyvault.controller.common.util.CertificateRequestMapperUtil.createCertificateWithAttributes; import static com.github.nagyesta.lowkeyvault.controller.common.util.CertificateRequestMapperUtil.importCertificateWithAttributes; @Slf4j -public abstract class CommonCertificateController extends GenericEntityController { - - /** - * Default parameter value for including the pending certificates. - */ - protected static final String TRUE = "true"; - /** - * Parameter name for including the pending certificates. - */ - protected static final String INCLUDE_PENDING_PARAM = "includePending"; - private final CertificateEntityToV73PendingCertificateOperationModelConverter pendingModelConverter; - private final LifetimeActionsPolicyToV73ModelConverter lifetimeActionsModelConverter; +public abstract class CommonCertificateController extends BaseCertificateController { protected CommonCertificateController( - @NonNull final CertificateEntityToV73ModelConverter modelConverter, - @NonNull final CertificateEntityToV73CertificateItemModelConverter itemModelConverter, - @NonNull final CertificateEntityToV73CertificateVersionItemModelConverter versionItemModelConverter, - @lombok.NonNull final CertificateEntityToV73PendingCertificateOperationModelConverter pendingModelConverter, - @lombok.NonNull final LifetimeActionsPolicyToV73ModelConverter lifetimeActionsModelConverter, + @NonNull final CertificateConverterRegistry registry, @NonNull final VaultService vaultService) { - super(modelConverter, itemModelConverter, versionItemModelConverter, vaultService, VaultFake::certificateVaultFake); - this.pendingModelConverter = pendingModelConverter; - this.lifetimeActionsModelConverter = lifetimeActionsModelConverter; + super(registry, vaultService); } public ResponseEntity create( @@ -61,7 +40,7 @@ public ResponseEntity create( final CertificateVaultFake vaultFake = getVaultByUri(baseUri); final VersionedCertificateEntityId entityId = createCertificateWithAttributes(vaultFake, certificateName, request); final ReadOnlyKeyVaultCertificateEntity readOnlyEntity = vaultFake.getEntities().getReadOnlyEntity(entityId); - return ResponseEntity.accepted().body(pendingModelConverter.convert(readOnlyEntity, baseUri)); + return ResponseEntity.accepted().body(registry().pendingOperationConverters(apiVersion()).convert(readOnlyEntity, baseUri)); } @@ -154,8 +133,13 @@ public ResponseEntity> versi log.info("Received request to {} list certificate versions: {} , (max results: {}, skip: {}) using API version: {}", baseUri.toString(), certificateName, maxResults, skipToken, apiVersion()); - return ResponseEntity.ok(getPageOfItemVersions( - baseUri, certificateName, maxResults, skipToken, "/certificates/" + certificateName + "/versions")); + return ResponseEntity.ok(getPageOfItemVersions(baseUri, certificateName, PaginationContext + .builder() + .apiVersion(apiVersion()) + .limit(maxResults) + .offset(skipToken) + .base(URI.create(baseUri + "/certificates/" + certificateName + "/versions")) + .build())); } public ResponseEntity> listCertificates( @@ -166,7 +150,14 @@ public ResponseEntity> listC log.info("Received request to {} list certificates, (max results: {}, skip: {}, includePending: {}) using API version: {}", baseUri.toString(), maxResults, skipToken, includePending, apiVersion()); - return ResponseEntity.ok(getPageOfItems(baseUri, maxResults, skipToken, includePending)); + return ResponseEntity.ok(getPageOfItems(baseUri, PaginationContext + .builder() + .apiVersion(apiVersion()) + .limit(maxResults) + .offset(skipToken) + .base(URI.create(baseUri + "/certificates")) + .additionalParameters(Map.of(INCLUDE_PENDING_PARAM, String.valueOf(includePending))) + .build())); } public ResponseEntity> listDeletedCertificates( @@ -177,62 +168,13 @@ public ResponseEntity log.info("Received request to {} list deleted certificates, (max results: {}, skip: {}, includePending: {}) using API version: {}", baseUri.toString(), maxResults, skipToken, includePending, apiVersion()); - return ResponseEntity.ok(getPageOfDeletedItems(baseUri, maxResults, skipToken, includePending)); - } - - @Override - protected KeyVaultCertificateModel getModelById( - final CertificateVaultFake entityVaultFake, - final VersionedCertificateEntityId entityId, - final URI baseUri, - final boolean includeDisabled) { - final KeyVaultCertificateModel model = super.getModelById(entityVaultFake, entityId, baseUri, includeDisabled); - lifetimeActionsModelConverter.populateLifetimeActions(entityVaultFake, entityId, model.getPolicy()::setLifetimeActions); - return model; - } - - @Override - protected DeletedKeyVaultCertificateModel getDeletedModelById( - final CertificateVaultFake entityVaultFake, - final VersionedCertificateEntityId entityId, - final URI baseUri, - final boolean includeDisabled) { - final DeletedKeyVaultCertificateModel model = super.getDeletedModelById(entityVaultFake, entityId, baseUri, includeDisabled); - lifetimeActionsModelConverter.populateLifetimeActions(entityVaultFake, entityId, model.getPolicy()::setLifetimeActions); - return model; - } - - private KeyVaultItemListModel getPageOfItems( - final URI baseUri, final int limit, final int offset, final boolean includePending) { - final KeyVaultItemListModel page = - super.getPageOfItems(baseUri, limit, offset, "/certificates"); - return fixNextLink(page, includePending); - } - - private KeyVaultItemListModel getPageOfDeletedItems( - final URI baseUri, final int limit, final int offset, final boolean includePending) { - final KeyVaultItemListModel page = - super.getPageOfDeletedItems(baseUri, limit, offset, "/deletedcertificates"); - return fixNextLink(page, includePending); - } - - @Override - protected VersionedCertificateEntityId versionedEntityId(final URI baseUri, final String name, final String version) { - return new VersionedCertificateEntityId(baseUri, name, version); - } - - @Override - protected CertificateEntityId entityId(final URI baseUri, final String name) { - return new CertificateEntityId(baseUri, name); - } - - private

  • KeyVaultItemListModel
  • fixNextLink( - final KeyVaultItemListModel
  • page, - final boolean includePending) { - final String nextLink = Optional.ofNullable(page.getNextLink()) - .map(next -> next + "&" + INCLUDE_PENDING_PARAM + "=" + includePending) - .orElse(null); - page.setNextLink(nextLink); - return page; + return ResponseEntity.ok(getPageOfDeletedItems(baseUri, PaginationContext + .builder() + .apiVersion(apiVersion()) + .limit(maxResults) + .offset(skipToken) + .base(URI.create(baseUri + "/deletedcertificates")) + .additionalParameters(Map.of(INCLUDE_PENDING_PARAM, String.valueOf(includePending))) + .build())); } } diff --git a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/controller/common/CommonCertificatePolicyController.java b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/controller/common/CommonCertificatePolicyController.java index bbfa299c..324c7023 100644 --- a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/controller/common/CommonCertificatePolicyController.java +++ b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/controller/common/CommonCertificatePolicyController.java @@ -1,15 +1,11 @@ package com.github.nagyesta.lowkeyvault.controller.common; -import com.github.nagyesta.lowkeyvault.mapper.v7_3.certificate.CertificateEntityToV73IssuancePolicyModelConverter; -import com.github.nagyesta.lowkeyvault.mapper.v7_3.certificate.CertificateEntityToV73PendingCertificateOperationModelConverter; -import com.github.nagyesta.lowkeyvault.mapper.v7_3.certificate.LifetimeActionsPolicyToV73ModelConverter; +import com.github.nagyesta.lowkeyvault.mapper.common.registry.CertificateConverterRegistry; import com.github.nagyesta.lowkeyvault.model.v7_3.certificate.CertificatePolicyModel; import com.github.nagyesta.lowkeyvault.model.v7_3.certificate.KeyVaultPendingCertificateModel; import com.github.nagyesta.lowkeyvault.service.certificate.CertificateVaultFake; import com.github.nagyesta.lowkeyvault.service.certificate.ReadOnlyKeyVaultCertificateEntity; -import com.github.nagyesta.lowkeyvault.service.certificate.id.CertificateEntityId; import com.github.nagyesta.lowkeyvault.service.certificate.id.VersionedCertificateEntityId; -import com.github.nagyesta.lowkeyvault.service.vault.VaultFake; import com.github.nagyesta.lowkeyvault.service.vault.VaultService; import lombok.extern.slf4j.Slf4j; import org.springframework.http.ResponseEntity; @@ -18,27 +14,15 @@ import javax.validation.Valid; import javax.validation.constraints.Pattern; import java.net.URI; -import java.util.function.Function; +import java.util.Objects; @Slf4j -public abstract class CommonCertificatePolicyController - extends BaseEntityReadController { - - private final CertificateEntityToV73PendingCertificateOperationModelConverter pendingOperationConverter; - private final CertificateEntityToV73IssuancePolicyModelConverter issuancePolicyConverter; - private final LifetimeActionsPolicyToV73ModelConverter lifetimeActionsConverter; +public abstract class CommonCertificatePolicyController extends BaseCertificateController { protected CommonCertificatePolicyController( - @lombok.NonNull final CertificateEntityToV73PendingCertificateOperationModelConverter pendingOperationConverter, - @lombok.NonNull final CertificateEntityToV73IssuancePolicyModelConverter issuancePolicyConverter, - @lombok.NonNull final LifetimeActionsPolicyToV73ModelConverter lifetimeActionsConverter, - @NonNull final VaultService vaultService, - @NonNull final Function toEntityVault) { - super(vaultService, toEntityVault); - this.pendingOperationConverter = pendingOperationConverter; - this.issuancePolicyConverter = issuancePolicyConverter; - this.lifetimeActionsConverter = lifetimeActionsConverter; + @NonNull final CertificateConverterRegistry registry, + @NonNull final VaultService vaultService) { + super(registry, vaultService); } public ResponseEntity pendingCreate( @@ -47,11 +31,11 @@ public ResponseEntity pendingCreate( log.info("Received request to {} get pending create certificate: {} using API version: {}", baseUri.toString(), certificateName, apiVersion()); final CertificateVaultFake vaultFake = getVaultByUri(baseUri); - final VersionedCertificateEntityId entityId = vaultFake - .getEntities().getLatestVersionOfEntity(entityId(baseUri, certificateName)); - final ReadOnlyKeyVaultCertificateEntity readOnlyEntity = vaultFake - .getEntities().getReadOnlyEntity(entityId); - return ResponseEntity.ok(pendingOperationConverter.convert(readOnlyEntity, baseUri)); + final VersionedCertificateEntityId entityId = vaultFake.getEntities() + .getLatestVersionOfEntity(entityId(baseUri, certificateName)); + final ReadOnlyKeyVaultCertificateEntity readOnlyEntity = vaultFake.getEntities() + .getReadOnlyEntity(entityId); + return ResponseEntity.ok(registry().pendingOperationConverters(apiVersion()).convert(readOnlyEntity, baseUri)); } public ResponseEntity pendingDelete( @@ -64,7 +48,7 @@ public ResponseEntity pendingDelete( .getLatestVersionOfEntity(entityId(baseUri, certificateName)); final ReadOnlyKeyVaultCertificateEntity readOnlyEntity = vaultFake .getDeletedEntities().getReadOnlyEntity(entityId); - return ResponseEntity.ok(pendingOperationConverter.convert(readOnlyEntity, baseUri)); + return ResponseEntity.ok(registry().pendingOperationConverters(apiVersion()).convert(readOnlyEntity, baseUri)); } public ResponseEntity getPolicy( @@ -73,20 +57,12 @@ public ResponseEntity getPolicy( log.info("Received request to {} get certificate policy: {} with version: -LATEST- using API version: {}", baseUri.toString(), certificateName, apiVersion()); final CertificateVaultFake vaultFake = getVaultByUri(baseUri); - final VersionedCertificateEntityId latest = vaultFake.getEntities().getLatestVersionOfEntity(entityId(baseUri, certificateName)); + final VersionedCertificateEntityId latest = vaultFake.getEntities() + .getLatestVersionOfEntity(entityId(baseUri, certificateName)); final ReadOnlyKeyVaultCertificateEntity entity = vaultFake.getEntities().getReadOnlyEntity(latest); - final CertificatePolicyModel model = issuancePolicyConverter.convert(entity, baseUri); - lifetimeActionsConverter.populateLifetimeActions(vaultFake, latest, model::setLifetimeActions); + final CertificatePolicyModel model = registry().issuancePolicyConverters(apiVersion()).convert(entity, baseUri); + populateLifetimeActions(vaultFake, latest, Objects.requireNonNull(model)); return ResponseEntity.ok(model); } - @Override - protected VersionedCertificateEntityId versionedEntityId(final URI baseUri, final String name, final String version) { - return new VersionedCertificateEntityId(baseUri, name, version); - } - - @Override - protected CertificateEntityId entityId(final URI baseUri, final String name) { - return new CertificateEntityId(baseUri, name); - } } diff --git a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/controller/common/CommonKeyBackupRestoreController.java b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/controller/common/CommonKeyBackupRestoreController.java index 3304a9fa..6637dbef 100644 --- a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/controller/common/CommonKeyBackupRestoreController.java +++ b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/controller/common/CommonKeyBackupRestoreController.java @@ -1,19 +1,19 @@ package com.github.nagyesta.lowkeyvault.controller.common; -import com.github.nagyesta.lowkeyvault.mapper.common.BackupConverter; +import com.github.nagyesta.lowkeyvault.mapper.common.registry.KeyConverterRegistry; +import com.github.nagyesta.lowkeyvault.mapper.v7_2.key.KeyEntityToV72KeyItemModelConverter; +import com.github.nagyesta.lowkeyvault.mapper.v7_2.key.KeyEntityToV72KeyVersionItemModelConverter; import com.github.nagyesta.lowkeyvault.mapper.v7_2.key.KeyEntityToV72ModelConverter; -import com.github.nagyesta.lowkeyvault.model.v7_2.common.BaseBackupListItem; -import com.github.nagyesta.lowkeyvault.model.v7_2.common.BaseBackupModel; -import com.github.nagyesta.lowkeyvault.model.v7_2.key.BackupListContainer; -import com.github.nagyesta.lowkeyvault.model.v7_2.key.DeletedKeyVaultKeyModel; -import com.github.nagyesta.lowkeyvault.model.v7_2.key.KeyPropertiesModel; -import com.github.nagyesta.lowkeyvault.model.v7_2.key.KeyVaultKeyModel; +import com.github.nagyesta.lowkeyvault.model.common.backup.KeyBackupList; +import com.github.nagyesta.lowkeyvault.model.common.backup.KeyBackupListItem; +import com.github.nagyesta.lowkeyvault.model.common.backup.KeyBackupModel; +import com.github.nagyesta.lowkeyvault.model.v7_2.key.*; import com.github.nagyesta.lowkeyvault.model.v7_2.key.request.JsonWebKeyImportRequest; import com.github.nagyesta.lowkeyvault.service.key.KeyVaultFake; import com.github.nagyesta.lowkeyvault.service.key.ReadOnlyKeyVaultKeyEntity; import com.github.nagyesta.lowkeyvault.service.key.id.KeyEntityId; import com.github.nagyesta.lowkeyvault.service.key.id.VersionedKeyEntityId; -import com.github.nagyesta.lowkeyvault.service.key.impl.KeyVaultKeyEntity; +import com.github.nagyesta.lowkeyvault.service.key.impl.KeyImportInput; import com.github.nagyesta.lowkeyvault.service.vault.VaultFake; import com.github.nagyesta.lowkeyvault.service.vault.VaultService; import lombok.extern.slf4j.Slf4j; @@ -23,33 +23,22 @@ import javax.validation.Valid; import javax.validation.constraints.Pattern; import java.net.URI; -import java.util.Collections; -import java.util.Objects; /** * Common logic of backup and restore controllers across the different API versions. - * - * @param The type of the list item representing one entity version in the backup model. - * @param The wrapper type of the list in the backup model. - * @param The type of the backup model. - * @param The converter, converting entities to list items of the backup models. */ @Slf4j -public abstract class CommonKeyBackupRestoreController, - BL extends BackupListContainer, B extends BaseBackupModel, - BC extends BackupConverter> - extends BaseBackupRestoreController { +public abstract class CommonKeyBackupRestoreController extends BaseBackupRestoreController { - protected CommonKeyBackupRestoreController( - @NonNull final KeyEntityToV72ModelConverter modelConverter, - @NonNull final BC backupConverter, - @NonNull final VaultService vaultService) { - super(modelConverter, backupConverter, vaultService, VaultFake::keyVaultFake); + protected CommonKeyBackupRestoreController(@NonNull final KeyConverterRegistry registry, @NonNull final VaultService vaultService) { + super(registry, vaultService, VaultFake::keyVaultFake); } - public ResponseEntity backup( + public ResponseEntity backup( @Valid @Pattern(regexp = NAME_PATTERN) final String keyName, final URI baseUri) { log.info("Received request to {} backup key: {} using API version: {}", @@ -59,7 +48,7 @@ public ResponseEntity backup( public ResponseEntity restore( final URI baseUri, - @Valid final B keyBackupModel) { + @Valid final KeyBackupModel keyBackupModel) { log.info("Received request to {} restore key: {} using API version: {}", baseUri.toString(), keyBackupModel.getValue().getVersions().get(0).getId(), apiVersion()); return ResponseEntity.ok(restoreEntity(keyBackupModel)); @@ -68,22 +57,34 @@ public ResponseEntity restore( @Override protected void restoreVersion(@NonNull final KeyVaultFake vault, @NonNull final VersionedKeyEntityId versionedEntityId, - @NonNull final BLI entityVersion) { - vault.importKeyVersion(versionedEntityId, getKeyMaterial(entityVersion)); - final KeyVaultKeyEntity entity = vault.getEntities().getEntity(versionedEntityId, KeyVaultKeyEntity.class); - entity.setOperations(Objects.requireNonNullElse(getKeyMaterial(entityVersion).getKeyOps(), Collections.emptyList())); - updateCommonFields(entityVersion, entity); + @NonNull final KeyBackupListItem entityVersion) { + final JsonWebKeyImportRequest keyMaterial = getKeyMaterial(entityVersion); + final KeyPropertiesModel attributes = entityVersion.getAttributes(); + vault.importKeyVersion(versionedEntityId, KeyImportInput.builder() + .key(keyMaterial) + .hsm(null) + .managed(false) + .enabled(attributes.isEnabled()) + .createdOn(attributes.getCreatedOn()) + .updatedOn(attributes.getUpdatedOn()) + .notBefore(attributes.getNotBefore()) + .expiresOn(attributes.getExpiresOn()) + .tags(entityVersion.getTags()) + .build()); } - @Override - protected VersionedKeyEntityId versionedEntityId(final URI baseUri, final String name, final String version) { - return new VersionedKeyEntityId(baseUri, name, version); + + private JsonWebKeyImportRequest getKeyMaterial(final KeyBackupListItem entityVersion) { + return entityVersion.getKeyMaterial(); } @Override - protected KeyEntityId entityId(final URI baseUri, final String name) { - return new KeyEntityId(baseUri, name); + protected KeyBackupList getBackupList() { + return new KeyBackupList(); } - protected abstract JsonWebKeyImportRequest getKeyMaterial(BLI entityVersion); + @Override + protected KeyBackupModel getBackupModel() { + return new KeyBackupModel(); + } } diff --git a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/controller/common/CommonKeyController.java b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/controller/common/CommonKeyController.java index 8baf04d2..c0462c6c 100644 --- a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/controller/common/CommonKeyController.java +++ b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/controller/common/CommonKeyController.java @@ -1,44 +1,33 @@ package com.github.nagyesta.lowkeyvault.controller.common; -import com.github.nagyesta.lowkeyvault.mapper.v7_2.key.KeyEntityToV72KeyItemModelConverter; -import com.github.nagyesta.lowkeyvault.mapper.v7_2.key.KeyEntityToV72KeyVersionItemModelConverter; -import com.github.nagyesta.lowkeyvault.mapper.v7_2.key.KeyEntityToV72ModelConverter; +import com.github.nagyesta.lowkeyvault.mapper.common.registry.KeyConverterRegistry; import com.github.nagyesta.lowkeyvault.model.common.KeyVaultItemListModel; -import com.github.nagyesta.lowkeyvault.model.v7_2.BasePropertiesUpdateModel; -import com.github.nagyesta.lowkeyvault.model.v7_2.key.*; +import com.github.nagyesta.lowkeyvault.model.v7_2.key.DeletedKeyVaultKeyItemModel; +import com.github.nagyesta.lowkeyvault.model.v7_2.key.DeletedKeyVaultKeyModel; +import com.github.nagyesta.lowkeyvault.model.v7_2.key.KeyVaultKeyItemModel; +import com.github.nagyesta.lowkeyvault.model.v7_2.key.KeyVaultKeyModel; import com.github.nagyesta.lowkeyvault.model.v7_2.key.request.CreateKeyRequest; import com.github.nagyesta.lowkeyvault.model.v7_2.key.request.ImportKeyRequest; -import com.github.nagyesta.lowkeyvault.model.v7_2.key.request.JsonWebKeyImportRequest; import com.github.nagyesta.lowkeyvault.model.v7_2.key.request.UpdateKeyRequest; import com.github.nagyesta.lowkeyvault.service.key.KeyVaultFake; -import com.github.nagyesta.lowkeyvault.service.key.ReadOnlyKeyVaultKeyEntity; import com.github.nagyesta.lowkeyvault.service.key.id.KeyEntityId; import com.github.nagyesta.lowkeyvault.service.key.id.VersionedKeyEntityId; -import com.github.nagyesta.lowkeyvault.service.vault.VaultFake; import com.github.nagyesta.lowkeyvault.service.vault.VaultService; import lombok.extern.slf4j.Slf4j; import org.springframework.http.ResponseEntity; import org.springframework.lang.NonNull; -import org.springframework.util.Assert; import javax.validation.Valid; import javax.validation.constraints.Pattern; import java.net.URI; -import java.util.Objects; import java.util.Optional; @Slf4j -public abstract class CommonKeyController extends GenericEntityController { - - protected CommonKeyController(@NonNull final KeyEntityToV72ModelConverter keyEntityToV72ModelConverter, - @NonNull final KeyEntityToV72KeyItemModelConverter keyEntityToV72KeyItemModelConverter, - @NonNull final KeyEntityToV72KeyVersionItemModelConverter keyEntityToV72KeyVersionItemModelConverter, +public abstract class CommonKeyController extends BaseKeyController { + + protected CommonKeyController(@NonNull final KeyConverterRegistry registry, @NonNull final VaultService vaultService) { - super(keyEntityToV72ModelConverter, keyEntityToV72KeyItemModelConverter, - keyEntityToV72KeyVersionItemModelConverter, vaultService, VaultFake::keyVaultFake); + super(registry, vaultService); } public ResponseEntity create( @@ -86,7 +75,13 @@ public ResponseEntity> versions( log.info("Received request to {} list key versions: {} , (max results: {}, skip: {}) using API version: {}", baseUri.toString(), keyName, maxResults, skipToken, apiVersion()); - return ResponseEntity.ok(getPageOfItemVersions(baseUri, keyName, maxResults, skipToken, "/keys/" + keyName + "/versions")); + return ResponseEntity.ok(getPageOfItemVersions(baseUri, keyName, PaginationContext + .builder() + .apiVersion(apiVersion()) + .limit(maxResults) + .offset(skipToken) + .base(URI.create(baseUri + "/keys/" + keyName + "/versions")) + .build())); } public ResponseEntity> listKeys( @@ -96,7 +91,13 @@ public ResponseEntity> listKeys( log.info("Received request to {} list keys, (max results: {}, skip: {}) using API version: {}", baseUri.toString(), maxResults, skipToken, apiVersion()); - return ResponseEntity.ok(getPageOfItems(baseUri, maxResults, skipToken, "/keys")); + return ResponseEntity.ok(getPageOfItems(baseUri, PaginationContext + .builder() + .apiVersion(apiVersion()) + .limit(maxResults) + .offset(skipToken) + .base(URI.create(baseUri + "/keys")) + .build())); } public ResponseEntity> listDeletedKeys( @@ -106,7 +107,13 @@ public ResponseEntity> listDe log.info("Received request to {} list deleted keys, (max results: {}, skip: {}) using API version: {}", baseUri.toString(), maxResults, skipToken, apiVersion()); - return ResponseEntity.ok(getPageOfDeletedItems(baseUri, maxResults, skipToken, "/deletedkeys")); + return ResponseEntity.ok(getPageOfDeletedItems(baseUri, PaginationContext + .builder() + .apiVersion(apiVersion()) + .limit(maxResults) + .offset(skipToken) + .base(URI.create(baseUri + "/deletedkeys")) + .build())); } public ResponseEntity get( @@ -181,41 +188,4 @@ public ResponseEntity purgeDeleted( keyVaultFake.purge(entityId); return ResponseEntity.noContent().build(); } - - @Override - protected VersionedKeyEntityId versionedEntityId(final URI baseUri, final String name, final String version) { - return new VersionedKeyEntityId(baseUri, name, version); - } - - @Override - protected KeyEntityId entityId(final URI baseUri, final String name) { - return new KeyEntityId(baseUri, name); - } - - private VersionedKeyEntityId createKeyWithAttributes( - final KeyVaultFake keyVaultFake, final String keyName, final CreateKeyRequest request) { - final KeyPropertiesModel properties = Objects.requireNonNullElse(request.getProperties(), new KeyPropertiesModel()); - final VersionedKeyEntityId keyEntityId = keyVaultFake.createKeyVersion(keyName, request.toKeyCreationInput()); - keyVaultFake.setKeyOperations(keyEntityId, request.getKeyOperations()); - keyVaultFake.addTags(keyEntityId, request.getTags()); - keyVaultFake.setExpiry(keyEntityId, properties.getNotBefore(), properties.getExpiresOn()); - keyVaultFake.setEnabled(keyEntityId, properties.isEnabled()); - //no need to set managed property as this endpoint cannot create managed entities by definition - return keyEntityId; - } - - private VersionedKeyEntityId importKeyWithAttributes( - final KeyVaultFake keyVaultFake, final String keyName, final ImportKeyRequest request) { - final BasePropertiesUpdateModel properties = Objects.requireNonNullElse(request.getProperties(), new BasePropertiesUpdateModel()); - Assert.isTrue(request.getHsm() == null || request.getHsm() == request.getKey().getKeyType().isHsm(), - "When HSM property is set in request, key type must match it."); - final VersionedKeyEntityId keyEntityId = keyVaultFake.importKeyVersion(keyName, request.getKey()); - final JsonWebKeyImportRequest keyImport = request.getKey(); - keyVaultFake.setKeyOperations(keyEntityId, keyImport.getKeyOps()); - keyVaultFake.addTags(keyEntityId, request.getTags()); - keyVaultFake.setExpiry(keyEntityId, properties.getNotBefore(), properties.getExpiresOn()); - keyVaultFake.setEnabled(keyEntityId, Objects.requireNonNullElse(properties.getEnabled(), true)); - //no need to set managed property as this endpoint cannot create managed entities by definition - return keyEntityId; - } } diff --git a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/controller/common/CommonKeyCryptoController.java b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/controller/common/CommonKeyCryptoController.java index d4779f41..812eed6f 100644 --- a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/controller/common/CommonKeyCryptoController.java +++ b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/controller/common/CommonKeyCryptoController.java @@ -1,17 +1,13 @@ package com.github.nagyesta.lowkeyvault.controller.common; -import com.github.nagyesta.lowkeyvault.mapper.v7_2.key.KeyEntityToV72KeyItemModelConverter; -import com.github.nagyesta.lowkeyvault.mapper.v7_2.key.KeyEntityToV72KeyVersionItemModelConverter; -import com.github.nagyesta.lowkeyvault.mapper.v7_2.key.KeyEntityToV72ModelConverter; -import com.github.nagyesta.lowkeyvault.model.v7_2.key.*; +import com.github.nagyesta.lowkeyvault.mapper.common.registry.KeyConverterRegistry; +import com.github.nagyesta.lowkeyvault.model.v7_2.key.KeyOperationsResult; +import com.github.nagyesta.lowkeyvault.model.v7_2.key.KeySignResult; +import com.github.nagyesta.lowkeyvault.model.v7_2.key.KeyVerifyResult; import com.github.nagyesta.lowkeyvault.model.v7_2.key.request.KeyOperationsParameters; import com.github.nagyesta.lowkeyvault.model.v7_2.key.request.KeySignParameters; import com.github.nagyesta.lowkeyvault.model.v7_2.key.request.KeyVerifyParameters; -import com.github.nagyesta.lowkeyvault.service.key.KeyVaultFake; import com.github.nagyesta.lowkeyvault.service.key.ReadOnlyKeyVaultKeyEntity; -import com.github.nagyesta.lowkeyvault.service.key.id.KeyEntityId; -import com.github.nagyesta.lowkeyvault.service.key.id.VersionedKeyEntityId; -import com.github.nagyesta.lowkeyvault.service.vault.VaultFake; import com.github.nagyesta.lowkeyvault.service.vault.VaultService; import lombok.extern.slf4j.Slf4j; import org.springframework.http.ResponseEntity; @@ -22,18 +18,10 @@ import java.net.URI; @Slf4j -public abstract class CommonKeyCryptoController extends GenericEntityController { +public abstract class CommonKeyCryptoController extends BaseKeyController { - protected CommonKeyCryptoController( - @NonNull final KeyEntityToV72ModelConverter keyEntityToV72ModelConverter, - @NonNull final KeyEntityToV72KeyItemModelConverter keyEntityToV72KeyItemModelConverter, - @NonNull final KeyEntityToV72KeyVersionItemModelConverter keyEntityToV72KeyVersionItemModelConverter, - @NonNull final VaultService vaultService) { - super(keyEntityToV72ModelConverter, keyEntityToV72KeyItemModelConverter, - keyEntityToV72KeyVersionItemModelConverter, vaultService, VaultFake::keyVaultFake); + protected CommonKeyCryptoController(@NonNull final KeyConverterRegistry registry, @NonNull final VaultService vaultService) { + super(registry, vaultService); } public ResponseEntity encrypt( @@ -91,14 +79,4 @@ public ResponseEntity verify( return ResponseEntity.ok(new KeyVerifyResult(result)); } - @Override - protected VersionedKeyEntityId versionedEntityId(final URI baseUri, final String name, final String version) { - return new VersionedKeyEntityId(baseUri, name, version); - } - - @Override - protected KeyEntityId entityId(final URI baseUri, final String name) { - return new KeyEntityId(baseUri, name); - } - } diff --git a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/controller/common/CommonSecretBackupRestoreController.java b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/controller/common/CommonSecretBackupRestoreController.java index 4a428566..a5f23a38 100644 --- a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/controller/common/CommonSecretBackupRestoreController.java +++ b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/controller/common/CommonSecretBackupRestoreController.java @@ -1,12 +1,18 @@ package com.github.nagyesta.lowkeyvault.controller.common; +import com.github.nagyesta.lowkeyvault.mapper.common.registry.SecretConverterRegistry; import com.github.nagyesta.lowkeyvault.mapper.v7_2.secret.SecretEntityToV72ModelConverter; +import com.github.nagyesta.lowkeyvault.mapper.v7_2.secret.SecretEntityToV72SecretItemModelConverter; +import com.github.nagyesta.lowkeyvault.mapper.v7_2.secret.SecretEntityToV72SecretVersionItemModelConverter; +import com.github.nagyesta.lowkeyvault.model.common.backup.SecretBackupList; +import com.github.nagyesta.lowkeyvault.model.common.backup.SecretBackupListItem; +import com.github.nagyesta.lowkeyvault.model.common.backup.SecretBackupModel; import com.github.nagyesta.lowkeyvault.model.v7_2.secret.*; import com.github.nagyesta.lowkeyvault.service.secret.ReadOnlyKeyVaultSecretEntity; import com.github.nagyesta.lowkeyvault.service.secret.SecretVaultFake; import com.github.nagyesta.lowkeyvault.service.secret.id.SecretEntityId; import com.github.nagyesta.lowkeyvault.service.secret.id.VersionedSecretEntityId; -import com.github.nagyesta.lowkeyvault.service.secret.impl.KeyVaultSecretEntity; +import com.github.nagyesta.lowkeyvault.service.secret.impl.SecretCreateInput; import com.github.nagyesta.lowkeyvault.service.vault.VaultFake; import com.github.nagyesta.lowkeyvault.service.vault.VaultService; import lombok.extern.slf4j.Slf4j; @@ -16,17 +22,18 @@ import javax.validation.Valid; import javax.validation.constraints.Pattern; import java.net.URI; +import java.util.Objects; @Slf4j public abstract class CommonSecretBackupRestoreController extends BaseBackupRestoreController { + ReadOnlyKeyVaultSecretEntity, KeyVaultSecretModel, DeletedKeyVaultSecretModel, KeyVaultSecretItemModel, + DeletedKeyVaultSecretItemModel, SecretEntityToV72ModelConverter, SecretEntityToV72SecretItemModelConverter, + SecretEntityToV72SecretVersionItemModelConverter, SecretVaultFake, SecretPropertiesModel, SecretBackupListItem, + SecretBackupList, SecretBackupModel, SecretConverterRegistry> { protected CommonSecretBackupRestoreController( - @NonNull final SecretEntityToV72ModelConverter modelConverter, - @NonNull final SecretEntityToV72BackupConverter backupConverter, - @NonNull final VaultService vaultService) { - super(modelConverter, backupConverter, vaultService, VaultFake::secretVaultFake); + @NonNull final SecretConverterRegistry registry, @NonNull final VaultService vaultService) { + super(registry, vaultService, VaultFake::secretVaultFake); } public ResponseEntity backup( @@ -49,9 +56,18 @@ public ResponseEntity restore( protected void restoreVersion(@NonNull final SecretVaultFake vault, @NonNull final VersionedSecretEntityId versionedEntityId, @NonNull final SecretBackupListItem entityVersion) { - vault.createSecretVersion(versionedEntityId, entityVersion.getValue(), entityVersion.getContentType()); - final KeyVaultSecretEntity entity = vault.getEntities().getEntity(versionedEntityId, KeyVaultSecretEntity.class); - updateCommonFields(entityVersion, entity); + final SecretPropertiesModel attributes = Objects.requireNonNullElse(entityVersion.getAttributes(), new SecretPropertiesModel()); + vault.createSecretVersion(versionedEntityId, SecretCreateInput.builder() + .value(entityVersion.getValue()) + .contentType(entityVersion.getContentType()) + .tags(entityVersion.getTags()) + .createdOn(attributes.getCreatedOn()) + .updatedOn(attributes.getUpdatedOn()) + .notBefore(attributes.getNotBefore()) + .expiresOn(attributes.getExpiresOn()) + .managed(false) + .enabled(attributes.isEnabled()) + .build()); } @Override @@ -64,13 +80,4 @@ protected SecretBackupModel getBackupModel() { return new SecretBackupModel(); } - @Override - protected VersionedSecretEntityId versionedEntityId(final URI baseUri, final String name, final String version) { - return new VersionedSecretEntityId(baseUri, name, version); - } - - @Override - protected SecretEntityId entityId(final URI baseUri, final String name) { - return new SecretEntityId(baseUri, name); - } } diff --git a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/controller/common/CommonSecretController.java b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/controller/common/CommonSecretController.java index 6ab19257..481ab191 100644 --- a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/controller/common/CommonSecretController.java +++ b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/controller/common/CommonSecretController.java @@ -1,17 +1,16 @@ package com.github.nagyesta.lowkeyvault.controller.common; -import com.github.nagyesta.lowkeyvault.mapper.v7_2.secret.SecretEntityToV72ModelConverter; -import com.github.nagyesta.lowkeyvault.mapper.v7_2.secret.SecretEntityToV72SecretItemModelConverter; -import com.github.nagyesta.lowkeyvault.mapper.v7_2.secret.SecretEntityToV72SecretVersionItemModelConverter; +import com.github.nagyesta.lowkeyvault.mapper.common.registry.SecretConverterRegistry; import com.github.nagyesta.lowkeyvault.model.common.KeyVaultItemListModel; -import com.github.nagyesta.lowkeyvault.model.v7_2.secret.*; +import com.github.nagyesta.lowkeyvault.model.v7_2.secret.DeletedKeyVaultSecretItemModel; +import com.github.nagyesta.lowkeyvault.model.v7_2.secret.DeletedKeyVaultSecretModel; +import com.github.nagyesta.lowkeyvault.model.v7_2.secret.KeyVaultSecretItemModel; +import com.github.nagyesta.lowkeyvault.model.v7_2.secret.KeyVaultSecretModel; import com.github.nagyesta.lowkeyvault.model.v7_2.secret.request.CreateSecretRequest; import com.github.nagyesta.lowkeyvault.model.v7_2.secret.request.UpdateSecretRequest; -import com.github.nagyesta.lowkeyvault.service.secret.ReadOnlyKeyVaultSecretEntity; import com.github.nagyesta.lowkeyvault.service.secret.SecretVaultFake; import com.github.nagyesta.lowkeyvault.service.secret.id.SecretEntityId; import com.github.nagyesta.lowkeyvault.service.secret.id.VersionedSecretEntityId; -import com.github.nagyesta.lowkeyvault.service.vault.VaultFake; import com.github.nagyesta.lowkeyvault.service.vault.VaultService; import lombok.extern.slf4j.Slf4j; import org.springframework.http.ResponseEntity; @@ -20,21 +19,12 @@ import javax.validation.Valid; import javax.validation.constraints.Pattern; import java.net.URI; -import java.util.Objects; @Slf4j -public abstract class CommonSecretController extends GenericEntityController { - - protected CommonSecretController( - @NonNull final SecretEntityToV72ModelConverter secretEntityToV72ModelConverter, - @NonNull final SecretEntityToV72SecretItemModelConverter secretEntityToV72SecretItemModelConverter, - @NonNull final SecretEntityToV72SecretVersionItemModelConverter secretEntityToV72SecretVersionItemModelConverter, - @NonNull final VaultService vaultService) { - super(secretEntityToV72ModelConverter, secretEntityToV72SecretItemModelConverter, - secretEntityToV72SecretVersionItemModelConverter, vaultService, VaultFake::secretVaultFake); +public abstract class CommonSecretController extends BaseSecretController { + + protected CommonSecretController(@NonNull final SecretConverterRegistry registry, @NonNull final VaultService vaultService) { + super(registry, vaultService); } public ResponseEntity create( @@ -70,8 +60,13 @@ public ResponseEntity> versions( log.info("Received request to {} list secret versions: {} , (max results: {}, skip: {}) using API version: {}", baseUri.toString(), secretName, maxResults, skipToken, apiVersion()); - return ResponseEntity - .ok(getPageOfItemVersions(baseUri, secretName, maxResults, skipToken, "/secrets/" + secretName + "/versions")); + return ResponseEntity.ok(getPageOfItemVersions(baseUri, secretName, PaginationContext + .builder() + .apiVersion(apiVersion()) + .limit(maxResults) + .offset(skipToken) + .base(URI.create(baseUri + ("/secrets/" + secretName + "/versions"))) + .build())); } public ResponseEntity> listSecrets( @@ -81,7 +76,13 @@ public ResponseEntity> listSecret log.info("Received request to {} list secrets, (max results: {}, skip: {}) using API version: {}", baseUri.toString(), maxResults, skipToken, apiVersion()); - return ResponseEntity.ok(getPageOfItems(baseUri, maxResults, skipToken, "/secrets")); + return ResponseEntity.ok(getPageOfItems(baseUri, PaginationContext + .builder() + .apiVersion(apiVersion()) + .limit(maxResults) + .offset(skipToken) + .base(URI.create(baseUri + "/secrets")) + .build())); } public ResponseEntity> listDeletedSecrets( @@ -91,7 +92,13 @@ public ResponseEntity> lis log.info("Received request to {} list deleted secrets, (max results: {}, skip: {}) using API version: {}", baseUri.toString(), maxResults, skipToken, apiVersion()); - return ResponseEntity.ok(getPageOfDeletedItems(baseUri, maxResults, skipToken, "/deletedsecrets")); + return ResponseEntity.ok(getPageOfDeletedItems(baseUri, PaginationContext + .builder() + .apiVersion(apiVersion()) + .limit(maxResults) + .offset(skipToken) + .base(URI.create(baseUri + "/deletedsecrets")) + .build())); } public ResponseEntity get( @@ -163,26 +170,4 @@ public ResponseEntity recoverDeletedSecret( final VersionedSecretEntityId latestVersion = secretVaultFake.getEntities().getLatestVersionOfEntity(entityId); return ResponseEntity.ok(getModelById(secretVaultFake, latestVersion, baseUri, true)); } - - @Override - protected VersionedSecretEntityId versionedEntityId(final URI baseUri, final String name, final String version) { - return new VersionedSecretEntityId(baseUri, name, version); - } - - @Override - protected SecretEntityId entityId(final URI baseUri, final String name) { - return new SecretEntityId(baseUri, name); - } - - private VersionedSecretEntityId createSecretWithAttributes( - final SecretVaultFake secretVaultFake, final String secretName, final CreateSecretRequest request) { - final SecretPropertiesModel properties = Objects.requireNonNullElse(request.getProperties(), new SecretPropertiesModel()); - final VersionedSecretEntityId secretEntityId = secretVaultFake - .createSecretVersion(secretName, request.getValue(), request.getContentType()); - secretVaultFake.addTags(secretEntityId, request.getTags()); - secretVaultFake.setExpiry(secretEntityId, properties.getNotBefore(), properties.getExpiresOn()); - secretVaultFake.setEnabled(secretEntityId, properties.isEnabled()); - //no need to set managed property as this endpoint cannot create managed entities by definition - return secretEntityId; - } } diff --git a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/controller/common/GenericEntityController.java b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/controller/common/GenericEntityController.java index 6d061139..894113bb 100644 --- a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/controller/common/GenericEntityController.java +++ b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/controller/common/GenericEntityController.java @@ -1,8 +1,13 @@ package com.github.nagyesta.lowkeyvault.controller.common; +import com.github.nagyesta.lowkeyvault.mapper.common.BaseEntityConverterRegistry; import com.github.nagyesta.lowkeyvault.mapper.common.RecoveryAwareConverter; import com.github.nagyesta.lowkeyvault.model.common.KeyVaultItemListModel; +import com.github.nagyesta.lowkeyvault.model.v7_2.BasePropertiesModel; import com.github.nagyesta.lowkeyvault.model.v7_2.BasePropertiesUpdateModel; +import com.github.nagyesta.lowkeyvault.model.v7_2.common.BaseBackupListItem; +import com.github.nagyesta.lowkeyvault.model.v7_2.common.BaseBackupModel; +import com.github.nagyesta.lowkeyvault.model.v7_2.key.BackupListContainer; import com.github.nagyesta.lowkeyvault.service.EntityId; import com.github.nagyesta.lowkeyvault.service.common.BaseVaultEntity; import com.github.nagyesta.lowkeyvault.service.common.BaseVaultFake; @@ -19,8 +24,6 @@ import java.util.function.Function; import java.util.stream.Collectors; -import static com.github.nagyesta.lowkeyvault.model.common.ApiConstants.API_VERSION_PREFIX; - /** * The base implementation of the entity controllers. * @@ -35,11 +38,23 @@ * @param The item converter, converting version item entities to item models. * @param The versioned item converter, converting version item entities to item models. * @param The fake type holding the entities. + * @param The type of the PropertiesModel. + * @param The list item type of the backup lists. + * @param The type of the backup list. + * @param The type of the backup model. + * @param The ConverterRegistry used for conversions. */ public abstract class GenericEntityController, - M, DM extends M, I, DI extends I, MC extends RecoveryAwareConverter, - IC extends RecoveryAwareConverter, VIC extends RecoveryAwareConverter, - S extends BaseVaultFake> extends BaseEntityReadController { + M, DM extends M, I, DI extends I, + MC extends RecoveryAwareConverter, + IC extends RecoveryAwareConverter, + VIC extends RecoveryAwareConverter, + S extends BaseVaultFake, + PM extends BasePropertiesModel, + BLI extends BaseBackupListItem, + BL extends BackupListContainer, + B extends BaseBackupModel, + R extends BaseEntityConverterRegistry> extends BaseEntityReadController { /** * Default page size used when returning available versions of an entity. */ @@ -56,19 +71,27 @@ public abstract class GenericEntityController toEntityVault) { super(vaultService, toEntityVault); - this.modelConverter = modelConverter; - this.itemConverter = itemConverter; - this.versionedItemConverter = versionedItemConverter; + this.registry = registry; + } + + @Override + protected final V versionedEntityId(final URI baseUri, final String name, final String version) { + return registry.versionedEntityId(baseUri, name, version); + } + + @Override + protected final K entityId(final URI baseUri, final String name) { + return registry.entityId(baseUri, name); } protected M getModelById(final S entityVaultFake, final V entityId, final URI baseUri, final boolean includeDisabled) { @@ -76,7 +99,7 @@ protected M getModelById(final S entityVaultFake, final V entityId, final URI ba if (!includeDisabled && !entity.isEnabled()) { throw new NotFoundException("Operation get is not allowed on a disabled entity."); } - return modelConverter.convert(entity, baseUri); + return registry.modelConverter(apiVersion()).convert(entity, baseUri); } protected DM getDeletedModelById(final S entityVaultFake, final V entityId, final URI baseUri, final boolean includeDisabled) { @@ -84,44 +107,73 @@ protected DM getDeletedModelById(final S entityVaultFake, final V entityId, fina if (!includeDisabled && !entity.isEnabled()) { throw new NotFoundException("Operation get is not allowed on a disabled entity."); } - return modelConverter.convertDeleted(entity, baseUri); + return registry.modelConverter(apiVersion()).convertDeleted(entity, baseUri); } protected M convertDetails(final E entity, final URI vaultUri) { - return modelConverter.convert(entity, vaultUri); + return registry.modelConverter(apiVersion()).convert(entity, vaultUri); } protected KeyVaultItemListModel getPageOfItemVersions( - final URI baseUri, final String name, final int limit, final int offset, final String uriPath) { + final URI baseUri, final String name, final PaginationContext pagination) { final S entityVaultFake = getVaultByUri(baseUri); final K entityId = entityId(baseUri, name); final List allItems = entityVaultFake.getEntities().getVersions(entityId) .stream() .sorted() .collect(Collectors.toList()); - final List items = filterList(limit, offset, allItems, v -> { + final List items = filterList(pagination.getLimit(), pagination.getOffset(), allItems, v -> { final E entity = getEntityByNameAndVersion(baseUri, name, v); - return versionedItemConverter.convert(entity, baseUri); + return registry.versionedItemConverter(apiVersion()).convert(entity, baseUri); }); - final URI nextUri = getNextUri(baseUri + uriPath, allItems, items, limit, offset); + final URI nextUri = PaginationContext.builder() + .base(pagination.getBase()) + .apiVersion(pagination.getApiVersion()) + .currentItems(items.size()) + .totalItems(allItems.size()) + .limit(pagination.getLimit()) + .offset(pagination.getOffset()) + .additionalParameters(pagination.getAdditionalParameters()) + .build() + .asNextUri(); return listModel(items, nextUri); } @SuppressWarnings("SameParameterValue") - protected KeyVaultItemListModel getPageOfItems(final URI baseUri, final int limit, final int offset, final String uriPath) { + protected KeyVaultItemListModel getPageOfItems(final URI baseUri, final PaginationContext pagination) { final S entityVaultFake = getVaultByUri(baseUri); final List allItems = entityVaultFake.getEntities().listLatestNonManagedEntities(); - final List items = filterList(limit, offset, allItems, source -> itemConverter.convert(source, baseUri)); - final URI nextUri = getNextUri(baseUri + uriPath, allItems, items, limit, offset); + final List items = filterList(pagination.getLimit(), pagination.getOffset(), allItems, + source -> registry.itemConverter(apiVersion()).convert(source, baseUri)); + final URI nextUri = PaginationContext.builder() + .base(pagination.getBase()) + .apiVersion(pagination.getApiVersion()) + .currentItems(items.size()) + .totalItems(allItems.size()) + .limit(pagination.getLimit()) + .offset(pagination.getOffset()) + .additionalParameters(pagination.getAdditionalParameters()) + .build() + .asNextUri(); return listModel(items, nextUri); } @SuppressWarnings("SameParameterValue") - protected KeyVaultItemListModel getPageOfDeletedItems(final URI baseUri, final int limit, final int offset, final String uriPath) { + protected KeyVaultItemListModel getPageOfDeletedItems(final URI baseUri, final PaginationContext pagination) { final S entityVaultFake = getVaultByUri(baseUri); final List allItems = entityVaultFake.getDeletedEntities().listLatestNonManagedEntities(); - final List items = filterList(limit, offset, allItems, source -> itemConverter.convertDeleted(source, baseUri)); - final URI nextUri = getNextUri(baseUri + uriPath, allItems, items, limit, offset); + final List items = filterList(pagination.getLimit(), pagination.getOffset(), allItems, + source -> registry.itemConverter(apiVersion()).convertDeleted(source, baseUri)); + final URI nextUri = PaginationContext.builder() + .base(pagination.getBase()) + .apiVersion(apiVersion()) + .currentItems(items.size()) + .totalItems(allItems.size()) + .limit(pagination.getLimit()) + .offset(pagination.getOffset()) + .additionalParameters(pagination.getAdditionalParameters()) + .build() + .asNextUri(); return listModel(items, nextUri); } @@ -160,15 +212,6 @@ protected
  • KeyVaultItemListModel
  • listModel(final List
  • items, final U return new KeyVaultItemListModel<>(items, nextUri); } - private URI getNextUri(final String prefix, final Collection allItems, - final Collection items, final int limit, final int offset) { - URI nextUri = null; - if (hasMorePages(limit, offset, allItems)) { - nextUri = URI.create(prefix + pageSuffix(limit, offset + items.size())); - } - return nextUri; - } - private List
  • filterList( final int limit, final int offset, final Collection allItems, final Function mapper) { return allItems.stream() @@ -178,12 +221,4 @@ private List
  • filterList( .collect(Collectors.toList()); } - private boolean hasMorePages(final int limit, final int offset, final Collection allItems) { - return limit + offset < allItems.size(); - } - - private String pageSuffix(final int maxResults, final int skip) { - return "?" + API_VERSION_PREFIX + apiVersion() + "&" + SKIP_TOKEN_PARAM + "=" + skip + "&" + MAX_RESULTS_PARAM + "=" + maxResults; - } - } diff --git a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/controller/common/PaginationContext.java b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/controller/common/PaginationContext.java new file mode 100644 index 00000000..f1a1f1ac --- /dev/null +++ b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/controller/common/PaginationContext.java @@ -0,0 +1,58 @@ +package com.github.nagyesta.lowkeyvault.controller.common; + +import lombok.Builder; +import lombok.Data; +import lombok.NonNull; + +import java.net.URI; +import java.util.Map; +import java.util.Optional; +import java.util.stream.Collectors; + +import static com.github.nagyesta.lowkeyvault.model.common.ApiConstants.API_VERSION_PREFIX; + +@Data +@Builder +class PaginationContext { + private static final String AND = "&"; + private static final String EQUALS = "="; + private static final String QUESTION_MARK = "?"; + private static final String EMPTY = ""; + @NonNull + private final URI base; + private final int totalItems; + private final int currentItems; + private final int limit; + private final int offset; + private Map additionalParameters; + @NonNull + private final String apiVersion; + + public URI asNextUri() { + URI nextUri = null; + if (hasMorePages()) { + nextUri = URI.create(base + + QUESTION_MARK + API_VERSION_PREFIX + apiVersion + + AND + GenericEntityController.SKIP_TOKEN_PARAM + EQUALS + skipValue() + + AND + GenericEntityController.MAX_RESULTS_PARAM + EQUALS + limit + + additionalParametersAsQuery()); + } + return nextUri; + } + + private boolean hasMorePages() { + return limit + offset < totalItems; + } + + private int skipValue() { + return offset + currentItems; + } + + private String additionalParametersAsQuery() { + return Optional.ofNullable(additionalParameters) + .map(m -> AND + m.entrySet().stream() + .map(e -> e.getKey() + EQUALS + e.getValue()) + .collect(Collectors.joining(AND))) + .orElse(EMPTY); + } +} diff --git a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/controller/v7_2/KeyBackupRestoreController.java b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/controller/v7_2/KeyBackupRestoreController.java index 21a8e6e0..14655cf3 100644 --- a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/controller/v7_2/KeyBackupRestoreController.java +++ b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/controller/v7_2/KeyBackupRestoreController.java @@ -1,18 +1,15 @@ package com.github.nagyesta.lowkeyvault.controller.v7_2; import com.github.nagyesta.lowkeyvault.controller.common.CommonKeyBackupRestoreController; -import com.github.nagyesta.lowkeyvault.mapper.v7_2.key.KeyEntityToV72BackupConverter; -import com.github.nagyesta.lowkeyvault.mapper.v7_2.key.KeyEntityToV72ModelConverter; +import com.github.nagyesta.lowkeyvault.mapper.common.registry.KeyConverterRegistry; import com.github.nagyesta.lowkeyvault.model.common.ApiConstants; -import com.github.nagyesta.lowkeyvault.model.v7_2.key.KeyBackupList; -import com.github.nagyesta.lowkeyvault.model.v7_2.key.KeyBackupListItem; -import com.github.nagyesta.lowkeyvault.model.v7_2.key.KeyBackupModel; +import com.github.nagyesta.lowkeyvault.model.common.backup.KeyBackupModel; import com.github.nagyesta.lowkeyvault.model.v7_2.key.KeyVaultKeyModel; -import com.github.nagyesta.lowkeyvault.model.v7_2.key.request.JsonWebKeyImportRequest; import com.github.nagyesta.lowkeyvault.service.vault.VaultService; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; +import org.springframework.lang.NonNull; import org.springframework.stereotype.Component; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -29,22 +26,20 @@ @RestController @Validated @Component("KeyBackupRestoreControllerV72") -public class KeyBackupRestoreController - extends CommonKeyBackupRestoreController { +public class KeyBackupRestoreController extends CommonKeyBackupRestoreController { @Autowired - public KeyBackupRestoreController(final KeyEntityToV72ModelConverter modelConverter, - final KeyEntityToV72BackupConverter backupConverter, - final VaultService vaultService) { - super(modelConverter, backupConverter, vaultService); + public KeyBackupRestoreController(@NonNull final KeyConverterRegistry registry, @NonNull final VaultService vaultService) { + super(registry, vaultService); } @Override @PostMapping(value = "/keys/{keyName}/backup", params = API_VERSION_7_2, produces = APPLICATION_JSON_VALUE) - public ResponseEntity backup(@PathVariable @Valid @Pattern(regexp = NAME_PATTERN) final String keyName, - @RequestAttribute(name = ApiConstants.REQUEST_BASE_URI) final URI baseUri) { + public ResponseEntity backup( + @PathVariable @Valid @Pattern(regexp = NAME_PATTERN) final String keyName, + @RequestAttribute(name = ApiConstants.REQUEST_BASE_URI) final URI baseUri) { return super.backup(keyName, baseUri); } @@ -53,26 +48,12 @@ public ResponseEntity backup(@PathVariable @Valid @Pattern(regex params = API_VERSION_7_2, consumes = APPLICATION_JSON_VALUE, produces = APPLICATION_JSON_VALUE) - public ResponseEntity restore(@RequestAttribute(name = ApiConstants.REQUEST_BASE_URI) final URI baseUri, - @Valid @RequestBody final KeyBackupModel keyBackupModel) { + public ResponseEntity restore( + @RequestAttribute(name = ApiConstants.REQUEST_BASE_URI) final URI baseUri, + @Valid @RequestBody final KeyBackupModel keyBackupModel) { return super.restore(baseUri, keyBackupModel); } - @Override - protected JsonWebKeyImportRequest getKeyMaterial(final KeyBackupListItem entityVersion) { - return entityVersion.getKeyMaterial(); - } - - @Override - protected KeyBackupList getBackupList() { - return new KeyBackupList(); - } - - @Override - protected KeyBackupModel getBackupModel() { - return new KeyBackupModel(); - } - @Override protected String apiVersion() { return V_7_2; diff --git a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/controller/v7_2/KeyController.java b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/controller/v7_2/KeyController.java index 049a2fbf..bc9f1e67 100644 --- a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/controller/v7_2/KeyController.java +++ b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/controller/v7_2/KeyController.java @@ -1,9 +1,7 @@ package com.github.nagyesta.lowkeyvault.controller.v7_2; import com.github.nagyesta.lowkeyvault.controller.common.CommonKeyController; -import com.github.nagyesta.lowkeyvault.mapper.v7_2.key.KeyEntityToV72KeyItemModelConverter; -import com.github.nagyesta.lowkeyvault.mapper.v7_2.key.KeyEntityToV72KeyVersionItemModelConverter; -import com.github.nagyesta.lowkeyvault.mapper.v7_2.key.KeyEntityToV72ModelConverter; +import com.github.nagyesta.lowkeyvault.mapper.common.registry.KeyConverterRegistry; import com.github.nagyesta.lowkeyvault.model.common.ApiConstants; import com.github.nagyesta.lowkeyvault.model.common.KeyVaultItemListModel; import com.github.nagyesta.lowkeyvault.model.v7_2.key.DeletedKeyVaultKeyItemModel; @@ -37,12 +35,8 @@ public class KeyController extends CommonKeyController { @Autowired - public KeyController(@NonNull final KeyEntityToV72ModelConverter keyEntityToV72ModelConverter, - @NonNull final KeyEntityToV72KeyItemModelConverter keyEntityToV72KeyItemModelConverter, - @NonNull final KeyEntityToV72KeyVersionItemModelConverter keyEntityToV72KeyVersionItemModelConverter, - @NonNull final VaultService vaultService) { - super(keyEntityToV72ModelConverter, keyEntityToV72KeyItemModelConverter, - keyEntityToV72KeyVersionItemModelConverter, vaultService); + public KeyController(@NonNull final KeyConverterRegistry registry, @NonNull final VaultService vaultService) { + super(registry, vaultService); } @Override diff --git a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/controller/v7_2/KeyCryptoController.java b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/controller/v7_2/KeyCryptoController.java index 1508dd32..a7c05087 100644 --- a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/controller/v7_2/KeyCryptoController.java +++ b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/controller/v7_2/KeyCryptoController.java @@ -1,9 +1,7 @@ package com.github.nagyesta.lowkeyvault.controller.v7_2; import com.github.nagyesta.lowkeyvault.controller.common.CommonKeyCryptoController; -import com.github.nagyesta.lowkeyvault.mapper.v7_2.key.KeyEntityToV72KeyItemModelConverter; -import com.github.nagyesta.lowkeyvault.mapper.v7_2.key.KeyEntityToV72KeyVersionItemModelConverter; -import com.github.nagyesta.lowkeyvault.mapper.v7_2.key.KeyEntityToV72ModelConverter; +import com.github.nagyesta.lowkeyvault.mapper.common.registry.KeyConverterRegistry; import com.github.nagyesta.lowkeyvault.model.common.ApiConstants; import com.github.nagyesta.lowkeyvault.model.v7_2.key.KeyOperationsResult; import com.github.nagyesta.lowkeyvault.model.v7_2.key.KeySignResult; @@ -35,12 +33,8 @@ public class KeyCryptoController extends CommonKeyCryptoController { @Autowired - public KeyCryptoController(@NonNull final KeyEntityToV72ModelConverter keyEntityToV72ModelConverter, - @NonNull final KeyEntityToV72KeyItemModelConverter keyEntityToV72KeyItemModelConverter, - @NonNull final KeyEntityToV72KeyVersionItemModelConverter keyEntityToV72KeyVersionItemModelConverter, - @NonNull final VaultService vaultService) { - super(keyEntityToV72ModelConverter, keyEntityToV72KeyItemModelConverter, - keyEntityToV72KeyVersionItemModelConverter, vaultService); + public KeyCryptoController(@NonNull final KeyConverterRegistry registry, @NonNull final VaultService vaultService) { + super(registry, vaultService); } @Override diff --git a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/controller/v7_2/SecretBackupRestoreController.java b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/controller/v7_2/SecretBackupRestoreController.java index 6e58f2bf..5d742837 100644 --- a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/controller/v7_2/SecretBackupRestoreController.java +++ b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/controller/v7_2/SecretBackupRestoreController.java @@ -1,11 +1,10 @@ package com.github.nagyesta.lowkeyvault.controller.v7_2; import com.github.nagyesta.lowkeyvault.controller.common.CommonSecretBackupRestoreController; -import com.github.nagyesta.lowkeyvault.mapper.v7_2.secret.SecretEntityToV72ModelConverter; +import com.github.nagyesta.lowkeyvault.mapper.common.registry.SecretConverterRegistry; import com.github.nagyesta.lowkeyvault.model.common.ApiConstants; +import com.github.nagyesta.lowkeyvault.model.common.backup.SecretBackupModel; import com.github.nagyesta.lowkeyvault.model.v7_2.secret.KeyVaultSecretModel; -import com.github.nagyesta.lowkeyvault.model.v7_2.secret.SecretBackupModel; -import com.github.nagyesta.lowkeyvault.model.v7_2.secret.SecretEntityToV72BackupConverter; import com.github.nagyesta.lowkeyvault.service.vault.VaultService; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; @@ -30,11 +29,8 @@ public class SecretBackupRestoreController extends CommonSecretBackupRestoreController { @Autowired - public SecretBackupRestoreController( - @NonNull final SecretEntityToV72ModelConverter modelConverter, - @NonNull final SecretEntityToV72BackupConverter backupConverter, - @NonNull final VaultService vaultService) { - super(modelConverter, backupConverter, vaultService); + public SecretBackupRestoreController(@NonNull final SecretConverterRegistry registry, @NonNull final VaultService vaultService) { + super(registry, vaultService); } @Override diff --git a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/controller/v7_2/SecretController.java b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/controller/v7_2/SecretController.java index a79d9f6c..8da86f08 100644 --- a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/controller/v7_2/SecretController.java +++ b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/controller/v7_2/SecretController.java @@ -1,9 +1,7 @@ package com.github.nagyesta.lowkeyvault.controller.v7_2; import com.github.nagyesta.lowkeyvault.controller.common.CommonSecretController; -import com.github.nagyesta.lowkeyvault.mapper.v7_2.secret.SecretEntityToV72ModelConverter; -import com.github.nagyesta.lowkeyvault.mapper.v7_2.secret.SecretEntityToV72SecretItemModelConverter; -import com.github.nagyesta.lowkeyvault.mapper.v7_2.secret.SecretEntityToV72SecretVersionItemModelConverter; +import com.github.nagyesta.lowkeyvault.mapper.common.registry.SecretConverterRegistry; import com.github.nagyesta.lowkeyvault.model.common.ApiConstants; import com.github.nagyesta.lowkeyvault.model.common.KeyVaultItemListModel; import com.github.nagyesta.lowkeyvault.model.v7_2.secret.DeletedKeyVaultSecretItemModel; @@ -36,13 +34,8 @@ public class SecretController extends CommonSecretController { @Autowired - public SecretController( - @NonNull final SecretEntityToV72ModelConverter secretEntityToV72ModelConverter, - @NonNull final SecretEntityToV72SecretItemModelConverter secretEntityToV72SecretItemModelConverter, - @NonNull final SecretEntityToV72SecretVersionItemModelConverter secretEntityToV72SecretVersionItemModelConverter, - @NonNull final VaultService vaultService) { - super(secretEntityToV72ModelConverter, secretEntityToV72SecretItemModelConverter, - secretEntityToV72SecretVersionItemModelConverter, vaultService); + public SecretController(@NonNull final SecretConverterRegistry registry, @NonNull final VaultService vaultService) { + super(registry, vaultService); } @Override diff --git a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/controller/v7_3/CertificateController.java b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/controller/v7_3/CertificateController.java index 7c4db261..62076162 100644 --- a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/controller/v7_3/CertificateController.java +++ b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/controller/v7_3/CertificateController.java @@ -1,14 +1,13 @@ package com.github.nagyesta.lowkeyvault.controller.v7_3; import com.github.nagyesta.lowkeyvault.controller.common.CommonCertificateController; -import com.github.nagyesta.lowkeyvault.mapper.v7_3.certificate.*; +import com.github.nagyesta.lowkeyvault.mapper.common.registry.CertificateConverterRegistry; import com.github.nagyesta.lowkeyvault.model.common.ApiConstants; import com.github.nagyesta.lowkeyvault.model.common.KeyVaultItemListModel; import com.github.nagyesta.lowkeyvault.model.v7_3.certificate.*; import com.github.nagyesta.lowkeyvault.service.vault.VaultService; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.http.ResponseEntity; import org.springframework.lang.NonNull; import org.springframework.stereotype.Component; @@ -29,16 +28,8 @@ @Component("CertificateControllerV73") public class CertificateController extends CommonCertificateController { @Autowired - public CertificateController( - @NonNull final CertificateEntityToV73ModelConverter modelConverter, - @Qualifier("certificateEntityToV73CertificateItemModelConverter") - @NonNull final CertificateEntityToV73CertificateItemModelConverter itemModelConverter, - @NonNull final CertificateEntityToV73CertificateVersionItemModelConverter versionItemModelConverter, - @NonNull final CertificateEntityToV73PendingCertificateOperationModelConverter pendingModelConverter, - @NonNull final LifetimeActionsPolicyToV73ModelConverter lifetimeActionsModelConverter, - @NonNull final VaultService vaultService) { - super(modelConverter, itemModelConverter, versionItemModelConverter, - pendingModelConverter, lifetimeActionsModelConverter, vaultService); + public CertificateController(@NonNull final CertificateConverterRegistry registry, @NonNull final VaultService vaultService) { + super(registry, vaultService); } @Override diff --git a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/controller/v7_3/CertificatePolicyController.java b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/controller/v7_3/CertificatePolicyController.java index 4a601150..1c0f394d 100644 --- a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/controller/v7_3/CertificatePolicyController.java +++ b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/controller/v7_3/CertificatePolicyController.java @@ -1,13 +1,10 @@ package com.github.nagyesta.lowkeyvault.controller.v7_3; import com.github.nagyesta.lowkeyvault.controller.common.CommonCertificatePolicyController; -import com.github.nagyesta.lowkeyvault.mapper.v7_3.certificate.CertificateEntityToV73IssuancePolicyModelConverter; -import com.github.nagyesta.lowkeyvault.mapper.v7_3.certificate.CertificateEntityToV73PendingCertificateOperationModelConverter; -import com.github.nagyesta.lowkeyvault.mapper.v7_3.certificate.LifetimeActionsPolicyToV73ModelConverter; +import com.github.nagyesta.lowkeyvault.mapper.common.registry.CertificateConverterRegistry; import com.github.nagyesta.lowkeyvault.model.common.ApiConstants; import com.github.nagyesta.lowkeyvault.model.v7_3.certificate.CertificatePolicyModel; import com.github.nagyesta.lowkeyvault.model.v7_3.certificate.KeyVaultPendingCertificateModel; -import com.github.nagyesta.lowkeyvault.service.vault.VaultFake; import com.github.nagyesta.lowkeyvault.service.vault.VaultService; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; @@ -31,12 +28,8 @@ @Component("CertificatePolicyControllerV73") public class CertificatePolicyController extends CommonCertificatePolicyController { @Autowired - public CertificatePolicyController( - @NonNull final CertificateEntityToV73PendingCertificateOperationModelConverter pendingOperationConverter, - @NonNull final CertificateEntityToV73IssuancePolicyModelConverter issuancePolicyConverter, - @NonNull final LifetimeActionsPolicyToV73ModelConverter lifetimeActionsConverter, - @NonNull final VaultService vaultService) { - super(pendingOperationConverter, issuancePolicyConverter, lifetimeActionsConverter, vaultService, VaultFake::certificateVaultFake); + public CertificatePolicyController(@NonNull final CertificateConverterRegistry registry, @NonNull final VaultService vaultService) { + super(registry, vaultService); } @Override diff --git a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/controller/v7_3/KeyBackupRestoreController.java b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/controller/v7_3/KeyBackupRestoreController.java index c06da86e..e2833614 100644 --- a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/controller/v7_3/KeyBackupRestoreController.java +++ b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/controller/v7_3/KeyBackupRestoreController.java @@ -1,16 +1,11 @@ package com.github.nagyesta.lowkeyvault.controller.v7_3; import com.github.nagyesta.lowkeyvault.controller.common.CommonKeyBackupRestoreController; -import com.github.nagyesta.lowkeyvault.mapper.v7_2.key.KeyEntityToV72BackupConverter; -import com.github.nagyesta.lowkeyvault.mapper.v7_2.key.KeyEntityToV72ModelConverter; -import com.github.nagyesta.lowkeyvault.mapper.v7_3.key.KeyRotationPolicyToV73ModelConverter; -import com.github.nagyesta.lowkeyvault.mapper.v7_3.key.KeyRotationPolicyV73ModelToEntityConverter; +import com.github.nagyesta.lowkeyvault.mapper.common.registry.KeyConverterRegistry; import com.github.nagyesta.lowkeyvault.model.common.ApiConstants; -import com.github.nagyesta.lowkeyvault.model.v7_2.key.KeyBackupListItem; +import com.github.nagyesta.lowkeyvault.model.common.backup.KeyBackupList; +import com.github.nagyesta.lowkeyvault.model.common.backup.KeyBackupModel; import com.github.nagyesta.lowkeyvault.model.v7_2.key.KeyVaultKeyModel; -import com.github.nagyesta.lowkeyvault.model.v7_2.key.request.JsonWebKeyImportRequest; -import com.github.nagyesta.lowkeyvault.model.v7_3.key.KeyBackupList; -import com.github.nagyesta.lowkeyvault.model.v7_3.key.KeyBackupModel; import com.github.nagyesta.lowkeyvault.model.v7_3.key.KeyRotationPolicyModel; import com.github.nagyesta.lowkeyvault.service.key.KeyVaultFake; import com.github.nagyesta.lowkeyvault.service.key.ReadOnlyRotationPolicy; @@ -18,6 +13,7 @@ import com.github.nagyesta.lowkeyvault.service.vault.VaultService; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.DependsOn; import org.springframework.http.ResponseEntity; import org.springframework.lang.NonNull; import org.springframework.stereotype.Component; @@ -36,30 +32,22 @@ @Slf4j @RestController @Validated +@DependsOn({"keyModelConverter", "keyRotationPolicyEntityConverter"}) @Component("KeyBackupRestoreControllerV73") -public class KeyBackupRestoreController - extends CommonKeyBackupRestoreController { - - private final KeyRotationPolicyToV73ModelConverter keyRotationPolicyToV73ModelConverter; - private final KeyRotationPolicyV73ModelToEntityConverter rotationV73ModelToEntityConverter; +public class KeyBackupRestoreController extends CommonKeyBackupRestoreController { @Autowired - public KeyBackupRestoreController(@NonNull final KeyEntityToV72ModelConverter modelConverter, - @NonNull final KeyEntityToV72BackupConverter backupConverter, - @NonNull final VaultService vaultService, - @NonNull final KeyRotationPolicyToV73ModelConverter keyRotationPolicyToV73ModelConverter, - @NonNull final KeyRotationPolicyV73ModelToEntityConverter rotationV73ModelToEntityConverter) { - super(modelConverter, backupConverter, vaultService); - this.keyRotationPolicyToV73ModelConverter = keyRotationPolicyToV73ModelConverter; - this.rotationV73ModelToEntityConverter = rotationV73ModelToEntityConverter; + public KeyBackupRestoreController(@NonNull final KeyConverterRegistry registry, @NonNull final VaultService vaultService) { + super(registry, vaultService); } @Override @PostMapping(value = "/keys/{keyName}/backup", params = API_VERSION_7_3, produces = APPLICATION_JSON_VALUE) - public ResponseEntity backup(@PathVariable @Valid @Pattern(regexp = NAME_PATTERN) final String keyName, - @RequestAttribute(name = ApiConstants.REQUEST_BASE_URI) final URI baseUri) { + public ResponseEntity + backup(@PathVariable @Valid @Pattern(regexp = NAME_PATTERN) final String keyName, + @RequestAttribute(name = ApiConstants.REQUEST_BASE_URI) final URI baseUri) { return super.backup(keyName, baseUri); } @@ -78,7 +66,7 @@ protected KeyBackupModel backupEntity(final KeyEntityId entityId) { final KeyBackupModel keyBackupModel = super.backupEntity(entityId); final KeyBackupList value = keyBackupModel.getValue(); final ReadOnlyRotationPolicy rotationPolicy = getVaultByUri(entityId.vault()).rotationPolicy(entityId); - value.setKeyRotationPolicy(keyRotationPolicyToV73ModelConverter.convert(rotationPolicy, entityId.vault())); + value.setKeyRotationPolicy(registry().rotationPolicyModelConverter(apiVersion()).convert(rotationPolicy, entityId.vault())); return keyBackupModel; } @@ -91,7 +79,11 @@ protected KeyVaultKeyModel restoreEntity(final KeyBackupModel backupModel) { final KeyVaultFake vaultByUri = getVaultByUri(baseUri); final KeyRotationPolicyModel keyRotationPolicy = backupModel.getValue().getKeyRotationPolicy(); Optional.ofNullable(keyRotationPolicy) - .map(r -> rotationV73ModelToEntityConverter.convert(keyEntityId, r)) + .map(r -> { + r.setKeyEntityId(keyEntityId); + return r; + }) + .map(r -> registry().rotationPolicyEntityConverter(apiVersion()).convert(r)) .ifPresent(vaultByUri::setRotationPolicy); return keyVaultKeyModel; } @@ -100,19 +92,4 @@ protected KeyVaultKeyModel restoreEntity(final KeyBackupModel backupModel) { protected String apiVersion() { return V_7_3; } - - @Override - protected JsonWebKeyImportRequest getKeyMaterial(final KeyBackupListItem entityVersion) { - return entityVersion.getKeyMaterial(); - } - - @Override - protected KeyBackupList getBackupList() { - return new KeyBackupList(); - } - - @Override - protected KeyBackupModel getBackupModel() { - return new KeyBackupModel(); - } } diff --git a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/controller/v7_3/KeyController.java b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/controller/v7_3/KeyController.java index 1551f016..3d9a71ac 100644 --- a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/controller/v7_3/KeyController.java +++ b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/controller/v7_3/KeyController.java @@ -1,9 +1,7 @@ package com.github.nagyesta.lowkeyvault.controller.v7_3; import com.github.nagyesta.lowkeyvault.controller.common.CommonKeyController; -import com.github.nagyesta.lowkeyvault.mapper.v7_2.key.KeyEntityToV72KeyItemModelConverter; -import com.github.nagyesta.lowkeyvault.mapper.v7_2.key.KeyEntityToV72KeyVersionItemModelConverter; -import com.github.nagyesta.lowkeyvault.mapper.v7_2.key.KeyEntityToV72ModelConverter; +import com.github.nagyesta.lowkeyvault.mapper.common.registry.KeyConverterRegistry; import com.github.nagyesta.lowkeyvault.model.common.ApiConstants; import com.github.nagyesta.lowkeyvault.model.common.KeyVaultItemListModel; import com.github.nagyesta.lowkeyvault.model.v7_2.key.DeletedKeyVaultKeyItemModel; @@ -39,12 +37,8 @@ public class KeyController extends CommonKeyController { @Autowired - public KeyController(@NonNull final KeyEntityToV72ModelConverter keyEntityToV72ModelConverter, - @NonNull final KeyEntityToV72KeyItemModelConverter keyEntityToV72KeyItemModelConverter, - @NonNull final KeyEntityToV72KeyVersionItemModelConverter keyEntityToV72KeyVersionItemModelConverter, - @NonNull final VaultService vaultService) { - super(keyEntityToV72ModelConverter, keyEntityToV72KeyItemModelConverter, - keyEntityToV72KeyVersionItemModelConverter, vaultService); + public KeyController(@NonNull final KeyConverterRegistry registry, @NonNull final VaultService vaultService) { + super(registry, vaultService); } @Override diff --git a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/controller/v7_3/KeyCryptoController.java b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/controller/v7_3/KeyCryptoController.java index 89ca5767..67c7f05e 100644 --- a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/controller/v7_3/KeyCryptoController.java +++ b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/controller/v7_3/KeyCryptoController.java @@ -1,9 +1,7 @@ package com.github.nagyesta.lowkeyvault.controller.v7_3; import com.github.nagyesta.lowkeyvault.controller.common.CommonKeyCryptoController; -import com.github.nagyesta.lowkeyvault.mapper.v7_2.key.KeyEntityToV72KeyItemModelConverter; -import com.github.nagyesta.lowkeyvault.mapper.v7_2.key.KeyEntityToV72KeyVersionItemModelConverter; -import com.github.nagyesta.lowkeyvault.mapper.v7_2.key.KeyEntityToV72ModelConverter; +import com.github.nagyesta.lowkeyvault.mapper.common.registry.KeyConverterRegistry; import com.github.nagyesta.lowkeyvault.model.common.ApiConstants; import com.github.nagyesta.lowkeyvault.model.v7_2.key.KeyOperationsResult; import com.github.nagyesta.lowkeyvault.model.v7_2.key.KeySignResult; @@ -38,12 +36,8 @@ public class KeyCryptoController extends CommonKeyCryptoController { @Autowired - public KeyCryptoController(@NonNull final KeyEntityToV72ModelConverter keyEntityToV72ModelConverter, - @NonNull final KeyEntityToV72KeyItemModelConverter keyEntityToV72KeyItemModelConverter, - @NonNull final KeyEntityToV72KeyVersionItemModelConverter keyEntityToV72KeyVersionItemModelConverter, - @NonNull final VaultService vaultService) { - super(keyEntityToV72ModelConverter, keyEntityToV72KeyItemModelConverter, - keyEntityToV72KeyVersionItemModelConverter, vaultService); + public KeyCryptoController(@NonNull final KeyConverterRegistry registry, @NonNull final VaultService vaultService) { + super(registry, vaultService); } @Override diff --git a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/controller/v7_3/KeyPolicyController.java b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/controller/v7_3/KeyPolicyController.java index 8c1be4df..7a63fcae 100644 --- a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/controller/v7_3/KeyPolicyController.java +++ b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/controller/v7_3/KeyPolicyController.java @@ -1,18 +1,15 @@ package com.github.nagyesta.lowkeyvault.controller.v7_3; -import com.github.nagyesta.lowkeyvault.controller.common.BaseEntityReadController; -import com.github.nagyesta.lowkeyvault.mapper.v7_3.key.KeyRotationPolicyToV73ModelConverter; -import com.github.nagyesta.lowkeyvault.mapper.v7_3.key.KeyRotationPolicyV73ModelToEntityConverter; +import com.github.nagyesta.lowkeyvault.controller.common.BaseKeyController; +import com.github.nagyesta.lowkeyvault.mapper.common.AliasAwareConverter; +import com.github.nagyesta.lowkeyvault.mapper.common.registry.KeyConverterRegistry; import com.github.nagyesta.lowkeyvault.model.common.ApiConstants; import com.github.nagyesta.lowkeyvault.model.v7_3.key.KeyRotationPolicyModel; import com.github.nagyesta.lowkeyvault.model.v7_3.key.validator.Update; import com.github.nagyesta.lowkeyvault.service.key.KeyVaultFake; -import com.github.nagyesta.lowkeyvault.service.key.ReadOnlyKeyVaultKeyEntity; import com.github.nagyesta.lowkeyvault.service.key.ReadOnlyRotationPolicy; import com.github.nagyesta.lowkeyvault.service.key.RotationPolicy; import com.github.nagyesta.lowkeyvault.service.key.id.KeyEntityId; -import com.github.nagyesta.lowkeyvault.service.key.id.VersionedKeyEntityId; -import com.github.nagyesta.lowkeyvault.service.vault.VaultFake; import com.github.nagyesta.lowkeyvault.service.vault.VaultService; import lombok.extern.slf4j.Slf4j; import org.springframework.http.ResponseEntity; @@ -33,18 +30,10 @@ @RestController @Validated @Component("KeyPolicyControllerV73") -public class KeyPolicyController - extends BaseEntityReadController { +public class KeyPolicyController extends BaseKeyController { - private final KeyRotationPolicyToV73ModelConverter keyRotationPolicyToV73ModelConverter; - private final KeyRotationPolicyV73ModelToEntityConverter rotationV73ModelToEntityConverter; - - public KeyPolicyController(@NonNull final VaultService vaultService, - @lombok.NonNull final KeyRotationPolicyToV73ModelConverter keyRotationPolicyToV73ModelConverter, - @lombok.NonNull final KeyRotationPolicyV73ModelToEntityConverter rotationV73ModelToEntityConverter) { - super(vaultService, VaultFake::keyVaultFake); - this.keyRotationPolicyToV73ModelConverter = keyRotationPolicyToV73ModelConverter; - this.rotationV73ModelToEntityConverter = rotationV73ModelToEntityConverter; + public KeyPolicyController(@NonNull final KeyConverterRegistry registry, @NonNull final VaultService vaultService) { + super(registry, vaultService); } @GetMapping(value = "/keys/{keyName}/rotationpolicy", @@ -69,22 +58,13 @@ public ResponseEntity updateRotationPolicy( log.info("Received request to {} update rotation policy: {} using API version: {}", baseUri.toString(), keyName, apiVersion()); final KeyEntityId keyEntityId = entityId(baseUri, keyName); - final RotationPolicy rotationPolicy = rotationV73ModelToEntityConverter.convert(keyEntityId, request); + request.setKeyEntityId(keyEntityId); + final RotationPolicy rotationPolicy = registry().rotationPolicyEntityConverter(apiVersion()).convert(request); final KeyVaultFake keyVaultFake = getVaultByUri(baseUri); keyVaultFake.setRotationPolicy(rotationPolicy); return getRotationPolicyResponseEntity(keyVaultFake, keyEntityId, baseUri); } - @Override - protected VersionedKeyEntityId versionedEntityId(final URI baseUri, final String name, final String version) { - return new VersionedKeyEntityId(baseUri, name, version); - } - - @Override - protected KeyEntityId entityId(final URI baseUri, final String name) { - return new KeyEntityId(baseUri, name); - } - @Override protected String apiVersion() { return V_7_3; @@ -93,6 +73,8 @@ protected String apiVersion() { private ResponseEntity getRotationPolicyResponseEntity( final KeyVaultFake keyVaultFake, final KeyEntityId keyEntityId, final URI baseUri) { final ReadOnlyRotationPolicy policy = keyVaultFake.rotationPolicy(keyEntityId); - return ResponseEntity.ok(keyRotationPolicyToV73ModelConverter.convert(policy, baseUri)); + final AliasAwareConverter converter = registry() + .rotationPolicyModelConverter(apiVersion()); + return ResponseEntity.ok(converter.convert(policy, baseUri)); } } diff --git a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/controller/v7_3/SecretBackupRestoreController.java b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/controller/v7_3/SecretBackupRestoreController.java index 144c60b8..dee4633b 100644 --- a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/controller/v7_3/SecretBackupRestoreController.java +++ b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/controller/v7_3/SecretBackupRestoreController.java @@ -1,14 +1,14 @@ package com.github.nagyesta.lowkeyvault.controller.v7_3; import com.github.nagyesta.lowkeyvault.controller.common.CommonSecretBackupRestoreController; -import com.github.nagyesta.lowkeyvault.mapper.v7_2.secret.SecretEntityToV72ModelConverter; +import com.github.nagyesta.lowkeyvault.mapper.common.registry.SecretConverterRegistry; import com.github.nagyesta.lowkeyvault.model.common.ApiConstants; +import com.github.nagyesta.lowkeyvault.model.common.backup.SecretBackupModel; import com.github.nagyesta.lowkeyvault.model.v7_2.secret.KeyVaultSecretModel; -import com.github.nagyesta.lowkeyvault.model.v7_2.secret.SecretBackupModel; -import com.github.nagyesta.lowkeyvault.model.v7_2.secret.SecretEntityToV72BackupConverter; import com.github.nagyesta.lowkeyvault.service.vault.VaultService; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.DependsOn; import org.springframework.http.ResponseEntity; import org.springframework.lang.NonNull; import org.springframework.stereotype.Component; @@ -26,15 +26,13 @@ @Slf4j @RestController @Validated +@DependsOn("secretModelConverter") @Component("SecretBackupRestoreControllerV73") public class SecretBackupRestoreController extends CommonSecretBackupRestoreController { @Autowired - public SecretBackupRestoreController( - @NonNull final SecretEntityToV72ModelConverter modelConverter, - @NonNull final SecretEntityToV72BackupConverter backupConverter, - @NonNull final VaultService vaultService) { - super(modelConverter, backupConverter, vaultService); + public SecretBackupRestoreController(@NonNull final SecretConverterRegistry registry, @NonNull final VaultService vaultService) { + super(registry, vaultService); } @Override diff --git a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/controller/v7_3/SecretController.java b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/controller/v7_3/SecretController.java index 5d8adb4f..60e23268 100644 --- a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/controller/v7_3/SecretController.java +++ b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/controller/v7_3/SecretController.java @@ -1,9 +1,7 @@ package com.github.nagyesta.lowkeyvault.controller.v7_3; import com.github.nagyesta.lowkeyvault.controller.common.CommonSecretController; -import com.github.nagyesta.lowkeyvault.mapper.v7_2.secret.SecretEntityToV72ModelConverter; -import com.github.nagyesta.lowkeyvault.mapper.v7_2.secret.SecretEntityToV72SecretItemModelConverter; -import com.github.nagyesta.lowkeyvault.mapper.v7_2.secret.SecretEntityToV72SecretVersionItemModelConverter; +import com.github.nagyesta.lowkeyvault.mapper.common.registry.SecretConverterRegistry; import com.github.nagyesta.lowkeyvault.model.common.ApiConstants; import com.github.nagyesta.lowkeyvault.model.common.KeyVaultItemListModel; import com.github.nagyesta.lowkeyvault.model.v7_2.secret.DeletedKeyVaultSecretItemModel; @@ -36,13 +34,8 @@ public class SecretController extends CommonSecretController { @Autowired - public SecretController( - @NonNull final SecretEntityToV72ModelConverter secretEntityToV72ModelConverter, - @NonNull final SecretEntityToV72SecretItemModelConverter secretEntityToV72SecretItemModelConverter, - @NonNull final SecretEntityToV72SecretVersionItemModelConverter secretEntityToV72SecretVersionItemModelConverter, - @NonNull final VaultService vaultService) { - super(secretEntityToV72ModelConverter, secretEntityToV72SecretItemModelConverter, - secretEntityToV72SecretVersionItemModelConverter, vaultService); + public SecretController(@NonNull final SecretConverterRegistry registry, @NonNull final VaultService vaultService) { + super(registry, vaultService); } @Override diff --git a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/AliasAwareConverter.java b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/common/AliasAwareConverter.java similarity index 59% rename from lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/AliasAwareConverter.java rename to lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/common/AliasAwareConverter.java index 370f7343..a132e04f 100644 --- a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/AliasAwareConverter.java +++ b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/common/AliasAwareConverter.java @@ -1,5 +1,7 @@ -package com.github.nagyesta.lowkeyvault.mapper; +package com.github.nagyesta.lowkeyvault.mapper.common; +import com.github.nagyesta.lowkeyvault.context.ApiVersionAware; +import org.springframework.beans.factory.InitializingBean; import org.springframework.lang.NonNull; import org.springframework.lang.Nullable; @@ -12,7 +14,7 @@ * @param the source type * @param the target type */ -public interface AliasAwareConverter { +public interface AliasAwareConverter extends ApiVersionAware, InitializingBean { @Nullable T convert(S source, @NonNull URI vaultUri); } diff --git a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/common/ApiVersionAwareConverter.java b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/common/ApiVersionAwareConverter.java new file mode 100644 index 00000000..eb4565a8 --- /dev/null +++ b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/common/ApiVersionAwareConverter.java @@ -0,0 +1,8 @@ +package com.github.nagyesta.lowkeyvault.mapper.common; + +import com.github.nagyesta.lowkeyvault.context.ApiVersionAware; +import org.springframework.beans.factory.InitializingBean; +import org.springframework.core.convert.converter.Converter; + +public interface ApiVersionAwareConverter extends Converter, ApiVersionAware, InitializingBean { +} diff --git a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/common/BackupConverter.java b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/common/BackupConverter.java index f2e4b201..a770db18 100644 --- a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/common/BackupConverter.java +++ b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/common/BackupConverter.java @@ -1,23 +1,15 @@ package com.github.nagyesta.lowkeyvault.mapper.common; -import com.github.nagyesta.lowkeyvault.mapper.AliasAwareConverter; import com.github.nagyesta.lowkeyvault.model.v7_2.BasePropertiesModel; import com.github.nagyesta.lowkeyvault.model.v7_2.common.BaseBackupListItem; import com.github.nagyesta.lowkeyvault.service.EntityId; import com.github.nagyesta.lowkeyvault.service.common.BaseVaultEntity; -import org.springframework.core.convert.converter.Converter; import org.springframework.lang.NonNull; import java.util.Map; -public abstract class BackupConverter, P extends BasePropertiesModel, - BLI extends BaseBackupListItem

    > implements Converter { - - private final AliasAwareConverter propertiesConverter; - - protected BackupConverter(@lombok.NonNull final AliasAwareConverter propertiesConverter) { - this.propertiesConverter = propertiesConverter; - } +public abstract class BackupConverter, P extends BasePropertiesModel, + BLI extends BaseBackupListItem

    > implements ApiVersionAwareConverter { @NonNull @Override @@ -33,9 +25,11 @@ private BLI mapCommonFields(final E source, final BLI item) { item.setVaultBaseUri(entityId.vault()); item.setId(entityId.id()); item.setVersion(entityId.version()); - item.setAttributes(propertiesConverter.convert(source, entityId.vault())); + item.setAttributes(propertiesConverter().convert(source, entityId.vault())); item.setTags(Map.copyOf(source.getTags())); item.setManaged(source.isManaged()); return item; } + + protected abstract AliasAwareConverter propertiesConverter(); } diff --git a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/common/BaseEntityConverterRegistry.java b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/common/BaseEntityConverterRegistry.java new file mode 100644 index 00000000..7080e00d --- /dev/null +++ b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/common/BaseEntityConverterRegistry.java @@ -0,0 +1,74 @@ +package com.github.nagyesta.lowkeyvault.mapper.common; + +import com.github.nagyesta.lowkeyvault.model.v7_2.BasePropertiesModel; +import com.github.nagyesta.lowkeyvault.model.v7_2.common.BaseBackupListItem; +import com.github.nagyesta.lowkeyvault.model.v7_2.common.BaseBackupModel; +import com.github.nagyesta.lowkeyvault.model.v7_2.key.BackupListContainer; +import com.github.nagyesta.lowkeyvault.service.EntityId; +import com.github.nagyesta.lowkeyvault.service.common.BaseVaultEntity; + +import java.util.HashMap; +import java.util.Map; + +public abstract class BaseEntityConverterRegistry, M, DM extends M, PM extends BasePropertiesModel, IM, DIM extends IM, + BLI extends BaseBackupListItem, BL extends BackupListContainer, + B extends BaseBackupModel> + implements EntityConverterRegistry { + + private final Map> modelConverters = new HashMap<>(); + private final Map> propertiesConverters = new HashMap<>(); + private final Map> itemConverters = new HashMap<>(); + private final Map> versionedItemConverters = new HashMap<>(); + private final Map> backupConverters = new HashMap<>(); + + @Override + public RecoveryAwareConverter modelConverter(final String apiVersion) { + return modelConverters.get(apiVersion); + } + + @Override + public void registerModelConverter(final RecoveryAwareConverter converter) { + converter.supportedVersions().forEach(v -> modelConverters.put(v, converter)); + } + + @Override + public AliasAwareConverter propertiesConverter(final String apiVersion) { + return propertiesConverters.get(apiVersion); + } + + @Override + public void registerPropertiesConverter(final AliasAwareConverter converter) { + converter.supportedVersions().forEach(v -> propertiesConverters.put(v, converter)); + } + + @Override + public RecoveryAwareConverter itemConverter(final String apiVersion) { + return itemConverters.get(apiVersion); + } + + @Override + public void registerItemConverter(final RecoveryAwareConverter converter) { + converter.supportedVersions().forEach(v -> itemConverters.put(v, converter)); + } + + @Override + public RecoveryAwareConverter versionedItemConverter(final String apiVersion) { + return versionedItemConverters.get(apiVersion); + } + + @Override + public void registerVersionedItemConverter(final RecoveryAwareConverter converter) { + converter.supportedVersions().forEach(v -> versionedItemConverters.put(v, converter)); + } + + @Override + public BackupConverter backupConverter(final String apiVersion) { + return backupConverters.get(apiVersion); + } + + @Override + public void registerBackupConverter(final BackupConverter converter) { + converter.supportedVersions().forEach(v -> backupConverters.put(v, converter)); + } +} diff --git a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/common/BaseEntityToV72PropertiesModelConverter.java b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/common/BasePropertiesModelConverter.java similarity index 67% rename from lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/common/BaseEntityToV72PropertiesModelConverter.java rename to lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/common/BasePropertiesModelConverter.java index cfc1961d..a2a1f8b9 100644 --- a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/common/BaseEntityToV72PropertiesModelConverter.java +++ b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/common/BasePropertiesModelConverter.java @@ -1,11 +1,14 @@ package com.github.nagyesta.lowkeyvault.mapper.common; import com.github.nagyesta.lowkeyvault.model.v7_2.BasePropertiesModel; +import com.github.nagyesta.lowkeyvault.service.EntityId; import com.github.nagyesta.lowkeyvault.service.common.BaseVaultEntity; -public class BaseEntityToV72PropertiesModelConverter { +public abstract class BasePropertiesModelConverter, M extends BasePropertiesModel> + implements AliasAwareConverter { - protected M mapCommonFields(final BaseVaultEntity entity, final M attributes) { + protected M mapCommonFields(final E entity, final M attributes) { attributes.setCreatedOn(entity.getCreated()); attributes.setUpdatedOn(entity.getUpdated()); attributes.setEnabled(entity.isEnabled()); diff --git a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/common/EntityConverterRegistry.java b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/common/EntityConverterRegistry.java new file mode 100644 index 00000000..95bd841d --- /dev/null +++ b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/common/EntityConverterRegistry.java @@ -0,0 +1,40 @@ +package com.github.nagyesta.lowkeyvault.mapper.common; + +import com.github.nagyesta.lowkeyvault.model.v7_2.BasePropertiesModel; +import com.github.nagyesta.lowkeyvault.model.v7_2.common.BaseBackupListItem; +import com.github.nagyesta.lowkeyvault.model.v7_2.common.BaseBackupModel; +import com.github.nagyesta.lowkeyvault.model.v7_2.key.BackupListContainer; +import com.github.nagyesta.lowkeyvault.service.EntityId; +import com.github.nagyesta.lowkeyvault.service.common.BaseVaultEntity; + +import java.net.URI; + +public interface EntityConverterRegistry, M, DM extends M, PM extends BasePropertiesModel, IM, DIM extends IM, + BLI extends BaseBackupListItem, BL extends BackupListContainer, + B extends BaseBackupModel> { + + K entityId(URI baseUri, String name); + + V versionedEntityId(URI baseUri, String name, String version); + + RecoveryAwareConverter modelConverter(String apiVersion); + + void registerModelConverter(RecoveryAwareConverter converter); + + AliasAwareConverter propertiesConverter(String apiVersion); + + void registerPropertiesConverter(AliasAwareConverter converter); + + RecoveryAwareConverter itemConverter(String apiVersion); + + void registerItemConverter(RecoveryAwareConverter converter); + + RecoveryAwareConverter versionedItemConverter(String apiVersion); + + void registerVersionedItemConverter(RecoveryAwareConverter converter); + + BackupConverter backupConverter(String apiVersion); + + void registerBackupConverter(BackupConverter converter); +} diff --git a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/common/RecoveryAwareConverter.java b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/common/RecoveryAwareConverter.java index 42cc6763..7847be0c 100644 --- a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/common/RecoveryAwareConverter.java +++ b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/common/RecoveryAwareConverter.java @@ -1,5 +1,7 @@ package com.github.nagyesta.lowkeyvault.mapper.common; +import com.github.nagyesta.lowkeyvault.context.ApiVersionAware; +import org.springframework.beans.factory.InitializingBean; import org.springframework.lang.NonNull; import org.springframework.lang.Nullable; @@ -12,7 +14,7 @@ * @param The active target type. * @param

    The deleted target type. */ -public interface RecoveryAwareConverter { +public interface RecoveryAwareConverter extends ApiVersionAware, InitializingBean { @Nullable T convert(S source, @NonNull URI vaultUri); diff --git a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/common/registry/CertificateConverterRegistry.java b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/common/registry/CertificateConverterRegistry.java new file mode 100644 index 00000000..60040fe7 --- /dev/null +++ b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/common/registry/CertificateConverterRegistry.java @@ -0,0 +1,85 @@ +package com.github.nagyesta.lowkeyvault.mapper.common.registry; + +import com.github.nagyesta.lowkeyvault.mapper.common.AliasAwareConverter; +import com.github.nagyesta.lowkeyvault.mapper.common.ApiVersionAwareConverter; +import com.github.nagyesta.lowkeyvault.mapper.common.BaseEntityConverterRegistry; +import com.github.nagyesta.lowkeyvault.model.common.backup.CertificateBackupList; +import com.github.nagyesta.lowkeyvault.model.common.backup.CertificateBackupListItem; +import com.github.nagyesta.lowkeyvault.model.common.backup.CertificateBackupModel; +import com.github.nagyesta.lowkeyvault.model.v7_3.certificate.*; +import com.github.nagyesta.lowkeyvault.service.certificate.LifetimeActionPolicy; +import com.github.nagyesta.lowkeyvault.service.certificate.ReadOnlyKeyVaultCertificateEntity; +import com.github.nagyesta.lowkeyvault.service.certificate.id.CertificateEntityId; +import com.github.nagyesta.lowkeyvault.service.certificate.id.VersionedCertificateEntityId; +import lombok.EqualsAndHashCode; + +import java.net.URI; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@EqualsAndHashCode(callSuper = true) +public class CertificateConverterRegistry extends BaseEntityConverterRegistry { + + private final Map> + policyConverters = new HashMap<>(); + private final Map> + issuancePolicyConverters = new HashMap<>(); + private final Map> + pendingOperationConverters = new HashMap<>(); + private final Map>> + lifetimeActionConverters = new HashMap<>(); + + @Override + public CertificateEntityId entityId(final URI baseUri, final String name) { + return new CertificateEntityId(baseUri, name); + } + + @Override + public VersionedCertificateEntityId versionedEntityId(final URI baseUri, final String name, final String version) { + return new VersionedCertificateEntityId(baseUri, name, version); + } + + public AliasAwareConverter policyConverters( + final String apiVersion) { + return policyConverters.get(apiVersion); + } + + public void registerPolicyConverter( + final AliasAwareConverter converter) { + converter.supportedVersions().forEach(v -> policyConverters.put(v, converter)); + } + + public AliasAwareConverter issuancePolicyConverters( + final String apiVersion) { + return issuancePolicyConverters.get(apiVersion); + } + + public void registerIssuancePolicyConverter( + final AliasAwareConverter converter) { + converter.supportedVersions().forEach(v -> issuancePolicyConverters.put(v, converter)); + } + + public AliasAwareConverter pendingOperationConverters( + final String apiVersion) { + return pendingOperationConverters.get(apiVersion); + } + + public void registerPendingOperationConverter( + final AliasAwareConverter converter) { + converter.supportedVersions().forEach(v -> pendingOperationConverters.put(v, converter)); + } + + public ApiVersionAwareConverter> lifetimeActionConverters( + final String apiVersion) { + return lifetimeActionConverters.get(apiVersion); + } + + public void registerLifetimeActionConverter( + final ApiVersionAwareConverter> converter) { + converter.supportedVersions().forEach(v -> lifetimeActionConverters.put(v, converter)); + } +} diff --git a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/common/registry/KeyConverterRegistry.java b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/common/registry/KeyConverterRegistry.java new file mode 100644 index 00000000..7bc80d24 --- /dev/null +++ b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/common/registry/KeyConverterRegistry.java @@ -0,0 +1,60 @@ +package com.github.nagyesta.lowkeyvault.mapper.common.registry; + +import com.github.nagyesta.lowkeyvault.mapper.common.AliasAwareConverter; +import com.github.nagyesta.lowkeyvault.mapper.common.ApiVersionAwareConverter; +import com.github.nagyesta.lowkeyvault.mapper.common.BaseEntityConverterRegistry; +import com.github.nagyesta.lowkeyvault.model.common.backup.KeyBackupList; +import com.github.nagyesta.lowkeyvault.model.common.backup.KeyBackupListItem; +import com.github.nagyesta.lowkeyvault.model.common.backup.KeyBackupModel; +import com.github.nagyesta.lowkeyvault.model.v7_2.key.*; +import com.github.nagyesta.lowkeyvault.model.v7_3.key.KeyRotationPolicyModel; +import com.github.nagyesta.lowkeyvault.service.key.ReadOnlyKeyVaultKeyEntity; +import com.github.nagyesta.lowkeyvault.service.key.ReadOnlyRotationPolicy; +import com.github.nagyesta.lowkeyvault.service.key.RotationPolicy; +import com.github.nagyesta.lowkeyvault.service.key.id.KeyEntityId; +import com.github.nagyesta.lowkeyvault.service.key.id.VersionedKeyEntityId; +import lombok.EqualsAndHashCode; + +import java.net.URI; +import java.util.HashMap; +import java.util.Map; + +@EqualsAndHashCode(callSuper = true) +public class KeyConverterRegistry extends BaseEntityConverterRegistry { + + private final Map> rotationPolicyModelConverters = + new HashMap<>(); + + private final Map> rotationPolicyEntityConverters = + new HashMap<>(); + + @Override + public KeyEntityId entityId(final URI baseUri, final String name) { + return new KeyEntityId(baseUri, name); + } + + @Override + public VersionedKeyEntityId versionedEntityId(final URI baseUri, final String name, final String version) { + return new VersionedKeyEntityId(baseUri, name, version); + } + + public AliasAwareConverter rotationPolicyModelConverter( + final String apiVersion) { + return rotationPolicyModelConverters.get(apiVersion); + } + + public void registerRotationPolicyModelConverter(final AliasAwareConverter converter) { + converter.supportedVersions().forEach(v -> rotationPolicyModelConverters.put(v, converter)); + } + + public ApiVersionAwareConverter rotationPolicyEntityConverter( + final String apiVersion) { + return rotationPolicyEntityConverters.get(apiVersion); + } + + public void registerRotationPolicyEntityConverter(final ApiVersionAwareConverter converter) { + converter.supportedVersions().forEach(v -> rotationPolicyEntityConverters.put(v, converter)); + } +} diff --git a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/common/registry/SecretConverterRegistry.java b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/common/registry/SecretConverterRegistry.java new file mode 100644 index 00000000..5bf654c6 --- /dev/null +++ b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/common/registry/SecretConverterRegistry.java @@ -0,0 +1,29 @@ +package com.github.nagyesta.lowkeyvault.mapper.common.registry; + +import com.github.nagyesta.lowkeyvault.mapper.common.BaseEntityConverterRegistry; +import com.github.nagyesta.lowkeyvault.model.common.backup.SecretBackupList; +import com.github.nagyesta.lowkeyvault.model.common.backup.SecretBackupListItem; +import com.github.nagyesta.lowkeyvault.model.common.backup.SecretBackupModel; +import com.github.nagyesta.lowkeyvault.model.v7_2.secret.*; +import com.github.nagyesta.lowkeyvault.service.secret.ReadOnlyKeyVaultSecretEntity; +import com.github.nagyesta.lowkeyvault.service.secret.id.SecretEntityId; +import com.github.nagyesta.lowkeyvault.service.secret.id.VersionedSecretEntityId; +import lombok.EqualsAndHashCode; + +import java.net.URI; + +@EqualsAndHashCode(callSuper = true) +public class SecretConverterRegistry extends BaseEntityConverterRegistry { + + @Override + public SecretEntityId entityId(final URI baseUri, final String name) { + return new SecretEntityId(baseUri, name); + } + + @Override + public VersionedSecretEntityId versionedEntityId(final URI baseUri, final String name, final String version) { + return new VersionedSecretEntityId(baseUri, name, version); + } +} diff --git a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/v7_2/key/KeyEntityToV72BackupConverter.java b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/v7_2/key/KeyEntityToV72BackupConverter.java index ec309cb1..97a0de86 100644 --- a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/v7_2/key/KeyEntityToV72BackupConverter.java +++ b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/v7_2/key/KeyEntityToV72BackupConverter.java @@ -1,28 +1,37 @@ package com.github.nagyesta.lowkeyvault.mapper.v7_2.key; -import com.github.nagyesta.lowkeyvault.mapper.AliasAwareConverter; +import com.github.nagyesta.lowkeyvault.context.ApiVersionAware; +import com.github.nagyesta.lowkeyvault.mapper.common.AliasAwareConverter; import com.github.nagyesta.lowkeyvault.mapper.common.BackupConverter; -import com.github.nagyesta.lowkeyvault.model.v7_2.key.KeyBackupListItem; +import com.github.nagyesta.lowkeyvault.mapper.common.registry.KeyConverterRegistry; +import com.github.nagyesta.lowkeyvault.model.common.backup.KeyBackupListItem; import com.github.nagyesta.lowkeyvault.model.v7_2.key.KeyPropertiesModel; import com.github.nagyesta.lowkeyvault.model.v7_2.key.request.JsonWebKeyImportRequest; import com.github.nagyesta.lowkeyvault.service.key.ReadOnlyAesKeyVaultKeyEntity; import com.github.nagyesta.lowkeyvault.service.key.ReadOnlyEcKeyVaultKeyEntity; import com.github.nagyesta.lowkeyvault.service.key.ReadOnlyKeyVaultKeyEntity; import com.github.nagyesta.lowkeyvault.service.key.ReadOnlyRsaKeyVaultKeyEntity; +import com.github.nagyesta.lowkeyvault.service.key.id.KeyEntityId; import com.github.nagyesta.lowkeyvault.service.key.id.VersionedKeyEntityId; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.lang.NonNull; -import org.springframework.stereotype.Component; import org.springframework.util.Assert; -@Component +import java.util.SortedSet; + public class KeyEntityToV72BackupConverter - extends BackupConverter { + extends BackupConverter { + + private final KeyConverterRegistry registry; @Autowired - public KeyEntityToV72BackupConverter( - @NonNull final AliasAwareConverter propertiesConverter) { - super(propertiesConverter); + public KeyEntityToV72BackupConverter(@lombok.NonNull final KeyConverterRegistry registry) { + this.registry = registry; + } + + @Override + public void afterPropertiesSet() { + registry.registerBackupConverter(this); } @Override @@ -33,6 +42,11 @@ protected KeyBackupListItem convertUniqueFields(@NonNull final ReadOnlyKeyVaultK return listItem; } + @Override + protected AliasAwareConverter propertiesConverter() { + return registry.propertiesConverter(supportedVersions().last()); + } + private JsonWebKeyImportRequest convertKeyMaterial(final ReadOnlyKeyVaultKeyEntity source) { final JsonWebKeyImportRequest keyMaterial = new JsonWebKeyImportRequest(); if (source.getKeyType().isRsa()) { @@ -76,4 +90,9 @@ private JsonWebKeyImportRequest populateCommonKeyFields( keyMaterial.setKeyHsm(null); return keyMaterial; } + + @Override + public SortedSet supportedVersions() { + return ApiVersionAware.V7_2_AND_V7_3; + } } diff --git a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/v7_2/key/KeyEntityToV72KeyItemModelConverter.java b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/v7_2/key/KeyEntityToV72KeyItemModelConverter.java index cfabe179..9d9ae1c8 100644 --- a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/v7_2/key/KeyEntityToV72KeyItemModelConverter.java +++ b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/v7_2/key/KeyEntityToV72KeyItemModelConverter.java @@ -1,35 +1,45 @@ package com.github.nagyesta.lowkeyvault.mapper.v7_2.key; +import com.github.nagyesta.lowkeyvault.context.ApiVersionAware; import com.github.nagyesta.lowkeyvault.mapper.common.BaseRecoveryAwareConverter; +import com.github.nagyesta.lowkeyvault.mapper.common.registry.KeyConverterRegistry; import com.github.nagyesta.lowkeyvault.model.v7_2.key.DeletedKeyVaultKeyItemModel; import com.github.nagyesta.lowkeyvault.model.v7_2.key.KeyVaultKeyItemModel; import com.github.nagyesta.lowkeyvault.service.key.ReadOnlyKeyVaultKeyEntity; import com.github.nagyesta.lowkeyvault.service.key.id.VersionedKeyEntityId; import lombok.NonNull; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; import java.net.URI; +import java.util.SortedSet; -@Component public class KeyEntityToV72KeyItemModelConverter extends BaseRecoveryAwareConverter { - private final KeyEntityToV72PropertiesModelConverter keyEntityToV72PropertiesModelConverter; + private final KeyConverterRegistry registry; @Autowired public KeyEntityToV72KeyItemModelConverter( - @NonNull final KeyEntityToV72PropertiesModelConverter keyEntityToV72PropertiesModelConverter) { + @NonNull final KeyConverterRegistry registry) { super(KeyVaultKeyItemModel::new, DeletedKeyVaultKeyItemModel::new); - this.keyEntityToV72PropertiesModelConverter = keyEntityToV72PropertiesModelConverter; + this.registry = registry; + } + + @Override + public void afterPropertiesSet() { + register(registry); + } + + protected void register(final KeyConverterRegistry registry) { + registry.registerItemConverter(this); } @Override protected M mapActiveFields( final ReadOnlyKeyVaultKeyEntity source, final M model, final URI vaultUri) { model.setKeyId(convertKeyId(source, vaultUri)); - model.setAttributes(keyEntityToV72PropertiesModelConverter.convert(source, vaultUri)); + model.setAttributes(registry.propertiesConverter(supportedVersions().last()).convert(source, vaultUri)); model.setTags(source.getTags()); return model; } @@ -37,4 +47,9 @@ protected M mapActiveFields( protected String convertKeyId(final ReadOnlyKeyVaultKeyEntity source, final URI vaultUri) { return source.getId().asUriNoVersion(vaultUri).toString(); } + + @Override + public SortedSet supportedVersions() { + return ApiVersionAware.V7_2_AND_V7_3; + } } diff --git a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/v7_2/key/KeyEntityToV72KeyVersionItemModelConverter.java b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/v7_2/key/KeyEntityToV72KeyVersionItemModelConverter.java index c86f6eab..69494e87 100644 --- a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/v7_2/key/KeyEntityToV72KeyVersionItemModelConverter.java +++ b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/v7_2/key/KeyEntityToV72KeyVersionItemModelConverter.java @@ -1,20 +1,22 @@ package com.github.nagyesta.lowkeyvault.mapper.v7_2.key; +import com.github.nagyesta.lowkeyvault.mapper.common.registry.KeyConverterRegistry; import com.github.nagyesta.lowkeyvault.service.key.ReadOnlyKeyVaultKeyEntity; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.lang.NonNull; -import org.springframework.stereotype.Component; import java.net.URI; -@Component -public class KeyEntityToV72KeyVersionItemModelConverter - extends KeyEntityToV72KeyItemModelConverter { +public class KeyEntityToV72KeyVersionItemModelConverter extends KeyEntityToV72KeyItemModelConverter { @Autowired - public KeyEntityToV72KeyVersionItemModelConverter( - @NonNull final KeyEntityToV72PropertiesModelConverter keyEntityToV72PropertiesModelConverter) { - super(keyEntityToV72PropertiesModelConverter); + public KeyEntityToV72KeyVersionItemModelConverter(@NonNull final KeyConverterRegistry registry) { + super(registry); + } + + @Override + protected void register(final KeyConverterRegistry registry) { + registry.registerVersionedItemConverter(this); } @Override diff --git a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/v7_2/key/KeyEntityToV72ModelConverter.java b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/v7_2/key/KeyEntityToV72ModelConverter.java index 46b6e755..6f22283d 100644 --- a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/v7_2/key/KeyEntityToV72ModelConverter.java +++ b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/v7_2/key/KeyEntityToV72ModelConverter.java @@ -1,6 +1,8 @@ package com.github.nagyesta.lowkeyvault.mapper.v7_2.key; +import com.github.nagyesta.lowkeyvault.context.ApiVersionAware; import com.github.nagyesta.lowkeyvault.mapper.common.BaseRecoveryAwareConverter; +import com.github.nagyesta.lowkeyvault.mapper.common.registry.KeyConverterRegistry; import com.github.nagyesta.lowkeyvault.model.v7_2.key.DeletedKeyVaultKeyModel; import com.github.nagyesta.lowkeyvault.model.v7_2.key.JsonWebKeyModel; import com.github.nagyesta.lowkeyvault.model.v7_2.key.KeyVaultKeyModel; @@ -11,27 +13,31 @@ import com.github.nagyesta.lowkeyvault.service.key.id.VersionedKeyEntityId; import lombok.NonNull; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; import org.springframework.util.Assert; import java.net.URI; +import java.util.SortedSet; -@Component public class KeyEntityToV72ModelConverter extends BaseRecoveryAwareConverter { - private final KeyEntityToV72PropertiesModelConverter keyEntityToV72PropertiesModelConverter; + private final KeyConverterRegistry registry; @Autowired - public KeyEntityToV72ModelConverter(@NonNull final KeyEntityToV72PropertiesModelConverter keyEntityToV72PropertiesModelConverter) { + public KeyEntityToV72ModelConverter(@NonNull final KeyConverterRegistry registry) { super(KeyVaultKeyModel::new, DeletedKeyVaultKeyModel::new); - this.keyEntityToV72PropertiesModelConverter = keyEntityToV72PropertiesModelConverter; + this.registry = registry; + } + + @Override + public void afterPropertiesSet() { + registry.registerModelConverter(this); } @Override protected M mapActiveFields(final ReadOnlyKeyVaultKeyEntity source, final M model, final URI vaultUri) { model.setKey(mapJsonWebKey(source, vaultUri)); - model.setAttributes(keyEntityToV72PropertiesModelConverter.convert(source, vaultUri)); + model.setAttributes(registry.propertiesConverter(supportedVersions().last()).convert(source, vaultUri)); model.setTags(source.getTags()); model.setManaged(source.isManaged()); return model; @@ -77,4 +83,9 @@ private JsonWebKeyModel mapCommonKeyProperties(final ReadOnlyKeyVaultKeyEntity e jsonWebKeyModel.setKeyOps(entity.getOperations()); return jsonWebKeyModel; } + + @Override + public SortedSet supportedVersions() { + return ApiVersionAware.V7_2_AND_V7_3; + } } diff --git a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/v7_2/key/KeyEntityToV72PropertiesModelConverter.java b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/v7_2/key/KeyEntityToV72PropertiesModelConverter.java index f21d2ae7..7ad8a6aa 100644 --- a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/v7_2/key/KeyEntityToV72PropertiesModelConverter.java +++ b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/v7_2/key/KeyEntityToV72PropertiesModelConverter.java @@ -1,17 +1,33 @@ package com.github.nagyesta.lowkeyvault.mapper.v7_2.key; -import com.github.nagyesta.lowkeyvault.mapper.AliasAwareConverter; -import com.github.nagyesta.lowkeyvault.mapper.common.BaseEntityToV72PropertiesModelConverter; +import com.github.nagyesta.lowkeyvault.context.ApiVersionAware; +import com.github.nagyesta.lowkeyvault.mapper.common.AliasAwareConverter; +import com.github.nagyesta.lowkeyvault.mapper.common.BasePropertiesModelConverter; +import com.github.nagyesta.lowkeyvault.mapper.common.registry.KeyConverterRegistry; import com.github.nagyesta.lowkeyvault.model.v7_2.key.KeyPropertiesModel; import com.github.nagyesta.lowkeyvault.service.key.ReadOnlyKeyVaultKeyEntity; +import com.github.nagyesta.lowkeyvault.service.key.id.VersionedKeyEntityId; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.lang.NonNull; -import org.springframework.stereotype.Component; import java.net.URI; +import java.util.SortedSet; -@Component public class KeyEntityToV72PropertiesModelConverter - extends BaseEntityToV72PropertiesModelConverter implements AliasAwareConverter { + extends BasePropertiesModelConverter + implements AliasAwareConverter { + + private final KeyConverterRegistry registry; + + @Autowired + public KeyEntityToV72PropertiesModelConverter(@lombok.NonNull final KeyConverterRegistry registry) { + this.registry = registry; + } + + @Override + public void afterPropertiesSet() { + registry.registerPropertiesConverter(this); + } @Override @NonNull @@ -21,4 +37,8 @@ public KeyPropertiesModel convert( return mapCommonFields(source, new KeyPropertiesModel()); } + @Override + public SortedSet supportedVersions() { + return ApiVersionAware.V7_2_AND_V7_3; + } } diff --git a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/v7_2/secret/SecretEntityToV72BackupConverter.java b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/v7_2/secret/SecretEntityToV72BackupConverter.java new file mode 100644 index 00000000..1c27a9b2 --- /dev/null +++ b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/v7_2/secret/SecretEntityToV72BackupConverter.java @@ -0,0 +1,49 @@ +package com.github.nagyesta.lowkeyvault.mapper.v7_2.secret; + +import com.github.nagyesta.lowkeyvault.context.ApiVersionAware; +import com.github.nagyesta.lowkeyvault.mapper.common.AliasAwareConverter; +import com.github.nagyesta.lowkeyvault.mapper.common.BackupConverter; +import com.github.nagyesta.lowkeyvault.mapper.common.registry.SecretConverterRegistry; +import com.github.nagyesta.lowkeyvault.model.common.backup.SecretBackupListItem; +import com.github.nagyesta.lowkeyvault.model.v7_2.secret.SecretPropertiesModel; +import com.github.nagyesta.lowkeyvault.service.secret.ReadOnlyKeyVaultSecretEntity; +import com.github.nagyesta.lowkeyvault.service.secret.id.SecretEntityId; +import com.github.nagyesta.lowkeyvault.service.secret.id.VersionedSecretEntityId; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.lang.NonNull; + +import java.util.SortedSet; + +public class SecretEntityToV72BackupConverter extends BackupConverter< + SecretEntityId, VersionedSecretEntityId, ReadOnlyKeyVaultSecretEntity, SecretPropertiesModel, SecretBackupListItem> { + + private final SecretConverterRegistry registry; + + @Autowired + public SecretEntityToV72BackupConverter(@lombok.NonNull final SecretConverterRegistry registry) { + this.registry = registry; + } + + @Override + public void afterPropertiesSet() { + registry.registerBackupConverter(this); + } + + @Override + protected SecretBackupListItem convertUniqueFields(@NonNull final ReadOnlyKeyVaultSecretEntity source) { + final SecretBackupListItem listItem = new SecretBackupListItem(); + listItem.setValue(source.getValue()); + listItem.setContentType(source.getContentType()); + return listItem; + } + + @Override + protected AliasAwareConverter propertiesConverter() { + return registry.propertiesConverter(supportedVersions().last()); + } + + @Override + public SortedSet supportedVersions() { + return ApiVersionAware.V7_2_AND_V7_3; + } +} diff --git a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/v7_2/secret/SecretEntityToV72ModelConverter.java b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/v7_2/secret/SecretEntityToV72ModelConverter.java index 06d90470..b359a2c7 100644 --- a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/v7_2/secret/SecretEntityToV72ModelConverter.java +++ b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/v7_2/secret/SecretEntityToV72ModelConverter.java @@ -1,6 +1,8 @@ package com.github.nagyesta.lowkeyvault.mapper.v7_2.secret; +import com.github.nagyesta.lowkeyvault.context.ApiVersionAware; import com.github.nagyesta.lowkeyvault.mapper.common.BaseRecoveryAwareConverter; +import com.github.nagyesta.lowkeyvault.mapper.common.registry.SecretConverterRegistry; import com.github.nagyesta.lowkeyvault.model.v7_2.secret.DeletedKeyVaultSecretModel; import com.github.nagyesta.lowkeyvault.model.v7_2.secret.KeyVaultSecretModel; import com.github.nagyesta.lowkeyvault.service.key.id.VersionedKeyEntityId; @@ -8,22 +10,24 @@ import com.github.nagyesta.lowkeyvault.service.secret.id.VersionedSecretEntityId; import lombok.NonNull; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; import java.net.URI; +import java.util.SortedSet; -@Component public class SecretEntityToV72ModelConverter extends BaseRecoveryAwareConverter { - - private final SecretEntityToV72PropertiesModelConverter secretEntityToV72PropertiesModelConverter; + private final SecretConverterRegistry registry; @Autowired - public SecretEntityToV72ModelConverter( - @NonNull final SecretEntityToV72PropertiesModelConverter secretEntityToV72PropertiesModelConverter) { + public SecretEntityToV72ModelConverter(@NonNull final SecretConverterRegistry registry) { super(KeyVaultSecretModel::new, DeletedKeyVaultSecretModel::new); - this.secretEntityToV72PropertiesModelConverter = secretEntityToV72PropertiesModelConverter; + this.registry = registry; + } + + @Override + public void afterPropertiesSet() { + registry.registerModelConverter(this); } @Override @@ -32,7 +36,7 @@ protected M mapActiveFields( model.setId(source.getId().asUri(vaultUri).toString()); model.setContentType(source.getContentType()); model.setValue(source.getValue()); - model.setAttributes(secretEntityToV72PropertiesModelConverter.convert(source, vaultUri)); + model.setAttributes(registry.propertiesConverter(supportedVersions().last()).convert(source, vaultUri)); model.setTags(source.getTags()); model.setManaged(source.isManaged()); if (source.isManaged()) { @@ -41,4 +45,9 @@ protected M mapActiveFields( } return model; } + + @Override + public SortedSet supportedVersions() { + return ApiVersionAware.V7_2_AND_V7_3; + } } diff --git a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/v7_2/secret/SecretEntityToV72PropertiesModelConverter.java b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/v7_2/secret/SecretEntityToV72PropertiesModelConverter.java index b1f177c1..7839e5b1 100644 --- a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/v7_2/secret/SecretEntityToV72PropertiesModelConverter.java +++ b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/v7_2/secret/SecretEntityToV72PropertiesModelConverter.java @@ -1,23 +1,42 @@ package com.github.nagyesta.lowkeyvault.mapper.v7_2.secret; -import com.github.nagyesta.lowkeyvault.mapper.AliasAwareConverter; -import com.github.nagyesta.lowkeyvault.mapper.common.BaseEntityToV72PropertiesModelConverter; +import com.github.nagyesta.lowkeyvault.context.ApiVersionAware; +import com.github.nagyesta.lowkeyvault.mapper.common.AliasAwareConverter; +import com.github.nagyesta.lowkeyvault.mapper.common.BasePropertiesModelConverter; +import com.github.nagyesta.lowkeyvault.mapper.common.registry.SecretConverterRegistry; import com.github.nagyesta.lowkeyvault.model.v7_2.secret.SecretPropertiesModel; import com.github.nagyesta.lowkeyvault.service.secret.ReadOnlyKeyVaultSecretEntity; +import com.github.nagyesta.lowkeyvault.service.secret.id.VersionedSecretEntityId; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.lang.NonNull; -import org.springframework.stereotype.Component; import java.net.URI; +import java.util.SortedSet; -@Component public class SecretEntityToV72PropertiesModelConverter - extends BaseEntityToV72PropertiesModelConverter + extends BasePropertiesModelConverter implements AliasAwareConverter { + private final SecretConverterRegistry registry; + + @Autowired + public SecretEntityToV72PropertiesModelConverter(@lombok.NonNull final SecretConverterRegistry registry) { + this.registry = registry; + } + + @Override + public void afterPropertiesSet() { + registry.registerPropertiesConverter(this); + } + @Override @NonNull public SecretPropertiesModel convert(@NonNull final ReadOnlyKeyVaultSecretEntity source, @NonNull final URI vaultUri) { return mapCommonFields(source, new SecretPropertiesModel()); } + @Override + public SortedSet supportedVersions() { + return ApiVersionAware.V7_2_AND_V7_3; + } } diff --git a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/v7_2/secret/SecretEntityToV72SecretItemModelConverter.java b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/v7_2/secret/SecretEntityToV72SecretItemModelConverter.java index faca3083..7d245bf7 100644 --- a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/v7_2/secret/SecretEntityToV72SecretItemModelConverter.java +++ b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/v7_2/secret/SecretEntityToV72SecretItemModelConverter.java @@ -1,35 +1,44 @@ package com.github.nagyesta.lowkeyvault.mapper.v7_2.secret; +import com.github.nagyesta.lowkeyvault.context.ApiVersionAware; import com.github.nagyesta.lowkeyvault.mapper.common.BaseRecoveryAwareConverter; +import com.github.nagyesta.lowkeyvault.mapper.common.registry.SecretConverterRegistry; import com.github.nagyesta.lowkeyvault.model.v7_2.secret.DeletedKeyVaultSecretItemModel; import com.github.nagyesta.lowkeyvault.model.v7_2.secret.KeyVaultSecretItemModel; import com.github.nagyesta.lowkeyvault.service.secret.ReadOnlyKeyVaultSecretEntity; import com.github.nagyesta.lowkeyvault.service.secret.id.VersionedSecretEntityId; import lombok.NonNull; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; import java.net.URI; +import java.util.SortedSet; -@Component public class SecretEntityToV72SecretItemModelConverter extends BaseRecoveryAwareConverter { - private final SecretEntityToV72PropertiesModelConverter secretEntityToV72PropertiesModelConverter; + private final SecretConverterRegistry registry; @Autowired - public SecretEntityToV72SecretItemModelConverter( - @NonNull final SecretEntityToV72PropertiesModelConverter secretEntityToV72PropertiesModelConverter) { + public SecretEntityToV72SecretItemModelConverter(@NonNull final SecretConverterRegistry registry) { super(KeyVaultSecretItemModel::new, DeletedKeyVaultSecretItemModel::new); - this.secretEntityToV72PropertiesModelConverter = secretEntityToV72PropertiesModelConverter; + this.registry = registry; + } + + @Override + public void afterPropertiesSet() { + register(registry); + } + + protected void register(final SecretConverterRegistry registry) { + registry.registerItemConverter(this); } @Override protected M mapActiveFields( final ReadOnlyKeyVaultSecretEntity source, final M model, final URI vaultUri) { model.setId(convertSecretId(source, vaultUri)); - model.setAttributes(secretEntityToV72PropertiesModelConverter.convert(source, vaultUri)); + model.setAttributes(registry.propertiesConverter(supportedVersions().last()).convert(source, vaultUri)); model.setTags(source.getTags()); return model; } @@ -37,4 +46,9 @@ protected M mapActiveFields( protected String convertSecretId(final ReadOnlyKeyVaultSecretEntity source, final URI vaultUri) { return source.getId().asUriNoVersion(vaultUri).toString(); } + + @Override + public SortedSet supportedVersions() { + return ApiVersionAware.V7_2_AND_V7_3; + } } diff --git a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/v7_2/secret/SecretEntityToV72SecretVersionItemModelConverter.java b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/v7_2/secret/SecretEntityToV72SecretVersionItemModelConverter.java index e789e9c1..0305a138 100644 --- a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/v7_2/secret/SecretEntityToV72SecretVersionItemModelConverter.java +++ b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/v7_2/secret/SecretEntityToV72SecretVersionItemModelConverter.java @@ -1,20 +1,22 @@ package com.github.nagyesta.lowkeyvault.mapper.v7_2.secret; +import com.github.nagyesta.lowkeyvault.mapper.common.registry.SecretConverterRegistry; import com.github.nagyesta.lowkeyvault.service.secret.ReadOnlyKeyVaultSecretEntity; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.lang.NonNull; -import org.springframework.stereotype.Component; import java.net.URI; -@Component public class SecretEntityToV72SecretVersionItemModelConverter extends SecretEntityToV72SecretItemModelConverter { @Autowired - public SecretEntityToV72SecretVersionItemModelConverter( - @NonNull final SecretEntityToV72PropertiesModelConverter secretEntityToV72PropertiesModelConverter) { - super(secretEntityToV72PropertiesModelConverter); + public SecretEntityToV72SecretVersionItemModelConverter(@NonNull final SecretConverterRegistry registry) { + super(registry); + } + + protected void register(final SecretConverterRegistry registry) { + registry.registerVersionedItemConverter(this); } @Override diff --git a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/v7_3/certificate/BaseCertificateEntityToV73PolicyModelConverter.java b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/v7_3/certificate/BaseCertificateEntityToV73PolicyModelConverter.java index 42519106..76775c8a 100644 --- a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/v7_3/certificate/BaseCertificateEntityToV73PolicyModelConverter.java +++ b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/v7_3/certificate/BaseCertificateEntityToV73PolicyModelConverter.java @@ -1,16 +1,18 @@ package com.github.nagyesta.lowkeyvault.mapper.v7_3.certificate; -import com.github.nagyesta.lowkeyvault.mapper.AliasAwareConverter; +import com.github.nagyesta.lowkeyvault.context.ApiVersionAware; +import com.github.nagyesta.lowkeyvault.mapper.common.AliasAwareConverter; import com.github.nagyesta.lowkeyvault.model.v7_3.certificate.*; import com.github.nagyesta.lowkeyvault.service.certificate.ReadOnlyKeyVaultCertificateEntity; import com.github.nagyesta.lowkeyvault.service.certificate.impl.ReadOnlyCertificatePolicy; import lombok.NonNull; import java.net.URI; +import java.util.SortedSet; import java.util.function.Function; import java.util.function.Supplier; -public class BaseCertificateEntityToV73PolicyModelConverter +public abstract class BaseCertificateEntityToV73PolicyModelConverter implements AliasAwareConverter { private final Supplier modelSupplier; @@ -95,5 +97,8 @@ private CertificateKeyModel convertKeyProperties(final ReadOnlyKeyVaultCertifica return model; } - + @Override + public SortedSet supportedVersions() { + return ApiVersionAware.V7_3; + } } diff --git a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/v7_3/certificate/CertificateEntityToV73CertificateItemModelConverter.java b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/v7_3/certificate/CertificateEntityToV73CertificateItemModelConverter.java index 96809cf2..64a7889e 100644 --- a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/v7_3/certificate/CertificateEntityToV73CertificateItemModelConverter.java +++ b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/v7_3/certificate/CertificateEntityToV73CertificateItemModelConverter.java @@ -1,28 +1,38 @@ package com.github.nagyesta.lowkeyvault.mapper.v7_3.certificate; +import com.github.nagyesta.lowkeyvault.context.ApiVersionAware; import com.github.nagyesta.lowkeyvault.mapper.common.BaseRecoveryAwareConverter; +import com.github.nagyesta.lowkeyvault.mapper.common.registry.CertificateConverterRegistry; import com.github.nagyesta.lowkeyvault.model.v7_3.certificate.DeletedKeyVaultCertificateItemModel; import com.github.nagyesta.lowkeyvault.model.v7_3.certificate.KeyVaultCertificateItemModel; import com.github.nagyesta.lowkeyvault.service.certificate.ReadOnlyKeyVaultCertificateEntity; import com.github.nagyesta.lowkeyvault.service.certificate.id.VersionedCertificateEntityId; import lombok.NonNull; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; import java.net.URI; +import java.util.SortedSet; -@Component public class CertificateEntityToV73CertificateItemModelConverter extends BaseRecoveryAwareConverter { - private final CertificateEntityToV73PropertiesModelConverter certificateEntityToV73PropertiesModelConverter; + private final CertificateConverterRegistry registry; @Autowired public CertificateEntityToV73CertificateItemModelConverter( - @NonNull final CertificateEntityToV73PropertiesModelConverter certificateEntityToV73PropertiesModelConverter) { + @NonNull final CertificateConverterRegistry registry) { super(KeyVaultCertificateItemModel::new, DeletedKeyVaultCertificateItemModel::new); - this.certificateEntityToV73PropertiesModelConverter = certificateEntityToV73PropertiesModelConverter; + this.registry = registry; + } + + @Override + public void afterPropertiesSet() { + register(registry); + } + + protected void register(final CertificateConverterRegistry registry) { + this.registry.registerItemConverter(this); } @Override @@ -30,7 +40,7 @@ protected M mapActiveFields( final ReadOnlyKeyVaultCertificateEntity source, final M model, final URI vaultUri) { model.setCertificateId(convertCertificateId(source, vaultUri)); model.setThumbprint(source.getThumbprint()); - model.setAttributes(certificateEntityToV73PropertiesModelConverter.convert(source, vaultUri)); + model.setAttributes(registry.propertiesConverter(supportedVersions().last()).convert(source, vaultUri)); model.setTags(source.getTags()); return model; } @@ -38,4 +48,9 @@ protected M mapActiveFields( protected String convertCertificateId(final ReadOnlyKeyVaultCertificateEntity source, final URI vaultUri) { return source.getId().asUriNoVersion(vaultUri).toString(); } + + @Override + public SortedSet supportedVersions() { + return ApiVersionAware.V7_3; + } } diff --git a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/v7_3/certificate/CertificateEntityToV73CertificateVersionItemModelConverter.java b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/v7_3/certificate/CertificateEntityToV73CertificateVersionItemModelConverter.java index f1520b55..5c9316bc 100644 --- a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/v7_3/certificate/CertificateEntityToV73CertificateVersionItemModelConverter.java +++ b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/v7_3/certificate/CertificateEntityToV73CertificateVersionItemModelConverter.java @@ -1,23 +1,27 @@ package com.github.nagyesta.lowkeyvault.mapper.v7_3.certificate; +import com.github.nagyesta.lowkeyvault.mapper.common.registry.CertificateConverterRegistry; import com.github.nagyesta.lowkeyvault.service.certificate.ReadOnlyKeyVaultCertificateEntity; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.lang.NonNull; -import org.springframework.stereotype.Component; import java.net.URI; -@Component public class CertificateEntityToV73CertificateVersionItemModelConverter extends CertificateEntityToV73CertificateItemModelConverter { + @Autowired - public CertificateEntityToV73CertificateVersionItemModelConverter( - @NonNull final CertificateEntityToV73PropertiesModelConverter certificateEntityToV73PropertiesModelConverter) { - super(certificateEntityToV73PropertiesModelConverter); + public CertificateEntityToV73CertificateVersionItemModelConverter(@NonNull final CertificateConverterRegistry registry) { + super(registry); } @Override protected String convertCertificateId(final ReadOnlyKeyVaultCertificateEntity source, final URI vaultUri) { return source.getId().asUri(vaultUri).toString(); } + + @Override + protected void register(final CertificateConverterRegistry registry) { + registry.registerVersionedItemConverter(this); + } } diff --git a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/v7_3/certificate/CertificateEntityToV73IssuancePolicyModelConverter.java b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/v7_3/certificate/CertificateEntityToV73IssuancePolicyModelConverter.java index d01a3d62..479088a2 100644 --- a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/v7_3/certificate/CertificateEntityToV73IssuancePolicyModelConverter.java +++ b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/v7_3/certificate/CertificateEntityToV73IssuancePolicyModelConverter.java @@ -1,12 +1,20 @@ package com.github.nagyesta.lowkeyvault.mapper.v7_3.certificate; +import com.github.nagyesta.lowkeyvault.mapper.common.registry.CertificateConverterRegistry; import com.github.nagyesta.lowkeyvault.service.certificate.ReadOnlyKeyVaultCertificateEntity; -import org.springframework.stereotype.Component; +import lombok.NonNull; -@Component("certificateEntityToV73IssuancePolicyModelConverter") public class CertificateEntityToV73IssuancePolicyModelConverter extends BaseCertificateEntityToV73PolicyModelConverter { - public CertificateEntityToV73IssuancePolicyModelConverter() { + + private final CertificateConverterRegistry registry; + + public CertificateEntityToV73IssuancePolicyModelConverter(@NonNull final CertificateConverterRegistry registry) { super(ReadOnlyKeyVaultCertificateEntity::getIssuancePolicy); + this.registry = registry; } + @Override + public void afterPropertiesSet() { + registry.registerIssuancePolicyConverter(this); + } } diff --git a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/v7_3/certificate/CertificateEntityToV73ModelConverter.java b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/v7_3/certificate/CertificateEntityToV73ModelConverter.java index ed391897..9a3d4fa3 100644 --- a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/v7_3/certificate/CertificateEntityToV73ModelConverter.java +++ b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/v7_3/certificate/CertificateEntityToV73ModelConverter.java @@ -1,30 +1,33 @@ package com.github.nagyesta.lowkeyvault.mapper.v7_3.certificate; +import com.github.nagyesta.lowkeyvault.context.ApiVersionAware; import com.github.nagyesta.lowkeyvault.mapper.common.BaseRecoveryAwareConverter; +import com.github.nagyesta.lowkeyvault.mapper.common.registry.CertificateConverterRegistry; import com.github.nagyesta.lowkeyvault.model.v7_3.certificate.DeletedKeyVaultCertificateModel; import com.github.nagyesta.lowkeyvault.model.v7_3.certificate.KeyVaultCertificateModel; import com.github.nagyesta.lowkeyvault.service.certificate.ReadOnlyKeyVaultCertificateEntity; import com.github.nagyesta.lowkeyvault.service.certificate.id.VersionedCertificateEntityId; import lombok.NonNull; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; import java.net.URI; +import java.util.SortedSet; -@Component("certificateEntityToV73ModelConverter") public class CertificateEntityToV73ModelConverter extends BaseRecoveryAwareConverter { - private final CertificateEntityToV73PropertiesModelConverter certificateEntityToV73PropertiesModelConverter; - private final CertificateEntityToV73PolicyModelConverter certificateEntityToV73PolicyModelConverter; + + private final CertificateConverterRegistry registry; @Autowired - public CertificateEntityToV73ModelConverter( - @NonNull final CertificateEntityToV73PropertiesModelConverter certificateEntityToV73PropertiesModelConverter, - @NonNull final CertificateEntityToV73PolicyModelConverter certificateEntityToV73PolicyModelConverter) { + public CertificateEntityToV73ModelConverter(@NonNull final CertificateConverterRegistry registry) { super(KeyVaultCertificateModel::new, DeletedKeyVaultCertificateModel::new); - this.certificateEntityToV73PropertiesModelConverter = certificateEntityToV73PropertiesModelConverter; - this.certificateEntityToV73PolicyModelConverter = certificateEntityToV73PolicyModelConverter; + this.registry = registry; + } + + @Override + public void afterPropertiesSet() { + registry.registerModelConverter(this); } @Override @@ -33,11 +36,16 @@ protected M mapActiveFields( model.setId(source.getId().asUri(vaultUri).toString()); model.setKid(source.getKid().asUri(vaultUri).toString()); model.setSid(source.getSid().asUri(vaultUri).toString()); - model.setPolicy(certificateEntityToV73PolicyModelConverter.convert(source, vaultUri)); + model.setPolicy(registry.policyConverters(supportedVersions().last()).convert(source, vaultUri)); model.setCertificate(source.getEncodedCertificate()); model.setThumbprint(source.getThumbprint()); - model.setAttributes(certificateEntityToV73PropertiesModelConverter.convert(source, vaultUri)); + model.setAttributes(registry.propertiesConverter(supportedVersions().last()).convert(source, vaultUri)); model.setTags(source.getTags()); return model; } + + @Override + public SortedSet supportedVersions() { + return ApiVersionAware.V7_3; + } } diff --git a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/v7_3/certificate/CertificateEntityToV73PendingCertificateOperationModelConverter.java b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/v7_3/certificate/CertificateEntityToV73PendingCertificateOperationModelConverter.java index cf193533..fe9c748f 100644 --- a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/v7_3/certificate/CertificateEntityToV73PendingCertificateOperationModelConverter.java +++ b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/v7_3/certificate/CertificateEntityToV73PendingCertificateOperationModelConverter.java @@ -1,19 +1,33 @@ package com.github.nagyesta.lowkeyvault.mapper.v7_3.certificate; -import com.github.nagyesta.lowkeyvault.mapper.AliasAwareConverter; +import com.github.nagyesta.lowkeyvault.context.ApiVersionAware; +import com.github.nagyesta.lowkeyvault.mapper.common.AliasAwareConverter; +import com.github.nagyesta.lowkeyvault.mapper.common.registry.CertificateConverterRegistry; import com.github.nagyesta.lowkeyvault.model.v7_3.certificate.IssuerParameterModel; import com.github.nagyesta.lowkeyvault.model.v7_3.certificate.KeyVaultPendingCertificateModel; import com.github.nagyesta.lowkeyvault.service.certificate.ReadOnlyKeyVaultCertificateEntity; import com.github.nagyesta.lowkeyvault.service.certificate.impl.CertAuthorityType; import lombok.NonNull; -import org.springframework.stereotype.Component; +import org.springframework.beans.factory.annotation.Autowired; import java.net.URI; +import java.util.SortedSet; -@Component public class CertificateEntityToV73PendingCertificateOperationModelConverter implements AliasAwareConverter { + private final CertificateConverterRegistry registry; + + @Autowired + public CertificateEntityToV73PendingCertificateOperationModelConverter(@NonNull final CertificateConverterRegistry registry) { + this.registry = registry; + } + + @Override + public void afterPropertiesSet() { + registry.registerPendingOperationConverter(this); + } + public @org.springframework.lang.NonNull KeyVaultPendingCertificateModel convert( final @NonNull ReadOnlyKeyVaultCertificateEntity source, final @NonNull URI baseUri) { final KeyVaultPendingCertificateModel model = new KeyVaultPendingCertificateModel(); @@ -27,4 +41,9 @@ public class CertificateEntityToV73PendingCertificateOperationModelConverter model.setTarget(source.getId().asUriNoVersion(baseUri).toString()); return model; } + + @Override + public SortedSet supportedVersions() { + return ApiVersionAware.V7_3; + } } diff --git a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/v7_3/certificate/CertificateEntityToV73PolicyModelConverter.java b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/v7_3/certificate/CertificateEntityToV73PolicyModelConverter.java index d513d211..3d5f1fa2 100644 --- a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/v7_3/certificate/CertificateEntityToV73PolicyModelConverter.java +++ b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/v7_3/certificate/CertificateEntityToV73PolicyModelConverter.java @@ -1,12 +1,22 @@ package com.github.nagyesta.lowkeyvault.mapper.v7_3.certificate; +import com.github.nagyesta.lowkeyvault.mapper.common.registry.CertificateConverterRegistry; import com.github.nagyesta.lowkeyvault.service.certificate.ReadOnlyKeyVaultCertificateEntity; -import org.springframework.stereotype.Component; +import lombok.NonNull; +import org.springframework.beans.factory.annotation.Autowired; -@Component("certificateEntityToV73PolicyModelConverter") public class CertificateEntityToV73PolicyModelConverter extends BaseCertificateEntityToV73PolicyModelConverter { - public CertificateEntityToV73PolicyModelConverter() { + + private final CertificateConverterRegistry registry; + + @Autowired + public CertificateEntityToV73PolicyModelConverter(@NonNull final CertificateConverterRegistry registry) { super(ReadOnlyKeyVaultCertificateEntity::getOriginalCertificatePolicy); + this.registry = registry; } + @Override + public void afterPropertiesSet() { + registry.registerPolicyConverter(this); + } } diff --git a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/v7_3/certificate/CertificateEntityToV73PropertiesModelConverter.java b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/v7_3/certificate/CertificateEntityToV73PropertiesModelConverter.java index 4ef149c4..14570ed6 100644 --- a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/v7_3/certificate/CertificateEntityToV73PropertiesModelConverter.java +++ b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/v7_3/certificate/CertificateEntityToV73PropertiesModelConverter.java @@ -1,19 +1,32 @@ package com.github.nagyesta.lowkeyvault.mapper.v7_3.certificate; -import com.github.nagyesta.lowkeyvault.mapper.AliasAwareConverter; -import com.github.nagyesta.lowkeyvault.mapper.common.BaseEntityToV72PropertiesModelConverter; +import com.github.nagyesta.lowkeyvault.context.ApiVersionAware; +import com.github.nagyesta.lowkeyvault.mapper.common.AliasAwareConverter; +import com.github.nagyesta.lowkeyvault.mapper.common.BasePropertiesModelConverter; +import com.github.nagyesta.lowkeyvault.mapper.common.registry.CertificateConverterRegistry; import com.github.nagyesta.lowkeyvault.model.v7_3.certificate.CertificatePropertiesModel; import com.github.nagyesta.lowkeyvault.service.certificate.ReadOnlyKeyVaultCertificateEntity; +import com.github.nagyesta.lowkeyvault.service.certificate.id.VersionedCertificateEntityId; import org.springframework.lang.NonNull; -import org.springframework.stereotype.Component; import java.net.URI; +import java.util.SortedSet; -@Component("certificateEntityToV73PropertiesModelConverter") public class CertificateEntityToV73PropertiesModelConverter - extends BaseEntityToV72PropertiesModelConverter + extends BasePropertiesModelConverter implements AliasAwareConverter { + private final CertificateConverterRegistry registry; + + public CertificateEntityToV73PropertiesModelConverter(@lombok.NonNull final CertificateConverterRegistry registry) { + this.registry = registry; + } + + @Override + public void afterPropertiesSet() { + registry.registerPropertiesConverter(this); + } + @Override @NonNull public CertificatePropertiesModel convert( @@ -21,4 +34,9 @@ public CertificatePropertiesModel convert( @org.springframework.lang.NonNull final URI vaultUri) { return mapCommonFields(source, new CertificatePropertiesModel()); } + + @Override + public SortedSet supportedVersions() { + return ApiVersionAware.V7_3; + } } diff --git a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/v7_3/certificate/LifetimeActionsPolicyToV73ModelConverter.java b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/v7_3/certificate/CertificateLifetimeActionsPolicyToV73ModelConverter.java similarity index 59% rename from lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/v7_3/certificate/LifetimeActionsPolicyToV73ModelConverter.java rename to lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/v7_3/certificate/CertificateLifetimeActionsPolicyToV73ModelConverter.java index 24260da6..1b13d833 100644 --- a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/v7_3/certificate/LifetimeActionsPolicyToV73ModelConverter.java +++ b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/v7_3/certificate/CertificateLifetimeActionsPolicyToV73ModelConverter.java @@ -1,33 +1,34 @@ package com.github.nagyesta.lowkeyvault.mapper.v7_3.certificate; +import com.github.nagyesta.lowkeyvault.context.ApiVersionAware; +import com.github.nagyesta.lowkeyvault.mapper.common.ApiVersionAwareConverter; +import com.github.nagyesta.lowkeyvault.mapper.common.registry.CertificateConverterRegistry; import com.github.nagyesta.lowkeyvault.model.v7_3.certificate.CertificateLifetimeActionModel; import com.github.nagyesta.lowkeyvault.model.v7_3.certificate.CertificateLifetimeActionTriggerModel; import com.github.nagyesta.lowkeyvault.service.certificate.CertificateLifetimeActionActivity; import com.github.nagyesta.lowkeyvault.service.certificate.CertificateLifetimeActionTrigger; -import com.github.nagyesta.lowkeyvault.service.certificate.CertificateVaultFake; import com.github.nagyesta.lowkeyvault.service.certificate.LifetimeActionPolicy; -import com.github.nagyesta.lowkeyvault.service.certificate.id.VersionedCertificateEntityId; -import org.springframework.core.convert.converter.Converter; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.lang.NonNull; -import org.springframework.stereotype.Component; import java.util.List; import java.util.Map; -import java.util.Optional; -import java.util.function.Consumer; +import java.util.SortedSet; import java.util.stream.Collectors; -@Component -public class LifetimeActionsPolicyToV73ModelConverter implements Converter> { +public class CertificateLifetimeActionsPolicyToV73ModelConverter + implements ApiVersionAwareConverter> { - public void populateLifetimeActions( - @NonNull final CertificateVaultFake vault, - @NonNull final VersionedCertificateEntityId entityId, - @NonNull final Consumer> consumer) { - Optional.ofNullable(vault.lifetimeActionPolicy(entityId)) - .map(this::convert) - .ifPresent(consumer); + private final CertificateConverterRegistry registry; + @Autowired + public CertificateLifetimeActionsPolicyToV73ModelConverter(@NonNull final CertificateConverterRegistry registry) { + this.registry = registry; + } + + @Override + public void afterPropertiesSet() { + registry.registerLifetimeActionConverter(this); } @Override @@ -44,4 +45,9 @@ private CertificateLifetimeActionModel convertLifetimeAction( actionModel.setTrigger(new CertificateLifetimeActionTriggerModel(e.getValue())); return actionModel; } + + @Override + public SortedSet supportedVersions() { + return ApiVersionAware.V7_3; + } } diff --git a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/v7_3/key/KeyRotationPolicyToV73ModelConverter.java b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/v7_3/key/KeyRotationPolicyToV73ModelConverter.java index 6fbacd1c..cbcbdefe 100644 --- a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/v7_3/key/KeyRotationPolicyToV73ModelConverter.java +++ b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/v7_3/key/KeyRotationPolicyToV73ModelConverter.java @@ -1,23 +1,37 @@ package com.github.nagyesta.lowkeyvault.mapper.v7_3.key; -import com.github.nagyesta.lowkeyvault.mapper.AliasAwareConverter; +import com.github.nagyesta.lowkeyvault.context.ApiVersionAware; +import com.github.nagyesta.lowkeyvault.mapper.common.AliasAwareConverter; +import com.github.nagyesta.lowkeyvault.mapper.common.registry.KeyConverterRegistry; import com.github.nagyesta.lowkeyvault.model.v7_3.key.*; import com.github.nagyesta.lowkeyvault.model.v7_3.key.constants.LifetimeActionType; import com.github.nagyesta.lowkeyvault.service.key.LifetimeAction; import com.github.nagyesta.lowkeyvault.service.key.ReadOnlyRotationPolicy; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.lang.NonNull; import org.springframework.lang.Nullable; -import org.springframework.stereotype.Component; import java.net.URI; import java.util.List; import java.util.Map; import java.util.Optional; +import java.util.SortedSet; import java.util.stream.Collectors; -@Component public class KeyRotationPolicyToV73ModelConverter implements AliasAwareConverter { + private final KeyConverterRegistry registry; + + @Autowired + public KeyRotationPolicyToV73ModelConverter(@lombok.NonNull final KeyConverterRegistry registry) { + this.registry = registry; + } + + @Override + public void afterPropertiesSet() { + registry.registerRotationPolicyModelConverter(this); + } + @Override public KeyRotationPolicyModel convert(@Nullable final ReadOnlyRotationPolicy source, @NonNull final URI vaultUri) { return Optional.ofNullable(source) @@ -53,4 +67,9 @@ private KeyLifetimeActionModel convertLifetimeAction(final LifetimeAction lifeti new KeyLifetimeActionTypeModel(lifetimeAction.getActionType()), new KeyLifetimeActionTriggerModel(lifetimeAction.getTrigger())); } + + @Override + public SortedSet supportedVersions() { + return ApiVersionAware.V7_3; + } } diff --git a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/v7_3/key/KeyRotationPolicyV73ModelToEntityConverter.java b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/v7_3/key/KeyRotationPolicyV73ModelToEntityConverter.java index 6455b568..4a39cb2a 100644 --- a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/v7_3/key/KeyRotationPolicyV73ModelToEntityConverter.java +++ b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/mapper/v7_3/key/KeyRotationPolicyV73ModelToEntityConverter.java @@ -1,33 +1,45 @@ package com.github.nagyesta.lowkeyvault.mapper.v7_3.key; +import com.github.nagyesta.lowkeyvault.context.ApiVersionAware; +import com.github.nagyesta.lowkeyvault.mapper.common.ApiVersionAwareConverter; +import com.github.nagyesta.lowkeyvault.mapper.common.registry.KeyConverterRegistry; import com.github.nagyesta.lowkeyvault.model.v7_3.key.*; import com.github.nagyesta.lowkeyvault.model.v7_3.key.constants.LifetimeActionType; import com.github.nagyesta.lowkeyvault.service.key.KeyLifetimeAction; import com.github.nagyesta.lowkeyvault.service.key.LifetimeAction; import com.github.nagyesta.lowkeyvault.service.key.RotationPolicy; -import com.github.nagyesta.lowkeyvault.service.key.id.KeyEntityId; import com.github.nagyesta.lowkeyvault.service.key.impl.KeyLifetimeActionTrigger; import com.github.nagyesta.lowkeyvault.service.key.impl.KeyRotationPolicy; +import lombok.NonNull; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.lang.Nullable; -import org.springframework.stereotype.Component; import org.springframework.util.Assert; import java.time.OffsetDateTime; import java.time.Period; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.Optional; +import java.util.*; import java.util.function.Function; import java.util.stream.Collectors; -@Component -public class KeyRotationPolicyV73ModelToEntityConverter { +public class KeyRotationPolicyV73ModelToEntityConverter implements ApiVersionAwareConverter { - public RotationPolicy convert(final KeyEntityId keyEntityId, @Nullable final KeyRotationPolicyModel source) { + private final KeyConverterRegistry registry; + + @Autowired + public KeyRotationPolicyV73ModelToEntityConverter(@NonNull final KeyConverterRegistry registry) { + this.registry = registry; + } + + @Override + public void afterPropertiesSet() throws Exception { + registry.registerRotationPolicyEntityConverter(this); + } + + @Override + public RotationPolicy convert(@Nullable final KeyRotationPolicyModel source) { return Optional.ofNullable(source) .filter(this::isNotEmpty) - .map(s -> convertNonNull(keyEntityId, s)) + .map(this::convertNonNull) .orElse(null); } @@ -39,13 +51,14 @@ private boolean hasAttributes(final KeyRotationPolicyModel rotationPolicyModel) return rotationPolicyModel.getAttributes() != null; } - private RotationPolicy convertNonNull(final KeyEntityId keyEntityId, final KeyRotationPolicyModel source) { + private RotationPolicy convertNonNull(final KeyRotationPolicyModel source) { + Assert.notNull(source.getKeyEntityId(), "EntityId cannot be null."); Assert.notNull(source.getAttributes(), "Attributes cannot be null."); Assert.notNull(source.getLifetimeActions(), "LifetimeActions cannot be null."); Assert.notEmpty(source.getLifetimeActions(), "LifetimeActions cannot be empty."); final Map actions = convertLifetimeActions(source.getLifetimeActions()); final Period expiryTime = source.getAttributes().getExpiryTime(); - final RotationPolicy entity = new KeyRotationPolicy(keyEntityId, expiryTime, actions); + final RotationPolicy entity = new KeyRotationPolicy(source.getKeyEntityId(), expiryTime, actions); return convertAttributes(source.getAttributes(), entity); } @@ -72,4 +85,9 @@ private LifetimeAction convertLifetimeAction(final KeyLifetimeActionModel source sourceTrigger.getTriggerPeriod(), sourceTrigger.getTriggerType()); return new KeyLifetimeAction(action.getType(), trigger); } + + @Override + public SortedSet supportedVersions() { + return ApiVersionAware.V7_3; + } } diff --git a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/model/common/backup/CertificateBackupList.java b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/model/common/backup/CertificateBackupList.java new file mode 100644 index 00000000..24b202a3 --- /dev/null +++ b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/model/common/backup/CertificateBackupList.java @@ -0,0 +1,28 @@ +package com.github.nagyesta.lowkeyvault.model.common.backup; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.github.nagyesta.lowkeyvault.model.v7_2.key.BackupListContainer; +import lombok.EqualsAndHashCode; + +import javax.validation.Valid; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; +import java.util.List; + +@EqualsAndHashCode +public class CertificateBackupList implements BackupListContainer { + + @Valid + @NotNull + @Size(min = 1) + @JsonProperty("versions") + private List versions = List.of(); + + public List getVersions() { + return versions; + } + + public void setVersions(final List versions) { + this.versions = List.copyOf(versions); + } +} diff --git a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/model/common/backup/CertificateBackupListItem.java b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/model/common/backup/CertificateBackupListItem.java new file mode 100644 index 00000000..55299008 --- /dev/null +++ b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/model/common/backup/CertificateBackupListItem.java @@ -0,0 +1,15 @@ +package com.github.nagyesta.lowkeyvault.model.common.backup; + +import com.github.nagyesta.lowkeyvault.model.v7_2.common.BaseBackupListItem; +import com.github.nagyesta.lowkeyvault.model.v7_3.certificate.CertificatePropertiesModel; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class CertificateBackupListItem extends BaseBackupListItem { + + //add all certificate properties here, which are needed for successful import +} diff --git a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/model/common/backup/CertificateBackupModel.java b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/model/common/backup/CertificateBackupModel.java new file mode 100644 index 00000000..ca7f83e8 --- /dev/null +++ b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/model/common/backup/CertificateBackupModel.java @@ -0,0 +1,25 @@ +package com.github.nagyesta.lowkeyvault.model.common.backup; + +import com.github.nagyesta.lowkeyvault.model.v7_2.common.BaseBackupModel; +import com.github.nagyesta.lowkeyvault.model.v7_3.certificate.CertificatePropertiesModel; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class CertificateBackupModel extends BaseBackupModel { + + //@JsonSerialize(using = Base64ZipSecretSerializer.class) + @Override + public CertificateBackupList getValue() { + return super.getValue(); + } + + //@JsonDeserialize(using = Base64ZipSecretDeserializer.class) + @Override + public void setValue(final CertificateBackupList value) { + super.setValue(value); + } +} diff --git a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/model/v7_2/key/KeyBackupList.java b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/model/common/backup/KeyBackupList.java similarity index 50% rename from lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/model/v7_2/key/KeyBackupList.java rename to lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/model/common/backup/KeyBackupList.java index c2f02532..e4d082d3 100644 --- a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/model/v7_2/key/KeyBackupList.java +++ b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/model/common/backup/KeyBackupList.java @@ -1,6 +1,9 @@ -package com.github.nagyesta.lowkeyvault.model.v7_2.key; +package com.github.nagyesta.lowkeyvault.model.common.backup; +import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; +import com.github.nagyesta.lowkeyvault.model.v7_2.key.BackupListContainer; +import com.github.nagyesta.lowkeyvault.model.v7_3.key.KeyRotationPolicyModel; import lombok.EqualsAndHashCode; import javax.validation.Valid; @@ -24,4 +27,17 @@ public List getVersions() { public void setVersions(final List versions) { this.versions = List.copyOf(versions); } + + @Valid + @JsonProperty("rotationPolicy") + @JsonInclude(JsonInclude.Include.NON_NULL) + private KeyRotationPolicyModel keyRotationPolicy; + + public KeyRotationPolicyModel getKeyRotationPolicy() { + return keyRotationPolicy; + } + + public void setKeyRotationPolicy(final KeyRotationPolicyModel keyRotationPolicy) { + this.keyRotationPolicy = keyRotationPolicy; + } } diff --git a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/model/v7_2/key/KeyBackupListItem.java b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/model/common/backup/KeyBackupListItem.java similarity index 82% rename from lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/model/v7_2/key/KeyBackupListItem.java rename to lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/model/common/backup/KeyBackupListItem.java index 248e0135..10435261 100644 --- a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/model/v7_2/key/KeyBackupListItem.java +++ b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/model/common/backup/KeyBackupListItem.java @@ -1,7 +1,8 @@ -package com.github.nagyesta.lowkeyvault.model.v7_2.key; +package com.github.nagyesta.lowkeyvault.model.common.backup; import com.fasterxml.jackson.annotation.JsonProperty; import com.github.nagyesta.lowkeyvault.model.v7_2.common.BaseBackupListItem; +import com.github.nagyesta.lowkeyvault.model.v7_2.key.KeyPropertiesModel; import com.github.nagyesta.lowkeyvault.model.v7_2.key.request.JsonWebKeyImportRequest; import lombok.Data; import lombok.EqualsAndHashCode; diff --git a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/model/v7_3/key/KeyBackupModel.java b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/model/common/backup/KeyBackupModel.java similarity index 74% rename from lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/model/v7_3/key/KeyBackupModel.java rename to lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/model/common/backup/KeyBackupModel.java index 5ef627e5..bd1bac7b 100644 --- a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/model/v7_3/key/KeyBackupModel.java +++ b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/model/common/backup/KeyBackupModel.java @@ -1,11 +1,10 @@ -package com.github.nagyesta.lowkeyvault.model.v7_3.key; +package com.github.nagyesta.lowkeyvault.model.common.backup; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.databind.annotation.JsonSerialize; -import com.github.nagyesta.lowkeyvault.model.json.util.Base64ZipV73KeyDeserializer; -import com.github.nagyesta.lowkeyvault.model.json.util.Base64ZipV73KeySerializer; +import com.github.nagyesta.lowkeyvault.model.json.util.Base64ZipKeyDeserializer; +import com.github.nagyesta.lowkeyvault.model.json.util.Base64ZipKeySerializer; import com.github.nagyesta.lowkeyvault.model.v7_2.common.BaseBackupModel; -import com.github.nagyesta.lowkeyvault.model.v7_2.key.KeyBackupListItem; import com.github.nagyesta.lowkeyvault.model.v7_2.key.KeyPropertiesModel; import lombok.Data; import lombok.EqualsAndHashCode; @@ -16,13 +15,13 @@ @ToString(callSuper = true) public class KeyBackupModel extends BaseBackupModel { - @JsonSerialize(using = Base64ZipV73KeySerializer.class) + @JsonSerialize(using = Base64ZipKeySerializer.class) @Override public KeyBackupList getValue() { return super.getValue(); } - @JsonDeserialize(using = Base64ZipV73KeyDeserializer.class) + @JsonDeserialize(using = Base64ZipKeyDeserializer.class) @Override public void setValue(final KeyBackupList value) { super.setValue(value); diff --git a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/model/v7_2/secret/SecretBackupList.java b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/model/common/backup/SecretBackupList.java similarity index 92% rename from lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/model/v7_2/secret/SecretBackupList.java rename to lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/model/common/backup/SecretBackupList.java index 97dbe69a..e97b777a 100644 --- a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/model/v7_2/secret/SecretBackupList.java +++ b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/model/common/backup/SecretBackupList.java @@ -1,4 +1,4 @@ -package com.github.nagyesta.lowkeyvault.model.v7_2.secret; +package com.github.nagyesta.lowkeyvault.model.common.backup; import com.fasterxml.jackson.annotation.JsonProperty; import com.github.nagyesta.lowkeyvault.model.v7_2.key.BackupListContainer; diff --git a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/model/v7_2/secret/SecretBackupListItem.java b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/model/common/backup/SecretBackupListItem.java similarity index 79% rename from lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/model/v7_2/secret/SecretBackupListItem.java rename to lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/model/common/backup/SecretBackupListItem.java index eacb440b..4236fd96 100644 --- a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/model/v7_2/secret/SecretBackupListItem.java +++ b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/model/common/backup/SecretBackupListItem.java @@ -1,7 +1,8 @@ -package com.github.nagyesta.lowkeyvault.model.v7_2.secret; +package com.github.nagyesta.lowkeyvault.model.common.backup; import com.fasterxml.jackson.annotation.JsonProperty; import com.github.nagyesta.lowkeyvault.model.v7_2.common.BaseBackupListItem; +import com.github.nagyesta.lowkeyvault.model.v7_2.secret.SecretPropertiesModel; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; diff --git a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/model/v7_2/secret/SecretBackupModel.java b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/model/common/backup/SecretBackupModel.java similarity index 87% rename from lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/model/v7_2/secret/SecretBackupModel.java rename to lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/model/common/backup/SecretBackupModel.java index 9c36109a..4b668298 100644 --- a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/model/v7_2/secret/SecretBackupModel.java +++ b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/model/common/backup/SecretBackupModel.java @@ -1,10 +1,11 @@ -package com.github.nagyesta.lowkeyvault.model.v7_2.secret; +package com.github.nagyesta.lowkeyvault.model.common.backup; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.databind.annotation.JsonSerialize; import com.github.nagyesta.lowkeyvault.model.json.util.Base64ZipSecretDeserializer; import com.github.nagyesta.lowkeyvault.model.json.util.Base64ZipSecretSerializer; import com.github.nagyesta.lowkeyvault.model.v7_2.common.BaseBackupModel; +import com.github.nagyesta.lowkeyvault.model.v7_2.secret.SecretPropertiesModel; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; diff --git a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/model/json/util/Base64ZipV73KeyDeserializer.java b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/model/json/util/Base64ZipKeyDeserializer.java similarity index 52% rename from lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/model/json/util/Base64ZipV73KeyDeserializer.java rename to lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/model/json/util/Base64ZipKeyDeserializer.java index 8a3b285d..56619ff0 100644 --- a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/model/json/util/Base64ZipV73KeyDeserializer.java +++ b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/model/json/util/Base64ZipKeyDeserializer.java @@ -1,15 +1,15 @@ package com.github.nagyesta.lowkeyvault.model.json.util; import com.fasterxml.jackson.databind.ObjectMapper; -import com.github.nagyesta.lowkeyvault.model.v7_3.key.KeyBackupList; +import com.github.nagyesta.lowkeyvault.model.common.backup.KeyBackupList; -public class Base64ZipV73KeyDeserializer extends AbstractBase64ZipDeserializer { +public class Base64ZipKeyDeserializer extends AbstractBase64ZipDeserializer { - public Base64ZipV73KeyDeserializer() { + public Base64ZipKeyDeserializer() { this(new Base64Deserializer(), new ObjectMapper().findAndRegisterModules()); } - protected Base64ZipV73KeyDeserializer(final Base64Deserializer base64Deserializer, final ObjectMapper objectMapper) { + protected Base64ZipKeyDeserializer(final Base64Deserializer base64Deserializer, final ObjectMapper objectMapper) { super(base64Deserializer, objectMapper); } diff --git a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/model/json/util/Base64ZipKeySerializer.java b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/model/json/util/Base64ZipKeySerializer.java new file mode 100644 index 00000000..92a1583e --- /dev/null +++ b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/model/json/util/Base64ZipKeySerializer.java @@ -0,0 +1,15 @@ +package com.github.nagyesta.lowkeyvault.model.json.util; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.github.nagyesta.lowkeyvault.model.common.backup.KeyBackupList; + +public class Base64ZipKeySerializer extends AbstractBase64ZipSerializer { + + public Base64ZipKeySerializer() { + this(new Base64Serializer(), new ObjectMapper().findAndRegisterModules()); + } + + protected Base64ZipKeySerializer(final Base64Serializer base64Serializer, final ObjectMapper objectMapper) { + super(base64Serializer, objectMapper); + } +} diff --git a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/model/json/util/Base64ZipSecretDeserializer.java b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/model/json/util/Base64ZipSecretDeserializer.java index 97d65a0c..6d52d02e 100644 --- a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/model/json/util/Base64ZipSecretDeserializer.java +++ b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/model/json/util/Base64ZipSecretDeserializer.java @@ -1,7 +1,7 @@ package com.github.nagyesta.lowkeyvault.model.json.util; import com.fasterxml.jackson.databind.ObjectMapper; -import com.github.nagyesta.lowkeyvault.model.v7_2.secret.SecretBackupList; +import com.github.nagyesta.lowkeyvault.model.common.backup.SecretBackupList; public class Base64ZipSecretDeserializer extends AbstractBase64ZipDeserializer { diff --git a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/model/json/util/Base64ZipSecretSerializer.java b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/model/json/util/Base64ZipSecretSerializer.java index 55e30c6d..6c094122 100644 --- a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/model/json/util/Base64ZipSecretSerializer.java +++ b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/model/json/util/Base64ZipSecretSerializer.java @@ -1,7 +1,7 @@ package com.github.nagyesta.lowkeyvault.model.json.util; import com.fasterxml.jackson.databind.ObjectMapper; -import com.github.nagyesta.lowkeyvault.model.v7_2.secret.SecretBackupList; +import com.github.nagyesta.lowkeyvault.model.common.backup.SecretBackupList; public class Base64ZipSecretSerializer extends AbstractBase64ZipSerializer { diff --git a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/model/json/util/Base64ZipV72KeyDeserializer.java b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/model/json/util/Base64ZipV72KeyDeserializer.java deleted file mode 100644 index 767c4fc4..00000000 --- a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/model/json/util/Base64ZipV72KeyDeserializer.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.github.nagyesta.lowkeyvault.model.json.util; - -import com.fasterxml.jackson.databind.ObjectMapper; -import com.github.nagyesta.lowkeyvault.model.v7_2.key.KeyBackupList; - -public class Base64ZipV72KeyDeserializer extends AbstractBase64ZipDeserializer { - - public Base64ZipV72KeyDeserializer() { - this(new Base64Deserializer(), new ObjectMapper()); - } - - protected Base64ZipV72KeyDeserializer(final Base64Deserializer base64Deserializer, final ObjectMapper objectMapper) { - super(base64Deserializer, objectMapper); - } - - @Override - protected Class getType() { - return KeyBackupList.class; - } -} diff --git a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/model/json/util/Base64ZipV72KeySerializer.java b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/model/json/util/Base64ZipV72KeySerializer.java deleted file mode 100644 index 62cb2d1b..00000000 --- a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/model/json/util/Base64ZipV72KeySerializer.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.github.nagyesta.lowkeyvault.model.json.util; - -import com.fasterxml.jackson.databind.ObjectMapper; -import com.github.nagyesta.lowkeyvault.model.v7_2.key.KeyBackupList; - -public class Base64ZipV72KeySerializer extends AbstractBase64ZipSerializer { - - public Base64ZipV72KeySerializer() { - this(new Base64Serializer(), new ObjectMapper()); - } - - protected Base64ZipV72KeySerializer(final Base64Serializer base64Serializer, final ObjectMapper objectMapper) { - super(base64Serializer, objectMapper); - } -} diff --git a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/model/json/util/Base64ZipV73KeySerializer.java b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/model/json/util/Base64ZipV73KeySerializer.java deleted file mode 100644 index d4f349cd..00000000 --- a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/model/json/util/Base64ZipV73KeySerializer.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.github.nagyesta.lowkeyvault.model.json.util; - -import com.fasterxml.jackson.databind.ObjectMapper; -import com.github.nagyesta.lowkeyvault.model.v7_3.key.KeyBackupList; - -public class Base64ZipV73KeySerializer extends AbstractBase64ZipSerializer { - - public Base64ZipV73KeySerializer() { - this(new Base64Serializer(), new ObjectMapper().findAndRegisterModules()); - } - - protected Base64ZipV73KeySerializer(final Base64Serializer base64Serializer, final ObjectMapper objectMapper) { - super(base64Serializer, objectMapper); - } -} diff --git a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/model/management/VaultBackupModel.java b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/model/management/VaultBackupModel.java index d264836e..21e2d018 100644 --- a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/model/management/VaultBackupModel.java +++ b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/model/management/VaultBackupModel.java @@ -2,8 +2,8 @@ import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; -import com.github.nagyesta.lowkeyvault.model.v7_2.secret.SecretBackupList; -import com.github.nagyesta.lowkeyvault.model.v7_3.key.KeyBackupList; +import com.github.nagyesta.lowkeyvault.model.common.backup.KeyBackupList; +import com.github.nagyesta.lowkeyvault.model.common.backup.SecretBackupList; import lombok.Data; import javax.validation.Valid; diff --git a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/model/v7_2/key/KeyBackupModel.java b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/model/v7_2/key/KeyBackupModel.java deleted file mode 100644 index 793ab6ed..00000000 --- a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/model/v7_2/key/KeyBackupModel.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.github.nagyesta.lowkeyvault.model.v7_2.key; - -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -import com.fasterxml.jackson.databind.annotation.JsonSerialize; -import com.github.nagyesta.lowkeyvault.model.json.util.Base64ZipV72KeyDeserializer; -import com.github.nagyesta.lowkeyvault.model.json.util.Base64ZipV72KeySerializer; -import com.github.nagyesta.lowkeyvault.model.v7_2.common.BaseBackupModel; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.ToString; - -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -public class KeyBackupModel extends BaseBackupModel { - - @JsonSerialize(using = Base64ZipV72KeySerializer.class) - @Override - public KeyBackupList getValue() { - return super.getValue(); - } - - @JsonDeserialize(using = Base64ZipV72KeyDeserializer.class) - @Override - public void setValue(final KeyBackupList value) { - super.setValue(value); - } -} diff --git a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/model/v7_2/secret/SecretEntityToV72BackupConverter.java b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/model/v7_2/secret/SecretEntityToV72BackupConverter.java deleted file mode 100644 index 5e72d3b3..00000000 --- a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/model/v7_2/secret/SecretEntityToV72BackupConverter.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.github.nagyesta.lowkeyvault.model.v7_2.secret; - -import com.github.nagyesta.lowkeyvault.mapper.AliasAwareConverter; -import com.github.nagyesta.lowkeyvault.mapper.common.BackupConverter; -import com.github.nagyesta.lowkeyvault.service.secret.ReadOnlyKeyVaultSecretEntity; -import com.github.nagyesta.lowkeyvault.service.secret.id.VersionedSecretEntityId; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.lang.NonNull; -import org.springframework.stereotype.Component; - -@Component -public class SecretEntityToV72BackupConverter - extends BackupConverter { - - @Autowired - public SecretEntityToV72BackupConverter( - @NonNull final AliasAwareConverter propertiesConverter) { - super(propertiesConverter); - } - - @Override - protected SecretBackupListItem convertUniqueFields(@NonNull final ReadOnlyKeyVaultSecretEntity source) { - final SecretBackupListItem listItem = new SecretBackupListItem(); - listItem.setValue(source.getValue()); - listItem.setContentType(source.getContentType()); - return listItem; - } -} diff --git a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/model/v7_3/key/KeyBackupList.java b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/model/v7_3/key/KeyBackupList.java deleted file mode 100644 index 697dce22..00000000 --- a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/model/v7_3/key/KeyBackupList.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.github.nagyesta.lowkeyvault.model.v7_3.key; - -import com.fasterxml.jackson.annotation.JsonProperty; -import lombok.EqualsAndHashCode; - -import javax.validation.Valid; - -@EqualsAndHashCode(callSuper = true) -public class KeyBackupList extends com.github.nagyesta.lowkeyvault.model.v7_2.key.KeyBackupList { - - @Valid - @JsonProperty("rotationPolicy") - private KeyRotationPolicyModel keyRotationPolicy; - - public KeyRotationPolicyModel getKeyRotationPolicy() { - return keyRotationPolicy; - } - - public void setKeyRotationPolicy(final KeyRotationPolicyModel keyRotationPolicy) { - this.keyRotationPolicy = keyRotationPolicy; - } -} diff --git a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/model/v7_3/key/KeyRotationPolicyModel.java b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/model/v7_3/key/KeyRotationPolicyModel.java index 3aa01b79..da6c6874 100644 --- a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/model/v7_3/key/KeyRotationPolicyModel.java +++ b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/model/v7_3/key/KeyRotationPolicyModel.java @@ -1,9 +1,11 @@ package com.github.nagyesta.lowkeyvault.model.v7_3.key; +import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonPropertyOrder; import com.github.nagyesta.lowkeyvault.model.v7_3.key.validator.Restore; import com.github.nagyesta.lowkeyvault.model.v7_3.key.validator.Update; +import com.github.nagyesta.lowkeyvault.service.key.id.KeyEntityId; import lombok.Data; import javax.validation.Valid; @@ -29,4 +31,6 @@ public class KeyRotationPolicyModel { @JsonProperty("lifetimeActions") private List lifetimeActions; + @JsonIgnore + private KeyEntityId keyEntityId; } diff --git a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/service/certificate/impl/CertificateBackingEntityGenerator.java b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/service/certificate/impl/CertificateBackingEntityGenerator.java new file mode 100644 index 00000000..551a74d2 --- /dev/null +++ b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/service/certificate/impl/CertificateBackingEntityGenerator.java @@ -0,0 +1,85 @@ +package com.github.nagyesta.lowkeyvault.service.certificate.impl; + +import com.github.nagyesta.lowkeyvault.model.v7_2.key.constants.KeyOperation; +import com.github.nagyesta.lowkeyvault.model.v7_2.key.request.JsonWebKeyImportRequest; +import com.github.nagyesta.lowkeyvault.service.key.ReadOnlyAsymmetricKeyVaultKeyEntity; +import com.github.nagyesta.lowkeyvault.service.key.id.VersionedKeyEntityId; +import com.github.nagyesta.lowkeyvault.service.key.impl.KeyCreateDetailedInput; +import com.github.nagyesta.lowkeyvault.service.key.impl.KeyImportInput; +import com.github.nagyesta.lowkeyvault.service.secret.id.VersionedSecretEntityId; +import com.github.nagyesta.lowkeyvault.service.secret.impl.KeyVaultSecretEntity; +import com.github.nagyesta.lowkeyvault.service.secret.impl.SecretCreateInput; +import com.github.nagyesta.lowkeyvault.service.vault.VaultFake; + +import java.security.KeyPair; +import java.security.cert.Certificate; +import java.time.OffsetDateTime; +import java.time.ZoneOffset; +import java.util.List; + +public class CertificateBackingEntityGenerator { + private final VaultFake vaultFake; + + public CertificateBackingEntityGenerator(final VaultFake vaultFake) { + this.vaultFake = vaultFake; + } + + public VersionedKeyEntityId generateKeyPair(final ReadOnlyCertificatePolicy input) { + final OffsetDateTime now = OffsetDateTime.now(ZoneOffset.UTC); + final OffsetDateTime expiry = now.plusMonths(input.getValidityMonths()); + return vaultFake.keyVaultFake().createKeyVersion(input.getName(), KeyCreateDetailedInput.builder() + .key(input.toKeyCreationInput()) + .keyOperations(List.of( + KeyOperation.SIGN, KeyOperation.VERIFY, + KeyOperation.ENCRYPT, KeyOperation.DECRYPT, + KeyOperation.WRAP_KEY, KeyOperation.UNWRAP_KEY)) + .notBefore(now) + .expiresOn(expiry) + .enabled(true) + .managed(true) + .build()); + } + + public VersionedKeyEntityId importKeyPair( + final ReadOnlyCertificatePolicy input, final JsonWebKeyImportRequest keyImportRequest) { + return vaultFake.keyVaultFake().importKeyVersion(input.getName(), KeyImportInput.builder() + .key(keyImportRequest) + .createdOn(input.getValidityStart()) + .updatedOn(input.getValidityStart()) + .expiresOn(input.getValidityStart().plusMonths(input.getValidityMonths())) + .notBefore(input.getValidityStart()) + .managed(true) + .enabled(true) + .build()); + } + + public VersionedSecretEntityId generateSecret(final ReadOnlyCertificatePolicy input, + final Certificate certificate, + final VersionedKeyEntityId kid, + final VersionedSecretEntityId sid) { + final KeyPair key = vaultFake.keyVaultFake().getEntities().getEntity(kid, ReadOnlyAsymmetricKeyVaultKeyEntity.class).getKey(); + final String value = input.getContentType().asBase64CertificatePackage(certificate, key); + final OffsetDateTime start = input.getValidityStart(); + final OffsetDateTime expiry = start.plusMonths(input.getValidityMonths()); + return vaultFake.secretVaultFake().createSecretVersion(sid, SecretCreateInput.builder() + .value(value) + .contentType(input.getContentType().getMimeType()) + .createdOn(start) + .updatedOn(start) + .notBefore(start) + .expiresOn(expiry) + .enabled(true) + .managed(true) + .build()); + } + + public void updateSecretValueWithNewCertificate(final CertificatePolicy updated, + final Certificate certificate, + final VersionedKeyEntityId kid, + final VersionedSecretEntityId sid) { + final ReadOnlyAsymmetricKeyVaultKeyEntity key = vaultFake.keyVaultFake().getEntities() + .getEntity(kid, ReadOnlyAsymmetricKeyVaultKeyEntity.class); + final KeyVaultSecretEntity secret = vaultFake.secretVaultFake().getEntities().getEntity(sid, KeyVaultSecretEntity.class); + secret.setValue(updated.getContentType().asBase64CertificatePackage(certificate, key.getKey())); + } +} diff --git a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/service/certificate/impl/CertificateVaultFakeImpl.java b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/service/certificate/impl/CertificateVaultFakeImpl.java index e4051f15..6353c89c 100644 --- a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/service/certificate/impl/CertificateVaultFakeImpl.java +++ b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/service/certificate/impl/CertificateVaultFakeImpl.java @@ -8,6 +8,7 @@ import com.github.nagyesta.lowkeyvault.service.certificate.id.VersionedCertificateEntityId; import com.github.nagyesta.lowkeyvault.service.common.ReadOnlyVersionedEntityMultiMap; import com.github.nagyesta.lowkeyvault.service.common.impl.BaseVaultFakeImpl; +import com.github.nagyesta.lowkeyvault.service.key.KeyVaultFake; import com.github.nagyesta.lowkeyvault.service.key.ReadOnlyKeyVaultKeyEntity; import com.github.nagyesta.lowkeyvault.service.key.id.KeyEntityId; import com.github.nagyesta.lowkeyvault.service.key.id.VersionedKeyEntityId; @@ -101,20 +102,25 @@ private VersionedCertificateEntityId generateIdOfNewCertificateEntity( } private VersionedKeyEntityId rotateIfNeededAndGetLastKeyId(final ReadOnlyCertificatePolicy input) { - final ReadOnlyVersionedEntityMultiMap entities = vaultFake() - .keyVaultFake().getEntities(); + final KeyVaultFake keyVaultFake = vaultFake().keyVaultFake(); + final ReadOnlyVersionedEntityMultiMap entities = keyVaultFake + .getEntities(); final VersionedKeyEntityId versionedKeyEntityId; if (input.isReuseKeyOnRenewal()) { final String lastVersion = entities.getVersions(new KeyEntityId(vaultFake().baseUri(), input.getName())).getLast(); versionedKeyEntityId = new VersionedKeyEntityId(vaultFake().baseUri(), input.getName(), lastVersion); + final OffsetDateTime notBefore = entities.getReadOnlyEntity(versionedKeyEntityId) + .getNotBefore().orElseThrow(() -> new IllegalStateException("Managed keys should always have notBefore timestamps.")); + final OffsetDateTime newExpiry = input.getValidityStart().plusMonths(input.getValidityMonths()); + //extend expiry until the certificate expiry + keyVaultFake.setExpiry(versionedKeyEntityId, notBefore, newExpiry); } else { - versionedKeyEntityId = vaultFake().keyVaultFake().rotateKey(new KeyEntityId(vaultFake().baseUri(), input.getName())); + versionedKeyEntityId = keyVaultFake.rotateKey(new KeyEntityId(vaultFake().baseUri(), input.getName())); //update timestamps final OffsetDateTime notBefore = input.getValidityStart(); final OffsetDateTime expiry = notBefore.plusMonths(input.getValidityMonths()); - vaultFake().keyVaultFake().setExpiry(versionedKeyEntityId, notBefore, expiry); - final KeyVaultKeyEntity entity = vaultFake() - .keyVaultFake().getEntities().getEntity(versionedKeyEntityId, KeyVaultKeyEntity.class); + keyVaultFake.setExpiry(versionedKeyEntityId, notBefore, expiry); + final KeyVaultKeyEntity entity = keyVaultFake.getEntities().getEntity(versionedKeyEntityId, KeyVaultKeyEntity.class); entity.setManaged(true); entity.setCreatedOn(notBefore); entity.setUpdatedOn(notBefore); diff --git a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/service/certificate/impl/KeyVaultCertificateEntity.java b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/service/certificate/impl/KeyVaultCertificateEntity.java index fe8b16b1..f4f017a2 100644 --- a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/service/certificate/impl/KeyVaultCertificateEntity.java +++ b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/service/certificate/impl/KeyVaultCertificateEntity.java @@ -5,24 +5,20 @@ import com.github.nagyesta.lowkeyvault.service.certificate.id.VersionedCertificateEntityId; import com.github.nagyesta.lowkeyvault.service.common.impl.KeyVaultBaseEntity; import com.github.nagyesta.lowkeyvault.service.exception.CryptoException; -import com.github.nagyesta.lowkeyvault.service.key.ReadOnlyAsymmetricKeyVaultKeyEntity; import com.github.nagyesta.lowkeyvault.service.key.id.KeyEntityId; import com.github.nagyesta.lowkeyvault.service.key.id.VersionedKeyEntityId; import com.github.nagyesta.lowkeyvault.service.secret.id.SecretEntityId; import com.github.nagyesta.lowkeyvault.service.secret.id.VersionedSecretEntityId; -import com.github.nagyesta.lowkeyvault.service.secret.impl.KeyVaultSecretEntity; import com.github.nagyesta.lowkeyvault.service.vault.VaultFake; import lombok.NonNull; import lombok.extern.slf4j.Slf4j; import org.bouncycastle.pkcs.PKCS10CertificationRequest; import org.springframework.util.Assert; -import java.security.KeyPair; import java.security.MessageDigest; import java.security.cert.Certificate; import java.security.cert.X509Certificate; import java.time.OffsetDateTime; -import java.time.ZoneOffset; import java.time.temporal.ChronoUnit; import java.util.Date; import java.util.Optional; @@ -35,6 +31,7 @@ public class KeyVaultCertificateEntity private final VersionedCertificateEntityId id; private final VersionedKeyEntityId kid; private final VersionedSecretEntityId sid; + private final CertificateBackingEntityGenerator generator; private X509Certificate certificate; private ReadOnlyCertificatePolicy originalCertificatePolicy; private final String originalCertificateContents; @@ -62,14 +59,15 @@ public KeyVaultCertificateEntity(@NonNull final String name, "Secret must not exist to be able to store certificate data in it. " + sid.asUriNoVersion(vault.baseUri())); this.issuancePolicy = new CertificatePolicy(input); this.originalCertificatePolicy = new CertificatePolicy(input); - this.kid = generateKeyPair(input, vault); + this.generator = new CertificateBackingEntityGenerator(vault); + this.kid = generator.generateKeyPair(input); //reuse the generated key version to produce matching version numbers in all keys this.id = new VersionedCertificateEntityId(vault.baseUri(), name, this.kid.version()); final CertificateGenerator certificateGenerator = new CertificateGenerator(vault, this.kid); this.certificate = certificateGenerator.generateCertificate(input); this.csr = certificateGenerator.generateCertificateSigningRequest(name, this.certificate); final VersionedSecretEntityId secretEntityId = new VersionedSecretEntityId(vault.baseUri(), input.getName(), this.kid.version()); - this.sid = generateSecret(this.originalCertificatePolicy, vault, this.certificate, this.kid, secretEntityId); + this.sid = generator.generateSecret(this.originalCertificatePolicy, this.certificate, this.kid, secretEntityId); this.originalCertificateContents = vault.secretVaultFake().getEntities().getReadOnlyEntity(this.sid).getValue(); normalizeCoreTimeStamps(input, now()); } @@ -104,14 +102,15 @@ public KeyVaultCertificateEntity(@NonNull final String name, "Secret must not exist to be able to store certificate data in it. " + sid.asUriNoVersion(vault.baseUri())); this.issuancePolicy = new CertificatePolicy(policy); this.originalCertificatePolicy = new CertificatePolicy(originalCertificateData); - this.kid = importKeyPair(policy, keyImportRequest, vault); + this.generator = new CertificateBackingEntityGenerator(vault); + this.kid = generator.importKeyPair(policy, keyImportRequest); //reuse the generated key version to produce matching version numbers in all keys this.id = new VersionedCertificateEntityId(vault.baseUri(), name, this.kid.version()); final CertificateGenerator certificateGenerator = new CertificateGenerator(vault, this.kid); this.certificate = certificate; this.csr = certificateGenerator.generateCertificateSigningRequest(name, this.certificate); final VersionedSecretEntityId secretEntityId = new VersionedSecretEntityId(vault.baseUri(), input.getName(), this.kid.version()); - this.sid = generateSecret(this.originalCertificatePolicy, vault, this.certificate, this.kid, secretEntityId); + this.sid = generator.generateSecret(this.originalCertificatePolicy, this.certificate, this.kid, secretEntityId); this.originalCertificateContents = vault.secretVaultFake().getEntities().getReadOnlyEntity(this.sid).getValue(); normalizeCoreTimeStamps(policy, now()); } @@ -142,33 +141,12 @@ public KeyVaultCertificateEntity(@NonNull final ReadOnlyCertificatePolicy input, this.certificate = certificateGenerator.generateCertificate(input); this.csr = certificateGenerator.generateCertificateSigningRequest(input.getName(), this.certificate); final VersionedSecretEntityId secretEntityId = new VersionedSecretEntityId(vault.baseUri(), input.getName(), id.version()); - this.sid = generateSecret(this.originalCertificatePolicy, vault, this.certificate, this.kid, secretEntityId); + this.generator = new CertificateBackingEntityGenerator(vault); + this.sid = generator.generateSecret(this.originalCertificatePolicy, this.certificate, this.kid, secretEntityId); this.originalCertificateContents = vault.secretVaultFake().getEntities().getReadOnlyEntity(this.sid).getValue(); normalizeCoreTimeStamps(input, input.getValidityStart()); } - private VersionedSecretEntityId generateSecret(final ReadOnlyCertificatePolicy input, - final VaultFake vault, - final Certificate certificate, - final VersionedKeyEntityId kid, - final VersionedSecretEntityId sid) { - final KeyPair key = vault.keyVaultFake().getEntities().getEntity(kid, ReadOnlyAsymmetricKeyVaultKeyEntity.class).getKey(); - final String value = input.getContentType().asBase64CertificatePackage(certificate, key); - final OffsetDateTime start = input.getValidityStart(); - final OffsetDateTime expiry = start.plusMonths(input.getValidityMonths()); - return vault.secretVaultFake().createSecretVersionForCertificate(sid, value, input.getContentType(), start, expiry); - } - - private VersionedKeyEntityId generateKeyPair(final ReadOnlyCertificatePolicy input, final VaultFake vault) { - final OffsetDateTime now = OffsetDateTime.now(ZoneOffset.UTC); - final OffsetDateTime expiry = now.plusMonths(input.getValidityMonths()); - return vault.keyVaultFake().createKeyVersionForCertificate(input.getName(), input.toKeyCreationInput(), now, expiry); - } - - private VersionedKeyEntityId importKeyPair( - final ReadOnlyCertificatePolicy input, final JsonWebKeyImportRequest keyImportRequest, final VaultFake vault) { - return vault.keyVaultFake().importManagedKeyVersion(input.getName(), keyImportRequest); - } @Override public VersionedCertificateEntityId getId() { @@ -264,7 +242,7 @@ public void regenerateCertificate(final VaultFake vault) { final CertificatePolicy updated = new CertificatePolicy(originalCertificatePolicy); updated.setValidityStart(getCreated()); regenerateCertificateData(vault, updated); - updateSecretValueWithNewCertificate(vault, updated); + generator.updateSecretValueWithNewCertificate(updated, certificate, kid, sid); } else { log.debug("Validity start date is still accurate certificate won't be changed: {}", id); } @@ -279,13 +257,6 @@ private void normalizeCoreTimeStamps(final ReadOnlyCertificatePolicy certPolicy, this.setUpdatedOn(createOrUpdate); } - private void updateSecretValueWithNewCertificate(final VaultFake vault, final CertificatePolicy updated) { - final ReadOnlyAsymmetricKeyVaultKeyEntity key = vault.keyVaultFake().getEntities() - .getEntity(kid, ReadOnlyAsymmetricKeyVaultKeyEntity.class); - final KeyVaultSecretEntity secret = vault.secretVaultFake().getEntities().getEntity(this.sid, KeyVaultSecretEntity.class); - secret.setValue(updated.getContentType().asBase64CertificatePackage(certificate, key.getKey())); - } - private void regenerateCertificateData(final VaultFake vaultFake, final CertificatePolicy updated) { final CertificateGenerator certificateGenerator = new CertificateGenerator(vaultFake, this.kid); this.certificate = certificateGenerator.generateCertificate(updated); diff --git a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/service/common/BaseVaultEntity.java b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/service/common/BaseVaultEntity.java index f8cbb197..01abb216 100644 --- a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/service/common/BaseVaultEntity.java +++ b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/service/common/BaseVaultEntity.java @@ -2,6 +2,7 @@ import com.github.nagyesta.lowkeyvault.model.v7_2.common.constants.RecoveryLevel; import com.github.nagyesta.lowkeyvault.service.EntityId; +import com.github.nagyesta.lowkeyvault.service.key.ReadOnlyDeletedEntity; import java.time.OffsetDateTime; import java.util.Map; @@ -12,9 +13,7 @@ * * @param The type of the versioned Id identifying this entity. */ -public interface BaseVaultEntity extends TimeAware { - - V getId(); +public interface BaseVaultEntity extends ReadOnlyDeletedEntity, TimeAware { boolean isEnabled(); @@ -40,12 +39,8 @@ public interface BaseVaultEntity extends TimeAware { void setTags(Map tags); - Optional getDeletedDate(); - void setDeletedDate(OffsetDateTime deletedDate); - Optional getScheduledPurgeDate(); - void setScheduledPurgeDate(OffsetDateTime scheduledPurgeDate); boolean isPurgeExpired(); diff --git a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/service/common/impl/BaseVaultFakeImpl.java b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/service/common/impl/BaseVaultFakeImpl.java index 97ab2ec6..4d00bbdd 100644 --- a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/service/common/impl/BaseVaultFakeImpl.java +++ b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/service/common/impl/BaseVaultFakeImpl.java @@ -83,6 +83,20 @@ public void setExpiry(@NonNull final V entityId, entity.setExpiry(expiry); } + protected void setCreatedAndUpdatedOn(final V entityId, final OffsetDateTime created, final OffsetDateTime updated) { + if (created == null && updated == null) { + return; + } + final OffsetDateTime createdOn = Optional.ofNullable(created).orElse(OffsetDateTime.now(ZoneOffset.UTC)); + final OffsetDateTime updatedOn = Optional.ofNullable(updated).orElse(createdOn); + if (createdOn.isAfter(updatedOn)) { + throw new IllegalArgumentException("Updated cannot be before created."); + } + final ME entity = entities.getEntity(entityId); + entity.setCreatedOn(createdOn); + entity.setUpdatedOn(updatedOn); + } + @Override public void delete(@NonNull final K entityId) { if (!entities.containsName(entityId.id())) { @@ -124,7 +138,7 @@ protected Set keepNamesReadyForRemoval(final Set names) { .collect(Collectors.toSet()); } - protected void setManaged(@NonNull final V entityId, final boolean managed) { + protected void setManaged(final V entityId, final boolean managed) { entities.getEntity(entityId).setManaged(managed); } diff --git a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/service/key/KeyVaultFake.java b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/service/key/KeyVaultFake.java index e22145ca..f4b02943 100644 --- a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/service/key/KeyVaultFake.java +++ b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/service/key/KeyVaultFake.java @@ -6,20 +6,13 @@ import com.github.nagyesta.lowkeyvault.service.exception.CryptoException; import com.github.nagyesta.lowkeyvault.service.key.id.KeyEntityId; import com.github.nagyesta.lowkeyvault.service.key.id.VersionedKeyEntityId; -import com.github.nagyesta.lowkeyvault.service.key.impl.EcKeyCreationInput; -import com.github.nagyesta.lowkeyvault.service.key.impl.KeyCreationInput; -import com.github.nagyesta.lowkeyvault.service.key.impl.OctKeyCreationInput; -import com.github.nagyesta.lowkeyvault.service.key.impl.RsaKeyCreationInput; +import com.github.nagyesta.lowkeyvault.service.key.impl.*; -import java.time.OffsetDateTime; import java.util.List; public interface KeyVaultFake extends BaseVaultFake { - > VersionedKeyEntityId createKeyVersion(String keyName, T input); - - > VersionedKeyEntityId createKeyVersionForCertificate( - String keyName, T input, OffsetDateTime notBefore, OffsetDateTime expiry); + VersionedKeyEntityId createKeyVersion(String keyName, KeyCreateDetailedInput input); VersionedKeyEntityId createRsaKeyVersion(String keyName, RsaKeyCreationInput input); @@ -29,11 +22,9 @@ > VersionedKeyEntityId createKeyVersionForCerti void setKeyOperations(VersionedKeyEntityId keyEntityId, List keyOperations); - VersionedKeyEntityId importKeyVersion(String keyName, JsonWebKeyImportRequest key) throws CryptoException; - - VersionedKeyEntityId importManagedKeyVersion(String keyName, JsonWebKeyImportRequest key) throws CryptoException; + VersionedKeyEntityId importKeyVersion(String keyName, KeyImportInput key) throws CryptoException; - VersionedKeyEntityId importKeyVersion(VersionedKeyEntityId keyEntityId, JsonWebKeyImportRequest key) throws CryptoException; + VersionedKeyEntityId importKeyVersion(VersionedKeyEntityId keyEntityId, KeyImportInput key) throws CryptoException; VersionedKeyEntityId importEcKeyVersion(VersionedKeyEntityId keyEntityId, JsonWebKeyImportRequest key) throws CryptoException; diff --git a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/service/key/impl/KeyCreateDetailedInput.java b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/service/key/impl/KeyCreateDetailedInput.java new file mode 100644 index 00000000..de9ba71b --- /dev/null +++ b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/service/key/impl/KeyCreateDetailedInput.java @@ -0,0 +1,103 @@ +package com.github.nagyesta.lowkeyvault.service.key.impl; + + +import com.github.nagyesta.lowkeyvault.model.v7_2.key.constants.KeyOperation; +import lombok.Data; +import lombok.NonNull; +import lombok.ToString; +import org.springframework.util.Assert; + +import java.time.OffsetDateTime; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Objects; + +@SuppressWarnings("checkstyle:MagicNumber") +@Data +public class KeyCreateDetailedInput { + + private final KeyCreationInput key; + private final List keyOperations; + private final OffsetDateTime expiresOn; + private final OffsetDateTime notBefore; + private final Boolean enabled; + private final boolean hsm; + private final boolean managed; + private final Map tags; + + KeyCreateDetailedInput(final KeyCreateDetailedInputBuilder builder) { + Assert.notNull(builder.key, "Key parameters cannot be null!"); + this.key = builder.key; + this.keyOperations = List.copyOf(Objects.requireNonNullElse(builder.keyOperations, Collections.emptyList())); + this.expiresOn = builder.expiresOn; + this.notBefore = builder.notBefore; + this.enabled = builder.enabled; + this.hsm = builder.hsm; + this.managed = builder.managed; + this.tags = Map.copyOf(Objects.requireNonNullElse(builder.tags, Collections.emptyMap())); + } + + public static KeyCreateDetailedInputBuilder builder() { + return new KeyCreateDetailedInputBuilder(); + } + + @ToString + public static class KeyCreateDetailedInputBuilder { + private KeyCreationInput key; + private List keyOperations; + private OffsetDateTime expiresOn; + private OffsetDateTime notBefore; + private Boolean enabled; + private boolean hsm; + private boolean managed; + private Map tags; + + KeyCreateDetailedInputBuilder() { + } + + public KeyCreateDetailedInputBuilder key(@NonNull final KeyCreationInput key) { + this.key = key; + return this; + } + + public KeyCreateDetailedInputBuilder keyOperations(final List keyOperations) { + this.keyOperations = keyOperations; + return this; + } + + public KeyCreateDetailedInputBuilder expiresOn(final OffsetDateTime expiresOn) { + this.expiresOn = expiresOn; + return this; + } + + public KeyCreateDetailedInputBuilder notBefore(final OffsetDateTime notBefore) { + this.notBefore = notBefore; + return this; + } + + public KeyCreateDetailedInputBuilder enabled(final Boolean enabled) { + this.enabled = enabled; + return this; + } + + public KeyCreateDetailedInputBuilder hsm(final boolean hsm) { + this.hsm = hsm; + return this; + } + + public KeyCreateDetailedInputBuilder managed(final boolean managed) { + this.managed = managed; + return this; + } + + public KeyCreateDetailedInputBuilder tags(final Map tags) { + this.tags = Map.copyOf(Objects.requireNonNullElse(tags, Collections.emptyMap())); + return this; + } + + public KeyCreateDetailedInput build() { + return new KeyCreateDetailedInput(this); + } + } +} diff --git a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/service/key/impl/KeyImportInput.java b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/service/key/impl/KeyImportInput.java new file mode 100644 index 00000000..e3d96ca1 --- /dev/null +++ b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/service/key/impl/KeyImportInput.java @@ -0,0 +1,108 @@ +package com.github.nagyesta.lowkeyvault.service.key.impl; + + +import com.github.nagyesta.lowkeyvault.model.v7_2.key.request.JsonWebKeyImportRequest; +import lombok.Data; +import lombok.NonNull; +import lombok.ToString; + +import java.time.OffsetDateTime; +import java.util.Collections; +import java.util.Map; +import java.util.Objects; + +@SuppressWarnings("checkstyle:MagicNumber") +@Data +public class KeyImportInput { + + private final JsonWebKeyImportRequest key; + private final OffsetDateTime createdOn; + private final OffsetDateTime updatedOn; + private final OffsetDateTime expiresOn; + private final OffsetDateTime notBefore; + private final Boolean enabled; + private final Boolean hsm; + private final boolean managed; + private final Map tags; + + KeyImportInput(final KeyImportInputBuilder builder) { + this.key = builder.key; + this.createdOn = builder.createdOn; + this.updatedOn = builder.updatedOn; + this.expiresOn = builder.expiresOn; + this.notBefore = builder.notBefore; + this.enabled = builder.enabled; + this.hsm = builder.hsm; + this.managed = builder.managed; + this.tags = Map.copyOf(Objects.requireNonNullElse(builder.tags, Collections.emptyMap())); + } + + public static KeyImportInputBuilder builder() { + return new KeyImportInputBuilder(); + } + + @ToString + public static class KeyImportInputBuilder { + private JsonWebKeyImportRequest key; + private OffsetDateTime createdOn; + private OffsetDateTime updatedOn; + private OffsetDateTime expiresOn; + private OffsetDateTime notBefore; + private Boolean enabled; + private Boolean hsm; + private boolean managed; + private Map tags; + + KeyImportInputBuilder() { + } + + public KeyImportInputBuilder key(@NonNull final JsonWebKeyImportRequest key) { + this.key = key; + return this; + } + + public KeyImportInputBuilder createdOn(final OffsetDateTime createdOn) { + this.createdOn = createdOn; + return this; + } + + public KeyImportInputBuilder updatedOn(final OffsetDateTime updatedOn) { + this.updatedOn = updatedOn; + return this; + } + + public KeyImportInputBuilder expiresOn(final OffsetDateTime expiresOn) { + this.expiresOn = expiresOn; + return this; + } + + public KeyImportInputBuilder notBefore(final OffsetDateTime notBefore) { + this.notBefore = notBefore; + return this; + } + + public KeyImportInputBuilder enabled(final Boolean enabled) { + this.enabled = enabled; + return this; + } + + public KeyImportInputBuilder hsm(final Boolean hsm) { + this.hsm = hsm; + return this; + } + + public KeyImportInputBuilder managed(final boolean managed) { + this.managed = managed; + return this; + } + + public KeyImportInputBuilder tags(final Map tags) { + this.tags = Map.copyOf(Objects.requireNonNullElse(tags, Collections.emptyMap())); + return this; + } + + public KeyImportInput build() { + return new KeyImportInput(this); + } + } +} diff --git a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/service/key/impl/KeyVaultFakeImpl.java b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/service/key/impl/KeyVaultFakeImpl.java index 4925b927..c274c36e 100644 --- a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/service/key/impl/KeyVaultFakeImpl.java +++ b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/service/key/impl/KeyVaultFakeImpl.java @@ -36,7 +36,6 @@ public class KeyVaultFakeImpl private final RsaJsonWebKeyImportRequestConverter rsaConverter = new RsaJsonWebKeyImportRequestConverter(); private final EcJsonWebKeyImportRequestConverter ecConverter = new EcJsonWebKeyImportRequestConverter(); private final AesJsonWebKeyImportRequestConverter aesConverter = new AesJsonWebKeyImportRequestConverter(); - private final ConcurrentMap rotationPolicies = new ConcurrentHashMap<>(); public KeyVaultFakeImpl(@org.springframework.lang.NonNull final VaultFake vaultFake, @@ -51,49 +50,42 @@ protected VersionedKeyEntityId createVersionedId(final String id, final String v } @Override - public > VersionedKeyEntityId createKeyVersion( - @NonNull final String keyName, @NonNull final T input) { - return input.getKeyType().createKey(this, keyName, input); - } - - @Override - public > VersionedKeyEntityId createKeyVersionForCertificate( - @NonNull final String keyName, - @NonNull final T input, - @NonNull final OffsetDateTime notBefore, - @NonNull final OffsetDateTime expiry) { - final VersionedKeyEntityId entityId = this.createKeyVersion(keyName, input); - this.setKeyOperations(entityId, List.of( - KeyOperation.SIGN, KeyOperation.VERIFY, - KeyOperation.ENCRYPT, KeyOperation.DECRYPT, - KeyOperation.WRAP_KEY, KeyOperation.UNWRAP_KEY)); - this.setEnabled(entityId, true); - this.setExpiry(entityId, notBefore, expiry); - this.setManaged(entityId, true); - return entityId; + public VersionedKeyEntityId createKeyVersion(@NonNull final String keyName, @NonNull final KeyCreateDetailedInput input) { + Assert.isTrue(!input.isManaged() || (input.getExpiresOn() != null && input.getNotBefore() != null), + "Managed key (name=" + keyName + ") must have notBefore and expiresOn parameters set!"); + final VersionedKeyEntityId keyEntityId = input.getKey().getKeyType().createKey(this, keyName, input.getKey()); + setKeyOperations(keyEntityId, input.getKeyOperations()); + //avoid overwriting expiry if it was generated by the rotation policy + if (getEntities().getReadOnlyEntity(keyEntityId).getExpiry().isEmpty()) { + setExpiry(keyEntityId, input.getNotBefore(), input.getExpiresOn()); + } + setEnabled(keyEntityId, Objects.requireNonNullElse(input.getEnabled(), true)); + setManaged(keyEntityId, input.isManaged()); + addTags(keyEntityId, input.getTags()); + return keyEntityId; } @Override - public VersionedKeyEntityId importKeyVersion( - final String keyName, final JsonWebKeyImportRequest key) { + public VersionedKeyEntityId importKeyVersion(final String keyName, final KeyImportInput input) { final VersionedKeyEntityId keyEntityId = new VersionedKeyEntityId(vaultFake().baseUri(), keyName); - return importKeyVersion(keyEntityId, key); + return importKeyVersion(keyEntityId, input); } @Override - public VersionedKeyEntityId importManagedKeyVersion(final String keyName, final JsonWebKeyImportRequest key) { - final VersionedKeyEntityId keyEntityId = importKeyVersion(keyName, key); - this.setManaged(keyEntityId, true); + public VersionedKeyEntityId importKeyVersion(final VersionedKeyEntityId keyEntityId, final KeyImportInput input) { + Assert.isTrue(input.getHsm() == null || input.getHsm() == input.getKey().getKeyType().isHsm(), + "When HSM property is set in request, key type must match it."); + final KeyType keyType = Objects.requireNonNull(input.getKey()).getKeyType(); + keyType.importKey(this, keyEntityId, input.getKey()); + setKeyOperations(keyEntityId, input.getKey().getKeyOps()); + addTags(keyEntityId, input.getTags()); + setExpiry(keyEntityId, input.getNotBefore(), input.getExpiresOn()); + setEnabled(keyEntityId, Objects.requireNonNullElse(input.getEnabled(), true)); + setManaged(keyEntityId, input.isManaged()); + setCreatedAndUpdatedOn(keyEntityId, input.getCreatedOn(), input.getUpdatedOn()); return keyEntityId; } - @Override - public VersionedKeyEntityId importKeyVersion( - final VersionedKeyEntityId keyEntityId, final JsonWebKeyImportRequest key) { - final KeyType keyType = Objects.requireNonNull(key).getKeyType(); - return keyType.importKey(this, keyEntityId, key); - } - @Override public VersionedKeyEntityId importRsaKeyVersion( final VersionedKeyEntityId keyEntityId, final JsonWebKeyImportRequest key) { @@ -188,6 +180,7 @@ public RotationPolicy rotationPolicy(@NonNull final KeyEntityId keyEntityId) { @Override public void setRotationPolicy(@NonNull final RotationPolicy rotationPolicy) { final ReadOnlyKeyVaultKeyEntity readOnlyEntity = latestReadOnlyKeyVersion(rotationPolicy.getId()); + Assert.state(!readOnlyEntity.isManaged(), "Cannot set rotation policy to managed entity: " + rotationPolicy.getId()); rotationPolicy.validate(readOnlyEntity.getExpiry().orElse(null)); final RotationPolicy existingPolicy = rotationPolicy(rotationPolicy.getId()); if (existingPolicy == null) { @@ -201,12 +194,15 @@ public void setRotationPolicy(@NonNull final RotationPolicy rotationPolicy) { @Override public VersionedKeyEntityId rotateKey(@NonNull final KeyEntityId keyEntityId) { final ReadOnlyKeyVaultKeyEntity readOnlyEntity = latestReadOnlyKeyVersion(keyEntityId); - final VersionedKeyEntityId rotatedKeyId = createKeyVersion(keyEntityId.id(), readOnlyEntity.keyCreationInput()); - final KeyVaultKeyEntity rotatedEntity = getEntities().getEntity(rotatedKeyId, KeyVaultKeyEntity.class); - rotatedEntity.setOperations(readOnlyEntity.getOperations()); - rotatedEntity.setEnabled(true); - rotatedEntity.setTags(readOnlyEntity.getTags()); - return rotatedKeyId; + return createKeyVersion(keyEntityId.id(), KeyCreateDetailedInput.builder() + .key(readOnlyEntity.keyCreationInput()) + .keyOperations(readOnlyEntity.getOperations()) + .enabled(true) + //never rotate managed entities + .managed(false) + .tags(readOnlyEntity.getTags()) + //expiry will be automatically set based on rotation policy when created + .build()); } private void setExpiryBasedOnRotationPolicy(final VersionedKeyEntityId keyEntityId, final KeyVaultKeyEntity keyEntity) { diff --git a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/service/secret/ReadOnlyKeyVaultSecretEntity.java b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/service/secret/ReadOnlyKeyVaultSecretEntity.java index 5a61dca5..d8a26d73 100644 --- a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/service/secret/ReadOnlyKeyVaultSecretEntity.java +++ b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/service/secret/ReadOnlyKeyVaultSecretEntity.java @@ -1,11 +1,10 @@ package com.github.nagyesta.lowkeyvault.service.secret; import com.github.nagyesta.lowkeyvault.service.common.BaseVaultEntity; -import com.github.nagyesta.lowkeyvault.service.key.ReadOnlyDeletedEntity; import com.github.nagyesta.lowkeyvault.service.secret.id.VersionedSecretEntityId; public interface ReadOnlyKeyVaultSecretEntity - extends BaseVaultEntity, ReadOnlyDeletedEntity { + extends BaseVaultEntity { String getValue(); diff --git a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/service/secret/SecretVaultFake.java b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/service/secret/SecretVaultFake.java index 969f190c..2b64275e 100644 --- a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/service/secret/SecretVaultFake.java +++ b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/service/secret/SecretVaultFake.java @@ -1,18 +1,14 @@ package com.github.nagyesta.lowkeyvault.service.secret; -import com.github.nagyesta.lowkeyvault.service.certificate.impl.CertContentType; import com.github.nagyesta.lowkeyvault.service.common.BaseVaultFake; import com.github.nagyesta.lowkeyvault.service.secret.id.SecretEntityId; import com.github.nagyesta.lowkeyvault.service.secret.id.VersionedSecretEntityId; - -import java.time.OffsetDateTime; +import com.github.nagyesta.lowkeyvault.service.secret.impl.SecretCreateInput; public interface SecretVaultFake extends BaseVaultFake { - VersionedSecretEntityId createSecretVersion(String secretName, String value, String contentType); + VersionedSecretEntityId createSecretVersion(String secretName, SecretCreateInput input); - VersionedSecretEntityId createSecretVersion(VersionedSecretEntityId entityId, String value, String contentType); + VersionedSecretEntityId createSecretVersion(VersionedSecretEntityId entityId, SecretCreateInput input); - VersionedSecretEntityId createSecretVersionForCertificate( - VersionedSecretEntityId id, String value, CertContentType contentType, OffsetDateTime notBefore, OffsetDateTime expiry); } diff --git a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/service/secret/impl/SecretCreateInput.java b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/service/secret/impl/SecretCreateInput.java new file mode 100644 index 00000000..ae49fa8b --- /dev/null +++ b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/service/secret/impl/SecretCreateInput.java @@ -0,0 +1,109 @@ +package com.github.nagyesta.lowkeyvault.service.secret.impl; + + +import lombok.Data; +import lombok.NonNull; +import lombok.ToString; +import org.springframework.util.Assert; + +import java.time.OffsetDateTime; +import java.util.Collections; +import java.util.Map; +import java.util.Objects; + +@SuppressWarnings("checkstyle:MagicNumber") +@Data +public class SecretCreateInput { + + private final String value; + private final String contentType; + private final OffsetDateTime createdOn; + private final OffsetDateTime updatedOn; + private final OffsetDateTime expiresOn; + private final OffsetDateTime notBefore; + private final boolean enabled; + private final boolean managed; + private final Map tags; + + SecretCreateInput(final SecretCreateInputBuilder builder) { + Assert.notNull(builder.value, "Secret value cannot be null!"); + this.value = builder.value; + this.contentType = builder.contentType; + this.createdOn = builder.createdOn; + this.updatedOn = builder.updatedOn; + this.expiresOn = builder.expiresOn; + this.notBefore = builder.notBefore; + this.enabled = builder.enabled; + this.managed = builder.managed; + this.tags = Map.copyOf(Objects.requireNonNullElse(builder.tags, Collections.emptyMap())); + } + + public static SecretCreateInputBuilder builder() { + return new SecretCreateInputBuilder(); + } + + @ToString + public static class SecretCreateInputBuilder { + private String value; + private String contentType; + private OffsetDateTime createdOn; + private OffsetDateTime updatedOn; + private OffsetDateTime expiresOn; + private OffsetDateTime notBefore; + private boolean enabled; + private boolean managed; + private Map tags; + + SecretCreateInputBuilder() { + } + + public SecretCreateInputBuilder value(@NonNull final String value) { + this.value = value; + return this; + } + + public SecretCreateInputBuilder contentType(final String contentType) { + this.contentType = contentType; + return this; + } + + public SecretCreateInputBuilder createdOn(final OffsetDateTime createdOn) { + this.createdOn = createdOn; + return this; + } + + public SecretCreateInputBuilder updatedOn(final OffsetDateTime updatedOn) { + this.updatedOn = updatedOn; + return this; + } + + public SecretCreateInputBuilder expiresOn(final OffsetDateTime expiresOn) { + this.expiresOn = expiresOn; + return this; + } + + public SecretCreateInputBuilder notBefore(final OffsetDateTime notBefore) { + this.notBefore = notBefore; + return this; + } + + public SecretCreateInputBuilder enabled(final boolean enabled) { + this.enabled = enabled; + return this; + } + + public SecretCreateInputBuilder managed(final boolean managed) { + this.managed = managed; + return this; + } + + public SecretCreateInputBuilder tags(final Map tags) { + this.tags = Map.copyOf(Objects.requireNonNullElse(tags, Collections.emptyMap())); + return this; + } + + public SecretCreateInput build() { + return new SecretCreateInput(this); + } + } +} diff --git a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/service/secret/impl/SecretVaultFakeImpl.java b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/service/secret/impl/SecretVaultFakeImpl.java index e9dacead..71719bf0 100644 --- a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/service/secret/impl/SecretVaultFakeImpl.java +++ b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/service/secret/impl/SecretVaultFakeImpl.java @@ -1,7 +1,6 @@ package com.github.nagyesta.lowkeyvault.service.secret.impl; import com.github.nagyesta.lowkeyvault.model.v7_2.common.constants.RecoveryLevel; -import com.github.nagyesta.lowkeyvault.service.certificate.impl.CertContentType; import com.github.nagyesta.lowkeyvault.service.common.impl.BaseVaultFakeImpl; import com.github.nagyesta.lowkeyvault.service.secret.ReadOnlyKeyVaultSecretEntity; import com.github.nagyesta.lowkeyvault.service.secret.SecretVaultFake; @@ -9,8 +8,7 @@ import com.github.nagyesta.lowkeyvault.service.secret.id.VersionedSecretEntityId; import com.github.nagyesta.lowkeyvault.service.vault.VaultFake; import lombok.NonNull; - -import java.time.OffsetDateTime; +import org.springframework.util.Assert; public class SecretVaultFakeImpl extends BaseVaultFakeImpl @@ -29,32 +27,25 @@ protected VersionedSecretEntityId createVersionedId(final String id, final Strin @Override public VersionedSecretEntityId createSecretVersion( - @NonNull final String secretName, @NonNull final String value, final String contentType) { + @NonNull final String secretName, final SecretCreateInput input) { final VersionedSecretEntityId entityId = new VersionedSecretEntityId(vaultFake().baseUri(), secretName); - return createSecretVersion(entityId, value, contentType); + return createSecretVersion(entityId, input); } @Override public VersionedSecretEntityId createSecretVersion( - @NonNull final VersionedSecretEntityId entityId, @NonNull final String value, final String contentType) { - final KeyVaultSecretEntity secretEntity = new KeyVaultSecretEntity(entityId, vaultFake(), value, contentType); - return addVersion(entityId, secretEntity); - } - - @Override - public VersionedSecretEntityId createSecretVersionForCertificate( - @NonNull final VersionedSecretEntityId id, - @NonNull final String value, - @NonNull final CertContentType contentType, - @NonNull final OffsetDateTime notBefore, - @NonNull final OffsetDateTime expiry) { - final VersionedSecretEntityId secretEntityId = createSecretVersion(id, value, contentType.getMimeType()); - setExpiry(secretEntityId, notBefore, expiry); - setManaged(secretEntityId, true); - setEnabled(secretEntityId, true); - final KeyVaultSecretEntity secretEntity = getEntities().getEntity(secretEntityId, KeyVaultSecretEntity.class); - secretEntity.setCreatedOn(notBefore); - secretEntity.setUpdatedOn(notBefore); + @NonNull final VersionedSecretEntityId entityId, @NonNull final SecretCreateInput input) { + Assert.isTrue(!input.isManaged() || (input.getExpiresOn() != null && input.getNotBefore() != null), + "Managed secret (name=" + entityId.id() + ") must have notBefore and expiresOn parameters set!"); + Assert.isTrue(!input.isManaged() || input.getContentType() != null, + "Managed secret (name=" + entityId.id() + ") must have the content type parameter set!"); + final KeyVaultSecretEntity secretEntity = new KeyVaultSecretEntity(entityId, vaultFake(), input.getValue(), input.getContentType()); + final VersionedSecretEntityId secretEntityId = addVersion(entityId, secretEntity); + addTags(secretEntityId, input.getTags()); + setExpiry(secretEntityId, input.getNotBefore(), input.getExpiresOn()); + setEnabled(secretEntityId, input.isEnabled()); + setManaged(secretEntityId, input.isManaged()); + setCreatedAndUpdatedOn(secretEntityId, input.getCreatedOn(), input.getUpdatedOn()); return secretEntityId; } } diff --git a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/template/backup/VaultImporter.java b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/template/backup/VaultImporter.java index 038c1a68..9b1b0795 100644 --- a/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/template/backup/VaultImporter.java +++ b/lowkey-vault-app/src/main/java/com/github/nagyesta/lowkeyvault/template/backup/VaultImporter.java @@ -2,13 +2,13 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.github.jknack.handlebars.internal.Files; +import com.github.nagyesta.lowkeyvault.model.common.backup.KeyBackupList; +import com.github.nagyesta.lowkeyvault.model.common.backup.KeyBackupModel; +import com.github.nagyesta.lowkeyvault.model.common.backup.SecretBackupList; +import com.github.nagyesta.lowkeyvault.model.common.backup.SecretBackupModel; import com.github.nagyesta.lowkeyvault.model.management.VaultBackupListModel; import com.github.nagyesta.lowkeyvault.model.management.VaultBackupModel; import com.github.nagyesta.lowkeyvault.model.management.VaultModel; -import com.github.nagyesta.lowkeyvault.model.v7_2.secret.SecretBackupList; -import com.github.nagyesta.lowkeyvault.model.v7_2.secret.SecretBackupModel; -import com.github.nagyesta.lowkeyvault.model.v7_3.key.KeyBackupList; -import com.github.nagyesta.lowkeyvault.model.v7_3.key.KeyBackupModel; import lombok.NonNull; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.InitializingBean; diff --git a/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/controller/VaultBackupConfiguration.java b/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/controller/VaultBackupConfiguration.java index c0990056..a545c0b6 100644 --- a/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/controller/VaultBackupConfiguration.java +++ b/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/controller/VaultBackupConfiguration.java @@ -4,15 +4,17 @@ import com.github.nagyesta.lowkeyvault.controller.v7_3.KeyBackupRestoreController; import com.github.nagyesta.lowkeyvault.controller.v7_3.SecretBackupRestoreController; import com.github.nagyesta.lowkeyvault.mapper.common.VaultFakeToVaultModelConverter; +import com.github.nagyesta.lowkeyvault.mapper.common.registry.KeyConverterRegistry; +import com.github.nagyesta.lowkeyvault.mapper.common.registry.SecretConverterRegistry; import com.github.nagyesta.lowkeyvault.mapper.v7_2.key.KeyEntityToV72BackupConverter; import com.github.nagyesta.lowkeyvault.mapper.v7_2.key.KeyEntityToV72ModelConverter; import com.github.nagyesta.lowkeyvault.mapper.v7_2.key.KeyEntityToV72PropertiesModelConverter; +import com.github.nagyesta.lowkeyvault.mapper.v7_2.secret.SecretEntityToV72BackupConverter; import com.github.nagyesta.lowkeyvault.mapper.v7_2.secret.SecretEntityToV72ModelConverter; import com.github.nagyesta.lowkeyvault.mapper.v7_2.secret.SecretEntityToV72PropertiesModelConverter; import com.github.nagyesta.lowkeyvault.mapper.v7_3.key.KeyRotationPolicyToV73ModelConverter; import com.github.nagyesta.lowkeyvault.mapper.v7_3.key.KeyRotationPolicyV73ModelToEntityConverter; import com.github.nagyesta.lowkeyvault.model.v7_2.key.validator.ImportKeyValidator; -import com.github.nagyesta.lowkeyvault.model.v7_2.secret.SecretEntityToV72BackupConverter; import com.github.nagyesta.lowkeyvault.service.vault.VaultService; import com.github.nagyesta.lowkeyvault.service.vault.impl.VaultServiceImpl; import com.github.nagyesta.lowkeyvault.template.backup.BackupTemplateProcessor; @@ -35,53 +37,62 @@ public class VaultBackupConfiguration { @Bean public SecretBackupRestoreController secretBackupRestoreController() { - return new SecretBackupRestoreController(secretEntityToV72ModelConverter(), secretEntityToV72BackupConverter(), vaultService()); + return new SecretBackupRestoreController(secretConverterRegistry(), vaultService()); } @Bean public SecretEntityToV72ModelConverter secretEntityToV72ModelConverter() { - return new SecretEntityToV72ModelConverter(secretEntityToV72PropertiesModelConverter()); + return new SecretEntityToV72ModelConverter(secretConverterRegistry()); } @Bean public SecretEntityToV72BackupConverter secretEntityToV72BackupConverter() { - return new SecretEntityToV72BackupConverter(secretEntityToV72PropertiesModelConverter()); + return new SecretEntityToV72BackupConverter(secretConverterRegistry()); } @Bean public SecretEntityToV72PropertiesModelConverter secretEntityToV72PropertiesModelConverter() { - return new SecretEntityToV72PropertiesModelConverter(); + return new SecretEntityToV72PropertiesModelConverter(secretConverterRegistry()); + } + + @Bean + public SecretConverterRegistry secretConverterRegistry() { + return new SecretConverterRegistry(); + } + + @Bean + public KeyConverterRegistry keyConverterRegistry() { + return new KeyConverterRegistry(); } @Bean public KeyBackupRestoreController keyBackupRestoreController() { - return new KeyBackupRestoreController(keyEntityToV72ModelConverter(), keyEntityToV72BackupConverter(), vaultService(), - keyRotationPolicyToV73ModelConverter(), keyRotationPolicyV73ModelToEntityConverter()); + return new KeyBackupRestoreController(keyConverterRegistry(), vaultService()); } @Bean public KeyEntityToV72ModelConverter keyEntityToV72ModelConverter() { - return new KeyEntityToV72ModelConverter(keyEntityToV72PropertiesModelConverter()); + return new KeyEntityToV72ModelConverter(keyConverterRegistry()); } @Bean public KeyEntityToV72PropertiesModelConverter keyEntityToV72PropertiesModelConverter() { - return new KeyEntityToV72PropertiesModelConverter(); + return new KeyEntityToV72PropertiesModelConverter(keyConverterRegistry()); } @Bean public KeyEntityToV72BackupConverter keyEntityToV72BackupConverter() { - return new KeyEntityToV72BackupConverter(keyEntityToV72PropertiesModelConverter()); + return new KeyEntityToV72BackupConverter(keyConverterRegistry()); } @Bean public KeyRotationPolicyToV73ModelConverter keyRotationPolicyToV73ModelConverter() { - return new KeyRotationPolicyToV73ModelConverter(); + return new KeyRotationPolicyToV73ModelConverter(keyConverterRegistry()); } @Bean public KeyRotationPolicyV73ModelToEntityConverter keyRotationPolicyV73ModelToEntityConverter() { - return new KeyRotationPolicyV73ModelToEntityConverter(); + return new KeyRotationPolicyV73ModelToEntityConverter(keyConverterRegistry()); } @Bean diff --git a/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/controller/VaultBackupManagementControllerIntegrationTest.java b/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/controller/VaultBackupManagementControllerIntegrationTest.java index fa125578..08fed312 100644 --- a/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/controller/VaultBackupManagementControllerIntegrationTest.java +++ b/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/controller/VaultBackupManagementControllerIntegrationTest.java @@ -3,11 +3,11 @@ import com.github.nagyesta.abortmission.booster.jupiter.annotation.LaunchAbortArmed; import com.github.nagyesta.lowkeyvault.controller.v7_3.KeyBackupRestoreController; import com.github.nagyesta.lowkeyvault.controller.v7_3.SecretBackupRestoreController; +import com.github.nagyesta.lowkeyvault.model.common.backup.KeyBackupListItem; +import com.github.nagyesta.lowkeyvault.model.common.backup.SecretBackupListItem; import com.github.nagyesta.lowkeyvault.model.management.VaultBackupListModel; import com.github.nagyesta.lowkeyvault.model.management.VaultBackupModel; -import com.github.nagyesta.lowkeyvault.model.v7_2.key.KeyBackupListItem; import com.github.nagyesta.lowkeyvault.model.v7_2.key.constants.KeyCurveName; -import com.github.nagyesta.lowkeyvault.model.v7_2.secret.SecretBackupListItem; import com.github.nagyesta.lowkeyvault.service.key.KeyVaultFake; import com.github.nagyesta.lowkeyvault.service.key.ReadOnlyKeyVaultKeyEntity; import com.github.nagyesta.lowkeyvault.service.key.id.VersionedKeyEntityId; diff --git a/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/controller/v7_2/KeyBackupRestoreControllerIntegrationTest.java b/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/controller/v7_2/KeyBackupRestoreControllerIntegrationTest.java index 8c757f48..3b27b552 100644 --- a/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/controller/v7_2/KeyBackupRestoreControllerIntegrationTest.java +++ b/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/controller/v7_2/KeyBackupRestoreControllerIntegrationTest.java @@ -2,10 +2,13 @@ import com.github.nagyesta.abortmission.booster.jupiter.annotation.LaunchAbortArmed; import com.github.nagyesta.lowkeyvault.TestConstantsUri; -import com.github.nagyesta.lowkeyvault.mapper.v7_2.key.KeyEntityToV72BackupConverter; -import com.github.nagyesta.lowkeyvault.mapper.v7_2.key.KeyEntityToV72ModelConverter; +import com.github.nagyesta.lowkeyvault.mapper.common.registry.KeyConverterRegistry; +import com.github.nagyesta.lowkeyvault.model.common.backup.KeyBackupList; +import com.github.nagyesta.lowkeyvault.model.common.backup.KeyBackupListItem; +import com.github.nagyesta.lowkeyvault.model.common.backup.KeyBackupModel; import com.github.nagyesta.lowkeyvault.model.v7_2.common.constants.RecoveryLevel; -import com.github.nagyesta.lowkeyvault.model.v7_2.key.*; +import com.github.nagyesta.lowkeyvault.model.v7_2.key.KeyPropertiesModel; +import com.github.nagyesta.lowkeyvault.model.v7_2.key.KeyVaultKeyModel; import com.github.nagyesta.lowkeyvault.model.v7_2.key.constants.KeyCurveName; import com.github.nagyesta.lowkeyvault.model.v7_2.key.constants.KeyOperation; import com.github.nagyesta.lowkeyvault.model.v7_2.key.constants.KeyType; @@ -14,6 +17,7 @@ import com.github.nagyesta.lowkeyvault.service.key.KeyVaultFake; import com.github.nagyesta.lowkeyvault.service.key.id.VersionedKeyEntityId; import com.github.nagyesta.lowkeyvault.service.key.impl.EcKeyCreationInput; +import com.github.nagyesta.lowkeyvault.service.key.impl.KeyCreateDetailedInput; import com.github.nagyesta.lowkeyvault.service.key.util.KeyGenUtil; import com.github.nagyesta.lowkeyvault.service.vault.VaultService; import org.junit.jupiter.api.AfterEach; @@ -56,13 +60,9 @@ class KeyBackupRestoreControllerIntegrationTest { public static Stream nullProvider() { return Stream.builder() - .add(Arguments.of(null, null, null)) - .add(Arguments.of(mock(KeyEntityToV72ModelConverter.class), null, null)) - .add(Arguments.of(null, mock(KeyEntityToV72BackupConverter.class), null)) - .add(Arguments.of(null, null, mock(VaultService.class))) - .add(Arguments.of(null, mock(KeyEntityToV72BackupConverter.class), null)) - .add(Arguments.of(mock(KeyEntityToV72ModelConverter.class), null, mock(VaultService.class))) - .add(Arguments.of(mock(KeyEntityToV72ModelConverter.class), mock(KeyEntityToV72BackupConverter.class), null)) + .add(Arguments.of(null, null)) + .add(Arguments.of(mock(KeyConverterRegistry.class), null)) + .add(Arguments.of(null, mock(VaultService.class))) .build(); } @@ -82,14 +82,13 @@ void tearDown() { @ParameterizedTest @MethodSource("nullProvider") void testConstructorShouldThrowExceptionWhenCalledWithNulls( - final KeyEntityToV72ModelConverter modelConverter, - final KeyEntityToV72BackupConverter backupConverter, + final KeyConverterRegistry registry, final VaultService vaultService) { //given //when Assertions.assertThrows(IllegalArgumentException.class, - () -> new KeyBackupRestoreController(modelConverter, backupConverter, vaultService)); + () -> new KeyBackupRestoreController(registry, vaultService)); //then + exception } @@ -181,7 +180,9 @@ void testRestoreEntityShouldThrowExceptionWhenNameMatchesActiveKey() { addVersionToList(uri, KEY_NAME_1, KEY_VERSION_1, backupModel, TAGS_EMPTY); addVersionToList(uri, KEY_NAME_1, KEY_VERSION_2, backupModel, TAGS_ONE_KEY); vaultService.findByUri(uri).keyVaultFake() - .createKeyVersion(KEY_NAME_1, new EcKeyCreationInput(KeyType.EC, KeyCurveName.P_256)); + .createKeyVersion(KEY_NAME_1, KeyCreateDetailedInput.builder() + .key(new EcKeyCreationInput(KeyType.EC, KeyCurveName.P_256)) + .build()); //when Assertions.assertThrows(IllegalArgumentException.class, () -> underTest.restore(uri, backupModel)); @@ -198,7 +199,9 @@ void testRestoreEntityShouldThrowExceptionWhenNameMatchesDeletedKey() { addVersionToList(uri, KEY_NAME_1, KEY_VERSION_2, backupModel, TAGS_ONE_KEY); final KeyVaultFake vaultFake = vaultService.findByUri(uri).keyVaultFake(); final VersionedKeyEntityId keyVersion = vaultFake - .createKeyVersion(KEY_NAME_1, new EcKeyCreationInput(KeyType.EC, KeyCurveName.P_256)); + .createKeyVersion(KEY_NAME_1, KeyCreateDetailedInput.builder() + .key(new EcKeyCreationInput(KeyType.EC, KeyCurveName.P_256)) + .build()); vaultFake.delete(keyVersion); //when diff --git a/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/controller/v7_2/KeyControllerTest.java b/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/controller/v7_2/KeyControllerTest.java index edc9d152..cf8abd27 100644 --- a/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/controller/v7_2/KeyControllerTest.java +++ b/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/controller/v7_2/KeyControllerTest.java @@ -1,8 +1,10 @@ package com.github.nagyesta.lowkeyvault.controller.v7_2; +import com.github.nagyesta.lowkeyvault.mapper.common.registry.KeyConverterRegistry; import com.github.nagyesta.lowkeyvault.mapper.v7_2.key.KeyEntityToV72KeyItemModelConverter; import com.github.nagyesta.lowkeyvault.mapper.v7_2.key.KeyEntityToV72KeyVersionItemModelConverter; import com.github.nagyesta.lowkeyvault.mapper.v7_2.key.KeyEntityToV72ModelConverter; +import com.github.nagyesta.lowkeyvault.model.common.ApiConstants; import com.github.nagyesta.lowkeyvault.model.common.ErrorMessage; import com.github.nagyesta.lowkeyvault.model.common.ErrorModel; import com.github.nagyesta.lowkeyvault.model.common.KeyVaultItemListModel; @@ -21,6 +23,7 @@ import com.github.nagyesta.lowkeyvault.service.key.ReadOnlyKeyVaultKeyEntity; import com.github.nagyesta.lowkeyvault.service.key.id.KeyEntityId; import com.github.nagyesta.lowkeyvault.service.key.id.VersionedKeyEntityId; +import com.github.nagyesta.lowkeyvault.service.key.impl.KeyCreateDetailedInput; import com.github.nagyesta.lowkeyvault.service.key.impl.KeyVaultKeyEntity; import com.github.nagyesta.lowkeyvault.service.key.impl.RsaKeyVaultKeyEntity; import com.github.nagyesta.lowkeyvault.service.vault.VaultFake; @@ -71,6 +74,8 @@ class KeyControllerTest { @Mock private KeyVaultFake keyVaultFake; @Mock + private KeyConverterRegistry registry; + @Mock private ReadOnlyVersionedEntityMultiMap entities; @Mock private ReadOnlyVersionedEntityMultiMap deletedEntities; @@ -123,19 +128,10 @@ public static Stream keyAttributeProvider() { } public static Stream nullProvider() { - final KeyEntityToV72ModelConverter ec = mock(KeyEntityToV72ModelConverter.class); - final KeyEntityToV72KeyItemModelConverter ic = mock(KeyEntityToV72KeyItemModelConverter.class); - final KeyEntityToV72KeyVersionItemModelConverter vic = mock(KeyEntityToV72KeyVersionItemModelConverter.class); return Stream.builder() - .add(Arguments.of(null, null, null, null)) - .add(Arguments.of(ec, null, null, null)) - .add(Arguments.of(null, ic, null, null)) - .add(Arguments.of(null, null, vic, null)) - .add(Arguments.of(null, null, null, mock(VaultService.class))) - .add(Arguments.of(null, ic, vic, mock(VaultService.class))) - .add(Arguments.of(ec, null, vic, mock(VaultService.class))) - .add(Arguments.of(ec, ic, null, mock(VaultService.class))) - .add(Arguments.of(ec, ic, vic, null)) + .add(Arguments.of(null, null)) + .add(Arguments.of(mock(KeyConverterRegistry.class), null)) + .add(Arguments.of(null, mock(VaultService.class))) .build(); } @@ -170,8 +166,12 @@ public static Stream exceptionProvider() { @BeforeEach void setUp() { openMocks = MockitoAnnotations.openMocks(this); - underTest = new KeyController(keyEntityToV72ModelConverter, keyEntityToV72KeyItemModelConverter, - keyEntityToV72KeyVersionItemModelConverter, vaultService); + when(registry.modelConverter(eq(ApiConstants.V_7_2))).thenReturn(keyEntityToV72ModelConverter); + when(registry.itemConverter(eq(ApiConstants.V_7_2))).thenReturn(keyEntityToV72KeyItemModelConverter); + when(registry.versionedItemConverter(eq(ApiConstants.V_7_2))).thenReturn(keyEntityToV72KeyVersionItemModelConverter); + when(registry.versionedEntityId(any(URI.class), anyString(), anyString())).thenCallRealMethod(); + when(registry.entityId(any(URI.class), anyString())).thenCallRealMethod(); + underTest = new KeyController(registry, vaultService); when(vaultService.findByUri(eq(HTTPS_LOCALHOST_8443))).thenReturn(vaultFake); when(vaultFake.baseUri()).thenReturn(HTTPS_LOCALHOST_8443); when(vaultFake.keyVaultFake()).thenReturn(keyVaultFake); @@ -232,16 +232,13 @@ void testErrorHandlerConvertsIllegalArgumentExceptionWhenCaught() { @ParameterizedTest @MethodSource("nullProvider") void testConstructorShouldThrowExceptionWhenCalledWithNull( - final KeyEntityToV72ModelConverter keyEntityToV72ModelConverter, - final KeyEntityToV72KeyItemModelConverter keyEntityToV72KeyItemModelConverter, - final KeyEntityToV72KeyVersionItemModelConverter keyEntityToV72KeyVersionItemModelConverter, + final KeyConverterRegistry registry, final VaultService vaultService) { //given //when Assertions.assertThrows(IllegalArgumentException.class, - () -> new KeyController(keyEntityToV72ModelConverter, keyEntityToV72KeyItemModelConverter, - keyEntityToV72KeyVersionItemModelConverter, vaultService)); + () -> new KeyController(registry, vaultService)); //then + exception } @@ -256,7 +253,7 @@ void testCreateShouldUseInputParametersWhenCalled( when(vaultFake.getRecoverableDays()).thenReturn(null); final CreateKeyRequest request = createRequest(operations, expiry, notBefore); final ReadOnlyKeyVaultKeyEntity entity = createEntity(VERSIONED_KEY_ENTITY_ID_1_VERSION_1, request); - when(keyVaultFake.createKeyVersion(eq(KEY_NAME_1), eq(request.toKeyCreationInput()))) + when(keyVaultFake.createKeyVersion(eq(KEY_NAME_1), any(KeyCreateDetailedInput.class))) .thenReturn(VERSIONED_KEY_ENTITY_ID_1_VERSION_1); when(keyVaultFake.getEntities()) .thenReturn(entities); @@ -278,14 +275,9 @@ void testCreateShouldUseInputParametersWhenCalled( Assertions.assertSame(RESPONSE, actual.getBody()); verify(vaultService).findByUri(eq(HTTPS_LOCALHOST_8443)); verify(vaultFake).keyVaultFake(); - verify(keyVaultFake).createKeyVersion(eq(KEY_NAME_1), eq(request.toKeyCreationInput())); - verify(keyVaultFake) - .setKeyOperations(eq(VERSIONED_KEY_ENTITY_ID_1_VERSION_1), eq(operations)); + verify(keyVaultFake).createKeyVersion(eq(KEY_NAME_1), any(KeyCreateDetailedInput.class)); verify(vaultFake).getRecoveryLevel(); verify(vaultFake).getRecoverableDays(); - verify(keyVaultFake).setExpiry(eq(VERSIONED_KEY_ENTITY_ID_1_VERSION_1), eq(notBefore), eq(expiry)); - verify(keyVaultFake).setEnabled(eq(VERSIONED_KEY_ENTITY_ID_1_VERSION_1), eq(true)); - verify(keyVaultFake).addTags(eq(VERSIONED_KEY_ENTITY_ID_1_VERSION_1), same(TAGS_TWO_KEYS)); verify(keyEntityToV72ModelConverter).convert(same(entity), eq(HTTPS_LOCALHOST_8443)); } diff --git a/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/controller/v7_2/KeyCryptoControllerTest.java b/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/controller/v7_2/KeyCryptoControllerTest.java index 163cdbc7..142c4e53 100644 --- a/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/controller/v7_2/KeyCryptoControllerTest.java +++ b/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/controller/v7_2/KeyCryptoControllerTest.java @@ -1,8 +1,10 @@ package com.github.nagyesta.lowkeyvault.controller.v7_2; +import com.github.nagyesta.lowkeyvault.mapper.common.registry.KeyConverterRegistry; import com.github.nagyesta.lowkeyvault.mapper.v7_2.key.KeyEntityToV72KeyItemModelConverter; import com.github.nagyesta.lowkeyvault.mapper.v7_2.key.KeyEntityToV72KeyVersionItemModelConverter; import com.github.nagyesta.lowkeyvault.mapper.v7_2.key.KeyEntityToV72ModelConverter; +import com.github.nagyesta.lowkeyvault.model.common.ApiConstants; import com.github.nagyesta.lowkeyvault.model.v7_2.key.*; import com.github.nagyesta.lowkeyvault.model.v7_2.key.constants.EncryptionAlgorithm; import com.github.nagyesta.lowkeyvault.model.v7_2.key.constants.KeyOperation; @@ -34,6 +36,7 @@ import org.springframework.http.ResponseEntity; import org.springframework.lang.NonNull; +import java.net.URI; import java.nio.charset.StandardCharsets; import java.util.Base64; import java.util.List; @@ -65,6 +68,8 @@ class KeyCryptoControllerTest { @Mock private KeyVaultFake keyVaultFake; @Mock + private KeyConverterRegistry registry; + @Mock private ReadOnlyVersionedEntityMultiMap entities; private KeyCryptoController underTest; private AutoCloseable openMocks; @@ -78,27 +83,22 @@ private static KeyVaultKeyModel createResponse() { } public static Stream nullProvider() { - final KeyEntityToV72ModelConverter ec = mock(KeyEntityToV72ModelConverter.class); - final KeyEntityToV72KeyItemModelConverter ic = mock(KeyEntityToV72KeyItemModelConverter.class); - final KeyEntityToV72KeyVersionItemModelConverter vic = mock(KeyEntityToV72KeyVersionItemModelConverter.class); return Stream.builder() - .add(Arguments.of(null, null, null, null)) - .add(Arguments.of(ec, null, null, null)) - .add(Arguments.of(null, ic, null, null)) - .add(Arguments.of(null, null, vic, null)) - .add(Arguments.of(null, null, null, mock(VaultService.class))) - .add(Arguments.of(null, ic, vic, mock(VaultService.class))) - .add(Arguments.of(ec, null, vic, mock(VaultService.class))) - .add(Arguments.of(ec, ic, null, mock(VaultService.class))) - .add(Arguments.of(ec, ic, vic, null)) + .add(Arguments.of(null, null)) + .add(Arguments.of(mock(KeyConverterRegistry.class), null)) + .add(Arguments.of(null, mock(VaultService.class))) .build(); } @BeforeEach void setUp() { openMocks = MockitoAnnotations.openMocks(this); - underTest = new KeyCryptoController(keyEntityToV72ModelConverter, keyEntityToV72KeyItemModelConverter, - keyEntityToV72KeyVersionItemModelConverter, vaultService); + when(registry.modelConverter(eq(ApiConstants.V_7_2))).thenReturn(keyEntityToV72ModelConverter); + when(registry.itemConverter(eq(ApiConstants.V_7_2))).thenReturn(keyEntityToV72KeyItemModelConverter); + when(registry.versionedItemConverter(eq(ApiConstants.V_7_2))).thenReturn(keyEntityToV72KeyVersionItemModelConverter); + when(registry.versionedEntityId(any(URI.class), anyString(), anyString())).thenCallRealMethod(); + when(registry.entityId(any(URI.class), anyString())).thenCallRealMethod(); + underTest = new KeyCryptoController(registry, vaultService); when(vaultService.findByUri(eq(HTTPS_LOCALHOST_8443))).thenReturn(vaultFake); when(vaultFake.baseUri()).thenReturn(HTTPS_LOCALHOST_8443); when(vaultFake.keyVaultFake()).thenReturn(keyVaultFake); @@ -112,16 +112,13 @@ void tearDown() throws Exception { @ParameterizedTest @MethodSource("nullProvider") void testConstructorShouldThrowExceptionWhenCalledWithNull( - final KeyEntityToV72ModelConverter keyEntityToV72ModelConverter, - final KeyEntityToV72KeyItemModelConverter keyEntityToV72KeyItemModelConverter, - final KeyEntityToV72KeyVersionItemModelConverter keyEntityToV72KeyVersionItemModelConverter, + final KeyConverterRegistry registry, final VaultService vaultService) { //given //when Assertions.assertThrows(IllegalArgumentException.class, - () -> new KeyCryptoController(keyEntityToV72ModelConverter, keyEntityToV72KeyItemModelConverter, - keyEntityToV72KeyVersionItemModelConverter, vaultService)); + () -> new KeyCryptoController(registry, vaultService)); //then + exception } diff --git a/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/controller/v7_2/SecretBackupRestoreControllerIntegrationTest.java b/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/controller/v7_2/SecretBackupRestoreControllerIntegrationTest.java index e966e487..e8d6998f 100644 --- a/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/controller/v7_2/SecretBackupRestoreControllerIntegrationTest.java +++ b/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/controller/v7_2/SecretBackupRestoreControllerIntegrationTest.java @@ -2,12 +2,17 @@ import com.github.nagyesta.abortmission.booster.jupiter.annotation.LaunchAbortArmed; import com.github.nagyesta.lowkeyvault.TestConstantsUri; -import com.github.nagyesta.lowkeyvault.mapper.v7_2.secret.SecretEntityToV72ModelConverter; +import com.github.nagyesta.lowkeyvault.mapper.common.registry.SecretConverterRegistry; +import com.github.nagyesta.lowkeyvault.model.common.backup.SecretBackupList; +import com.github.nagyesta.lowkeyvault.model.common.backup.SecretBackupListItem; +import com.github.nagyesta.lowkeyvault.model.common.backup.SecretBackupModel; import com.github.nagyesta.lowkeyvault.model.v7_2.common.constants.RecoveryLevel; -import com.github.nagyesta.lowkeyvault.model.v7_2.secret.*; +import com.github.nagyesta.lowkeyvault.model.v7_2.secret.KeyVaultSecretModel; +import com.github.nagyesta.lowkeyvault.model.v7_2.secret.SecretPropertiesModel; import com.github.nagyesta.lowkeyvault.service.exception.NotFoundException; import com.github.nagyesta.lowkeyvault.service.secret.SecretVaultFake; import com.github.nagyesta.lowkeyvault.service.secret.id.VersionedSecretEntityId; +import com.github.nagyesta.lowkeyvault.service.secret.impl.SecretCreateInput; import com.github.nagyesta.lowkeyvault.service.vault.VaultService; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Assertions; @@ -47,13 +52,9 @@ class SecretBackupRestoreControllerIntegrationTest { public static Stream nullProvider() { return Stream.builder() - .add(Arguments.of(null, null, null)) - .add(Arguments.of(mock(SecretEntityToV72ModelConverter.class), null, null)) - .add(Arguments.of(null, mock(SecretEntityToV72BackupConverter.class), null)) - .add(Arguments.of(null, null, mock(VaultService.class))) - .add(Arguments.of(null, mock(SecretEntityToV72BackupConverter.class), null)) - .add(Arguments.of(mock(SecretEntityToV72ModelConverter.class), null, mock(VaultService.class))) - .add(Arguments.of(mock(SecretEntityToV72ModelConverter.class), mock(SecretEntityToV72BackupConverter.class), null)) + .add(Arguments.of(null, null)) + .add(Arguments.of(mock(SecretConverterRegistry.class), null)) + .add(Arguments.of(null, mock(VaultService.class))) .build(); } @@ -73,14 +74,13 @@ void tearDown() { @ParameterizedTest @MethodSource("nullProvider") void testConstructorShouldThrowExceptionWhenCalledWithNulls( - final SecretEntityToV72ModelConverter modelConverter, - final SecretEntityToV72BackupConverter backupConverter, + final SecretConverterRegistry registry, final VaultService vaultService) { //given //when Assertions.assertThrows(IllegalArgumentException.class, - () -> new SecretBackupRestoreController(modelConverter, backupConverter, vaultService)); + () -> new SecretBackupRestoreController(registry, vaultService)); //then + exception } @@ -171,7 +171,9 @@ void testRestoreEntityShouldThrowExceptionWhenNameMatchesActiveSecret() { backupModel.setValue(new SecretBackupList()); addVersionToList(uri, SECRET_NAME_1, SECRET_VERSION_1, backupModel, TAGS_EMPTY); addVersionToList(uri, SECRET_NAME_1, SECRET_VERSION_2, backupModel, TAGS_ONE_KEY); - vaultService.findByUri(uri).secretVaultFake().createSecretVersion(SECRET_NAME_1, LOWKEY_VAULT, null); + vaultService.findByUri(uri).secretVaultFake().createSecretVersion(SECRET_NAME_1, SecretCreateInput.builder() + .value(LOWKEY_VAULT) + .build()); //when Assertions.assertThrows(IllegalArgumentException.class, () -> underTest.restore(uri, backupModel)); @@ -187,7 +189,9 @@ void testRestoreEntityShouldThrowExceptionWhenNameMatchesDeletedSecret() { addVersionToList(uri, SECRET_NAME_1, SECRET_VERSION_1, backupModel, TAGS_EMPTY); addVersionToList(uri, SECRET_NAME_1, SECRET_VERSION_2, backupModel, TAGS_ONE_KEY); final SecretVaultFake vaultFake = vaultService.findByUri(uri).secretVaultFake(); - final VersionedSecretEntityId secretVersion = vaultFake.createSecretVersion(SECRET_NAME_1, LOWKEY_VAULT, null); + final VersionedSecretEntityId secretVersion = vaultFake.createSecretVersion(SECRET_NAME_1, SecretCreateInput.builder() + .value(LOWKEY_VAULT) + .build()); vaultFake.delete(secretVersion); //when diff --git a/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/controller/v7_2/SecretControllerTest.java b/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/controller/v7_2/SecretControllerTest.java index 4be38d15..3c8fd045 100644 --- a/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/controller/v7_2/SecretControllerTest.java +++ b/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/controller/v7_2/SecretControllerTest.java @@ -1,8 +1,10 @@ package com.github.nagyesta.lowkeyvault.controller.v7_2; +import com.github.nagyesta.lowkeyvault.mapper.common.registry.SecretConverterRegistry; import com.github.nagyesta.lowkeyvault.mapper.v7_2.secret.SecretEntityToV72ModelConverter; import com.github.nagyesta.lowkeyvault.mapper.v7_2.secret.SecretEntityToV72SecretItemModelConverter; import com.github.nagyesta.lowkeyvault.mapper.v7_2.secret.SecretEntityToV72SecretVersionItemModelConverter; +import com.github.nagyesta.lowkeyvault.model.common.ApiConstants; import com.github.nagyesta.lowkeyvault.model.common.KeyVaultItemListModel; import com.github.nagyesta.lowkeyvault.model.v7_2.BasePropertiesUpdateModel; import com.github.nagyesta.lowkeyvault.model.v7_2.common.constants.RecoveryLevel; @@ -16,6 +18,7 @@ import com.github.nagyesta.lowkeyvault.service.secret.id.SecretEntityId; import com.github.nagyesta.lowkeyvault.service.secret.id.VersionedSecretEntityId; import com.github.nagyesta.lowkeyvault.service.secret.impl.KeyVaultSecretEntity; +import com.github.nagyesta.lowkeyvault.service.secret.impl.SecretCreateInput; import com.github.nagyesta.lowkeyvault.service.vault.VaultFake; import com.github.nagyesta.lowkeyvault.service.vault.VaultService; import org.junit.jupiter.api.AfterEach; @@ -63,6 +66,8 @@ class SecretControllerTest { @Mock private SecretVaultFake secretVaultFake; @Mock + private SecretConverterRegistry registry; + @Mock private ReadOnlyVersionedEntityMultiMap entities; @Mock private ReadOnlyVersionedEntityMultiMap deletedEntities; @@ -105,19 +110,10 @@ public static Stream secretAttributeProvider() { } public static Stream nullProvider() { - final SecretEntityToV72ModelConverter ec = mock(SecretEntityToV72ModelConverter.class); - final SecretEntityToV72SecretItemModelConverter ic = mock(SecretEntityToV72SecretItemModelConverter.class); - final SecretEntityToV72SecretVersionItemModelConverter vic = mock(SecretEntityToV72SecretVersionItemModelConverter.class); return Stream.builder() - .add(Arguments.of(null, null, null, null)) - .add(Arguments.of(ec, null, null, null)) - .add(Arguments.of(null, ic, null, null)) - .add(Arguments.of(null, null, vic, null)) - .add(Arguments.of(null, null, null, mock(VaultService.class))) - .add(Arguments.of(null, ic, vic, mock(VaultService.class))) - .add(Arguments.of(ec, null, vic, mock(VaultService.class))) - .add(Arguments.of(ec, ic, null, mock(VaultService.class))) - .add(Arguments.of(ec, ic, vic, null)) + .add(Arguments.of(null, null)) + .add(Arguments.of(mock(SecretConverterRegistry.class), null)) + .add(Arguments.of(null, mock(VaultService.class))) .build(); } @@ -136,8 +132,12 @@ public static Stream updateAttributeProvider() { @BeforeEach void setUp() { openMocks = MockitoAnnotations.openMocks(this); - underTest = new SecretController(secretEntityToV72ModelConverter, secretEntityToV72SecretItemModelConverter, - secretEntityToV72SecretVersionItemModelConverter, vaultService); + when(registry.modelConverter(eq(ApiConstants.V_7_2))).thenReturn(secretEntityToV72ModelConverter); + when(registry.itemConverter(eq(ApiConstants.V_7_2))).thenReturn(secretEntityToV72SecretItemModelConverter); + when(registry.versionedItemConverter(eq(ApiConstants.V_7_2))).thenReturn(secretEntityToV72SecretVersionItemModelConverter); + when(registry.versionedEntityId(any(URI.class), anyString(), anyString())).thenCallRealMethod(); + when(registry.entityId(any(URI.class), anyString())).thenCallRealMethod(); + underTest = new SecretController(registry, vaultService); when(vaultService.findByUri(eq(HTTPS_LOCALHOST_8443))).thenReturn(vaultFake); when(vaultFake.baseUri()).thenReturn(HTTPS_LOCALHOST_8443); when(vaultFake.secretVaultFake()).thenReturn(secretVaultFake); @@ -151,16 +151,13 @@ void tearDown() throws Exception { @ParameterizedTest @MethodSource("nullProvider") void testConstructorShouldThrowExceptionWhenCalledWithNull( - final SecretEntityToV72ModelConverter secretEntityToV72ModelConverter, - final SecretEntityToV72SecretItemModelConverter secretEntityToV72SecretItemModelConverter, - final SecretEntityToV72SecretVersionItemModelConverter secretEntityToV72SecretVersionItemModelConverter, + final SecretConverterRegistry registry, final VaultService vaultService) { //given //when Assertions.assertThrows(IllegalArgumentException.class, - () -> new SecretController(secretEntityToV72ModelConverter, secretEntityToV72SecretItemModelConverter, - secretEntityToV72SecretVersionItemModelConverter, vaultService)); + () -> new SecretController(registry, vaultService)); //then + exception } @@ -175,7 +172,7 @@ void testCreateShouldUseInputParametersWhenCalled( when(vaultFake.getRecoverableDays()).thenReturn(null); final CreateSecretRequest request = createRequest(expiry, notBefore); final ReadOnlyKeyVaultSecretEntity entity = createEntity(VERSIONED_SECRET_ENTITY_ID_1_VERSION_1, request); - when(secretVaultFake.createSecretVersion(eq(SECRET_NAME_1), eq(request.getValue()), eq(request.getContentType()))) + when(secretVaultFake.createSecretVersion(eq(SECRET_NAME_1), any(SecretCreateInput.class))) .thenReturn(VERSIONED_SECRET_ENTITY_ID_1_VERSION_1); when(secretVaultFake.getEntities()) .thenReturn(entities); @@ -197,12 +194,9 @@ void testCreateShouldUseInputParametersWhenCalled( Assertions.assertSame(RESPONSE, actual.getBody()); verify(vaultService).findByUri(eq(HTTPS_LOCALHOST_8443)); verify(vaultFake).secretVaultFake(); - verify(secretVaultFake).createSecretVersion(eq(SECRET_NAME_1), eq(request.getValue()), eq(request.getContentType())); + verify(secretVaultFake).createSecretVersion(eq(SECRET_NAME_1), any(SecretCreateInput.class)); verify(vaultFake).getRecoveryLevel(); verify(vaultFake).getRecoverableDays(); - verify(secretVaultFake).setExpiry(eq(VERSIONED_SECRET_ENTITY_ID_1_VERSION_1), eq(notBefore), eq(expiry)); - verify(secretVaultFake).setEnabled(eq(VERSIONED_SECRET_ENTITY_ID_1_VERSION_1), eq(true)); - verify(secretVaultFake).addTags(eq(VERSIONED_SECRET_ENTITY_ID_1_VERSION_1), same(TAGS_TWO_KEYS)); verify(secretEntityToV72ModelConverter).convert(same(entity), eq(HTTPS_LOCALHOST_8443)); } diff --git a/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/controller/v7_3/CertificateControllerTest.java b/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/controller/v7_3/CertificateControllerTest.java index f96a84ea..3d748dfd 100644 --- a/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/controller/v7_3/CertificateControllerTest.java +++ b/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/controller/v7_3/CertificateControllerTest.java @@ -1,6 +1,6 @@ package com.github.nagyesta.lowkeyvault.controller.v7_3; -import com.github.nagyesta.lowkeyvault.mapper.v7_3.certificate.*; +import com.github.nagyesta.lowkeyvault.mapper.common.registry.CertificateConverterRegistry; import com.github.nagyesta.lowkeyvault.service.vault.VaultService; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.params.ParameterizedTest; @@ -14,56 +14,25 @@ class CertificateControllerTest { public static Stream nullProvider() { - final CertificateEntityToV73ModelConverter modelConverter = - mock(CertificateEntityToV73ModelConverter.class); - final CertificateEntityToV73CertificateItemModelConverter itemModelConverter = - mock(CertificateEntityToV73CertificateItemModelConverter.class); - final CertificateEntityToV73CertificateVersionItemModelConverter versionItemModelConverter = - mock(CertificateEntityToV73CertificateVersionItemModelConverter.class); - final CertificateEntityToV73PendingCertificateOperationModelConverter pendingModelConverter = - mock(CertificateEntityToV73PendingCertificateOperationModelConverter.class); - final LifetimeActionsPolicyToV73ModelConverter lifetimeActionsModelConverter = - mock(LifetimeActionsPolicyToV73ModelConverter.class); + final CertificateConverterRegistry registry = mock(CertificateConverterRegistry.class); final VaultService vaultService = mock(VaultService.class); return Stream.builder() - .add(Arguments.of(null, null, null, null, null, null)) - .add(Arguments.of(modelConverter, null, null, null, null, null)) - .add(Arguments.of(null, itemModelConverter, null, null, null, null)) - .add(Arguments.of(null, null, versionItemModelConverter, null, null, null)) - .add(Arguments.of(null, null, null, pendingModelConverter, null, null)) - .add(Arguments.of(null, null, null, null, lifetimeActionsModelConverter, null)) - .add(Arguments.of(null, null, null, null, null, vaultService)) - .add(Arguments.of(null, itemModelConverter, versionItemModelConverter, - pendingModelConverter, lifetimeActionsModelConverter, vaultService)) - .add(Arguments.of(modelConverter, null, versionItemModelConverter, - pendingModelConverter, lifetimeActionsModelConverter, vaultService)) - .add(Arguments.of(modelConverter, itemModelConverter, null, - pendingModelConverter, lifetimeActionsModelConverter, vaultService)) - .add(Arguments.of(modelConverter, itemModelConverter, versionItemModelConverter, - null, lifetimeActionsModelConverter, vaultService)) - .add(Arguments.of(modelConverter, itemModelConverter, versionItemModelConverter, - pendingModelConverter, null, vaultService)) - .add(Arguments.of(modelConverter, itemModelConverter, versionItemModelConverter, - pendingModelConverter, lifetimeActionsModelConverter, null)) + .add(Arguments.of(null, null)) + .add(Arguments.of(registry, null)) + .add(Arguments.of(null, vaultService)) .build(); } @ParameterizedTest @MethodSource("nullProvider") void testConstructorShouldThrowExceptionWhenCalledWithNulls( - final CertificateEntityToV73ModelConverter modelConverter, - final CertificateEntityToV73CertificateItemModelConverter itemModelConverter, - final CertificateEntityToV73CertificateVersionItemModelConverter versionItemModelConverter, - final CertificateEntityToV73PendingCertificateOperationModelConverter pendingModelConverter, - final LifetimeActionsPolicyToV73ModelConverter lifetimeActionsModelConverter, + final CertificateConverterRegistry registry, final VaultService vaultService) { //given //when Assertions.assertThrows(IllegalArgumentException.class, - () -> new CertificateController( - modelConverter, itemModelConverter, versionItemModelConverter, - pendingModelConverter, lifetimeActionsModelConverter, vaultService)); + () -> new CertificateController(registry, vaultService)); //then + exception } diff --git a/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/controller/v7_3/CertificatePolicyControllerTest.java b/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/controller/v7_3/CertificatePolicyControllerTest.java index caf34268..17fc8b02 100644 --- a/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/controller/v7_3/CertificatePolicyControllerTest.java +++ b/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/controller/v7_3/CertificatePolicyControllerTest.java @@ -1,8 +1,6 @@ package com.github.nagyesta.lowkeyvault.controller.v7_3; -import com.github.nagyesta.lowkeyvault.mapper.v7_3.certificate.CertificateEntityToV73IssuancePolicyModelConverter; -import com.github.nagyesta.lowkeyvault.mapper.v7_3.certificate.CertificateEntityToV73PendingCertificateOperationModelConverter; -import com.github.nagyesta.lowkeyvault.mapper.v7_3.certificate.LifetimeActionsPolicyToV73ModelConverter; +import com.github.nagyesta.lowkeyvault.mapper.common.registry.CertificateConverterRegistry; import com.github.nagyesta.lowkeyvault.service.vault.VaultService; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.params.ParameterizedTest; @@ -16,39 +14,25 @@ class CertificatePolicyControllerTest { public static Stream nullProvider() { - final CertificateEntityToV73PendingCertificateOperationModelConverter pendingOperationConverter = - mock(CertificateEntityToV73PendingCertificateOperationModelConverter.class); - final CertificateEntityToV73IssuancePolicyModelConverter issuancePolicyConverter = - mock(CertificateEntityToV73IssuancePolicyModelConverter.class); - final LifetimeActionsPolicyToV73ModelConverter lifetimeActionsConverter = - mock(LifetimeActionsPolicyToV73ModelConverter.class); + final CertificateConverterRegistry registry = mock(CertificateConverterRegistry.class); final VaultService vaultService = mock(VaultService.class); return Stream.builder() - .add(Arguments.of(null, null, null, null)) - .add(Arguments.of(pendingOperationConverter, null, null, null)) - .add(Arguments.of(null, issuancePolicyConverter, null, null)) - .add(Arguments.of(null, null, lifetimeActionsConverter, null)) - .add(Arguments.of(null, null, null, vaultService)) - .add(Arguments.of(null, issuancePolicyConverter, lifetimeActionsConverter, vaultService)) - .add(Arguments.of(pendingOperationConverter, null, lifetimeActionsConverter, vaultService)) - .add(Arguments.of(pendingOperationConverter, issuancePolicyConverter, null, vaultService)) - .add(Arguments.of(pendingOperationConverter, issuancePolicyConverter, lifetimeActionsConverter, null)) + .add(Arguments.of(null, null)) + .add(Arguments.of(registry, null)) + .add(Arguments.of(null, vaultService)) .build(); } @ParameterizedTest @MethodSource("nullProvider") void testConstructorShouldThrowExceptionWhenCalledWithNull( - final CertificateEntityToV73PendingCertificateOperationModelConverter pendingOperationConverter, - final CertificateEntityToV73IssuancePolicyModelConverter issuancePolicyConverter, - final LifetimeActionsPolicyToV73ModelConverter lifetimeActionsConverter, + final CertificateConverterRegistry registry, final VaultService vaultService) { //given //when Assertions.assertThrows(IllegalArgumentException.class, - () -> new CertificatePolicyController(pendingOperationConverter, issuancePolicyConverter, - lifetimeActionsConverter, vaultService)); + () -> new CertificatePolicyController(registry, vaultService)); //then + exception } diff --git a/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/controller/v7_3/KeyBackupRestoreControllerIntegrationTest.java b/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/controller/v7_3/KeyBackupRestoreControllerIntegrationTest.java index 18a2eb3b..f775182a 100644 --- a/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/controller/v7_3/KeyBackupRestoreControllerIntegrationTest.java +++ b/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/controller/v7_3/KeyBackupRestoreControllerIntegrationTest.java @@ -2,12 +2,11 @@ import com.github.nagyesta.abortmission.booster.jupiter.annotation.LaunchAbortArmed; import com.github.nagyesta.lowkeyvault.TestConstantsUri; -import com.github.nagyesta.lowkeyvault.mapper.v7_2.key.KeyEntityToV72BackupConverter; -import com.github.nagyesta.lowkeyvault.mapper.v7_2.key.KeyEntityToV72ModelConverter; -import com.github.nagyesta.lowkeyvault.mapper.v7_3.key.KeyRotationPolicyToV73ModelConverter; -import com.github.nagyesta.lowkeyvault.mapper.v7_3.key.KeyRotationPolicyV73ModelToEntityConverter; +import com.github.nagyesta.lowkeyvault.mapper.common.registry.KeyConverterRegistry; +import com.github.nagyesta.lowkeyvault.model.common.backup.KeyBackupList; +import com.github.nagyesta.lowkeyvault.model.common.backup.KeyBackupListItem; +import com.github.nagyesta.lowkeyvault.model.common.backup.KeyBackupModel; import com.github.nagyesta.lowkeyvault.model.v7_2.common.constants.RecoveryLevel; -import com.github.nagyesta.lowkeyvault.model.v7_2.key.KeyBackupListItem; import com.github.nagyesta.lowkeyvault.model.v7_2.key.KeyPropertiesModel; import com.github.nagyesta.lowkeyvault.model.v7_2.key.KeyVaultKeyModel; import com.github.nagyesta.lowkeyvault.model.v7_2.key.constants.KeyCurveName; @@ -23,6 +22,7 @@ import com.github.nagyesta.lowkeyvault.service.key.id.KeyEntityId; import com.github.nagyesta.lowkeyvault.service.key.id.VersionedKeyEntityId; import com.github.nagyesta.lowkeyvault.service.key.impl.EcKeyCreationInput; +import com.github.nagyesta.lowkeyvault.service.key.impl.KeyCreateDetailedInput; import com.github.nagyesta.lowkeyvault.service.key.util.KeyGenUtil; import com.github.nagyesta.lowkeyvault.service.vault.VaultService; import org.junit.jupiter.api.AfterEach; @@ -62,21 +62,13 @@ class KeyBackupRestoreControllerIntegrationTest { private KeyBackupRestoreController underTest; @Autowired private VaultService vaultService; - @Autowired - private KeyRotationPolicyToV73ModelConverter toModelConverter; - @Autowired - private KeyRotationPolicyV73ModelToEntityConverter toEntityConverter; private URI uri; public static Stream nullProvider() { return Stream.builder() - .add(Arguments.of(null, null, null)) - .add(Arguments.of(mock(KeyEntityToV72ModelConverter.class), null, null)) - .add(Arguments.of(null, mock(KeyEntityToV72BackupConverter.class), null)) - .add(Arguments.of(null, null, mock(VaultService.class))) - .add(Arguments.of(null, mock(KeyEntityToV72BackupConverter.class), null)) - .add(Arguments.of(mock(KeyEntityToV72ModelConverter.class), null, mock(VaultService.class))) - .add(Arguments.of(mock(KeyEntityToV72ModelConverter.class), mock(KeyEntityToV72BackupConverter.class), null)) + .add(Arguments.of(null, null)) + .add(Arguments.of(mock(VaultService.class), null)) + .add(Arguments.of(null, mock(KeyConverterRegistry.class))) .build(); } @@ -95,15 +87,12 @@ void tearDown() { @ParameterizedTest @MethodSource("nullProvider") - void testConstructorShouldThrowExceptionWhenCalledWithNulls( - final KeyEntityToV72ModelConverter modelConverter, - final KeyEntityToV72BackupConverter backupConverter, - final VaultService vaultService) { + void testConstructorShouldThrowExceptionWhenCalledWithNulls(final VaultService vaultService, final KeyConverterRegistry registry) { //given //when Assertions.assertThrows(IllegalArgumentException.class, - () -> new KeyBackupRestoreController(modelConverter, backupConverter, vaultService, toModelConverter, toEntityConverter)); + () -> new KeyBackupRestoreController(registry, vaultService)); //then + exception } @@ -225,7 +214,9 @@ void testRestoreEntityShouldThrowExceptionWhenNameMatchesActiveKey() { addVersionToList(uri, KEY_NAME_1, KEY_VERSION_1, backupModel, TAGS_EMPTY); addVersionToList(uri, KEY_NAME_1, KEY_VERSION_2, backupModel, TAGS_ONE_KEY); vaultService.findByUri(uri).keyVaultFake() - .createKeyVersion(KEY_NAME_1, new EcKeyCreationInput(KeyType.EC, KeyCurveName.P_256)); + .createKeyVersion(KEY_NAME_1, KeyCreateDetailedInput.builder() + .key(new EcKeyCreationInput(KeyType.EC, KeyCurveName.P_256)) + .build()); //when Assertions.assertThrows(IllegalArgumentException.class, () -> underTest.restore(uri, backupModel)); @@ -242,7 +233,9 @@ void testRestoreEntityShouldThrowExceptionWhenNameMatchesDeletedKey() { addVersionToList(uri, KEY_NAME_1, KEY_VERSION_2, backupModel, TAGS_ONE_KEY); final KeyVaultFake vaultFake = vaultService.findByUri(uri).keyVaultFake(); final VersionedKeyEntityId keyVersion = vaultFake - .createKeyVersion(KEY_NAME_1, new EcKeyCreationInput(KeyType.EC, KeyCurveName.P_256)); + .createKeyVersion(KEY_NAME_1, KeyCreateDetailedInput.builder() + .key(new EcKeyCreationInput(KeyType.EC, KeyCurveName.P_256)) + .build()); vaultFake.delete(keyVersion); //when diff --git a/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/controller/v7_3/KeyControllerTest.java b/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/controller/v7_3/KeyControllerTest.java index 88c20ea7..922b8f4a 100644 --- a/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/controller/v7_3/KeyControllerTest.java +++ b/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/controller/v7_3/KeyControllerTest.java @@ -1,8 +1,10 @@ package com.github.nagyesta.lowkeyvault.controller.v7_3; +import com.github.nagyesta.lowkeyvault.mapper.common.registry.KeyConverterRegistry; import com.github.nagyesta.lowkeyvault.mapper.v7_2.key.KeyEntityToV72KeyItemModelConverter; import com.github.nagyesta.lowkeyvault.mapper.v7_2.key.KeyEntityToV72KeyVersionItemModelConverter; import com.github.nagyesta.lowkeyvault.mapper.v7_2.key.KeyEntityToV72ModelConverter; +import com.github.nagyesta.lowkeyvault.model.common.ApiConstants; import com.github.nagyesta.lowkeyvault.model.common.ErrorMessage; import com.github.nagyesta.lowkeyvault.model.common.ErrorModel; import com.github.nagyesta.lowkeyvault.model.common.KeyVaultItemListModel; @@ -21,7 +23,9 @@ import com.github.nagyesta.lowkeyvault.service.key.ReadOnlyKeyVaultKeyEntity; import com.github.nagyesta.lowkeyvault.service.key.id.KeyEntityId; import com.github.nagyesta.lowkeyvault.service.key.id.VersionedKeyEntityId; +import com.github.nagyesta.lowkeyvault.service.key.impl.KeyCreateDetailedInput; import com.github.nagyesta.lowkeyvault.service.key.impl.KeyVaultKeyEntity; +import com.github.nagyesta.lowkeyvault.service.key.impl.RsaKeyCreationInput; import com.github.nagyesta.lowkeyvault.service.key.impl.RsaKeyVaultKeyEntity; import com.github.nagyesta.lowkeyvault.service.vault.VaultFake; import com.github.nagyesta.lowkeyvault.service.vault.VaultService; @@ -71,6 +75,8 @@ class KeyControllerTest { @Mock private KeyVaultFake keyVaultFake; @Mock + private KeyConverterRegistry registry; + @Mock private ReadOnlyVersionedEntityMultiMap entities; @Mock private ReadOnlyVersionedEntityMultiMap deletedEntities; @@ -123,19 +129,11 @@ public static Stream keyAttributeProvider() { } public static Stream nullProvider() { - final KeyEntityToV72ModelConverter ec = mock(KeyEntityToV72ModelConverter.class); - final KeyEntityToV72KeyItemModelConverter ic = mock(KeyEntityToV72KeyItemModelConverter.class); - final KeyEntityToV72KeyVersionItemModelConverter vic = mock(KeyEntityToV72KeyVersionItemModelConverter.class); + final KeyConverterRegistry registry = mock(KeyConverterRegistry.class); return Stream.builder() - .add(Arguments.of(null, null, null, null)) - .add(Arguments.of(ec, null, null, null)) - .add(Arguments.of(null, ic, null, null)) - .add(Arguments.of(null, null, vic, null)) - .add(Arguments.of(null, null, null, mock(VaultService.class))) - .add(Arguments.of(null, ic, vic, mock(VaultService.class))) - .add(Arguments.of(ec, null, vic, mock(VaultService.class))) - .add(Arguments.of(ec, ic, null, mock(VaultService.class))) - .add(Arguments.of(ec, ic, vic, null)) + .add(Arguments.of(null, null)) + .add(Arguments.of(registry, null)) + .add(Arguments.of(null, mock(VaultService.class))) .build(); } @@ -170,8 +168,12 @@ public static Stream exceptionProvider() { @BeforeEach void setUp() { openMocks = MockitoAnnotations.openMocks(this); - underTest = new KeyController(keyEntityToV72ModelConverter, keyEntityToV72KeyItemModelConverter, - keyEntityToV72KeyVersionItemModelConverter, vaultService); + when(registry.modelConverter(eq(ApiConstants.V_7_3))).thenReturn(keyEntityToV72ModelConverter); + when(registry.itemConverter(eq(ApiConstants.V_7_3))).thenReturn(keyEntityToV72KeyItemModelConverter); + when(registry.versionedItemConverter(eq(ApiConstants.V_7_3))).thenReturn(keyEntityToV72KeyVersionItemModelConverter); + when(registry.versionedEntityId(any(URI.class), anyString(), anyString())).thenCallRealMethod(); + when(registry.entityId(any(URI.class), anyString())).thenCallRealMethod(); + underTest = new KeyController(registry, vaultService); when(vaultService.findByUri(eq(HTTPS_LOCALHOST_8443))).thenReturn(vaultFake); when(vaultFake.baseUri()).thenReturn(HTTPS_LOCALHOST_8443); when(vaultFake.keyVaultFake()).thenReturn(keyVaultFake); @@ -232,16 +234,13 @@ void testErrorHandlerConvertsIllegalArgumentExceptionWhenCaught() { @ParameterizedTest @MethodSource("nullProvider") void testConstructorShouldThrowExceptionWhenCalledWithNull( - final KeyEntityToV72ModelConverter keyEntityToV72ModelConverter, - final KeyEntityToV72KeyItemModelConverter keyEntityToV72KeyItemModelConverter, - final KeyEntityToV72KeyVersionItemModelConverter keyEntityToV72KeyVersionItemModelConverter, + final KeyConverterRegistry registry, final VaultService vaultService) { //given //when Assertions.assertThrows(IllegalArgumentException.class, - () -> new KeyController(keyEntityToV72ModelConverter, keyEntityToV72KeyItemModelConverter, - keyEntityToV72KeyVersionItemModelConverter, vaultService)); + () -> new KeyController(registry, vaultService)); //then + exception } @@ -255,8 +254,17 @@ void testCreateShouldUseInputParametersWhenCalled( when(vaultFake.getRecoveryLevel()).thenReturn(RecoveryLevel.PURGEABLE); when(vaultFake.getRecoverableDays()).thenReturn(null); final CreateKeyRequest request = createRequest(operations, expiry, notBefore); + final KeyCreateDetailedInput input = KeyCreateDetailedInput.builder() + .key(request.toKeyCreationInput()) + .keyOperations(operations) + .expiresOn(expiry) + .notBefore(notBefore) + .managed(false) + .enabled(true) + .tags(request.getTags()) + .build(); final ReadOnlyKeyVaultKeyEntity entity = createEntity(VERSIONED_KEY_ENTITY_ID_1_VERSION_1, request); - when(keyVaultFake.createKeyVersion(eq(KEY_NAME_1), eq(request.toKeyCreationInput()))) + when(keyVaultFake.createKeyVersion(eq(KEY_NAME_1), eq(input))) .thenReturn(VERSIONED_KEY_ENTITY_ID_1_VERSION_1); when(keyVaultFake.getEntities()) .thenReturn(entities); @@ -278,14 +286,9 @@ void testCreateShouldUseInputParametersWhenCalled( Assertions.assertSame(RESPONSE, actual.getBody()); verify(vaultService).findByUri(eq(HTTPS_LOCALHOST_8443)); verify(vaultFake).keyVaultFake(); - verify(keyVaultFake).createKeyVersion(eq(KEY_NAME_1), eq(request.toKeyCreationInput())); - verify(keyVaultFake) - .setKeyOperations(eq(VERSIONED_KEY_ENTITY_ID_1_VERSION_1), eq(operations)); + verify(keyVaultFake).createKeyVersion(eq(KEY_NAME_1), eq(input)); verify(vaultFake).getRecoveryLevel(); verify(vaultFake).getRecoverableDays(); - verify(keyVaultFake).setExpiry(eq(VERSIONED_KEY_ENTITY_ID_1_VERSION_1), eq(notBefore), eq(expiry)); - verify(keyVaultFake).setEnabled(eq(VERSIONED_KEY_ENTITY_ID_1_VERSION_1), eq(true)); - verify(keyVaultFake).addTags(eq(VERSIONED_KEY_ENTITY_ID_1_VERSION_1), same(TAGS_TWO_KEYS)); verify(keyEntityToV72ModelConverter).convert(same(entity), eq(HTTPS_LOCALHOST_8443)); } @@ -957,6 +960,22 @@ private CreateKeyRequest createRequest( return keyRequest; } + private KeyCreateDetailedInput detailedInput( + final List operations, + final OffsetDateTime expiry, final OffsetDateTime notBefore) { + final RsaKeyCreationInput keyRequest = new RsaKeyCreationInput(KeyType.RSA, + KeyType.RSA.getValidKeyParameters(Integer.class).first(), null); + return KeyCreateDetailedInput.builder() + .key(keyRequest) + .managed(false) + .keyOperations(operations) + .expiresOn(expiry) + .notBefore(notBefore) + .enabled(true) + .tags(TAGS_TWO_KEYS) + .build(); + } + @NonNull private KeyVaultKeyEntity createEntity(final VersionedKeyEntityId keyEntityId, final CreateKeyRequest createKeyRequest) { return new RsaKeyVaultKeyEntity(keyEntityId, vaultFake, createKeyRequest.getKeySize(), null, false); diff --git a/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/controller/v7_3/KeyCryptoControllerTest.java b/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/controller/v7_3/KeyCryptoControllerTest.java index ac6082fa..2c00667c 100644 --- a/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/controller/v7_3/KeyCryptoControllerTest.java +++ b/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/controller/v7_3/KeyCryptoControllerTest.java @@ -1,8 +1,10 @@ package com.github.nagyesta.lowkeyvault.controller.v7_3; +import com.github.nagyesta.lowkeyvault.mapper.common.registry.KeyConverterRegistry; import com.github.nagyesta.lowkeyvault.mapper.v7_2.key.KeyEntityToV72KeyItemModelConverter; import com.github.nagyesta.lowkeyvault.mapper.v7_2.key.KeyEntityToV72KeyVersionItemModelConverter; import com.github.nagyesta.lowkeyvault.mapper.v7_2.key.KeyEntityToV72ModelConverter; +import com.github.nagyesta.lowkeyvault.model.common.ApiConstants; import com.github.nagyesta.lowkeyvault.model.v7_2.key.*; import com.github.nagyesta.lowkeyvault.model.v7_2.key.constants.EncryptionAlgorithm; import com.github.nagyesta.lowkeyvault.model.v7_2.key.constants.KeyOperation; @@ -37,6 +39,7 @@ import org.springframework.http.ResponseEntity; import org.springframework.lang.NonNull; +import java.net.URI; import java.nio.charset.StandardCharsets; import java.util.Base64; import java.util.List; @@ -68,6 +71,8 @@ class KeyCryptoControllerTest { @Mock private KeyVaultFake keyVaultFake; @Mock + private KeyConverterRegistry registry; + @Mock private ReadOnlyVersionedEntityMultiMap entities; private KeyCryptoController underTest; private AutoCloseable openMocks; @@ -81,27 +86,23 @@ private static KeyVaultKeyModel createResponse() { } public static Stream nullProvider() { - final KeyEntityToV72ModelConverter ec = mock(KeyEntityToV72ModelConverter.class); - final KeyEntityToV72KeyItemModelConverter ic = mock(KeyEntityToV72KeyItemModelConverter.class); - final KeyEntityToV72KeyVersionItemModelConverter vic = mock(KeyEntityToV72KeyVersionItemModelConverter.class); + final KeyConverterRegistry registry = mock(KeyConverterRegistry.class); return Stream.builder() - .add(Arguments.of(null, null, null, null)) - .add(Arguments.of(ec, null, null, null)) - .add(Arguments.of(null, ic, null, null)) - .add(Arguments.of(null, null, vic, null)) - .add(Arguments.of(null, null, null, mock(VaultService.class))) - .add(Arguments.of(null, ic, vic, mock(VaultService.class))) - .add(Arguments.of(ec, null, vic, mock(VaultService.class))) - .add(Arguments.of(ec, ic, null, mock(VaultService.class))) - .add(Arguments.of(ec, ic, vic, null)) + .add(Arguments.of(null, null)) + .add(Arguments.of(registry, null)) + .add(Arguments.of(null, mock(VaultService.class))) .build(); } @BeforeEach void setUp() { openMocks = MockitoAnnotations.openMocks(this); - underTest = new KeyCryptoController(keyEntityToV72ModelConverter, keyEntityToV72KeyItemModelConverter, - keyEntityToV72KeyVersionItemModelConverter, vaultService); + when(registry.modelConverter(eq(ApiConstants.V_7_3))).thenReturn(keyEntityToV72ModelConverter); + when(registry.itemConverter(eq(ApiConstants.V_7_3))).thenReturn(keyEntityToV72KeyItemModelConverter); + when(registry.versionedItemConverter(eq(ApiConstants.V_7_3))).thenReturn(keyEntityToV72KeyVersionItemModelConverter); + when(registry.versionedEntityId(any(URI.class), anyString(), anyString())).thenCallRealMethod(); + when(registry.entityId(any(URI.class), anyString())).thenCallRealMethod(); + underTest = new KeyCryptoController(registry, vaultService); when(vaultService.findByUri(eq(HTTPS_LOCALHOST_8443))).thenReturn(vaultFake); when(vaultFake.baseUri()).thenReturn(HTTPS_LOCALHOST_8443); when(vaultFake.keyVaultFake()).thenReturn(keyVaultFake); @@ -115,16 +116,13 @@ void tearDown() throws Exception { @ParameterizedTest @MethodSource("nullProvider") void testConstructorShouldThrowExceptionWhenCalledWithNull( - final KeyEntityToV72ModelConverter keyEntityToV72ModelConverter, - final KeyEntityToV72KeyItemModelConverter keyEntityToV72KeyItemModelConverter, - final KeyEntityToV72KeyVersionItemModelConverter keyEntityToV72KeyVersionItemModelConverter, + final KeyConverterRegistry registry, final VaultService vaultService) { //given //when Assertions.assertThrows(IllegalArgumentException.class, - () -> new KeyCryptoController(keyEntityToV72ModelConverter, keyEntityToV72KeyItemModelConverter, - keyEntityToV72KeyVersionItemModelConverter, vaultService)); + () -> new KeyCryptoController(registry, vaultService)); //then + exception } diff --git a/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/controller/v7_3/KeyPolicyControllerTest.java b/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/controller/v7_3/KeyPolicyControllerTest.java index c0f64ea8..1787f4eb 100644 --- a/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/controller/v7_3/KeyPolicyControllerTest.java +++ b/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/controller/v7_3/KeyPolicyControllerTest.java @@ -1,11 +1,12 @@ package com.github.nagyesta.lowkeyvault.controller.v7_3; +import com.github.nagyesta.lowkeyvault.mapper.common.registry.KeyConverterRegistry; import com.github.nagyesta.lowkeyvault.mapper.v7_3.key.KeyRotationPolicyToV73ModelConverter; import com.github.nagyesta.lowkeyvault.mapper.v7_3.key.KeyRotationPolicyV73ModelToEntityConverter; +import com.github.nagyesta.lowkeyvault.model.common.ApiConstants; import com.github.nagyesta.lowkeyvault.model.v7_3.key.KeyRotationPolicyModel; import com.github.nagyesta.lowkeyvault.service.key.KeyVaultFake; import com.github.nagyesta.lowkeyvault.service.key.id.KeyEntityId; -import com.github.nagyesta.lowkeyvault.service.key.id.VersionedKeyEntityId; import com.github.nagyesta.lowkeyvault.service.key.impl.KeyRotationPolicy; import com.github.nagyesta.lowkeyvault.service.vault.VaultFake; import com.github.nagyesta.lowkeyvault.service.vault.VaultService; @@ -22,10 +23,10 @@ import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; +import java.net.URI; import java.util.stream.Stream; import static com.github.nagyesta.lowkeyvault.TestConstantsKeys.KEY_NAME_1; -import static com.github.nagyesta.lowkeyvault.TestConstantsKeys.KEY_VERSION_1; import static com.github.nagyesta.lowkeyvault.TestConstantsUri.HTTPS_LOCALHOST_8443; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.ArgumentMatchers.same; @@ -40,6 +41,8 @@ class KeyPolicyControllerTest { @Mock private KeyVaultFake keyVaultFake; @Mock + private KeyConverterRegistry registry; + @Mock private KeyRotationPolicyToV73ModelConverter keyRotationPolicyToV73ModelConverter; @Mock private KeyRotationPolicyV73ModelToEntityConverter rotationV73ModelToEntityConverter; @@ -48,23 +51,22 @@ class KeyPolicyControllerTest { public static Stream nullProvider() { final VaultService service = mock(VaultService.class); - final KeyRotationPolicyToV73ModelConverter entityConverter = mock(KeyRotationPolicyToV73ModelConverter.class); - final KeyRotationPolicyV73ModelToEntityConverter modelConverter = mock(KeyRotationPolicyV73ModelToEntityConverter.class); + final KeyConverterRegistry registry = mock(KeyConverterRegistry.class); return Stream.builder() - .add(Arguments.of(null, null, null)) - .add(Arguments.of(service, null, null)) - .add(Arguments.of(null, entityConverter, null)) - .add(Arguments.of(null, null, modelConverter)) - .add(Arguments.of(null, entityConverter, modelConverter)) - .add(Arguments.of(service, null, modelConverter)) - .add(Arguments.of(service, entityConverter, null)) + .add(Arguments.of(null, null)) + .add(Arguments.of(service, null)) + .add(Arguments.of(null, registry)) .build(); } @BeforeEach void setUp() { openMocks = MockitoAnnotations.openMocks(this); - underTest = new KeyPolicyController(vaultService, keyRotationPolicyToV73ModelConverter, rotationV73ModelToEntityConverter); + when(registry.rotationPolicyModelConverter(eq(ApiConstants.V_7_3))).thenReturn(keyRotationPolicyToV73ModelConverter); + when(registry.rotationPolicyEntityConverter(eq(ApiConstants.V_7_3))).thenReturn(rotationV73ModelToEntityConverter); + when(registry.versionedEntityId(any(URI.class), anyString(), anyString())).thenCallRealMethod(); + when(registry.entityId(any(URI.class), anyString())).thenCallRealMethod(); + underTest = new KeyPolicyController(registry, vaultService); when(vaultService.findByUri(eq(HTTPS_LOCALHOST_8443))).thenReturn(vaultFake); when(vaultFake.baseUri()).thenReturn(HTTPS_LOCALHOST_8443); when(vaultFake.keyVaultFake()).thenReturn(keyVaultFake); @@ -77,15 +79,12 @@ void tearDown() throws Exception { @ParameterizedTest @MethodSource("nullProvider") - void testConstructorShouldThrowExceptionWhenCalledWithNull( - final VaultService service, - final KeyRotationPolicyToV73ModelConverter entityConverter, - final KeyRotationPolicyV73ModelToEntityConverter modelConverter) { + void testConstructorShouldThrowExceptionWhenCalledWithNull(final VaultService service, final KeyConverterRegistry registry) { //given //when Assertions.assertThrows(IllegalArgumentException.class, - () -> new KeyPolicyController(service, entityConverter, modelConverter)); + () -> new KeyPolicyController(registry, service)); //then + exception } @@ -121,7 +120,7 @@ void testUpdateRotationPolicyShouldReturnTheRotationPolicyWhenItIsAlreadySet() { final KeyRotationPolicyModel output = mock(KeyRotationPolicyModel.class); when(keyVaultFake.rotationPolicy(eq(entityId))) .thenReturn(rotationPolicy); - when(rotationV73ModelToEntityConverter.convert(eq(entityId), same(input))) + when(rotationV73ModelToEntityConverter.convert(same(input))) .thenReturn(rotationPolicy); when(keyRotationPolicyToV73ModelConverter.convert(same(rotationPolicy), eq(HTTPS_LOCALHOST_8443))) .thenReturn(output); @@ -133,22 +132,9 @@ void testUpdateRotationPolicyShouldReturnTheRotationPolicyWhenItIsAlreadySet() { Assertions.assertEquals(HttpStatus.OK, actual.getStatusCode()); Assertions.assertSame(output, actual.getBody()); final InOrder inOrder = inOrder(keyVaultFake, rotationV73ModelToEntityConverter, keyRotationPolicyToV73ModelConverter); - inOrder.verify(rotationV73ModelToEntityConverter).convert(eq(entityId), same(input)); + inOrder.verify(rotationV73ModelToEntityConverter).convert(same(input)); inOrder.verify(keyVaultFake).setRotationPolicy(same(rotationPolicy)); inOrder.verify(keyVaultFake).rotationPolicy(eq(entityId)); inOrder.verify(keyRotationPolicyToV73ModelConverter).convert(same(rotationPolicy), eq(HTTPS_LOCALHOST_8443)); } - - @Test - void testVersionedEntityIdShouldReturnAVersionedKeyEntityIdWhenCalledWithValidInput() { - //given - - //when - final VersionedKeyEntityId actual = underTest.versionedEntityId(HTTPS_LOCALHOST_8443, KEY_NAME_1, KEY_VERSION_1); - - //then - Assertions.assertEquals(HTTPS_LOCALHOST_8443, actual.vault()); - Assertions.assertEquals(KEY_NAME_1, actual.id()); - Assertions.assertEquals(KEY_VERSION_1, actual.version()); - } } diff --git a/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/controller/v7_3/SecretBackupRestoreControllerIntegrationTest.java b/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/controller/v7_3/SecretBackupRestoreControllerIntegrationTest.java index 4e07bf48..517ef2bc 100644 --- a/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/controller/v7_3/SecretBackupRestoreControllerIntegrationTest.java +++ b/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/controller/v7_3/SecretBackupRestoreControllerIntegrationTest.java @@ -2,12 +2,17 @@ import com.github.nagyesta.abortmission.booster.jupiter.annotation.LaunchAbortArmed; import com.github.nagyesta.lowkeyvault.TestConstantsUri; -import com.github.nagyesta.lowkeyvault.mapper.v7_2.secret.SecretEntityToV72ModelConverter; +import com.github.nagyesta.lowkeyvault.mapper.common.registry.SecretConverterRegistry; +import com.github.nagyesta.lowkeyvault.model.common.backup.SecretBackupList; +import com.github.nagyesta.lowkeyvault.model.common.backup.SecretBackupListItem; +import com.github.nagyesta.lowkeyvault.model.common.backup.SecretBackupModel; import com.github.nagyesta.lowkeyvault.model.v7_2.common.constants.RecoveryLevel; -import com.github.nagyesta.lowkeyvault.model.v7_2.secret.*; +import com.github.nagyesta.lowkeyvault.model.v7_2.secret.KeyVaultSecretModel; +import com.github.nagyesta.lowkeyvault.model.v7_2.secret.SecretPropertiesModel; import com.github.nagyesta.lowkeyvault.service.exception.NotFoundException; import com.github.nagyesta.lowkeyvault.service.secret.SecretVaultFake; import com.github.nagyesta.lowkeyvault.service.secret.id.VersionedSecretEntityId; +import com.github.nagyesta.lowkeyvault.service.secret.impl.SecretCreateInput; import com.github.nagyesta.lowkeyvault.service.vault.VaultService; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Assertions; @@ -47,13 +52,9 @@ class SecretBackupRestoreControllerIntegrationTest { public static Stream nullProvider() { return Stream.builder() - .add(Arguments.of(null, null, null)) - .add(Arguments.of(mock(SecretEntityToV72ModelConverter.class), null, null)) - .add(Arguments.of(null, mock(SecretEntityToV72BackupConverter.class), null)) - .add(Arguments.of(null, null, mock(VaultService.class))) - .add(Arguments.of(null, mock(SecretEntityToV72BackupConverter.class), null)) - .add(Arguments.of(mock(SecretEntityToV72ModelConverter.class), null, mock(VaultService.class))) - .add(Arguments.of(mock(SecretEntityToV72ModelConverter.class), mock(SecretEntityToV72BackupConverter.class), null)) + .add(Arguments.of(null, null)) + .add(Arguments.of(mock(SecretConverterRegistry.class), null)) + .add(Arguments.of(null, mock(VaultService.class))) .build(); } @@ -73,14 +74,13 @@ void tearDown() { @ParameterizedTest @MethodSource("nullProvider") void testConstructorShouldThrowExceptionWhenCalledWithNulls( - final SecretEntityToV72ModelConverter modelConverter, - final SecretEntityToV72BackupConverter backupConverter, + final SecretConverterRegistry registry, final VaultService vaultService) { //given //when Assertions.assertThrows(IllegalArgumentException.class, - () -> new SecretBackupRestoreController(modelConverter, backupConverter, vaultService)); + () -> new SecretBackupRestoreController(registry, vaultService)); //then + exception } @@ -171,7 +171,9 @@ void testRestoreEntityShouldThrowExceptionWhenNameMatchesActiveSecret() { backupModel.setValue(new SecretBackupList()); addVersionToList(uri, SECRET_NAME_1, SECRET_VERSION_1, backupModel, TAGS_EMPTY); addVersionToList(uri, SECRET_NAME_1, SECRET_VERSION_2, backupModel, TAGS_ONE_KEY); - vaultService.findByUri(uri).secretVaultFake().createSecretVersion(SECRET_NAME_1, LOWKEY_VAULT, null); + vaultService.findByUri(uri).secretVaultFake().createSecretVersion(SECRET_NAME_1, SecretCreateInput.builder() + .value(LOWKEY_VAULT) + .build()); //when Assertions.assertThrows(IllegalArgumentException.class, () -> underTest.restore(uri, backupModel)); @@ -187,7 +189,9 @@ void testRestoreEntityShouldThrowExceptionWhenNameMatchesDeletedSecret() { addVersionToList(uri, SECRET_NAME_1, SECRET_VERSION_1, backupModel, TAGS_EMPTY); addVersionToList(uri, SECRET_NAME_1, SECRET_VERSION_2, backupModel, TAGS_ONE_KEY); final SecretVaultFake vaultFake = vaultService.findByUri(uri).secretVaultFake(); - final VersionedSecretEntityId secretVersion = vaultFake.createSecretVersion(SECRET_NAME_1, LOWKEY_VAULT, null); + final VersionedSecretEntityId secretVersion = vaultFake.createSecretVersion(SECRET_NAME_1, SecretCreateInput.builder() + .value(LOWKEY_VAULT) + .build()); vaultFake.delete(secretVersion); //when diff --git a/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/controller/v7_3/SecretControllerTest.java b/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/controller/v7_3/SecretControllerTest.java index ef62628f..927f8396 100644 --- a/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/controller/v7_3/SecretControllerTest.java +++ b/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/controller/v7_3/SecretControllerTest.java @@ -1,8 +1,10 @@ package com.github.nagyesta.lowkeyvault.controller.v7_3; +import com.github.nagyesta.lowkeyvault.mapper.common.registry.SecretConverterRegistry; import com.github.nagyesta.lowkeyvault.mapper.v7_2.secret.SecretEntityToV72ModelConverter; import com.github.nagyesta.lowkeyvault.mapper.v7_2.secret.SecretEntityToV72SecretItemModelConverter; import com.github.nagyesta.lowkeyvault.mapper.v7_2.secret.SecretEntityToV72SecretVersionItemModelConverter; +import com.github.nagyesta.lowkeyvault.model.common.ApiConstants; import com.github.nagyesta.lowkeyvault.model.common.KeyVaultItemListModel; import com.github.nagyesta.lowkeyvault.model.v7_2.BasePropertiesUpdateModel; import com.github.nagyesta.lowkeyvault.model.v7_2.common.constants.RecoveryLevel; @@ -16,6 +18,7 @@ import com.github.nagyesta.lowkeyvault.service.secret.id.SecretEntityId; import com.github.nagyesta.lowkeyvault.service.secret.id.VersionedSecretEntityId; import com.github.nagyesta.lowkeyvault.service.secret.impl.KeyVaultSecretEntity; +import com.github.nagyesta.lowkeyvault.service.secret.impl.SecretCreateInput; import com.github.nagyesta.lowkeyvault.service.vault.VaultFake; import com.github.nagyesta.lowkeyvault.service.vault.VaultService; import org.junit.jupiter.api.AfterEach; @@ -25,6 +28,7 @@ import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; +import org.mockito.ArgumentCaptor; import org.mockito.InOrder; import org.mockito.Mock; import org.mockito.MockitoAnnotations; @@ -63,6 +67,8 @@ class SecretControllerTest { @Mock private SecretVaultFake secretVaultFake; @Mock + private SecretConverterRegistry registry; + @Mock private ReadOnlyVersionedEntityMultiMap entities; @Mock private ReadOnlyVersionedEntityMultiMap deletedEntities; @@ -105,19 +111,10 @@ public static Stream secretAttributeProvider() { } public static Stream nullProvider() { - final SecretEntityToV72ModelConverter ec = mock(SecretEntityToV72ModelConverter.class); - final SecretEntityToV72SecretItemModelConverter ic = mock(SecretEntityToV72SecretItemModelConverter.class); - final SecretEntityToV72SecretVersionItemModelConverter vic = mock(SecretEntityToV72SecretVersionItemModelConverter.class); return Stream.builder() - .add(Arguments.of(null, null, null, null)) - .add(Arguments.of(ec, null, null, null)) - .add(Arguments.of(null, ic, null, null)) - .add(Arguments.of(null, null, vic, null)) - .add(Arguments.of(null, null, null, mock(VaultService.class))) - .add(Arguments.of(null, ic, vic, mock(VaultService.class))) - .add(Arguments.of(ec, null, vic, mock(VaultService.class))) - .add(Arguments.of(ec, ic, null, mock(VaultService.class))) - .add(Arguments.of(ec, ic, vic, null)) + .add(Arguments.of(null, null)) + .add(Arguments.of(mock(SecretConverterRegistry.class), null)) + .add(Arguments.of(null, mock(VaultService.class))) .build(); } @@ -136,8 +133,13 @@ public static Stream updateAttributeProvider() { @BeforeEach void setUp() { openMocks = MockitoAnnotations.openMocks(this); - underTest = new SecretController(secretEntityToV72ModelConverter, secretEntityToV72SecretItemModelConverter, - secretEntityToV72SecretVersionItemModelConverter, vaultService); + when(registry.modelConverter(eq(ApiConstants.V_7_3))).thenReturn(secretEntityToV72ModelConverter); + when(registry.itemConverter(eq(ApiConstants.V_7_3))).thenReturn(secretEntityToV72SecretItemModelConverter); + when(registry.versionedItemConverter(eq(ApiConstants.V_7_3))) + .thenReturn(secretEntityToV72SecretVersionItemModelConverter); + when(registry.versionedEntityId(any(URI.class), anyString(), anyString())).thenCallRealMethod(); + when(registry.entityId(any(URI.class), anyString())).thenCallRealMethod(); + underTest = new SecretController(registry, vaultService); when(vaultService.findByUri(eq(HTTPS_LOCALHOST_8443))).thenReturn(vaultFake); when(vaultFake.baseUri()).thenReturn(HTTPS_LOCALHOST_8443); when(vaultFake.secretVaultFake()).thenReturn(secretVaultFake); @@ -151,16 +153,13 @@ void tearDown() throws Exception { @ParameterizedTest @MethodSource("nullProvider") void testConstructorShouldThrowExceptionWhenCalledWithNull( - final SecretEntityToV72ModelConverter secretEntityToV72ModelConverter, - final SecretEntityToV72SecretItemModelConverter secretEntityToV72SecretItemModelConverter, - final SecretEntityToV72SecretVersionItemModelConverter secretEntityToV72SecretVersionItemModelConverter, + final SecretConverterRegistry registry, final VaultService vaultService) { //given //when Assertions.assertThrows(IllegalArgumentException.class, - () -> new SecretController(secretEntityToV72ModelConverter, secretEntityToV72SecretItemModelConverter, - secretEntityToV72SecretVersionItemModelConverter, vaultService)); + () -> new SecretController(registry, vaultService)); //then + exception } @@ -175,7 +174,8 @@ void testCreateShouldUseInputParametersWhenCalled( when(vaultFake.getRecoverableDays()).thenReturn(null); final CreateSecretRequest request = createRequest(expiry, notBefore); final ReadOnlyKeyVaultSecretEntity entity = createEntity(VERSIONED_SECRET_ENTITY_ID_1_VERSION_1, request); - when(secretVaultFake.createSecretVersion(eq(SECRET_NAME_1), eq(request.getValue()), eq(request.getContentType()))) + final ArgumentCaptor input = ArgumentCaptor.forClass(SecretCreateInput.class); + when(secretVaultFake.createSecretVersion(eq(SECRET_NAME_1), input.capture())) .thenReturn(VERSIONED_SECRET_ENTITY_ID_1_VERSION_1); when(secretVaultFake.getEntities()) .thenReturn(entities); @@ -197,13 +197,14 @@ void testCreateShouldUseInputParametersWhenCalled( Assertions.assertSame(RESPONSE, actual.getBody()); verify(vaultService).findByUri(eq(HTTPS_LOCALHOST_8443)); verify(vaultFake).secretVaultFake(); - verify(secretVaultFake).createSecretVersion(eq(SECRET_NAME_1), eq(request.getValue()), eq(request.getContentType())); + verify(secretVaultFake).createSecretVersion(eq(SECRET_NAME_1), any(SecretCreateInput.class)); verify(vaultFake).getRecoveryLevel(); verify(vaultFake).getRecoverableDays(); - verify(secretVaultFake).setExpiry(eq(VERSIONED_SECRET_ENTITY_ID_1_VERSION_1), eq(notBefore), eq(expiry)); - verify(secretVaultFake).setEnabled(eq(VERSIONED_SECRET_ENTITY_ID_1_VERSION_1), eq(true)); - verify(secretVaultFake).addTags(eq(VERSIONED_SECRET_ENTITY_ID_1_VERSION_1), same(TAGS_TWO_KEYS)); - verify(secretEntityToV72ModelConverter).convert(same(entity), eq(HTTPS_LOCALHOST_8443)); + final SecretCreateInput captured = input.getValue(); + Assertions.assertEquals(request.getValue(), captured.getValue()); + Assertions.assertEquals(request.getContentType(), captured.getContentType()); + Assertions.assertEquals(request.getProperties().getExpiresOn(), captured.getExpiresOn()); + Assertions.assertEquals(request.getProperties().getNotBefore(), captured.getNotBefore()); } @Test diff --git a/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/mapper/v7_2/key/KeyEntityToV72KeyItemModelConverterTest.java b/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/mapper/v7_2/key/KeyEntityToV72KeyItemModelConverterTest.java index d7bf03f9..2ca22a10 100644 --- a/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/mapper/v7_2/key/KeyEntityToV72KeyItemModelConverterTest.java +++ b/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/mapper/v7_2/key/KeyEntityToV72KeyItemModelConverterTest.java @@ -1,6 +1,7 @@ package com.github.nagyesta.lowkeyvault.mapper.v7_2.key; import com.github.nagyesta.lowkeyvault.TestConstants; +import com.github.nagyesta.lowkeyvault.mapper.common.registry.KeyConverterRegistry; import com.github.nagyesta.lowkeyvault.model.v7_2.key.DeletedKeyVaultKeyItemModel; import com.github.nagyesta.lowkeyvault.model.v7_2.key.KeyVaultKeyItemModel; import com.github.nagyesta.lowkeyvault.service.key.KeyVaultFake; @@ -15,7 +16,6 @@ import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; -import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.MockitoAnnotations; @@ -28,14 +28,12 @@ import static com.github.nagyesta.lowkeyvault.TestConstantsKeys.*; import static com.github.nagyesta.lowkeyvault.TestConstantsUri.HTTPS_LOCALHOST_8443; import static com.github.nagyesta.lowkeyvault.TestConstantsUri.HTTPS_LOWKEY_VAULT; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; class KeyEntityToV72KeyItemModelConverterTest { - @InjectMocks private KeyEntityToV72KeyItemModelConverter underTest; @Mock private KeyEntityToV72PropertiesModelConverter propertiesModelConverter; @@ -43,6 +41,8 @@ class KeyEntityToV72KeyItemModelConverterTest { private VaultFake vault; @Mock private KeyVaultFake keyVault; + @Mock + private KeyConverterRegistry registry; private AutoCloseable openMocks; @@ -110,6 +110,8 @@ private static DeletedKeyVaultKeyItemModel deletedKeyVaultKeyItemModel( @BeforeEach void setUp() { openMocks = MockitoAnnotations.openMocks(this); + underTest = new KeyEntityToV72KeyItemModelConverter(registry); + when(registry.propertiesConverter(anyString())).thenReturn(propertiesModelConverter); when(vault.keyVaultFake()).thenReturn(keyVault); when(propertiesModelConverter.convert(any(ReadOnlyKeyVaultKeyEntity.class), any(URI.class))).thenReturn(PROPERTIES_MODEL); } diff --git a/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/mapper/v7_2/key/KeyEntityToV72KeyVersionItemModelConverterTest.java b/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/mapper/v7_2/key/KeyEntityToV72KeyVersionItemModelConverterTest.java index 4d779a20..55e4013c 100644 --- a/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/mapper/v7_2/key/KeyEntityToV72KeyVersionItemModelConverterTest.java +++ b/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/mapper/v7_2/key/KeyEntityToV72KeyVersionItemModelConverterTest.java @@ -1,5 +1,6 @@ package com.github.nagyesta.lowkeyvault.mapper.v7_2.key; +import com.github.nagyesta.lowkeyvault.mapper.common.registry.KeyConverterRegistry; import com.github.nagyesta.lowkeyvault.model.v7_2.key.KeyVaultKeyItemModel; import com.github.nagyesta.lowkeyvault.service.key.KeyVaultFake; import com.github.nagyesta.lowkeyvault.service.key.ReadOnlyKeyVaultKeyEntity; @@ -13,7 +14,6 @@ import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; -import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.MockitoAnnotations; @@ -25,14 +25,12 @@ import static com.github.nagyesta.lowkeyvault.TestConstantsKeys.*; import static com.github.nagyesta.lowkeyvault.TestConstantsUri.HTTPS_LOCALHOST_8443; import static com.github.nagyesta.lowkeyvault.TestConstantsUri.HTTPS_LOWKEY_VAULT; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; class KeyEntityToV72KeyVersionItemModelConverterTest { - @InjectMocks private KeyEntityToV72KeyVersionItemModelConverter underTest; @Mock private KeyEntityToV72PropertiesModelConverter propertiesModelConverter; @@ -40,6 +38,8 @@ class KeyEntityToV72KeyVersionItemModelConverterTest { private VaultFake vault; @Mock private KeyVaultFake keyVault; + @Mock + private KeyConverterRegistry registry; private AutoCloseable openMocks; @@ -61,6 +61,8 @@ public static Stream validInputProvider() { @BeforeEach void setUp() { openMocks = MockitoAnnotations.openMocks(this); + underTest = new KeyEntityToV72KeyVersionItemModelConverter(registry); + when(registry.propertiesConverter(anyString())).thenReturn(propertiesModelConverter); when(vault.keyVaultFake()).thenReturn(keyVault); when(propertiesModelConverter.convert(any(ReadOnlyKeyVaultKeyEntity.class), any(URI.class))).thenReturn(PROPERTIES_MODEL); } diff --git a/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/mapper/v7_2/key/KeyEntityToV72ModelConverterTest.java b/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/mapper/v7_2/key/KeyEntityToV72ModelConverterTest.java index b4f6712f..d273c409 100644 --- a/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/mapper/v7_2/key/KeyEntityToV72ModelConverterTest.java +++ b/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/mapper/v7_2/key/KeyEntityToV72ModelConverterTest.java @@ -1,5 +1,6 @@ package com.github.nagyesta.lowkeyvault.mapper.v7_2.key; +import com.github.nagyesta.lowkeyvault.mapper.common.registry.KeyConverterRegistry; import com.github.nagyesta.lowkeyvault.model.v7_2.key.KeyVaultKeyModel; import com.github.nagyesta.lowkeyvault.model.v7_2.key.constants.KeyCurveName; import com.github.nagyesta.lowkeyvault.model.v7_2.key.constants.KeyType; @@ -30,8 +31,7 @@ import static com.github.nagyesta.lowkeyvault.TestConstantsKeys.*; import static com.github.nagyesta.lowkeyvault.TestConstantsUri.HTTPS_LOCALHOST_8443; import static com.github.nagyesta.lowkeyvault.TestConstantsUri.HTTPS_LOWKEY_VAULT; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -45,6 +45,8 @@ class KeyEntityToV72ModelConverterTest { private VaultFake vault; @Mock private KeyVaultFake keyVault; + @Mock + private KeyConverterRegistry registry; private AutoCloseable openMocks; @@ -81,6 +83,10 @@ public static Stream validOctInputProvider() { @BeforeEach void setUp() { openMocks = MockitoAnnotations.openMocks(this); + //Use any as the converter supports both versions and the internal call might use the latest version + when(registry.propertiesConverter(anyString())).thenReturn(propertiesModelConverter); + when(registry.versionedEntityId(any(URI.class), anyString(), anyString())).thenCallRealMethod(); + when(registry.entityId(any(URI.class), anyString())).thenCallRealMethod(); when(vault.keyVaultFake()).thenReturn(keyVault); when(propertiesModelConverter.convert(any(ReadOnlyKeyVaultKeyEntity.class), any(URI.class))).thenReturn(PROPERTIES_MODEL); } diff --git a/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/mapper/v7_2/key/KeyEntityToV72PropertiesModelConverterTest.java b/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/mapper/v7_2/key/KeyEntityToV72PropertiesModelConverterTest.java index ceafea4e..ba033ad4 100644 --- a/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/mapper/v7_2/key/KeyEntityToV72PropertiesModelConverterTest.java +++ b/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/mapper/v7_2/key/KeyEntityToV72PropertiesModelConverterTest.java @@ -1,5 +1,6 @@ package com.github.nagyesta.lowkeyvault.mapper.v7_2.key; +import com.github.nagyesta.lowkeyvault.mapper.common.registry.KeyConverterRegistry; import com.github.nagyesta.lowkeyvault.model.v7_2.common.constants.RecoveryLevel; import com.github.nagyesta.lowkeyvault.model.v7_2.key.KeyPropertiesModel; import com.github.nagyesta.lowkeyvault.model.v7_2.key.constants.EncryptionAlgorithm; @@ -12,10 +13,10 @@ import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; -import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.MockitoAnnotations; @@ -31,13 +32,13 @@ class KeyEntityToV72PropertiesModelConverterTest { - @InjectMocks private KeyEntityToV72PropertiesModelConverter underTest; @Mock private VaultFake vault; @Mock private KeyVaultFake keyVault; - + @Mock + private KeyConverterRegistry registry; private AutoCloseable openMocks; public static Stream validInputProvider() { @@ -56,6 +57,7 @@ public static Stream validInputProvider() { @BeforeEach void setUp() { openMocks = MockitoAnnotations.openMocks(this); + underTest = new KeyEntityToV72PropertiesModelConverter(registry); when(vault.keyVaultFake()).thenReturn(keyVault); when(vault.baseUri()).thenReturn(HTTPS_LOCALHOST); when(vault.matches(eq(HTTPS_LOCALHOST))).thenReturn(true); @@ -66,6 +68,17 @@ void tearDown() throws Exception { openMocks.close(); } + @SuppressWarnings("DataFlowIssue") + @Test + void testConstructorShouldThrowExceptionWhenCalledWithNull() { + //given + + //when + Assertions.assertThrows(IllegalArgumentException.class, () -> new KeyEntityToV72PropertiesModelConverter(null)); + + //then + exception + } + @ParameterizedTest @MethodSource("validInputProvider") void testConvertShouldConvertAllFieldsWhenTheyAreSet( diff --git a/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/mapper/v7_2/secret/SecretEntityToV72ModelConverterTest.java b/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/mapper/v7_2/secret/SecretEntityToV72ModelConverterTest.java index cf18f02f..9c500976 100644 --- a/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/mapper/v7_2/secret/SecretEntityToV72ModelConverterTest.java +++ b/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/mapper/v7_2/secret/SecretEntityToV72ModelConverterTest.java @@ -1,5 +1,6 @@ package com.github.nagyesta.lowkeyvault.mapper.v7_2.secret; +import com.github.nagyesta.lowkeyvault.mapper.common.registry.SecretConverterRegistry; import com.github.nagyesta.lowkeyvault.model.v7_2.secret.KeyVaultSecretModel; import com.github.nagyesta.lowkeyvault.service.secret.ReadOnlyKeyVaultSecretEntity; import com.github.nagyesta.lowkeyvault.service.secret.SecretVaultFake; @@ -13,7 +14,6 @@ import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; -import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.MockitoAnnotations; @@ -26,15 +26,13 @@ import static com.github.nagyesta.lowkeyvault.TestConstantsSecrets.*; import static com.github.nagyesta.lowkeyvault.TestConstantsUri.HTTPS_LOCALHOST_8443; import static com.github.nagyesta.lowkeyvault.TestConstantsUri.HTTPS_LOWKEY_VAULT; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import static org.springframework.util.MimeTypeUtils.APPLICATION_XML; class SecretEntityToV72ModelConverterTest { - @InjectMocks private SecretEntityToV72ModelConverter underTest; @Mock private SecretEntityToV72PropertiesModelConverter propertiesModelConverter; @@ -42,6 +40,8 @@ class SecretEntityToV72ModelConverterTest { private VaultFake vault; @Mock private SecretVaultFake secretVault; + @Mock + private SecretConverterRegistry registry; private AutoCloseable openMocks; @@ -58,6 +58,8 @@ public static Stream validInputProvider() { @BeforeEach void setUp() { openMocks = MockitoAnnotations.openMocks(this); + underTest = new SecretEntityToV72ModelConverter(registry); + when(registry.propertiesConverter(anyString())).thenReturn(propertiesModelConverter); when(vault.secretVaultFake()).thenReturn(secretVault); when(propertiesModelConverter.convert(any(ReadOnlyKeyVaultSecretEntity.class), any(URI.class))) .thenReturn(SECRET_PROPERTIES_MODEL); diff --git a/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/mapper/v7_2/secret/SecretEntityToV72PropertiesModelConverterTest.java b/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/mapper/v7_2/secret/SecretEntityToV72PropertiesModelConverterTest.java index 9b3b7810..2b78979a 100644 --- a/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/mapper/v7_2/secret/SecretEntityToV72PropertiesModelConverterTest.java +++ b/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/mapper/v7_2/secret/SecretEntityToV72PropertiesModelConverterTest.java @@ -1,5 +1,6 @@ package com.github.nagyesta.lowkeyvault.mapper.v7_2.secret; +import com.github.nagyesta.lowkeyvault.mapper.common.registry.SecretConverterRegistry; import com.github.nagyesta.lowkeyvault.model.v7_2.common.constants.RecoveryLevel; import com.github.nagyesta.lowkeyvault.model.v7_2.secret.SecretPropertiesModel; import com.github.nagyesta.lowkeyvault.service.secret.SecretVaultFake; @@ -8,10 +9,10 @@ import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; -import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.MockitoAnnotations; @@ -27,12 +28,13 @@ class SecretEntityToV72PropertiesModelConverterTest { - @InjectMocks private SecretEntityToV72PropertiesModelConverter underTest; @Mock private VaultFake vault; @Mock private SecretVaultFake secretVault; + @Mock + private SecretConverterRegistry registry; private AutoCloseable openMocks; @@ -52,6 +54,7 @@ public static Stream validInputProvider() { @BeforeEach void setUp() { openMocks = MockitoAnnotations.openMocks(this); + underTest = new SecretEntityToV72PropertiesModelConverter(registry); when(vault.secretVaultFake()).thenReturn(secretVault); when(vault.baseUri()).thenReturn(HTTPS_LOCALHOST); when(vault.matches(eq(HTTPS_LOCALHOST))).thenReturn(true); @@ -62,6 +65,17 @@ void tearDown() throws Exception { openMocks.close(); } + @SuppressWarnings("DataFlowIssue") + @Test + void testConstructorShouldThrowExceptionWhenCalledWithNull() { + //given + + //when + Assertions.assertThrows(IllegalArgumentException.class, () -> new SecretEntityToV72PropertiesModelConverter(null)); + + //then + exception + } + @ParameterizedTest @MethodSource("validInputProvider") void testConvertShouldConvertAllFieldsWhenTheyAreSet( diff --git a/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/mapper/v7_2/secret/SecretEntityToV72SecretItemModelConverterTest.java b/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/mapper/v7_2/secret/SecretEntityToV72SecretItemModelConverterTest.java index f751521d..c8aa2271 100644 --- a/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/mapper/v7_2/secret/SecretEntityToV72SecretItemModelConverterTest.java +++ b/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/mapper/v7_2/secret/SecretEntityToV72SecretItemModelConverterTest.java @@ -1,6 +1,7 @@ package com.github.nagyesta.lowkeyvault.mapper.v7_2.secret; import com.github.nagyesta.lowkeyvault.TestConstants; +import com.github.nagyesta.lowkeyvault.mapper.common.registry.SecretConverterRegistry; import com.github.nagyesta.lowkeyvault.model.v7_2.secret.DeletedKeyVaultSecretItemModel; import com.github.nagyesta.lowkeyvault.model.v7_2.secret.KeyVaultSecretItemModel; import com.github.nagyesta.lowkeyvault.service.secret.ReadOnlyKeyVaultSecretEntity; @@ -15,7 +16,6 @@ import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; -import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.MockitoAnnotations; @@ -28,14 +28,12 @@ import static com.github.nagyesta.lowkeyvault.TestConstantsSecrets.*; import static com.github.nagyesta.lowkeyvault.TestConstantsUri.HTTPS_LOCALHOST_8443; import static com.github.nagyesta.lowkeyvault.TestConstantsUri.HTTPS_LOWKEY_VAULT; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; class SecretEntityToV72SecretItemModelConverterTest { - @InjectMocks private SecretEntityToV72SecretItemModelConverter underTest; @Mock private SecretEntityToV72PropertiesModelConverter propertiesModelConverter; @@ -43,6 +41,8 @@ class SecretEntityToV72SecretItemModelConverterTest { private VaultFake vault; @Mock private SecretVaultFake secretVault; + @Mock + private SecretConverterRegistry registry; private AutoCloseable openMocks; @@ -110,6 +110,8 @@ private static DeletedKeyVaultSecretItemModel deletedKeyVaultSecretItemModel( @BeforeEach void setUp() { openMocks = MockitoAnnotations.openMocks(this); + underTest = new SecretEntityToV72SecretItemModelConverter(registry); + when(registry.propertiesConverter(anyString())).thenReturn(propertiesModelConverter); when(vault.secretVaultFake()).thenReturn(secretVault); when(propertiesModelConverter.convert(any(ReadOnlyKeyVaultSecretEntity.class), any(URI.class))) .thenReturn(SECRET_PROPERTIES_MODEL); diff --git a/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/mapper/v7_2/secret/SecretEntityToV72SecretVersionItemModelConverterTest.java b/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/mapper/v7_2/secret/SecretEntityToV72SecretVersionItemModelConverterTest.java index 37b3c979..c6d7eeb9 100644 --- a/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/mapper/v7_2/secret/SecretEntityToV72SecretVersionItemModelConverterTest.java +++ b/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/mapper/v7_2/secret/SecretEntityToV72SecretVersionItemModelConverterTest.java @@ -1,5 +1,6 @@ package com.github.nagyesta.lowkeyvault.mapper.v7_2.secret; +import com.github.nagyesta.lowkeyvault.mapper.common.registry.SecretConverterRegistry; import com.github.nagyesta.lowkeyvault.model.v7_2.secret.KeyVaultSecretItemModel; import com.github.nagyesta.lowkeyvault.service.secret.ReadOnlyKeyVaultSecretEntity; import com.github.nagyesta.lowkeyvault.service.secret.SecretVaultFake; @@ -13,7 +14,6 @@ import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; -import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.MockitoAnnotations; @@ -25,14 +25,12 @@ import static com.github.nagyesta.lowkeyvault.TestConstantsSecrets.*; import static com.github.nagyesta.lowkeyvault.TestConstantsUri.HTTPS_LOCALHOST_8443; import static com.github.nagyesta.lowkeyvault.TestConstantsUri.HTTPS_LOWKEY_VAULT; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; class SecretEntityToV72SecretVersionItemModelConverterTest { - @InjectMocks private SecretEntityToV72SecretVersionItemModelConverter underTest; @Mock private SecretEntityToV72PropertiesModelConverter propertiesModelConverter; @@ -40,6 +38,8 @@ class SecretEntityToV72SecretVersionItemModelConverterTest { private VaultFake vault; @Mock private SecretVaultFake secretVault; + @Mock + private SecretConverterRegistry registry; private AutoCloseable openMocks; @@ -69,6 +69,8 @@ private static KeyVaultSecretItemModel secretVaultSecretItemModel(final URI asUr @BeforeEach void setUp() { openMocks = MockitoAnnotations.openMocks(this); + underTest = new SecretEntityToV72SecretVersionItemModelConverter(registry); + when(registry.propertiesConverter(anyString())).thenReturn(propertiesModelConverter); when(vault.secretVaultFake()).thenReturn(secretVault); when(propertiesModelConverter.convert(any(ReadOnlyKeyVaultSecretEntity.class), any(URI.class))) .thenReturn(SECRET_PROPERTIES_MODEL); diff --git a/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/mapper/v7_3/certificate/CertificateEntityToV73CertificateItemModelConverterTest.java b/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/mapper/v7_3/certificate/CertificateEntityToV73CertificateItemModelConverterTest.java index 64c600be..512388f6 100644 --- a/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/mapper/v7_3/certificate/CertificateEntityToV73CertificateItemModelConverterTest.java +++ b/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/mapper/v7_3/certificate/CertificateEntityToV73CertificateItemModelConverterTest.java @@ -1,6 +1,8 @@ package com.github.nagyesta.lowkeyvault.mapper.v7_3.certificate; import com.github.nagyesta.lowkeyvault.TestConstantsCertificates; +import com.github.nagyesta.lowkeyvault.mapper.common.registry.CertificateConverterRegistry; +import com.github.nagyesta.lowkeyvault.model.common.ApiConstants; import com.github.nagyesta.lowkeyvault.model.v7_3.certificate.CertificatePropertiesModel; import com.github.nagyesta.lowkeyvault.model.v7_3.certificate.KeyVaultCertificateItemModel; import com.github.nagyesta.lowkeyvault.service.certificate.ReadOnlyKeyVaultCertificateEntity; @@ -35,9 +37,11 @@ void testConstructorShouldThrowExceptionWhenCalledWithNull() { @Test void testConvertCertificateIdShouldNotContainVersionWhenCalled() { //given - final CertificateEntityToV73CertificateItemModelConverter underTest - = new CertificateEntityToV73CertificateItemModelConverter( - mock(CertificateEntityToV73PropertiesModelConverter.class)); + final CertificateEntityToV73PropertiesModelConverter properties = mock(CertificateEntityToV73PropertiesModelConverter.class); + final CertificateConverterRegistry registry = mock(CertificateConverterRegistry.class); + when(registry.propertiesConverter(eq(ApiConstants.V_7_3))).thenReturn(properties); + final CertificateEntityToV73CertificateItemModelConverter underTest = + new CertificateEntityToV73CertificateItemModelConverter(registry); final ReadOnlyKeyVaultCertificateEntity input = mock(ReadOnlyKeyVaultCertificateEntity.class); when(input.getId()).thenReturn(TestConstantsCertificates.VERSIONED_CERT_ENTITY_ID_1_VERSION_3); @@ -51,15 +55,15 @@ void testConvertCertificateIdShouldNotContainVersionWhenCalled() { @Test void testConvertShouldMapThumbprintWhenCalledWithValidData() { //given - final CertificateEntityToV73PropertiesModelConverter propertiesModelConverter = - mock(CertificateEntityToV73PropertiesModelConverter.class); - - final CertificateEntityToV73CertificateItemModelConverter underTest - = new CertificateEntityToV73CertificateItemModelConverter(propertiesModelConverter); + final CertificateEntityToV73PropertiesModelConverter properties = mock(CertificateEntityToV73PropertiesModelConverter.class); + final CertificateConverterRegistry registry = mock(CertificateConverterRegistry.class); + when(registry.propertiesConverter(eq(ApiConstants.V_7_3))).thenReturn(properties); + final CertificateEntityToV73CertificateItemModelConverter underTest = + new CertificateEntityToV73CertificateItemModelConverter(registry); final byte[] expectedThumbprint = THUMBPRINT; final ReadOnlyKeyVaultCertificateEntity input = mock(ReadOnlyKeyVaultCertificateEntity.class); final CertificatePropertiesModel propertiesModel = new CertificatePropertiesModel(); - when(propertiesModelConverter.convert(same(input), eq(HTTPS_LOCALHOST_8443))).thenReturn(propertiesModel); + when(properties.convert(same(input), eq(HTTPS_LOCALHOST_8443))).thenReturn(propertiesModel); when(input.getId()).thenReturn(TestConstantsCertificates.VERSIONED_CERT_ENTITY_ID_1_VERSION_3); when(input.getThumbprint()).thenReturn(expectedThumbprint); when(input.getTags()).thenReturn(TAGS_ONE_KEY); @@ -74,6 +78,6 @@ void testConvertShouldMapThumbprintWhenCalledWithValidData() { Assertions.assertSame(propertiesModel, actual.getAttributes()); Assertions.assertTrue(actual.getAttributes().isEnabled()); Assertions.assertEquals(TAGS_ONE_KEY, actual.getTags()); - verify(propertiesModelConverter).convert(same(input), eq(HTTPS_LOCALHOST_8443)); + verify(properties).convert(same(input), eq(HTTPS_LOCALHOST_8443)); } } diff --git a/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/mapper/v7_3/certificate/CertificateEntityToV73CertificateVersionItemModelConverterTest.java b/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/mapper/v7_3/certificate/CertificateEntityToV73CertificateVersionItemModelConverterTest.java index 7b9f37cb..b7028531 100644 --- a/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/mapper/v7_3/certificate/CertificateEntityToV73CertificateVersionItemModelConverterTest.java +++ b/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/mapper/v7_3/certificate/CertificateEntityToV73CertificateVersionItemModelConverterTest.java @@ -1,6 +1,8 @@ package com.github.nagyesta.lowkeyvault.mapper.v7_3.certificate; import com.github.nagyesta.lowkeyvault.TestConstantsCertificates; +import com.github.nagyesta.lowkeyvault.mapper.common.registry.CertificateConverterRegistry; +import com.github.nagyesta.lowkeyvault.model.common.ApiConstants; import com.github.nagyesta.lowkeyvault.service.certificate.ReadOnlyKeyVaultCertificateEntity; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; @@ -8,6 +10,7 @@ import static com.github.nagyesta.lowkeyvault.TestConstantsCertificates.CERT_NAME_1; import static com.github.nagyesta.lowkeyvault.TestConstantsCertificates.CERT_VERSION_3; import static com.github.nagyesta.lowkeyvault.TestConstantsUri.HTTPS_LOWKEY_VAULT; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -29,9 +32,12 @@ void testConstructorShouldThrowExceptionWhenCalledWithNull() { @Test void testConvertCertificateIdShouldContainVersionWhenCalled() { //given - final CertificateEntityToV73CertificateVersionItemModelConverter underTest - = new CertificateEntityToV73CertificateVersionItemModelConverter( - mock(CertificateEntityToV73PropertiesModelConverter.class)); + final CertificateConverterRegistry registry = mock(CertificateConverterRegistry.class); + final CertificateEntityToV73PropertiesModelConverter properties = mock(CertificateEntityToV73PropertiesModelConverter.class); + when(registry.propertiesConverter(eq(ApiConstants.V_7_3))).thenReturn(properties); + registry.registerPropertiesConverter(properties); + final CertificateEntityToV73CertificateVersionItemModelConverter underTest = + new CertificateEntityToV73CertificateVersionItemModelConverter(registry); final ReadOnlyKeyVaultCertificateEntity input = mock(ReadOnlyKeyVaultCertificateEntity.class); when(input.getId()).thenReturn(TestConstantsCertificates.VERSIONED_CERT_ENTITY_ID_1_VERSION_3); diff --git a/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/mapper/v7_3/certificate/CertificateEntityToV73IssuancePolicyModelConverterTest.java b/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/mapper/v7_3/certificate/CertificateEntityToV73IssuancePolicyModelConverterTest.java new file mode 100644 index 00000000..1b240bec --- /dev/null +++ b/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/mapper/v7_3/certificate/CertificateEntityToV73IssuancePolicyModelConverterTest.java @@ -0,0 +1,18 @@ +package com.github.nagyesta.lowkeyvault.mapper.v7_3.certificate; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +class CertificateEntityToV73IssuancePolicyModelConverterTest { + + @SuppressWarnings("DataFlowIssue") + @Test + void testConstructorShouldThrowExceptionWhenCalledWithNull() { + //given + + //when + Assertions.assertThrows(IllegalArgumentException.class, () -> new CertificateEntityToV73IssuancePolicyModelConverter(null)); + + //then + exception + } +} diff --git a/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/mapper/v7_3/certificate/CertificateEntityToV73ModelConverterIntegrationTest.java b/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/mapper/v7_3/certificate/CertificateEntityToV73ModelConverterIntegrationTest.java index 04cb5aad..68fa1123 100644 --- a/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/mapper/v7_3/certificate/CertificateEntityToV73ModelConverterIntegrationTest.java +++ b/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/mapper/v7_3/certificate/CertificateEntityToV73ModelConverterIntegrationTest.java @@ -1,5 +1,6 @@ package com.github.nagyesta.lowkeyvault.mapper.v7_3.certificate; +import com.github.nagyesta.lowkeyvault.mapper.common.registry.CertificateConverterRegistry; import com.github.nagyesta.lowkeyvault.model.v7_2.key.constants.KeyCurveName; import com.github.nagyesta.lowkeyvault.model.v7_2.key.constants.KeyType; import com.github.nagyesta.lowkeyvault.model.v7_3.certificate.CertificatePolicyModel; @@ -39,10 +40,10 @@ class CertificateEntityToV73ModelConverterIntegrationTest { @Test void testConvertShouldConvertValuableFieldsWhenCalledWithValidCertificate() throws CertificateEncodingException { //given - final CertificateEntityToV73PropertiesModelConverter propertiesConverter = new CertificateEntityToV73PropertiesModelConverter(); - final CertificateEntityToV73PolicyModelConverter policyConverter = new CertificateEntityToV73PolicyModelConverter(); - final CertificateEntityToV73ModelConverter underTest = - new CertificateEntityToV73ModelConverter(propertiesConverter, policyConverter); + final CertificateConverterRegistry registry = new CertificateConverterRegistry(); + new CertificateEntityToV73PropertiesModelConverter(registry).afterPropertiesSet(); + new CertificateEntityToV73PolicyModelConverter(registry).afterPropertiesSet(); + final CertificateEntityToV73ModelConverter underTest = new CertificateEntityToV73ModelConverter(registry); final CertificateCreationInput input = CertificateCreationInput.builder() .validityStart(NOW) .subject("CN=" + LOCALHOST) diff --git a/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/mapper/v7_3/certificate/CertificateEntityToV73ModelConverterTest.java b/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/mapper/v7_3/certificate/CertificateEntityToV73ModelConverterTest.java index e1b3b02d..92716326 100644 --- a/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/mapper/v7_3/certificate/CertificateEntityToV73ModelConverterTest.java +++ b/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/mapper/v7_3/certificate/CertificateEntityToV73ModelConverterTest.java @@ -1,34 +1,18 @@ package com.github.nagyesta.lowkeyvault.mapper.v7_3.certificate; import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; - -import java.util.stream.Stream; - -import static org.mockito.Mockito.mock; +import org.junit.jupiter.api.Test; class CertificateEntityToV73ModelConverterTest { - public static Stream nullProvider() { - return Stream.builder() - .add(Arguments.of(null, null)) - .add(Arguments.of(mock(CertificateEntityToV73PropertiesModelConverter.class), null)) - .add(Arguments.of(null, mock(CertificateEntityToV73PolicyModelConverter.class))) - .build(); - } - - @ParameterizedTest - @MethodSource("nullProvider") - void testConstructorShouldThrowExceptionWhenCalledWithNull( - final CertificateEntityToV73PropertiesModelConverter propertiesConverter, - final CertificateEntityToV73PolicyModelConverter policyConverter) { + @SuppressWarnings("DataFlowIssue") + @Test + void testConstructorShouldThrowExceptionWhenCalledWithNull() { //given //when Assertions.assertThrows(IllegalArgumentException.class, - () -> new CertificateEntityToV73ModelConverter(propertiesConverter, policyConverter)); + () -> new CertificateEntityToV73ModelConverter(null)); //then + exceptions } diff --git a/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/mapper/v7_3/certificate/CertificateEntityToV73PendingCertificateOperationModelConverterIntegrationTest.java b/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/mapper/v7_3/certificate/CertificateEntityToV73PendingCertificateOperationModelConverterIntegrationTest.java index 2be93855..65227324 100644 --- a/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/mapper/v7_3/certificate/CertificateEntityToV73PendingCertificateOperationModelConverterIntegrationTest.java +++ b/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/mapper/v7_3/certificate/CertificateEntityToV73PendingCertificateOperationModelConverterIntegrationTest.java @@ -1,5 +1,6 @@ package com.github.nagyesta.lowkeyvault.mapper.v7_3.certificate; +import com.github.nagyesta.lowkeyvault.mapper.common.registry.CertificateConverterRegistry; import com.github.nagyesta.lowkeyvault.model.v7_2.key.constants.KeyCurveName; import com.github.nagyesta.lowkeyvault.model.v7_2.key.constants.KeyType; import com.github.nagyesta.lowkeyvault.model.v7_3.certificate.KeyVaultPendingCertificateModel; @@ -38,12 +39,25 @@ public static Stream nullProvider() { .build(); } + @SuppressWarnings("DataFlowIssue") + @Test + void testConstructorShouldThrowExceptionWhenCalledWithNull() { + //given + + //when + Assertions.assertThrows(IllegalArgumentException.class, + () -> new CertificateEntityToV73PendingCertificateOperationModelConverter(null)); + + //then + exception + } + @ParameterizedTest @MethodSource("nullProvider") void testConvertShouldThrowExceptionWhenCalledWithNulls(final ReadOnlyKeyVaultCertificateEntity source, final URI vaultUri) { //given + final CertificateConverterRegistry registry = mock(CertificateConverterRegistry.class); final CertificateEntityToV73PendingCertificateOperationModelConverter underTest = - new CertificateEntityToV73PendingCertificateOperationModelConverter(); + new CertificateEntityToV73PendingCertificateOperationModelConverter(registry); //when Assertions.assertThrows(IllegalArgumentException.class, () -> underTest.convert(source, vaultUri)); @@ -67,8 +81,9 @@ void testConvertShouldConvertValuableFieldsWhenCalledWithValidInput() { .build(); final VaultFake vault = new VaultFakeImpl(HTTPS_LOWKEY_VAULT); final KeyVaultCertificateEntity source = new KeyVaultCertificateEntity(CERT_NAME_1, input, vault); + final CertificateConverterRegistry registry = mock(CertificateConverterRegistry.class); final CertificateEntityToV73PendingCertificateOperationModelConverter underTest = - new CertificateEntityToV73PendingCertificateOperationModelConverter(); + new CertificateEntityToV73PendingCertificateOperationModelConverter(registry); //when final KeyVaultPendingCertificateModel actual = underTest.convert(source, vault.baseUri()); diff --git a/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/mapper/v7_3/certificate/CertificateEntityToV73PolicyModelConverterTest.java b/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/mapper/v7_3/certificate/CertificateEntityToV73PolicyModelConverterTest.java index 6400124f..be5cf82b 100644 --- a/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/mapper/v7_3/certificate/CertificateEntityToV73PolicyModelConverterTest.java +++ b/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/mapper/v7_3/certificate/CertificateEntityToV73PolicyModelConverterTest.java @@ -7,6 +7,17 @@ class CertificateEntityToV73PolicyModelConverterTest { + @SuppressWarnings("DataFlowIssue") + @Test + void testConstructorShouldThrowExceptionWhenCalledWithNull() { + //given + + //when + Assertions.assertThrows(IllegalArgumentException.class, () -> new CertificateEntityToV73PolicyModelConverter(null)); + + //then + exception + } + @SuppressWarnings("ConstantConditions") @Test void testConstructorShouldThrowExceptionWhenCalledWithNullModelSupplier() { @@ -15,7 +26,11 @@ void testConstructorShouldThrowExceptionWhenCalledWithNullModelSupplier() { //when Assertions.assertThrows(IllegalArgumentException.class, () -> new BaseCertificateEntityToV73PolicyModelConverter(null, - ReadOnlyKeyVaultCertificateEntity::getOriginalCertificatePolicy)); + ReadOnlyKeyVaultCertificateEntity::getOriginalCertificatePolicy) { + @Override + public void afterPropertiesSet() { + } + }); //then + exceptions } @@ -27,7 +42,11 @@ void testConstructorShouldThrowExceptionWhenCalledWithNullPolicyExtractor() { //when Assertions.assertThrows(IllegalArgumentException.class, - () -> new BaseCertificateEntityToV73PolicyModelConverter(CertificatePolicyModel::new, null)); + () -> new BaseCertificateEntityToV73PolicyModelConverter(CertificatePolicyModel::new, null) { + @Override + public void afterPropertiesSet() { + } + }); //then + exceptions } diff --git a/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/mapper/v7_3/certificate/CertificateEntityToV73PropertiesModelConverterTest.java b/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/mapper/v7_3/certificate/CertificateEntityToV73PropertiesModelConverterTest.java new file mode 100644 index 00000000..b62cc2b3 --- /dev/null +++ b/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/mapper/v7_3/certificate/CertificateEntityToV73PropertiesModelConverterTest.java @@ -0,0 +1,18 @@ +package com.github.nagyesta.lowkeyvault.mapper.v7_3.certificate; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +class CertificateEntityToV73PropertiesModelConverterTest { + + @SuppressWarnings("DataFlowIssue") + @Test + void testConstructorShouldThrowExceptionWhenCalledWithNull() { + //given + + //when + Assertions.assertThrows(IllegalArgumentException.class, () -> new CertificateEntityToV73PropertiesModelConverter(null)); + + //then + exception + } +} diff --git a/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/mapper/v7_3/certificate/LifetimeActionsPolicyToV73ModelConverterTest.java b/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/mapper/v7_3/certificate/CertificateLifetimeActionsPolicyToV73ModelConverterTest.java similarity index 78% rename from lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/mapper/v7_3/certificate/LifetimeActionsPolicyToV73ModelConverterTest.java rename to lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/mapper/v7_3/certificate/CertificateLifetimeActionsPolicyToV73ModelConverterTest.java index 4cec7f38..ba2f9e64 100644 --- a/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/mapper/v7_3/certificate/LifetimeActionsPolicyToV73ModelConverterTest.java +++ b/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/mapper/v7_3/certificate/CertificateLifetimeActionsPolicyToV73ModelConverterTest.java @@ -1,5 +1,6 @@ package com.github.nagyesta.lowkeyvault.mapper.v7_3.certificate; +import com.github.nagyesta.lowkeyvault.mapper.common.registry.CertificateConverterRegistry; import com.github.nagyesta.lowkeyvault.model.v7_3.certificate.CertificateLifetimeActionModel; import com.github.nagyesta.lowkeyvault.service.certificate.CertificateLifetimeActionTrigger; import com.github.nagyesta.lowkeyvault.service.certificate.CertificateLifetimeActionTriggerType; @@ -12,8 +13,9 @@ import static com.github.nagyesta.lowkeyvault.TestConstantsCertificates.UNVERSIONED_CERT_ENTITY_ID_1; import static com.github.nagyesta.lowkeyvault.service.certificate.CertificateLifetimeActionActivity.AUTO_RENEW; +import static org.mockito.Mockito.mock; -class LifetimeActionsPolicyToV73ModelConverterTest { +class CertificateLifetimeActionsPolicyToV73ModelConverterTest { public static final CertificateLifetimeActionTrigger TRIGGER_AT_80_PERCENT = new CertificateLifetimeActionTrigger(CertificateLifetimeActionTriggerType.LIFETIME_PERCENTAGE, 80); @@ -21,7 +23,9 @@ class LifetimeActionsPolicyToV73ModelConverterTest { @Test void testConvertShouldConvertPolicyToListWhenCalledWithValidData() { //given - final LifetimeActionsPolicyToV73ModelConverter underTest = new LifetimeActionsPolicyToV73ModelConverter(); + final CertificateConverterRegistry registry = mock(CertificateConverterRegistry.class); + final CertificateLifetimeActionsPolicyToV73ModelConverter underTest = + new CertificateLifetimeActionsPolicyToV73ModelConverter(registry); final CertificateLifetimeActionPolicy source = new CertificateLifetimeActionPolicy( UNVERSIONED_CERT_ENTITY_ID_1, Map.of(AUTO_RENEW, TRIGGER_AT_80_PERCENT)); diff --git a/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/mapper/v7_3/key/KeyRotationPolicyToV73ModelConverterTest.java b/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/mapper/v7_3/key/KeyRotationPolicyToV73ModelConverterTest.java index 3016a779..7afd7074 100644 --- a/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/mapper/v7_3/key/KeyRotationPolicyToV73ModelConverterTest.java +++ b/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/mapper/v7_3/key/KeyRotationPolicyToV73ModelConverterTest.java @@ -1,6 +1,7 @@ package com.github.nagyesta.lowkeyvault.mapper.v7_3.key; import com.github.nagyesta.lowkeyvault.TestConstantsKeys; +import com.github.nagyesta.lowkeyvault.mapper.common.registry.KeyConverterRegistry; import com.github.nagyesta.lowkeyvault.model.v7_3.key.KeyLifetimeActionModel; import com.github.nagyesta.lowkeyvault.model.v7_3.key.KeyRotationPolicyModel; import com.github.nagyesta.lowkeyvault.model.v7_3.key.constants.LifetimeActionType; @@ -18,9 +19,21 @@ import static com.github.nagyesta.lowkeyvault.TestConstants.TIME_10_MINUTES_AGO; import static com.github.nagyesta.lowkeyvault.TestConstants.TIME_IN_10_MINUTES; import static com.github.nagyesta.lowkeyvault.TestConstantsUri.HTTPS_LOCALHOST_8443; +import static org.mockito.Mockito.mock; class KeyRotationPolicyToV73ModelConverterTest { + @SuppressWarnings("DataFlowIssue") + @Test + void testConstructorShouldThrowExceptionWhenCalledWithNull() { + //given + + //when + Assertions.assertThrows(IllegalArgumentException.class, () -> new KeyRotationPolicyToV73ModelConverter(null)); + + //then + exception + } + @Test void testConvertShouldConvertValuableFieldsWhenCalledWithValidData() { //given @@ -33,8 +46,9 @@ void testConvertShouldConvertValuableFieldsWhenCalledWithValidData() { Map.of(LifetimeActionType.NOTIFY, new KeyLifetimeAction(LifetimeActionType.NOTIFY, trigger))); source.setCreatedOn(TIME_10_MINUTES_AGO); source.setUpdatedOn(TIME_IN_10_MINUTES); + final KeyConverterRegistry registry = mock(KeyConverterRegistry.class); - final KeyRotationPolicyToV73ModelConverter underTest = new KeyRotationPolicyToV73ModelConverter(); + final KeyRotationPolicyToV73ModelConverter underTest = new KeyRotationPolicyToV73ModelConverter(registry); //when final KeyRotationPolicyModel actual = underTest.convert(source, HTTPS_LOCALHOST_8443); diff --git a/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/mapper/v7_3/key/KeyRotationPolicyV73ModelToEntityConverterTest.java b/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/mapper/v7_3/key/KeyRotationPolicyV73ModelToEntityConverterTest.java index a613135e..6d9a7846 100644 --- a/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/mapper/v7_3/key/KeyRotationPolicyV73ModelToEntityConverterTest.java +++ b/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/mapper/v7_3/key/KeyRotationPolicyV73ModelToEntityConverterTest.java @@ -1,6 +1,7 @@ package com.github.nagyesta.lowkeyvault.mapper.v7_3.key; import com.github.nagyesta.lowkeyvault.TestConstantsKeys; +import com.github.nagyesta.lowkeyvault.mapper.common.registry.KeyConverterRegistry; import com.github.nagyesta.lowkeyvault.model.v7_3.key.*; import com.github.nagyesta.lowkeyvault.model.v7_3.key.constants.LifetimeActionType; import com.github.nagyesta.lowkeyvault.service.key.LifetimeAction; @@ -16,9 +17,20 @@ import static com.github.nagyesta.lowkeyvault.TestConstants.NOW; import static com.github.nagyesta.lowkeyvault.TestConstants.TIME_10_MINUTES_AGO; import static com.github.nagyesta.lowkeyvault.TestConstantsUri.HTTPS_LOCALHOST_8443; +import static org.mockito.Mockito.mock; class KeyRotationPolicyV73ModelToEntityConverterTest { + @SuppressWarnings("DataFlowIssue") + @Test + void testConstructorShouldThrowExceptionWhenCalledWithNull() { + //given + + //when + Assertions.assertThrows(IllegalArgumentException.class, () -> new KeyRotationPolicyV73ModelToEntityConverter(null)); + + //then + exception + } @Test void testConvertShouldConvertValuableFieldsWhenCalledWithValidData() { //given @@ -30,13 +42,16 @@ void testConvertShouldConvertValuableFieldsWhenCalledWithValidData() { model.setId(keyEntityId.asRotationPolicyUri(HTTPS_LOCALHOST_8443)); model.setAttributes(attributes(expiryTime)); model.setLifetimeActions(List.of(notifyAction(timeBeforeExpiry))); + model.setKeyEntityId(keyEntityId); - final KeyRotationPolicyV73ModelToEntityConverter underTest = new KeyRotationPolicyV73ModelToEntityConverter(); + final KeyConverterRegistry registry = mock(KeyConverterRegistry.class); + final KeyRotationPolicyV73ModelToEntityConverter underTest = new KeyRotationPolicyV73ModelToEntityConverter(registry); //when - final RotationPolicy actual = underTest.convert(keyEntityId, model); + final RotationPolicy actual = underTest.convert(model); //then + Assertions.assertNotNull(actual); Assertions.assertEquals(keyEntityId, actual.getId()); Assertions.assertEquals(TIME_10_MINUTES_AGO, actual.getCreatedOn()); Assertions.assertEquals(NOW, actual.getUpdatedOn()); @@ -60,13 +75,16 @@ void testConvertShouldUseDefaultsWhenCalledWithMinimalAttributes() { final KeyRotationPolicyAttributes attributes = new KeyRotationPolicyAttributes(); attributes.setExpiryTime(expiryTime); model.setAttributes(attributes); + model.setKeyEntityId(keyEntityId); - final KeyRotationPolicyV73ModelToEntityConverter underTest = new KeyRotationPolicyV73ModelToEntityConverter(); + final KeyConverterRegistry registry = mock(KeyConverterRegistry.class); + final KeyRotationPolicyV73ModelToEntityConverter underTest = new KeyRotationPolicyV73ModelToEntityConverter(registry); //when - final RotationPolicy actual = underTest.convert(keyEntityId, model); + final RotationPolicy actual = underTest.convert(model); //then + Assertions.assertNotNull(actual); Assertions.assertEquals(keyEntityId, actual.getId()); Assertions.assertTrue(actual.getCreatedOn().isAfter(NOW)); Assertions.assertTrue(actual.getUpdatedOn().isAfter(NOW)); @@ -86,11 +104,13 @@ void testConvertShouldThrowExceptionWhenCalledWithoutAttributes() { final KeyRotationPolicyModel model = new KeyRotationPolicyModel(); model.setId(keyEntityId.asRotationPolicyUri(HTTPS_LOCALHOST_8443)); model.setLifetimeActions(List.of(notifyAction(timeBeforeExpiry))); + model.setKeyEntityId(keyEntityId); - final KeyRotationPolicyV73ModelToEntityConverter underTest = new KeyRotationPolicyV73ModelToEntityConverter(); + final KeyConverterRegistry registry = mock(KeyConverterRegistry.class); + final KeyRotationPolicyV73ModelToEntityConverter underTest = new KeyRotationPolicyV73ModelToEntityConverter(registry); //when - Assertions.assertThrows(IllegalArgumentException.class, () -> underTest.convert(keyEntityId, model)); + Assertions.assertThrows(IllegalArgumentException.class, () -> underTest.convert(model)); //then + exception } @@ -102,11 +122,13 @@ void testConvertShouldReturnNullWhenCalledWithEmptyModel() { final KeyRotationPolicyModel model = new KeyRotationPolicyModel(); model.setId(keyEntityId.asRotationPolicyUri(HTTPS_LOCALHOST_8443)); + model.setKeyEntityId(keyEntityId); - final KeyRotationPolicyV73ModelToEntityConverter underTest = new KeyRotationPolicyV73ModelToEntityConverter(); + final KeyConverterRegistry registry = mock(KeyConverterRegistry.class); + final KeyRotationPolicyV73ModelToEntityConverter underTest = new KeyRotationPolicyV73ModelToEntityConverter(registry); //when - final RotationPolicy actual = underTest.convert(keyEntityId, model); + final RotationPolicy actual = underTest.convert(model); //then Assertions.assertNull(actual); @@ -121,11 +143,13 @@ void testConvertShouldThrowExceptionWhenCalledWithNoList() { final KeyRotationPolicyModel model = new KeyRotationPolicyModel(); model.setId(keyEntityId.asRotationPolicyUri(HTTPS_LOCALHOST_8443)); model.setAttributes(attributes(expiryTime)); + model.setKeyEntityId(keyEntityId); - final KeyRotationPolicyV73ModelToEntityConverter underTest = new KeyRotationPolicyV73ModelToEntityConverter(); + final KeyConverterRegistry registry = mock(KeyConverterRegistry.class); + final KeyRotationPolicyV73ModelToEntityConverter underTest = new KeyRotationPolicyV73ModelToEntityConverter(registry); //when - Assertions.assertThrows(IllegalArgumentException.class, () -> underTest.convert(keyEntityId, model)); + Assertions.assertThrows(IllegalArgumentException.class, () -> underTest.convert(model)); //then + exception } @@ -138,11 +162,13 @@ void testConvertShouldReturnNullWhenCalledWithoutAttributesAndEmptyList() { final KeyRotationPolicyModel model = new KeyRotationPolicyModel(); model.setId(keyEntityId.asRotationPolicyUri(HTTPS_LOCALHOST_8443)); model.setLifetimeActions(List.of()); + model.setKeyEntityId(keyEntityId); - final KeyRotationPolicyV73ModelToEntityConverter underTest = new KeyRotationPolicyV73ModelToEntityConverter(); + final KeyConverterRegistry registry = mock(KeyConverterRegistry.class); + final KeyRotationPolicyV73ModelToEntityConverter underTest = new KeyRotationPolicyV73ModelToEntityConverter(registry); //when - final RotationPolicy actual = underTest.convert(keyEntityId, model); + final RotationPolicy actual = underTest.convert(model); //then Assertions.assertNull(actual); diff --git a/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/model/json/util/Base64ZipV73KeyDeserializerTest.java b/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/model/json/util/Base64ZipKeyDeserializerTest.java similarity index 82% rename from lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/model/json/util/Base64ZipV73KeyDeserializerTest.java rename to lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/model/json/util/Base64ZipKeyDeserializerTest.java index 603ec4bf..fa0f86ff 100644 --- a/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/model/json/util/Base64ZipV73KeyDeserializerTest.java +++ b/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/model/json/util/Base64ZipKeyDeserializerTest.java @@ -3,7 +3,7 @@ import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.databind.DeserializationContext; import com.fasterxml.jackson.databind.ObjectMapper; -import com.github.nagyesta.lowkeyvault.model.v7_3.key.KeyBackupList; +import com.github.nagyesta.lowkeyvault.model.common.backup.KeyBackupList; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; @@ -11,14 +11,14 @@ import static org.mockito.Mockito.*; -class Base64ZipV73KeyDeserializerTest { +class Base64ZipKeyDeserializerTest { @Test void testDeserializeShouldThrowExceptionWhenDecodingFails() throws IOException { //given final Base64Deserializer base64Deserializer = mock(Base64Deserializer.class); final ObjectMapper objectMapper = mock(ObjectMapper.class); - final Base64ZipV73KeyDeserializer underTest = new Base64ZipV73KeyDeserializer(base64Deserializer, objectMapper); + final Base64ZipKeyDeserializer underTest = new Base64ZipKeyDeserializer(base64Deserializer, objectMapper); final JsonParser jsonParser = mock(JsonParser.class); final DeserializationContext context = mock(DeserializationContext.class); when(base64Deserializer.deserializeBase64(eq(jsonParser))).thenReturn(new byte[1]); @@ -34,7 +34,7 @@ void testDeserializeShouldThrowExceptionWhenDecodingFails() throws IOException { @Test void testDeserializeShouldWriteNullWhenCalledWithNullInput() throws IOException { //given - final Base64ZipV73KeyDeserializer underTest = new Base64ZipV73KeyDeserializer(); + final Base64ZipKeyDeserializer underTest = new Base64ZipKeyDeserializer(); final JsonParser jsonParser = mock(JsonParser.class); when(jsonParser.readValueAs(eq(String.class))).thenReturn(""); final DeserializationContext context = mock(DeserializationContext.class); @@ -50,7 +50,7 @@ void testDeserializeShouldWriteNullWhenCalledWithNullInput() throws IOException @Test void testGetTypeShouldReturnCorrectTypeWhenCalled() { //given - final Base64ZipV73KeyDeserializer underTest = new Base64ZipV73KeyDeserializer(); + final Base64ZipKeyDeserializer underTest = new Base64ZipKeyDeserializer(); //when final Class actual = underTest.getType(); diff --git a/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/model/json/util/Base64ZipKeySerializerDeserializerIntegrationTest.java b/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/model/json/util/Base64ZipKeySerializerDeserializerIntegrationTest.java index 37071c92..f5bd46db 100644 --- a/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/model/json/util/Base64ZipKeySerializerDeserializerIntegrationTest.java +++ b/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/model/json/util/Base64ZipKeySerializerDeserializerIntegrationTest.java @@ -3,10 +3,10 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.github.nagyesta.abortmission.booster.jupiter.annotation.LaunchAbortArmed; import com.github.nagyesta.lowkeyvault.TestConstantsKeys; +import com.github.nagyesta.lowkeyvault.model.common.backup.KeyBackupList; +import com.github.nagyesta.lowkeyvault.model.common.backup.KeyBackupListItem; +import com.github.nagyesta.lowkeyvault.model.common.backup.KeyBackupModel; import com.github.nagyesta.lowkeyvault.model.v7_2.common.constants.RecoveryLevel; -import com.github.nagyesta.lowkeyvault.model.v7_2.key.KeyBackupList; -import com.github.nagyesta.lowkeyvault.model.v7_2.key.KeyBackupListItem; -import com.github.nagyesta.lowkeyvault.model.v7_2.key.KeyBackupModel; import com.github.nagyesta.lowkeyvault.model.v7_2.key.KeyPropertiesModel; import com.github.nagyesta.lowkeyvault.model.v7_2.key.constants.KeyCurveName; import com.github.nagyesta.lowkeyvault.model.v7_2.key.constants.KeyType; diff --git a/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/model/json/util/Base64ZipV72KeySerializerTest.java b/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/model/json/util/Base64ZipKeySerializerTest.java similarity index 83% rename from lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/model/json/util/Base64ZipV72KeySerializerTest.java rename to lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/model/json/util/Base64ZipKeySerializerTest.java index 2b90977a..60f386b4 100644 --- a/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/model/json/util/Base64ZipV72KeySerializerTest.java +++ b/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/model/json/util/Base64ZipKeySerializerTest.java @@ -3,7 +3,7 @@ import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializerProvider; -import com.github.nagyesta.lowkeyvault.model.v7_2.key.KeyBackupList; +import com.github.nagyesta.lowkeyvault.model.common.backup.KeyBackupList; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; @@ -11,14 +11,14 @@ import static org.mockito.Mockito.*; -class Base64ZipV72KeySerializerTest { +class Base64ZipKeySerializerTest { @Test void testSerializeShouldThrowExceptionWhenEncodingFails() { //given final Base64Serializer base64Serializer = mock(Base64Serializer.class); final ObjectMapper objectMapper = new ObjectMapper(); - final Base64ZipV72KeySerializer underTest = new Base64ZipV72KeySerializer(base64Serializer, objectMapper); + final Base64ZipKeySerializer underTest = new Base64ZipKeySerializer(base64Serializer, objectMapper); final JsonGenerator gen = mock(JsonGenerator.class); final SerializerProvider serializers = mock(SerializerProvider.class); when(base64Serializer.base64Encode(any())).thenThrow(new IllegalStateException("Fail")); @@ -34,7 +34,7 @@ void testSerializeShouldThrowExceptionWhenEncodingFails() { @Test void testSerializeShouldWriteNullWhenCalledWithNullInput() throws IOException { //given - final Base64ZipV72KeySerializer underTest = new Base64ZipV72KeySerializer(); + final Base64ZipKeySerializer underTest = new Base64ZipKeySerializer(); final JsonGenerator gen = mock(JsonGenerator.class); final SerializerProvider serializers = mock(SerializerProvider.class); diff --git a/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/model/json/util/Base64ZipSecretSerializerDeserializerIntegrationTest.java b/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/model/json/util/Base64ZipSecretSerializerDeserializerIntegrationTest.java index 56125c3c..8e85edc1 100644 --- a/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/model/json/util/Base64ZipSecretSerializerDeserializerIntegrationTest.java +++ b/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/model/json/util/Base64ZipSecretSerializerDeserializerIntegrationTest.java @@ -3,10 +3,10 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.github.nagyesta.abortmission.booster.jupiter.annotation.LaunchAbortArmed; import com.github.nagyesta.lowkeyvault.TestConstantsSecrets; +import com.github.nagyesta.lowkeyvault.model.common.backup.SecretBackupList; +import com.github.nagyesta.lowkeyvault.model.common.backup.SecretBackupListItem; +import com.github.nagyesta.lowkeyvault.model.common.backup.SecretBackupModel; import com.github.nagyesta.lowkeyvault.model.v7_2.common.constants.RecoveryLevel; -import com.github.nagyesta.lowkeyvault.model.v7_2.secret.SecretBackupList; -import com.github.nagyesta.lowkeyvault.model.v7_2.secret.SecretBackupListItem; -import com.github.nagyesta.lowkeyvault.model.v7_2.secret.SecretBackupModel; import com.github.nagyesta.lowkeyvault.model.v7_2.secret.SecretPropertiesModel; import com.github.nagyesta.lowkeyvault.service.secret.id.SecretEntityId; import org.junit.jupiter.api.Assertions; diff --git a/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/model/json/util/Base64ZipV72KeyDeserializerTest.java b/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/model/json/util/Base64ZipV72KeyDeserializerTest.java deleted file mode 100644 index e577752f..00000000 --- a/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/model/json/util/Base64ZipV72KeyDeserializerTest.java +++ /dev/null @@ -1,49 +0,0 @@ -package com.github.nagyesta.lowkeyvault.model.json.util; - -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.databind.DeserializationContext; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.github.nagyesta.lowkeyvault.model.v7_2.key.KeyBackupList; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; - -import java.io.IOException; - -import static org.mockito.Mockito.*; - -class Base64ZipV72KeyDeserializerTest { - - @Test - void testDeserializeShouldThrowExceptionWhenDecodingFails() throws IOException { - //given - final Base64Deserializer base64Deserializer = mock(Base64Deserializer.class); - final ObjectMapper objectMapper = mock(ObjectMapper.class); - final Base64ZipV72KeyDeserializer underTest = new Base64ZipV72KeyDeserializer(base64Deserializer, objectMapper); - final JsonParser jsonParser = mock(JsonParser.class); - final DeserializationContext context = mock(DeserializationContext.class); - when(base64Deserializer.deserializeBase64(eq(jsonParser))).thenReturn(new byte[1]); - when(objectMapper.reader()).thenThrow(new IllegalStateException("Fail")); - - //when - Assertions.assertThrows(IllegalArgumentException.class, () -> underTest.deserialize(jsonParser, context)); - - //then + exception - verify(base64Deserializer).deserializeBase64(eq(jsonParser)); - } - - @Test - void testDeserializeShouldWriteNullWhenCalledWithNullInput() throws IOException { - //given - final Base64ZipV72KeyDeserializer underTest = new Base64ZipV72KeyDeserializer(); - final JsonParser jsonParser = mock(JsonParser.class); - when(jsonParser.readValueAs(eq(String.class))).thenReturn(""); - final DeserializationContext context = mock(DeserializationContext.class); - - //when - final KeyBackupList actual = underTest.deserialize(jsonParser, context); - - //then - Assertions.assertNull(actual); - verify(jsonParser).readValueAs(eq(String.class)); - } -} diff --git a/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/model/json/util/Base64ZipV73KeySerializerTest.java b/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/model/json/util/Base64ZipV73KeySerializerTest.java deleted file mode 100644 index 1b3a3132..00000000 --- a/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/model/json/util/Base64ZipV73KeySerializerTest.java +++ /dev/null @@ -1,48 +0,0 @@ -package com.github.nagyesta.lowkeyvault.model.json.util; - -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.SerializerProvider; -import com.github.nagyesta.lowkeyvault.model.v7_3.key.KeyBackupList; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; - -import java.io.IOException; - -import static org.mockito.Mockito.*; - -class Base64ZipV73KeySerializerTest { - - @Test - void testSerializeShouldThrowExceptionWhenEncodingFails() { - //given - final Base64Serializer base64Serializer = mock(Base64Serializer.class); - final ObjectMapper objectMapper = new ObjectMapper(); - final Base64ZipV73KeySerializer underTest = new Base64ZipV73KeySerializer(base64Serializer, objectMapper); - final JsonGenerator gen = mock(JsonGenerator.class); - final SerializerProvider serializers = mock(SerializerProvider.class); - when(base64Serializer.base64Encode(any())).thenThrow(new IllegalStateException("Fail")); - - //when - Assertions.assertThrows(IllegalArgumentException.class, () -> underTest.serialize(new KeyBackupList(), gen, serializers)); - - //then + exception - verify(base64Serializer).base64Encode(any()); - verifyNoInteractions(gen, serializers); - } - - @Test - void testSerializeShouldWriteNullWhenCalledWithNullInput() throws IOException { - //given - final Base64ZipV73KeySerializer underTest = new Base64ZipV73KeySerializer(); - final JsonGenerator gen = mock(JsonGenerator.class); - final SerializerProvider serializers = mock(SerializerProvider.class); - - //when - underTest.serialize(null, gen, serializers); - - //then - verify(gen).writeNull(); - verify(gen, never()).writeString(anyString()); - } -} diff --git a/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/model/v7_2/key/KeyEntityToV72BackupConverterTest.java b/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/model/v7_2/key/KeyEntityToV72BackupConverterTest.java index 50c5afca..20732de0 100644 --- a/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/model/v7_2/key/KeyEntityToV72BackupConverterTest.java +++ b/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/model/v7_2/key/KeyEntityToV72BackupConverterTest.java @@ -1,7 +1,9 @@ package com.github.nagyesta.lowkeyvault.model.v7_2.key; +import com.github.nagyesta.lowkeyvault.mapper.common.registry.KeyConverterRegistry; import com.github.nagyesta.lowkeyvault.mapper.v7_2.key.KeyEntityToV72BackupConverter; import com.github.nagyesta.lowkeyvault.mapper.v7_2.key.KeyEntityToV72PropertiesModelConverter; +import com.github.nagyesta.lowkeyvault.model.common.backup.KeyBackupListItem; import com.github.nagyesta.lowkeyvault.model.v7_2.key.constants.KeyCurveName; import com.github.nagyesta.lowkeyvault.model.v7_2.key.constants.KeyType; import com.github.nagyesta.lowkeyvault.model.v7_2.key.request.JsonWebKeyImportRequest; @@ -16,7 +18,6 @@ import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.MockitoAnnotations; @@ -35,17 +36,20 @@ class KeyEntityToV72BackupConverterTest { private static final KeyPropertiesModel KEY_PROPERTIES_MODEL = new KeyPropertiesModel(); + private KeyEntityToV72BackupConverter underTest; @Mock private VaultFake vaultFake; @Mock private KeyEntityToV72PropertiesModelConverter propertiesModelConverter; - @InjectMocks - private KeyEntityToV72BackupConverter underTest; + @Mock + private KeyConverterRegistry registry; private AutoCloseable openMocks; @BeforeEach void setUp() { openMocks = MockitoAnnotations.openMocks(this); + underTest = new KeyEntityToV72BackupConverter(registry); + when(registry.propertiesConverter(anyString())).thenReturn(propertiesModelConverter); when(propertiesModelConverter.convert(any(ReadOnlyKeyVaultKeyEntity.class), any(URI.class))).thenReturn(KEY_PROPERTIES_MODEL); } diff --git a/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/model/v7_2/secret/SecretEntityToV72BackupConverterTest.java b/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/model/v7_2/secret/SecretEntityToV72BackupConverterTest.java index 2cc96771..5120dffd 100644 --- a/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/model/v7_2/secret/SecretEntityToV72BackupConverterTest.java +++ b/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/model/v7_2/secret/SecretEntityToV72BackupConverterTest.java @@ -1,6 +1,9 @@ package com.github.nagyesta.lowkeyvault.model.v7_2.secret; +import com.github.nagyesta.lowkeyvault.mapper.common.registry.SecretConverterRegistry; +import com.github.nagyesta.lowkeyvault.mapper.v7_2.secret.SecretEntityToV72BackupConverter; import com.github.nagyesta.lowkeyvault.mapper.v7_2.secret.SecretEntityToV72PropertiesModelConverter; +import com.github.nagyesta.lowkeyvault.model.common.backup.SecretBackupListItem; import com.github.nagyesta.lowkeyvault.service.secret.ReadOnlyKeyVaultSecretEntity; import com.github.nagyesta.lowkeyvault.service.secret.impl.KeyVaultSecretEntity; import com.github.nagyesta.lowkeyvault.service.vault.VaultFake; @@ -29,6 +32,8 @@ class SecretEntityToV72BackupConverterTest { private VaultFake vaultFake; @Mock private SecretEntityToV72PropertiesModelConverter propertiesModelConverter; + @Mock + private SecretConverterRegistry registry; @InjectMocks private SecretEntityToV72BackupConverter underTest; private AutoCloseable openMocks; @@ -36,6 +41,7 @@ class SecretEntityToV72BackupConverterTest { @BeforeEach void setUp() { openMocks = MockitoAnnotations.openMocks(this); + when(registry.propertiesConverter(anyString())).thenReturn(propertiesModelConverter); when(propertiesModelConverter.convert(any(ReadOnlyKeyVaultSecretEntity.class), any(URI.class))) .thenReturn(SECRET_PROPERTIES_MODEL); } diff --git a/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/service/certificate/impl/KeyVaultCertificateEntityIntegrationTest.java b/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/service/certificate/impl/KeyVaultCertificateEntityIntegrationTest.java index 4debe87b..f198af27 100644 --- a/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/service/certificate/impl/KeyVaultCertificateEntityIntegrationTest.java +++ b/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/service/certificate/impl/KeyVaultCertificateEntityIntegrationTest.java @@ -7,6 +7,7 @@ import com.github.nagyesta.lowkeyvault.model.v7_3.certificate.SubjectAlternativeNames; import com.github.nagyesta.lowkeyvault.model.v7_3.certificate.X509CertificateModel; import com.github.nagyesta.lowkeyvault.service.key.impl.EcKeyCreationInput; +import com.github.nagyesta.lowkeyvault.service.secret.impl.SecretCreateInput; import com.github.nagyesta.lowkeyvault.service.vault.VaultFake; import com.github.nagyesta.lowkeyvault.service.vault.impl.VaultFakeImpl; import org.junit.jupiter.api.Assertions; @@ -102,7 +103,10 @@ void testImportConstructorShouldThrowExceptionWhenCalledWithAlreadyExistingSecre final CertificateImportInput input = new CertificateImportInput( CERT_NAME_1, certContent, EMPTY_PASSWORD, CertContentType.PKCS12, new CertificatePolicyModel()); final VaultFake vault = new VaultFakeImpl(HTTPS_LOCALHOST_8443); - vault.secretVaultFake().createSecretVersion(CERT_NAME_1, LOWKEY_VAULT, MimeTypeUtils.TEXT_PLAIN.getType()); + vault.secretVaultFake().createSecretVersion(CERT_NAME_1, SecretCreateInput.builder() + .value(LOWKEY_VAULT) + .contentType(MimeTypeUtils.TEXT_PLAIN.getType()) + .build()); //when Assertions.assertThrows(IllegalStateException.class, diff --git a/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/service/key/impl/KeyVaultFakeImplTest.java b/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/service/key/impl/KeyVaultFakeImplTest.java index a605ee01..82f0b0d0 100644 --- a/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/service/key/impl/KeyVaultFakeImplTest.java +++ b/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/service/key/impl/KeyVaultFakeImplTest.java @@ -45,6 +45,9 @@ class KeyVaultFakeImplTest { private static final int DAYS = 42; private static final int COUNT = 10; private static final EcKeyCreationInput EC_KEY_CREATION_INPUT = new EcKeyCreationInput(KeyType.EC, KeyCurveName.P_256); + private static final KeyCreateDetailedInput DETAILED_EC_KEY_CREATION_INPUT = KeyCreateDetailedInput.builder() + .key(EC_KEY_CREATION_INPUT) + .build(); private static final int OFFSET_SECONDS_120_DAYS = 120 * 24 * 60 * 60; private static final int ROTATIONS_UNDER_120_DAYS = 120 / MINIMUM_EXPIRY_PERIOD_IN_DAYS; @@ -52,11 +55,21 @@ public static Stream genericKeyCreateInputProvider() { return Stream.builder() .add(Arguments.of(null, null)) .add(Arguments.of(KEY_NAME_1, null)) - .add(Arguments.of(KEY_NAME_1, new KeyCreationInput(KeyType.RSA_HSM, null))) - .add(Arguments.of(KEY_NAME_1, new KeyCreationInput(KeyType.RSA, null))) - .add(Arguments.of(KEY_NAME_1, new KeyCreationInput(KeyType.OCT_HSM, null))) - .add(Arguments.of(KEY_NAME_1, new KeyCreationInput(KeyType.EC, null))) - .add(Arguments.of(KEY_NAME_1, new KeyCreationInput(KeyType.EC_HSM, null))) + .add(Arguments.of(KEY_NAME_1, KeyCreateDetailedInput.builder() + .key(new KeyCreationInput(KeyType.RSA_HSM, null)) + .build())) + .add(Arguments.of(KEY_NAME_1, KeyCreateDetailedInput.builder() + .key(new KeyCreationInput(KeyType.RSA, null)) + .build())) + .add(Arguments.of(KEY_NAME_1, KeyCreateDetailedInput.builder() + .key(new KeyCreationInput(KeyType.OCT_HSM, null)) + .build())) + .add(Arguments.of(KEY_NAME_1, KeyCreateDetailedInput.builder() + .key(new KeyCreationInput(KeyType.EC, null)) + .build())) + .add(Arguments.of(KEY_NAME_1, KeyCreateDetailedInput.builder() + .key(new KeyCreationInput(KeyType.EC_HSM, null)) + .build())) .build(); } @@ -91,8 +104,6 @@ public static Stream certificateNullProvider() { return Stream.builder() .add(Arguments.of(KEY_NAME_1, null, null, null)) .add(Arguments.of(null, input, null, null)) - .add(Arguments.of(null, null, TIME_10_MINUTES_AGO, null)) - .add(Arguments.of(null, null, null, TIME_IN_10_MINUTES)) .add(Arguments.of(null, input, TIME_10_MINUTES_AGO, TIME_IN_10_MINUTES)) .add(Arguments.of(KEY_NAME_1, null, TIME_10_MINUTES_AGO, TIME_IN_10_MINUTES)) .add(Arguments.of(KEY_NAME_1, input, null, TIME_IN_10_MINUTES)) @@ -119,8 +130,8 @@ void testGetKeyVersionsShouldReturnAllKeyVersionsInChronologicalOrderWhenFound() final List expected = insertMultipleVersionsOfSameKey(underTest, KEY_NAME_1).stream() .map(KeyEntityId::version) .collect(Collectors.toList()); - underTest.createKeyVersion(KEY_NAME_2, EC_KEY_CREATION_INPUT); - underTest.createKeyVersion(KEY_NAME_3, EC_KEY_CREATION_INPUT); + underTest.createKeyVersion(KEY_NAME_2, DETAILED_EC_KEY_CREATION_INPUT); + underTest.createKeyVersion(KEY_NAME_3, DETAILED_EC_KEY_CREATION_INPUT); final KeyEntityId keyEntityId = new KeyEntityId(HTTPS_LOCALHOST, KEY_NAME_1, null); @@ -176,8 +187,8 @@ void testGetLatestVersionOfKeyShouldReturnAllKeyVersionsInChronologicalOrderWhen .map(KeyEntityId::version) .skip(COUNT - 1) .findFirst().orElse(null); - underTest.createKeyVersion(KEY_NAME_2, EC_KEY_CREATION_INPUT); - underTest.createKeyVersion(KEY_NAME_3, EC_KEY_CREATION_INPUT); + underTest.createKeyVersion(KEY_NAME_2, DETAILED_EC_KEY_CREATION_INPUT); + underTest.createKeyVersion(KEY_NAME_3, DETAILED_EC_KEY_CREATION_INPUT); final KeyEntityId keyEntityId = new KeyEntityId(HTTPS_LOCALHOST, KEY_NAME_1, null); @@ -190,7 +201,7 @@ void testGetLatestVersionOfKeyShouldReturnAllKeyVersionsInChronologicalOrderWhen @ParameterizedTest @MethodSource("genericKeyCreateInputProvider") - void testCreateKeyVersionShouldThrowExceptionWhenCalledWithNull(final String name, final KeyCreationInput input) { + void testCreateKeyVersionShouldThrowExceptionWhenCalledWithNull(final String name, final KeyCreateDetailedInput input) { //given final KeyVaultFake underTest = createUnderTest(); @@ -249,7 +260,9 @@ void testCreateKeyVersionShouldThrowExceptionWhenCalledWithNullOct(final String void testCreateKeyVersionShouldReturnIdWhenCalledWithValidRsaParameter() { //given final KeyVaultFake underTest = createUnderTest(); - final RsaKeyCreationInput input = new RsaKeyCreationInput(KeyType.RSA_HSM, null, null); + final KeyCreateDetailedInput input = KeyCreateDetailedInput.builder() + .key(new RsaKeyCreationInput(KeyType.RSA_HSM, null, null)) + .build(); //when final VersionedKeyEntityId actual = underTest.createKeyVersion(KEY_NAME_1, input); @@ -265,7 +278,9 @@ void testCreateKeyVersionShouldReturnIdWhenCalledWithValidRsaParameter() { void testCreateKeyVersionShouldReturnIdWhenCalledWithValidEcParameter() { //given final KeyVaultFake underTest = createUnderTest(); - final EcKeyCreationInput input = new EcKeyCreationInput(KeyType.EC_HSM, KeyCurveName.P_256); + final KeyCreateDetailedInput input = KeyCreateDetailedInput.builder() + .key(new EcKeyCreationInput(KeyType.EC_HSM, KeyCurveName.P_256)) + .build(); //when final VersionedKeyEntityId actual = underTest.createKeyVersion(KEY_NAME_1, input); @@ -281,7 +296,9 @@ void testCreateKeyVersionShouldReturnIdWhenCalledWithValidEcParameter() { void testCreateKeyVersionShouldReturnIdWhenCalledWithValidOctParameter() { //given final KeyVaultFake underTest = createUnderTest(); - final OctKeyCreationInput input = new OctKeyCreationInput(KeyType.OCT_HSM, null); + final KeyCreateDetailedInput input = KeyCreateDetailedInput.builder() + .key(new OctKeyCreationInput(KeyType.OCT_HSM, null)) + .build(); //when final VersionedKeyEntityId actual = underTest.createKeyVersion(KEY_NAME_1, input); @@ -299,7 +316,9 @@ void testSetKeyOperationsShouldUpdateListWhenCalledWithValidValues(final List keyOperations = List.of( + KeyOperation.SIGN, KeyOperation.VERIFY, + KeyOperation.ENCRYPT, KeyOperation.DECRYPT, + KeyOperation.WRAP_KEY, KeyOperation.UNWRAP_KEY); + final KeyCreateDetailedInput input = KeyCreateDetailedInput.builder() + .key(new RsaKeyCreationInput(KeyType.RSA_HSM, null, null)) + .notBefore(TIME_10_MINUTES_AGO) + .expiresOn(TIME_IN_10_MINUTES) + .keyOperations(keyOperations) + .enabled(true) + .managed(true) + .build(); //when final VersionedKeyEntityId actual = underTest - .createKeyVersionForCertificate(KEY_NAME_1, input, TIME_10_MINUTES_AGO, TIME_IN_10_MINUTES); + .createKeyVersion(KEY_NAME_1, input); //then final ReadOnlyKeyVaultKeyEntity entity = underTest.getEntities().getReadOnlyEntity(actual); @@ -929,10 +971,6 @@ void testCreateKeyVersionForCertificateShouldSetFieldsAndManagedFlagWhenCalledWi Assertions.assertEquals(TIME_IN_10_MINUTES, entity.getExpiry().orElse(null)); Assertions.assertTrue(entity.isEnabled()); Assertions.assertTrue(entity.isManaged()); - final List keyOperations = List.of( - KeyOperation.SIGN, KeyOperation.VERIFY, - KeyOperation.ENCRYPT, KeyOperation.DECRYPT, - KeyOperation.WRAP_KEY, KeyOperation.UNWRAP_KEY); Assertions.assertIterableEquals(keyOperations, entity.getOperations()); } @@ -943,10 +981,19 @@ void testCreateKeyVersionForCertificateShouldThrowExceptionWhenCalledWithNulls( final OffsetDateTime notBefore, final OffsetDateTime expiry) { //given final KeyVaultFake underTest = createUnderTest(); + final KeyCreateDetailedInput detailedInput = Optional.ofNullable(input) + .map(key -> KeyCreateDetailedInput.builder() + .key(key) + .managed(true) + .notBefore(notBefore) + .expiresOn(expiry) + .enabled(true) + .build()) + .orElse(null); //when Assertions.assertThrows(IllegalArgumentException.class, - () -> underTest.createKeyVersionForCertificate(name, input, notBefore, expiry)); + () -> underTest.createKeyVersion(name, detailedInput)); //then + exception } diff --git a/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/service/secret/impl/SecretVaultFakeImplTest.java b/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/service/secret/impl/SecretVaultFakeImplTest.java index 1074fdfe..9b2d3aa6 100644 --- a/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/service/secret/impl/SecretVaultFakeImplTest.java +++ b/lowkey-vault-app/src/test/java/com/github/nagyesta/lowkeyvault/service/secret/impl/SecretVaultFakeImplTest.java @@ -13,6 +13,7 @@ import org.junit.jupiter.params.provider.MethodSource; import java.time.OffsetDateTime; +import java.util.Optional; import java.util.stream.Stream; import static com.github.nagyesta.lowkeyvault.TestConstants.*; @@ -29,9 +30,6 @@ public static Stream certificateCreationNullProvider() { .add(Arguments.of(null, null, null, null, null)) .add(Arguments.of(entityId, null, null, null, null)) .add(Arguments.of(null, LOWKEY_VAULT, null, null, null)) - .add(Arguments.of(null, null, CertContentType.PEM, null, null)) - .add(Arguments.of(null, null, null, TIME_10_MINUTES_AGO, null)) - .add(Arguments.of(null, null, null, null, TIME_IN_10_MINUTES)) .add(Arguments.of(null, LOWKEY_VAULT, CertContentType.PEM, TIME_10_MINUTES_AGO, TIME_IN_10_MINUTES)) .add(Arguments.of(entityId, null, CertContentType.PEM, TIME_10_MINUTES_AGO, TIME_IN_10_MINUTES)) .add(Arguments.of(entityId, LOWKEY_VAULT, null, TIME_10_MINUTES_AGO, TIME_IN_10_MINUTES)) @@ -69,7 +67,7 @@ void testCreateSecretVersionShouldThrowExceptionWhenCalledWithNullName() { //when Assertions.assertThrows(IllegalArgumentException.class, - () -> underTest.createSecretVersion((String) null, LOWKEY_VAULT, null)); + () -> underTest.createSecretVersion((String) null, null)); //then + exception } @@ -84,7 +82,7 @@ void testCreateSecretVersionShouldThrowExceptionWhenCalledWithNullValue() { //when Assertions.assertThrows(IllegalArgumentException.class, - () -> underTest.createSecretVersion(SECRET_NAME_1, null, null)); + () -> underTest.createSecretVersion(SECRET_NAME_1, null)); //then + exception } @@ -99,7 +97,7 @@ void testCreateSecretVersionUsingVersionedIdShouldThrowExceptionWhenCalledWithNu //when Assertions.assertThrows(IllegalArgumentException.class, - () -> underTest.createSecretVersion(VERSIONED_SECRET_ENTITY_ID_1_VERSION_1, null, null)); + () -> underTest.createSecretVersion(VERSIONED_SECRET_ENTITY_ID_1_VERSION_1, null)); //then + exception } @@ -111,10 +109,13 @@ void testCreateSecretVersionUsingVersionedIdShouldThrowExceptionWhenCalledWithNu final VaultFake vaultFake = new VaultFakeImpl(HTTPS_LOCALHOST_8443); final SecretVaultFakeImpl underTest = new SecretVaultFakeImpl(vaultFake, vaultFake.getRecoveryLevel(), vaultFake.getRecoverableDays()); + final SecretCreateInput secretCreateInput = SecretCreateInput.builder() + .value(LOWKEY_VAULT) + .build(); //when Assertions.assertThrows(IllegalArgumentException.class, - () -> underTest.createSecretVersion((VersionedSecretEntityId) null, LOWKEY_VAULT, null)); + () -> underTest.createSecretVersion((VersionedSecretEntityId) null, secretCreateInput)); //then + exception } @@ -127,7 +128,9 @@ void testCreateSecretVersionShouldCreateNewEntityWhenCalledWithValidInput() { new SecretVaultFakeImpl(vaultFake, vaultFake.getRecoveryLevel(), vaultFake.getRecoverableDays()); //when - final VersionedSecretEntityId secretVersion = underTest.createSecretVersion(SECRET_NAME_1, LOWKEY_VAULT, null); + final VersionedSecretEntityId secretVersion = underTest.createSecretVersion(SECRET_NAME_1, SecretCreateInput.builder() + .value(LOWKEY_VAULT) + .build()); //then final ReadOnlyKeyVaultSecretEntity actual = underTest.getEntities().getReadOnlyEntity(secretVersion); @@ -150,6 +153,7 @@ void testCreateVersionedSecretEntityIdShouldCreateNewEntityIdWhenCalledWithValid Assertions.assertEquals(VERSIONED_SECRET_ENTITY_ID_1_VERSION_1, actual); } + @SuppressWarnings("DataFlowIssue") @ParameterizedTest @MethodSource("certificateCreationNullProvider") void testCreateSecretVersionForCertificateShouldThrowExceptionWhenCalledWithNulls( @@ -162,10 +166,18 @@ void testCreateSecretVersionForCertificateShouldThrowExceptionWhenCalledWithNull final VaultFake vaultFake = mock(VaultFake.class); when(vaultFake.baseUri()).thenReturn(HTTPS_LOCALHOST_8443); final SecretVaultFakeImpl underTest = new SecretVaultFakeImpl(vaultFake, RecoveryLevel.PURGEABLE, null); + final SecretCreateInput secretCreateInput = Optional.ofNullable(value) + .map(v -> SecretCreateInput.builder() + .value(v) + .contentType(Optional.ofNullable(contentType).map(CertContentType::getMimeType).orElse(null)) + .notBefore(notBefore) + .expiresOn(expiry) + .managed(true) + .build()) + .orElse(null); //when - Assertions.assertThrows(IllegalArgumentException.class, - () -> underTest.createSecretVersionForCertificate(id, value, contentType, notBefore, expiry)); + Assertions.assertThrows(IllegalArgumentException.class, () -> underTest.createSecretVersion(id, secretCreateInput)); //then + exception } @@ -182,10 +194,19 @@ void testCreateSecretVersionForCertificateShouldSetValuesAndManagedFlagWhenCalle final VaultFake vaultFake = mock(VaultFake.class); when(vaultFake.baseUri()).thenReturn(HTTPS_LOCALHOST_8443); final SecretVaultFakeImpl underTest = new SecretVaultFakeImpl(vaultFake, RecoveryLevel.PURGEABLE, null); + final SecretCreateInput secretCreateInput = SecretCreateInput.builder() + .value(value) + .contentType(contentType.getMimeType()) + .notBefore(notBefore) + .createdOn(notBefore) + .updatedOn(notBefore) + .expiresOn(expiry) + .managed(true) + .enabled(true) + .build(); //when - final VersionedSecretEntityId actual = underTest - .createSecretVersionForCertificate(id, value, contentType, notBefore, expiry); + final VersionedSecretEntityId actual = underTest.createSecretVersion(id, secretCreateInput); //then final ReadOnlyKeyVaultSecretEntity entity = underTest.getEntities().getReadOnlyEntity(actual); @@ -201,4 +222,84 @@ void testCreateSecretVersionForCertificateShouldSetValuesAndManagedFlagWhenCalle Assertions.assertEquals(notBefore, entity.getCreated()); Assertions.assertEquals(notBefore, entity.getUpdated()); } + + @SuppressWarnings("ConstantConditions") + @Test + void testCreateSecretVersionShouldThrowExceptionWhenCalledWithUpdatedOnEarlierThanCreatedOn() { + //given + final VaultFake vaultFake = new VaultFakeImpl(HTTPS_LOCALHOST_8443); + final SecretVaultFakeImpl underTest = + new SecretVaultFakeImpl(vaultFake, vaultFake.getRecoveryLevel(), vaultFake.getRecoverableDays()); + final SecretCreateInput secretCreateInput = SecretCreateInput.builder() + .value(LOWKEY_VAULT) + .createdOn(TIME_IN_10_MINUTES) + .updatedOn(TIME_10_MINUTES_AGO) + .build(); + + //when + Assertions.assertThrows(IllegalArgumentException.class, + () -> underTest.createSecretVersion(SECRET_NAME_1, secretCreateInput)); + + //then + exception + } + + @SuppressWarnings("ConstantConditions") + @Test + void testCreateSecretVersionShouldSetBothValuesWhenCalledWithCreatedOnAndNoUpdatedOn() { + //given + final VaultFake vaultFake = new VaultFakeImpl(HTTPS_LOCALHOST_8443); + final SecretVaultFakeImpl underTest = + new SecretVaultFakeImpl(vaultFake, vaultFake.getRecoveryLevel(), vaultFake.getRecoverableDays()); + final SecretCreateInput secretCreateInput = SecretCreateInput.builder() + .value(LOWKEY_VAULT) + .createdOn(TIME_10_MINUTES_AGO) + .build(); + + //when + final VersionedSecretEntityId actual = underTest.createSecretVersion(SECRET_NAME_1, secretCreateInput); + + //then + final ReadOnlyKeyVaultSecretEntity entity = underTest.getEntities().getReadOnlyEntity(actual); + Assertions.assertEquals(TIME_10_MINUTES_AGO, entity.getCreated()); + Assertions.assertEquals(TIME_10_MINUTES_AGO, entity.getUpdated()); + } + + @Test + void testCreateSecretVersionShouldSetBothValuesWhenCalledWithUpdatedOnFromFutureAndNoCreatedOn() { + //given + final VaultFake vaultFake = new VaultFakeImpl(HTTPS_LOCALHOST_8443); + final SecretVaultFakeImpl underTest = + new SecretVaultFakeImpl(vaultFake, vaultFake.getRecoveryLevel(), vaultFake.getRecoverableDays()); + final SecretCreateInput secretCreateInput = SecretCreateInput.builder() + .value(LOWKEY_VAULT) + .updatedOn(TIME_IN_10_MINUTES) + .build(); + + //when + final VersionedSecretEntityId actual = underTest.createSecretVersion(SECRET_NAME_1, secretCreateInput); + + //then + final ReadOnlyKeyVaultSecretEntity entity = underTest.getEntities().getReadOnlyEntity(actual); + Assertions.assertTrue(entity.getCreated().isAfter(NOW)); + Assertions.assertTrue(entity.getCreated().isBefore(TIME_IN_10_MINUTES)); + Assertions.assertEquals(TIME_IN_10_MINUTES, entity.getUpdated()); + } + + @Test + void testCreateSecretVersionShouldThrowExceptionWhenCalledWithUpdatedOnFromThePastAndNoCreatedOn() { + //given + final VaultFake vaultFake = new VaultFakeImpl(HTTPS_LOCALHOST_8443); + final SecretVaultFakeImpl underTest = + new SecretVaultFakeImpl(vaultFake, vaultFake.getRecoveryLevel(), vaultFake.getRecoverableDays()); + final SecretCreateInput secretCreateInput = SecretCreateInput.builder() + .value(LOWKEY_VAULT) + .updatedOn(TIME_10_MINUTES_AGO) + .build(); + + //when + Assertions.assertThrows(IllegalArgumentException.class, + () -> underTest.createSecretVersion(SECRET_NAME_1, secretCreateInput)); + + //then + exception + } }