From 5ce3e9097cd6a592f38888cf2d14ca715a8c2db2 Mon Sep 17 00:00:00 2001 From: root Date: Wed, 20 Nov 2024 17:24:48 +0000 Subject: [PATCH 01/29] implement crypto services --- internal/app/services/key.go | 108 +++++++++++++++++++++++++++++++++++ 1 file changed, 108 insertions(+) diff --git a/internal/app/services/key.go b/internal/app/services/key.go index 09db71e..dc6a8de 100644 --- a/internal/app/services/key.go +++ b/internal/app/services/key.go @@ -1,8 +1,116 @@ package services +import ( + "crypto_vault_service/internal/domain/keys" + "crypto_vault_service/internal/infrastructure/connector" + "crypto_vault_service/internal/persistence/repository" + "fmt" + "time" + + "github.com/google/uuid" +) + type CryptKeyUploadService struct { + VaultConnector connector.VaultConnector + CryptoKeyRepo repository.CryptoKeyRepository +} + +func (s *CryptKeyUploadService) Upload(filePaths []string) ([]*keys.CryptoKeyMeta, error) { + // Step 1: Upload files to blob storage + userId := uuid.New().String() + blobMeta, err := s.VaultConnector.Upload(filePaths, userId) + if err != nil { + return nil, fmt.Errorf("failed to upload files: %w", err) + } + + // Step 2: Store the metadata in the database + var keyMetas []*keys.CryptoKeyMeta + for _, blob := range blobMeta { + // Map Blob metadata to CryptoKey metadata + keyMeta := &keys.CryptoKeyMeta{ + ID: uuid.New().String(), // Generate valid UUID for ID + Type: "RSA", // Example key type + DateTimeCreated: time.Now(), // Valid DateTimeCreated time + UserID: uuid.New().String(), // Generate valid UUID for UserID + } + + // Validate CryptoKeyMeta + if err := keyMeta.Validate(); err != nil { + return nil, fmt.Errorf("invalid key metadata: %w", err) + } + + // Save metadata to DB + if err := s.CryptoKeyRepo.Create(blob); err != nil { + return nil, fmt.Errorf("failed to create metadata for key of type %s: %w", keyMeta.Type, err) + } + + // Append to list + keyMetas = append(keyMetas, keyMeta) + } + + // Return metadata + return keyMetas, nil } + +// CryptoKeyMetadataService manages cryptographic key metadata. type CryptoKeyMetadataService struct { + CryptoKeyRepo repository.CryptoKeyRepository +} + +// List retrieves all cryptographic key metadata based on a query. +func (s *CryptoKeyMetadataService) List(query *keys.CryptoKeyQuery) ([]*keys.CryptoKeyMeta, error) { + // For now, let's just retrieve all metadata from the database + var keyMetas []*keys.CryptoKeyMeta + // TBD + + return keyMetas, nil +} + +// GetByID retrieves the metadata of a cryptographic key by its ID. +func (s *CryptoKeyMetadataService) GetByID(keyID string) (*keys.CryptoKeyMeta, error) { + // Retrieve the metadata from the database + keyMeta, err := s.CryptoKeyRepo.GetByID(keyID) + if err != nil { + return nil, fmt.Errorf("failed to retrieve key metadata: %w", err) + } + + return keyMeta, nil +} + +// DeleteByID deletes a cryptographic key's metadata by its ID. +func (s *CryptoKeyMetadataService) DeleteByID(keyID string) error { + // Delete the metadata from the database + err := s.CryptoKeyRepo.DeleteByID(keyID) + if err != nil { + return fmt.Errorf("failed to delete key metadata: %w", err) + } + return nil } + +// CryptoKeyDownloadService handles the download of cryptographic keys. type CryptoKeyDownloadService struct { + VaultConnector connector.VaultConnector +} + +// Download retrieves a cryptographic key by its ID and type. +func (s *CryptoKeyDownloadService) Download(keyID string, keyType keys.KeyType) ([]byte, error) { + blobName := "" // Declare the variable outside the blocks + + if keyType == keys.AsymmetricPublic { + blobName = "asymmetric-public-key" // Assign to the already declared variable + } else if keyType == keys.AsymmetricPrivate { + blobName = "asymmetric-private-key" // Assign to the already declared variable + } else if keyType == keys.Symmetric { + blobName = "symmetric-key" // Assign to the already declared variable + } else { + return nil, fmt.Errorf("unsupported key type: %v", keyType) + } + + blobData, err := s.VaultConnector.Download(keyID, blobName) + if err != nil { + return nil, fmt.Errorf("failed to download key from blob storage: %w", err) + } + + // Return the metadata and the downloaded content (as a byte slice) + return blobData, nil } From fdbb6da34cb3b488043fc65fd2e0ed1225cf8f7d Mon Sep 17 00:00:00 2001 From: root Date: Wed, 20 Nov 2024 17:42:57 +0000 Subject: [PATCH 02/29] consider descriptive file names --- internal/app/services/{blob.go => blob_services.go} | 0 .../app/services/{crypto.go => crypto_services.go} | 0 internal/app/services/{key.go => key_services.go} | 0 internal/domain/blobs/{contract.go => contracts.go} | 0 internal/domain/blobs/{model.go => models.go} | 0 internal/domain/blobs/{query.go => queries.go} | 0 internal/domain/keys/{contract.go => contracts.go} | 0 internal/domain/keys/{model.go => models.go} | 0 internal/domain/keys/{query.go => queries.go} | 0 .../domain/permissions/{contract.go => contracts.go} | 0 .../connector/{blob.go => blob_connectors.go} | 0 .../connector/{key.go => key_connectors.go} | 0 .../repository/{blob.go => blob_repository.go} | 0 .../repository/{key.go => key_repository.go} | 0 .../{az_blob_test.go => az_blob_connector_test.go} | 0 .../{az_vault_test.go => az_vault_connector_test.go} | 0 ...{blob_psql_test.go => psql_blob_repository_test.go} | 0 ...b_sqlite_test.go => sqlite_blob_repository_test.go} | 0 ...ey_sqlite_test.go => sqlite_key_repository_test.go} | 0 .../{test_context.go => test_repository_context.go} | 10 +++++----- test/unit/domain/blobs/{blob_test.go => model_test.go} | 0 test/unit/domain/keys/{key_test.go => model_test.go} | 0 22 files changed, 5 insertions(+), 5 deletions(-) rename internal/app/services/{blob.go => blob_services.go} (100%) rename internal/app/services/{crypto.go => crypto_services.go} (100%) rename internal/app/services/{key.go => key_services.go} (100%) rename internal/domain/blobs/{contract.go => contracts.go} (100%) rename internal/domain/blobs/{model.go => models.go} (100%) rename internal/domain/blobs/{query.go => queries.go} (100%) rename internal/domain/keys/{contract.go => contracts.go} (100%) rename internal/domain/keys/{model.go => models.go} (100%) rename internal/domain/keys/{query.go => queries.go} (100%) rename internal/domain/permissions/{contract.go => contracts.go} (100%) rename internal/infrastructure/connector/{blob.go => blob_connectors.go} (100%) rename internal/infrastructure/connector/{key.go => key_connectors.go} (100%) rename internal/persistence/repository/{blob.go => blob_repository.go} (100%) rename internal/persistence/repository/{key.go => key_repository.go} (100%) rename test/integration/infrastructure/connector/{az_blob_test.go => az_blob_connector_test.go} (100%) rename test/integration/infrastructure/connector/{az_vault_test.go => az_vault_connector_test.go} (100%) rename test/integration/persistence/repository/{blob_psql_test.go => psql_blob_repository_test.go} (100%) rename test/integration/persistence/repository/{blob_sqlite_test.go => sqlite_blob_repository_test.go} (100%) rename test/integration/persistence/repository/{key_sqlite_test.go => sqlite_key_repository_test.go} (100%) rename test/integration/persistence/repository/{test_context.go => test_repository_context.go} (92%) rename test/unit/domain/blobs/{blob_test.go => model_test.go} (100%) rename test/unit/domain/keys/{key_test.go => model_test.go} (100%) diff --git a/internal/app/services/blob.go b/internal/app/services/blob_services.go similarity index 100% rename from internal/app/services/blob.go rename to internal/app/services/blob_services.go diff --git a/internal/app/services/crypto.go b/internal/app/services/crypto_services.go similarity index 100% rename from internal/app/services/crypto.go rename to internal/app/services/crypto_services.go diff --git a/internal/app/services/key.go b/internal/app/services/key_services.go similarity index 100% rename from internal/app/services/key.go rename to internal/app/services/key_services.go diff --git a/internal/domain/blobs/contract.go b/internal/domain/blobs/contracts.go similarity index 100% rename from internal/domain/blobs/contract.go rename to internal/domain/blobs/contracts.go diff --git a/internal/domain/blobs/model.go b/internal/domain/blobs/models.go similarity index 100% rename from internal/domain/blobs/model.go rename to internal/domain/blobs/models.go diff --git a/internal/domain/blobs/query.go b/internal/domain/blobs/queries.go similarity index 100% rename from internal/domain/blobs/query.go rename to internal/domain/blobs/queries.go diff --git a/internal/domain/keys/contract.go b/internal/domain/keys/contracts.go similarity index 100% rename from internal/domain/keys/contract.go rename to internal/domain/keys/contracts.go diff --git a/internal/domain/keys/model.go b/internal/domain/keys/models.go similarity index 100% rename from internal/domain/keys/model.go rename to internal/domain/keys/models.go diff --git a/internal/domain/keys/query.go b/internal/domain/keys/queries.go similarity index 100% rename from internal/domain/keys/query.go rename to internal/domain/keys/queries.go diff --git a/internal/domain/permissions/contract.go b/internal/domain/permissions/contracts.go similarity index 100% rename from internal/domain/permissions/contract.go rename to internal/domain/permissions/contracts.go diff --git a/internal/infrastructure/connector/blob.go b/internal/infrastructure/connector/blob_connectors.go similarity index 100% rename from internal/infrastructure/connector/blob.go rename to internal/infrastructure/connector/blob_connectors.go diff --git a/internal/infrastructure/connector/key.go b/internal/infrastructure/connector/key_connectors.go similarity index 100% rename from internal/infrastructure/connector/key.go rename to internal/infrastructure/connector/key_connectors.go diff --git a/internal/persistence/repository/blob.go b/internal/persistence/repository/blob_repository.go similarity index 100% rename from internal/persistence/repository/blob.go rename to internal/persistence/repository/blob_repository.go diff --git a/internal/persistence/repository/key.go b/internal/persistence/repository/key_repository.go similarity index 100% rename from internal/persistence/repository/key.go rename to internal/persistence/repository/key_repository.go diff --git a/test/integration/infrastructure/connector/az_blob_test.go b/test/integration/infrastructure/connector/az_blob_connector_test.go similarity index 100% rename from test/integration/infrastructure/connector/az_blob_test.go rename to test/integration/infrastructure/connector/az_blob_connector_test.go diff --git a/test/integration/infrastructure/connector/az_vault_test.go b/test/integration/infrastructure/connector/az_vault_connector_test.go similarity index 100% rename from test/integration/infrastructure/connector/az_vault_test.go rename to test/integration/infrastructure/connector/az_vault_connector_test.go diff --git a/test/integration/persistence/repository/blob_psql_test.go b/test/integration/persistence/repository/psql_blob_repository_test.go similarity index 100% rename from test/integration/persistence/repository/blob_psql_test.go rename to test/integration/persistence/repository/psql_blob_repository_test.go diff --git a/test/integration/persistence/repository/blob_sqlite_test.go b/test/integration/persistence/repository/sqlite_blob_repository_test.go similarity index 100% rename from test/integration/persistence/repository/blob_sqlite_test.go rename to test/integration/persistence/repository/sqlite_blob_repository_test.go diff --git a/test/integration/persistence/repository/key_sqlite_test.go b/test/integration/persistence/repository/sqlite_key_repository_test.go similarity index 100% rename from test/integration/persistence/repository/key_sqlite_test.go rename to test/integration/persistence/repository/sqlite_key_repository_test.go diff --git a/test/integration/persistence/repository/test_context.go b/test/integration/persistence/repository/test_repository_context.go similarity index 92% rename from test/integration/persistence/repository/test_context.go rename to test/integration/persistence/repository/test_repository_context.go index 52a6cfe..c014a74 100644 --- a/test/integration/persistence/repository/test_context.go +++ b/test/integration/persistence/repository/test_repository_context.go @@ -13,15 +13,15 @@ import ( "gorm.io/gorm" ) -// TestContext struct to hold DB and repositories for each test -type TestContext struct { +// TestRepositoryContext struct to hold DB and repositories for each test +type TestRepositoryContext struct { DB *gorm.DB BlobRepo *repository.GormBlobRepository CryptoKeyRepo *repository.GormCryptoKeyRepository } // Setup function to initialize the test DB and repositories -func setupTestDB(t *testing.T) *TestContext { +func setupTestDB(t *testing.T) *TestRepositoryContext { var err error var db *gorm.DB @@ -95,7 +95,7 @@ func setupTestDB(t *testing.T) *TestContext { cryptoKeyRepo := &repository.GormCryptoKeyRepository{DB: db} // Return the test context that holds the DB and repositories - return &TestContext{ + return &TestRepositoryContext{ DB: db, BlobRepo: blobRepo, CryptoKeyRepo: cryptoKeyRepo, @@ -103,7 +103,7 @@ func setupTestDB(t *testing.T) *TestContext { } // Teardown function to clean up after tests (optional, for DB cleanup) -func teardownTestDB(t *testing.T, ctx *TestContext) { +func teardownTestDB(t *testing.T, ctx *TestRepositoryContext) { sqlDB, err := ctx.DB.DB() if err != nil { t.Fatalf("Failed to get DB connection: %v", err) diff --git a/test/unit/domain/blobs/blob_test.go b/test/unit/domain/blobs/model_test.go similarity index 100% rename from test/unit/domain/blobs/blob_test.go rename to test/unit/domain/blobs/model_test.go diff --git a/test/unit/domain/keys/key_test.go b/test/unit/domain/keys/model_test.go similarity index 100% rename from test/unit/domain/keys/key_test.go rename to test/unit/domain/keys/model_test.go From 381c4938fc33c128a21aaa813545fca119eb9f57 Mon Sep 17 00:00:00 2001 From: root Date: Wed, 20 Nov 2024 17:59:01 +0000 Subject: [PATCH 03/29] add missing character --- internal/app/services/key_services.go | 4 ++-- internal/domain/keys/contracts.go | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/internal/app/services/key_services.go b/internal/app/services/key_services.go index dc6a8de..95285f6 100644 --- a/internal/app/services/key_services.go +++ b/internal/app/services/key_services.go @@ -10,12 +10,12 @@ import ( "github.com/google/uuid" ) -type CryptKeyUploadService struct { +type CryptoKeyUploadService struct { VaultConnector connector.VaultConnector CryptoKeyRepo repository.CryptoKeyRepository } -func (s *CryptKeyUploadService) Upload(filePaths []string) ([]*keys.CryptoKeyMeta, error) { +func (s *CryptoKeyUploadService) Upload(filePaths []string) ([]*keys.CryptoKeyMeta, error) { // Step 1: Upload files to blob storage userId := uuid.New().String() blobMeta, err := s.VaultConnector.Upload(filePaths, userId) diff --git a/internal/domain/keys/contracts.go b/internal/domain/keys/contracts.go index 97fb1c4..c5086ad 100644 --- a/internal/domain/keys/contracts.go +++ b/internal/domain/keys/contracts.go @@ -10,8 +10,8 @@ const ( Symmetric // Symmetric key (e.g., AES) ) -// ICryptKeyUploadService defines methods for uploading cryptographic keys. -type ICryptKeyUploadService interface { +// ICryptoKeyUploadService defines methods for uploading cryptographic keys. +type ICryptoKeyUploadService interface { // Upload uploads cryptographic keys from specified file paths. // It returns a slice of CryptoKeyMeta and any error encountered during the upload process. Upload(filePaths []string) ([]*CryptoKeyMeta, error) From 22558e275a6637b25bc3fcc101de8d0fb3106c3e Mon Sep 17 00:00:00 2001 From: root Date: Wed, 20 Nov 2024 18:17:52 +0000 Subject: [PATCH 04/29] add help target --- Makefile | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 61cf7f9..8070935 100644 --- a/Makefile +++ b/Makefile @@ -3,25 +3,43 @@ SCRIPT_DIR = "scripts" .PHONY: format-and-lint run-unit-tests run-integration-tests \ spin-up-integration-test-docker-containers \ shut-down-integration-test-docker-containers \ - spin-up-docker-containers shut-down-docker-containers - + spin-up-docker-containers shut-down-docker-containers help + +# Help target to list all available targets +help: + @echo "Available Makefile targets:" + @echo " format-and-lint - Run the format and linting script" + @echo " run-unit-tests - Run the unit tests" + @echo " run-integration-tests - Run the integration tests" + @echo " spin-up-integration-test-docker-containers - Spin up Docker containers for integration tests (Postgres, Azure Blob Storage)" + @echo " shut-down-integration-test-docker-containers - Shut down Docker containers for integration tests" + @echo " spin-up-docker-containers - Spin up Docker containers with internal containerized applications" + @echo " shut-down-docker-containers - Shut down the application Docker containers" + +# Run the format and lint script format-and-lint: @cd $(SCRIPT_DIR) && ./format-and-lint.sh +# Run unit tests run-unit-tests: @cd $(SCRIPT_DIR) && ./run-test.sh -u +# Run integration tests run-integration-tests: @cd $(SCRIPT_DIR) && ./run-test.sh -i +# Spin up Docker containers for integration tests spin-up-integration-test-docker-containers: docker-compose up -d postgres azure-blob-storage +# Shut down Docker containers for integration tests shut-down-integration-test-docker-containers: docker-compose down postgres azure-blob-storage -v +# Spin up Docker containers with internal containerized applications spin-up-docker-containers: docker-compose up -d --build +# Shut down Docker containers with internal containerized applications shut-down-docker-containers: - docker-compose down -v \ No newline at end of file + docker-compose down -v From ec663c224e6331160c237ad57b87ea4c95991990 Mon Sep 17 00:00:00 2001 From: Marvin Gajek Date: Thu, 21 Nov 2024 09:17:22 +0100 Subject: [PATCH 05/29] merge main --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index dada0bb..8c8ea3d 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ ## Summary -RESTful Web API for managing cryptographic keys and securing data at rest (metadata, BLOB) +Interfaces (CLIs, gRPC APIs, RESTful Web APIs) for managing cryptographic keys and securing data at rest (metadata, BLOB) ## References From 129e97b75440563329609fc59542de783e81a37a Mon Sep 17 00:00:00 2001 From: Marvin Gajek Date: Thu, 21 Nov 2024 12:13:01 +0100 Subject: [PATCH 06/29] consider userId as input argument and fix Upload(...) logic --- internal/app/services/key_services.go | 24 ++++-------------------- internal/domain/keys/contracts.go | 2 +- 2 files changed, 5 insertions(+), 21 deletions(-) diff --git a/internal/app/services/key_services.go b/internal/app/services/key_services.go index 95285f6..664a97e 100644 --- a/internal/app/services/key_services.go +++ b/internal/app/services/key_services.go @@ -5,9 +5,6 @@ import ( "crypto_vault_service/internal/infrastructure/connector" "crypto_vault_service/internal/persistence/repository" "fmt" - "time" - - "github.com/google/uuid" ) type CryptoKeyUploadService struct { @@ -15,37 +12,24 @@ type CryptoKeyUploadService struct { CryptoKeyRepo repository.CryptoKeyRepository } -func (s *CryptoKeyUploadService) Upload(filePaths []string) ([]*keys.CryptoKeyMeta, error) { +func (s *CryptoKeyUploadService) Upload(filePaths []string, userId string) ([]*keys.CryptoKeyMeta, error) { // Step 1: Upload files to blob storage - userId := uuid.New().String() - blobMeta, err := s.VaultConnector.Upload(filePaths, userId) + keyMetas, err := s.VaultConnector.Upload(filePaths, userId) if err != nil { return nil, fmt.Errorf("failed to upload files: %w", err) } // Step 2: Store the metadata in the database - var keyMetas []*keys.CryptoKeyMeta - for _, blob := range blobMeta { - // Map Blob metadata to CryptoKey metadata - keyMeta := &keys.CryptoKeyMeta{ - ID: uuid.New().String(), // Generate valid UUID for ID - Type: "RSA", // Example key type - DateTimeCreated: time.Now(), // Valid DateTimeCreated time - UserID: uuid.New().String(), // Generate valid UUID for UserID - } - + for _, keyMeta := range keyMetas { // Validate CryptoKeyMeta if err := keyMeta.Validate(); err != nil { return nil, fmt.Errorf("invalid key metadata: %w", err) } // Save metadata to DB - if err := s.CryptoKeyRepo.Create(blob); err != nil { + if err := s.CryptoKeyRepo.Create(keyMeta); err != nil { return nil, fmt.Errorf("failed to create metadata for key of type %s: %w", keyMeta.Type, err) } - - // Append to list - keyMetas = append(keyMetas, keyMeta) } // Return metadata diff --git a/internal/domain/keys/contracts.go b/internal/domain/keys/contracts.go index c5086ad..dc49a1f 100644 --- a/internal/domain/keys/contracts.go +++ b/internal/domain/keys/contracts.go @@ -14,7 +14,7 @@ const ( type ICryptoKeyUploadService interface { // Upload uploads cryptographic keys from specified file paths. // It returns a slice of CryptoKeyMeta and any error encountered during the upload process. - Upload(filePaths []string) ([]*CryptoKeyMeta, error) + Upload(filePaths []string, userId string) ([]*CryptoKeyMeta, error) } // ICryptoKeyMetadataService defines methods for managing cryptographic key metadata and deleting keys. From 92f3ab77459f06ac2defee2923451246b7dc238b Mon Sep 17 00:00:00 2001 From: Marvin Gajek Date: Thu, 21 Nov 2024 12:15:14 +0100 Subject: [PATCH 07/29] rename variable --- internal/app/services/blob_services.go | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/internal/app/services/blob_services.go b/internal/app/services/blob_services.go index 1b6d092..0249ea0 100644 --- a/internal/app/services/blob_services.go +++ b/internal/app/services/blob_services.go @@ -25,28 +25,28 @@ func NewBlobUploadService(blobConnector connector.BlobConnector, blobRepository func (s *BlobUploadService) Upload(filePaths []string, userId string) ([]*blobs.BlobMeta, error) { // Use the BlobConnector to upload the files to Azure Blob Storage - blobMeta, err := s.BlobConnector.Upload(filePaths, userId) + blobMetas, err := s.BlobConnector.Upload(filePaths, userId) if err != nil { return nil, fmt.Errorf("failed to upload blobs: %w", err) } // If no blobs are uploaded, return early - if len(blobMeta) == 0 { + if len(blobMetas) == 0 { return nil, fmt.Errorf("no blobs uploaded") } // Store the metadata in the database using the BlobRepository - for _, blob := range blobMeta { - err := s.BlobRepository.Create(blob) + for _, blobMeta := range blobMetas { + err := s.BlobRepository.Create(blobMeta) if err != nil { // Rollback any previously uploaded blobs if the metadata fails to store // (you can call delete method to handle this as needed) - return nil, fmt.Errorf("failed to store metadata for blob '%s': %w", blob.Name, err) + return nil, fmt.Errorf("failed to store metadata for blob '%s': %w", blobMeta.Name, err) } } // Return the metadata of uploaded blobs - return blobMeta, nil + return blobMetas, nil } // BlobMetadataService implements the BlobMetadataService interface for retrieving and deleting blob metadata @@ -66,27 +66,27 @@ func NewBlobMetadataService(blobRepository repository.BlobRepository, blobConnec // List retrieves all blobs' metadata considering a query filter func (s *BlobMetadataService) List(query *blobs.BlobMetaQuery) ([]*blobs.BlobMeta, error) { // Assuming BlobRepository has a method to query metadata, you can adapt to GORM queries. - var blobsList []*blobs.BlobMeta + var blobMetas []*blobs.BlobMeta // TBD - return blobsList, nil + return blobMetas, nil } // GetByID retrieves a blob's metadata by its unique ID func (s *BlobMetadataService) GetByID(blobID string) (*blobs.BlobMeta, error) { // Retrieve the blob metadata using the BlobRepository - blob, err := s.BlobRepository.GetById(blobID) + blobMeta, err := s.BlobRepository.GetById(blobID) if err != nil { return nil, fmt.Errorf("failed to retrieve blob metadata by ID '%s': %w", blobID, err) } - return blob, nil + return blobMeta, nil } // DeleteByID deletes a blob and its associated metadata by ID func (s *BlobMetadataService) DeleteByID(blobID string) error { // Retrieve the blob metadata to ensure it exists - blob, err := s.BlobRepository.GetById(blobID) + blobMeta, err := s.BlobRepository.GetById(blobID) if err != nil { return fmt.Errorf("failed to retrieve blob metadata by ID '%s' for deletion: %w", blobID, err) } @@ -98,9 +98,9 @@ func (s *BlobMetadataService) DeleteByID(blobID string) error { } // Now, delete the actual blob from the Blob Storage - err = s.BlobConnector.Delete(blob.ID, blob.Name) + err = s.BlobConnector.Delete(blobMeta.ID, blobMeta.Name) if err != nil { - return fmt.Errorf("failed to delete blob '%s' from Blob Storage: %w", blob.Name, err) + return fmt.Errorf("failed to delete blob '%s' from Blob Storage: %w", blobMeta.Name, err) } return nil From 3cd7a0c6d2ab3e0184d790942b358208fcc198e0 Mon Sep 17 00:00:00 2001 From: Marvin Gajek Date: Thu, 21 Nov 2024 13:33:28 +0100 Subject: [PATCH 08/29] fail fast --- .../persistence/repository/psql_blob_repository_test.go | 7 +++---- .../repository/sqlite_blob_repository_test.go | 9 ++++----- .../persistence/repository/sqlite_key_repository_test.go | 7 +++---- 3 files changed, 10 insertions(+), 13 deletions(-) diff --git a/test/integration/persistence/repository/psql_blob_repository_test.go b/test/integration/persistence/repository/psql_blob_repository_test.go index 5d90cd6..ba6f4e7 100644 --- a/test/integration/persistence/repository/psql_blob_repository_test.go +++ b/test/integration/persistence/repository/psql_blob_repository_test.go @@ -3,7 +3,6 @@ package repository import ( "crypto_vault_service/internal/domain/blobs" "crypto_vault_service/internal/domain/keys" - "fmt" "os" "testing" "time" @@ -17,7 +16,7 @@ import ( func TestBlobPsqlRepository_Create(t *testing.T) { err := os.Setenv("DB_TYPE", "postgres") if err != nil { - fmt.Println("Error setting environment variable:", err) + t.Fatalf("Error setting environment variable:", err) } // Set up test context ctx := setupTestDB(t) @@ -59,7 +58,7 @@ func TestBlobPsqlRepository_Create(t *testing.T) { func TestBlobPsqlRepository_GetById(t *testing.T) { err := os.Setenv("DB_TYPE", "postgres") if err != nil { - fmt.Println("Error setting environment variable:", err) + t.Fatalf("Error setting environment variable:", err) } // Set up test context ctx := setupTestDB(t) @@ -101,7 +100,7 @@ func TestBlobPsqlRepository_GetById(t *testing.T) { func TestBlobPsqlRepository_UpdateById(t *testing.T) { err := os.Setenv("DB_TYPE", "postgres") if err != nil { - fmt.Println("Error setting environment variable:", err) + t.Fatalf("Error setting environment variable:", err) } // Set up test context ctx := setupTestDB(t) diff --git a/test/integration/persistence/repository/sqlite_blob_repository_test.go b/test/integration/persistence/repository/sqlite_blob_repository_test.go index f8a8ebd..daa4f62 100644 --- a/test/integration/persistence/repository/sqlite_blob_repository_test.go +++ b/test/integration/persistence/repository/sqlite_blob_repository_test.go @@ -3,7 +3,6 @@ package repository import ( "crypto_vault_service/internal/domain/blobs" "crypto_vault_service/internal/domain/keys" - "fmt" "os" "testing" "time" @@ -17,7 +16,7 @@ import ( func TestBlobInSqliteRepository_Create(t *testing.T) { err := os.Setenv("DB_TYPE", "sqlite") if err != nil { - fmt.Println("Error setting environment variable:", err) + t.Fatalf("Error setting environment variable:", err) } // Set up test context ctx := setupTestDB(t) @@ -59,7 +58,7 @@ func TestBlobInSqliteRepository_Create(t *testing.T) { func TestBlobInSqliteRepository_GetById(t *testing.T) { err := os.Setenv("DB_TYPE", "sqlite") if err != nil { - fmt.Println("Error setting environment variable:", err) + t.Fatalf("Error setting environment variable:", err) } // Set up test context ctx := setupTestDB(t) @@ -100,7 +99,7 @@ func TestBlobInSqliteRepository_GetById(t *testing.T) { func TestBlobInSqliteRepository_UpdateById(t *testing.T) { err := os.Setenv("DB_TYPE", "sqlite") if err != nil { - fmt.Println("Error setting environment variable:", err) + t.Fatalf("Error setting environment variable:", err) } // Set up test context ctx := setupTestDB(t) @@ -146,7 +145,7 @@ func TestBlobInSqliteRepository_UpdateById(t *testing.T) { func TestBlobInSqliteRepository_DeleteById(t *testing.T) { err := os.Setenv("DB_TYPE", "sqlite") if err != nil { - fmt.Println("Error setting environment variable:", err) + t.Fatalf("Error setting environment variable:", err) } // Set up test context ctx := setupTestDB(t) diff --git a/test/integration/persistence/repository/sqlite_key_repository_test.go b/test/integration/persistence/repository/sqlite_key_repository_test.go index ce38524..fc1e9a4 100644 --- a/test/integration/persistence/repository/sqlite_key_repository_test.go +++ b/test/integration/persistence/repository/sqlite_key_repository_test.go @@ -2,7 +2,6 @@ package repository import ( "crypto_vault_service/internal/domain/keys" - "fmt" "os" "testing" "time" @@ -16,7 +15,7 @@ import ( func TestCryptoKeySqliteRepository_Create(t *testing.T) { err := os.Setenv("DB_TYPE", "sqlite") if err != nil { - fmt.Println("Error setting environment variable:", err) + t.Fatalf("Error setting environment variable:", err) } // Set up test context ctx := setupTestDB(t) @@ -46,7 +45,7 @@ func TestCryptoKeySqliteRepository_Create(t *testing.T) { func TestCryptoKeySqliteRepository_GetByID(t *testing.T) { err := os.Setenv("DB_TYPE", "sqlite") if err != nil { - fmt.Println("Error setting environment variable:", err) + t.Fatalf("Error setting environment variable:", err) } // Set up test context ctx := setupTestDB(t) @@ -75,7 +74,7 @@ func TestCryptoKeySqliteRepository_GetByID(t *testing.T) { func TestCryptoKeySqliteRepository_UpdateByID(t *testing.T) { err := os.Setenv("DB_TYPE", "sqlite") if err != nil { - fmt.Println("Error setting environment variable:", err) + t.Fatalf("Error setting environment variable:", err) } // Set up test context ctx := setupTestDB(t) From ecde810a74801e4dc0e9460f21ec55c83427d815 Mon Sep 17 00:00:00 2001 From: Marvin Gajek Date: Thu, 21 Nov 2024 14:49:19 +0100 Subject: [PATCH 09/29] rename struct --- .../connector/az_blob_connector_test.go | 18 +++++++++--------- .../connector/az_vault_connector_test.go | 18 +++++++++--------- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/test/integration/infrastructure/connector/az_blob_connector_test.go b/test/integration/infrastructure/connector/az_blob_connector_test.go index 649d9a3..6e41944 100644 --- a/test/integration/infrastructure/connector/az_blob_connector_test.go +++ b/test/integration/infrastructure/connector/az_blob_connector_test.go @@ -12,7 +12,7 @@ import ( ) // Define a struct for the test context to reuse across multiple tests -type AzureBlobTest struct { +type AzureBlobConnectorTest struct { Connector *connector.AzureBlobConnector TestFilePath string TestFileContent []byte @@ -20,25 +20,25 @@ type AzureBlobTest struct { } // Helper function to create a test file -func (abt *AzureBlobTest) createTestFile(t *testing.T) { +func (abt *AzureBlobConnectorTest) createTestFile(t *testing.T) { err := os.WriteFile(abt.TestFilePath, abt.TestFileContent, 0644) require.NoError(t, err) } // Helper function to remove the test file -func (abt *AzureBlobTest) removeTestFile(t *testing.T) { +func (abt *AzureBlobConnectorTest) removeTestFile(t *testing.T) { err := os.Remove(abt.TestFilePath) require.NoError(t, err) } -// Helper function to create a new AzureBlobTest instance -func NewAzureBlobTest(t *testing.T) *AzureBlobTest { +// Helper function to create a new AzureBlobConnectorTest instance +func NewAzureBlobConnectorTest(t *testing.T) *AzureBlobConnectorTest { connectionString := "DefaultEndpointsProtocol=http;AccountName=devstoreaccount1;AccountKey=Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==;BlobEndpoint=http://127.0.0.1:10000/devstoreaccount1;" containerName := "testblobs" abc, err := connector.NewAzureBlobConnector(connectionString, containerName) require.NoError(t, err) - return &AzureBlobTest{ + return &AzureBlobConnectorTest{ Connector: abc, TestFilePath: "testfile.txt", TestFileContent: []byte("This is a test file content."), @@ -49,7 +49,7 @@ func NewAzureBlobTest(t *testing.T) *AzureBlobTest { // TestUpload tests the Upload method of AzureBlobConnector func TestUpload(t *testing.T) { // Initialize test struct - azureTest := NewAzureBlobTest(t) + azureTest := NewAzureBlobConnectorTest(t) // Prepare test file azureTest.createTestFile(t) @@ -76,7 +76,7 @@ func TestUpload(t *testing.T) { // TestDownload tests the Download method of AzureBlobConnector func TestDownload(t *testing.T) { // Initialize test struct - azureTest := NewAzureBlobTest(t) + azureTest := NewAzureBlobConnectorTest(t) // Prepare test file azureTest.createTestFile(t) @@ -103,7 +103,7 @@ func TestDownload(t *testing.T) { // TestDelete tests the Delete method of AzureBlobConnector func TestDelete(t *testing.T) { // Initialize test struct - azureTest := NewAzureBlobTest(t) + azureTest := NewAzureBlobConnectorTest(t) // Prepare test file azureTest.createTestFile(t) diff --git a/test/integration/infrastructure/connector/az_vault_connector_test.go b/test/integration/infrastructure/connector/az_vault_connector_test.go index c587713..9e08cdc 100644 --- a/test/integration/infrastructure/connector/az_vault_connector_test.go +++ b/test/integration/infrastructure/connector/az_vault_connector_test.go @@ -12,7 +12,7 @@ import ( ) // Define a struct for the test context to reuse across multiple tests -type AzureVaultTest struct { +type AzureVaultConnectorTest struct { Connector *connector.AzureVaultConnector TestFilePath string TestFileContent []byte @@ -21,26 +21,26 @@ type AzureVaultTest struct { } // Helper function to create a test file -func (abt *AzureVaultTest) createTestFile(t *testing.T) { +func (abt *AzureVaultConnectorTest) createTestFile(t *testing.T) { err := os.WriteFile(abt.TestFilePath, abt.TestFileContent, 0644) require.NoError(t, err) } // Helper function to remove the test file -func (abt *AzureVaultTest) removeTestFile(t *testing.T) { +func (abt *AzureVaultConnectorTest) removeTestFile(t *testing.T) { err := os.Remove(abt.TestFilePath) require.NoError(t, err) } -// Helper function to create a new AzureVaultTest instance -func NewAzureVaultTest(t *testing.T) *AzureVaultTest { +// Helper function to create a new AzureVaultConnectorTest instance +func NewAzureVaultConnectorTest(t *testing.T) *AzureVaultConnectorTest { connectionString := "DefaultEndpointsProtocol=http;AccountName=devstoreaccount1;AccountKey=Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==;BlobEndpoint=http://127.0.0.1:10000/devstoreaccount1;" containerName := "testblobs" // Create the Azure Vault Connector abc, err := connector.NewAzureVaultConnector(connectionString, containerName) require.NoError(t, err) - return &AzureVaultTest{ + return &AzureVaultConnectorTest{ Connector: abc, TestFilePath: "testfile.txt", TestFileContent: []byte("This is a test file content."), @@ -52,7 +52,7 @@ func NewAzureVaultTest(t *testing.T) *AzureVaultTest { // TestUpload tests the Upload method of AzureVaultConnector func TestAzureVaultConnector_Upload(t *testing.T) { // Initialize test struct - azureTest := NewAzureVaultTest(t) + azureTest := NewAzureVaultConnectorTest(t) // Prepare test file azureTest.createTestFile(t) @@ -79,7 +79,7 @@ func TestAzureVaultConnector_Upload(t *testing.T) { // TestDownload tests the Download method of AzureVaultConnector func TestAzureVaultConnector_Download(t *testing.T) { // Initialize test struct - azureTest := NewAzureVaultTest(t) + azureTest := NewAzureVaultConnectorTest(t) // Prepare test file azureTest.createTestFile(t) @@ -108,7 +108,7 @@ func TestAzureVaultConnector_Download(t *testing.T) { // TestDelete tests the Delete method of AzureVaultConnector func TestAzureVaultConnector_Delete(t *testing.T) { // Initialize test struct - azureTest := NewAzureVaultTest(t) + azureTest := NewAzureVaultConnectorTest(t) // Prepare test file azureTest.createTestFile(t) From 6f12014e9e43d4170dd6cd3da767d3ffc5961673 Mon Sep 17 00:00:00 2001 From: Marvin Gajek Date: Thu, 21 Nov 2024 14:51:12 +0100 Subject: [PATCH 10/29] modify comment --- .../infrastructure/connector/az_blob_connector_test.go | 2 +- .../infrastructure/connector/az_vault_connector_test.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test/integration/infrastructure/connector/az_blob_connector_test.go b/test/integration/infrastructure/connector/az_blob_connector_test.go index 6e41944..2dcfa41 100644 --- a/test/integration/infrastructure/connector/az_blob_connector_test.go +++ b/test/integration/infrastructure/connector/az_blob_connector_test.go @@ -11,7 +11,7 @@ import ( "github.com/stretchr/testify/require" ) -// Define a struct for the test context to reuse across multiple tests +// Define a struct to represent the test context for Azure Blob Connector tests. type AzureBlobConnectorTest struct { Connector *connector.AzureBlobConnector TestFilePath string diff --git a/test/integration/infrastructure/connector/az_vault_connector_test.go b/test/integration/infrastructure/connector/az_vault_connector_test.go index 9e08cdc..50a6144 100644 --- a/test/integration/infrastructure/connector/az_vault_connector_test.go +++ b/test/integration/infrastructure/connector/az_vault_connector_test.go @@ -11,7 +11,7 @@ import ( "github.com/stretchr/testify/require" ) -// Define a struct for the test context to reuse across multiple tests +// Define a struct to represent the test context for Azure Vault Connector tests. type AzureVaultConnectorTest struct { Connector *connector.AzureVaultConnector TestFilePath string From 99537f0cd79b67d81d67d1898f900a8f620bc832 Mon Sep 17 00:00:00 2001 From: Marvin Gajek Date: Thu, 21 Nov 2024 15:00:08 +0100 Subject: [PATCH 11/29] remove obsolete members variables in test contexts --- .../connector/az_blob_connector_test.go | 2 -- .../connector/az_vault_connector_test.go | 16 ++++++---------- 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/test/integration/infrastructure/connector/az_blob_connector_test.go b/test/integration/infrastructure/connector/az_blob_connector_test.go index 2dcfa41..3b0469e 100644 --- a/test/integration/infrastructure/connector/az_blob_connector_test.go +++ b/test/integration/infrastructure/connector/az_blob_connector_test.go @@ -16,7 +16,6 @@ type AzureBlobConnectorTest struct { Connector *connector.AzureBlobConnector TestFilePath string TestFileContent []byte - ContainerName string } // Helper function to create a test file @@ -42,7 +41,6 @@ func NewAzureBlobConnectorTest(t *testing.T) *AzureBlobConnectorTest { Connector: abc, TestFilePath: "testfile.txt", TestFileContent: []byte("This is a test file content."), - ContainerName: containerName, } } diff --git a/test/integration/infrastructure/connector/az_vault_connector_test.go b/test/integration/infrastructure/connector/az_vault_connector_test.go index 50a6144..ee6dbf8 100644 --- a/test/integration/infrastructure/connector/az_vault_connector_test.go +++ b/test/integration/infrastructure/connector/az_vault_connector_test.go @@ -13,11 +13,9 @@ import ( // Define a struct to represent the test context for Azure Vault Connector tests. type AzureVaultConnectorTest struct { - Connector *connector.AzureVaultConnector - TestFilePath string - TestFileContent []byte - ContainerName string - ConnectionString string + Connector *connector.AzureVaultConnector + TestFilePath string + TestFileContent []byte } // Helper function to create a test file @@ -41,11 +39,9 @@ func NewAzureVaultConnectorTest(t *testing.T) *AzureVaultConnectorTest { require.NoError(t, err) return &AzureVaultConnectorTest{ - Connector: abc, - TestFilePath: "testfile.txt", - TestFileContent: []byte("This is a test file content."), - ContainerName: containerName, - ConnectionString: connectionString, + Connector: abc, + TestFilePath: "testfile.txt", + TestFileContent: []byte("This is a test file content."), } } From eee3031eccd996c77386e8c4a1dcf94ff6d6b46a Mon Sep 17 00:00:00 2001 From: root Date: Thu, 21 Nov 2024 14:04:08 +0000 Subject: [PATCH 12/29] properly format the error message using %v --- .../repository/psql_blob_repository_test.go | 9 ++++++--- .../repository/sqlite_blob_repository_test.go | 12 ++++++++---- .../repository/sqlite_key_repository_test.go | 9 ++++++--- 3 files changed, 20 insertions(+), 10 deletions(-) diff --git a/test/integration/persistence/repository/psql_blob_repository_test.go b/test/integration/persistence/repository/psql_blob_repository_test.go index ba6f4e7..b250755 100644 --- a/test/integration/persistence/repository/psql_blob_repository_test.go +++ b/test/integration/persistence/repository/psql_blob_repository_test.go @@ -16,8 +16,9 @@ import ( func TestBlobPsqlRepository_Create(t *testing.T) { err := os.Setenv("DB_TYPE", "postgres") if err != nil { - t.Fatalf("Error setting environment variable:", err) + t.Fatalf("Error setting environment variable: %v", err) } + // Set up test context ctx := setupTestDB(t) defer teardownTestDB(t, ctx) @@ -58,8 +59,9 @@ func TestBlobPsqlRepository_Create(t *testing.T) { func TestBlobPsqlRepository_GetById(t *testing.T) { err := os.Setenv("DB_TYPE", "postgres") if err != nil { - t.Fatalf("Error setting environment variable:", err) + t.Fatalf("Error setting environment variable: %v", err) } + // Set up test context ctx := setupTestDB(t) defer teardownTestDB(t, ctx) @@ -100,8 +102,9 @@ func TestBlobPsqlRepository_GetById(t *testing.T) { func TestBlobPsqlRepository_UpdateById(t *testing.T) { err := os.Setenv("DB_TYPE", "postgres") if err != nil { - t.Fatalf("Error setting environment variable:", err) + t.Fatalf("Error setting environment variable: %v", err) } + // Set up test context ctx := setupTestDB(t) defer teardownTestDB(t, ctx) diff --git a/test/integration/persistence/repository/sqlite_blob_repository_test.go b/test/integration/persistence/repository/sqlite_blob_repository_test.go index daa4f62..32c1ff0 100644 --- a/test/integration/persistence/repository/sqlite_blob_repository_test.go +++ b/test/integration/persistence/repository/sqlite_blob_repository_test.go @@ -16,8 +16,9 @@ import ( func TestBlobInSqliteRepository_Create(t *testing.T) { err := os.Setenv("DB_TYPE", "sqlite") if err != nil { - t.Fatalf("Error setting environment variable:", err) + t.Fatalf("Error setting environment variable: %v", err) } + // Set up test context ctx := setupTestDB(t) defer teardownTestDB(t, ctx) @@ -58,8 +59,9 @@ func TestBlobInSqliteRepository_Create(t *testing.T) { func TestBlobInSqliteRepository_GetById(t *testing.T) { err := os.Setenv("DB_TYPE", "sqlite") if err != nil { - t.Fatalf("Error setting environment variable:", err) + t.Fatalf("Error setting environment variable: %v", err) } + // Set up test context ctx := setupTestDB(t) defer teardownTestDB(t, ctx) @@ -99,8 +101,9 @@ func TestBlobInSqliteRepository_GetById(t *testing.T) { func TestBlobInSqliteRepository_UpdateById(t *testing.T) { err := os.Setenv("DB_TYPE", "sqlite") if err != nil { - t.Fatalf("Error setting environment variable:", err) + t.Fatalf("Error setting environment variable: %v", err) } + // Set up test context ctx := setupTestDB(t) defer teardownTestDB(t, ctx) @@ -145,8 +148,9 @@ func TestBlobInSqliteRepository_UpdateById(t *testing.T) { func TestBlobInSqliteRepository_DeleteById(t *testing.T) { err := os.Setenv("DB_TYPE", "sqlite") if err != nil { - t.Fatalf("Error setting environment variable:", err) + t.Fatalf("Error setting environment variable: %v", err) } + // Set up test context ctx := setupTestDB(t) defer teardownTestDB(t, ctx) diff --git a/test/integration/persistence/repository/sqlite_key_repository_test.go b/test/integration/persistence/repository/sqlite_key_repository_test.go index fc1e9a4..be9548e 100644 --- a/test/integration/persistence/repository/sqlite_key_repository_test.go +++ b/test/integration/persistence/repository/sqlite_key_repository_test.go @@ -15,8 +15,9 @@ import ( func TestCryptoKeySqliteRepository_Create(t *testing.T) { err := os.Setenv("DB_TYPE", "sqlite") if err != nil { - t.Fatalf("Error setting environment variable:", err) + t.Fatalf("Error setting environment variable: %v", err) } + // Set up test context ctx := setupTestDB(t) defer teardownTestDB(t, ctx) @@ -45,8 +46,9 @@ func TestCryptoKeySqliteRepository_Create(t *testing.T) { func TestCryptoKeySqliteRepository_GetByID(t *testing.T) { err := os.Setenv("DB_TYPE", "sqlite") if err != nil { - t.Fatalf("Error setting environment variable:", err) + t.Fatalf("Error setting environment variable: %v", err) } + // Set up test context ctx := setupTestDB(t) defer teardownTestDB(t, ctx) @@ -74,8 +76,9 @@ func TestCryptoKeySqliteRepository_GetByID(t *testing.T) { func TestCryptoKeySqliteRepository_UpdateByID(t *testing.T) { err := os.Setenv("DB_TYPE", "sqlite") if err != nil { - t.Fatalf("Error setting environment variable:", err) + t.Fatalf("Error setting environment variable: %v", err) } + // Set up test context ctx := setupTestDB(t) defer teardownTestDB(t, ctx) From fa4e5e481bd7277dce88d748ddd14dcaa2be33cb Mon Sep 17 00:00:00 2001 From: root Date: Thu, 21 Nov 2024 14:05:52 +0000 Subject: [PATCH 13/29] remove test db setup and cleanup fro TestMain --- .../persistence/repository/test_repository_context.go | 4 ---- 1 file changed, 4 deletions(-) diff --git a/test/integration/persistence/repository/test_repository_context.go b/test/integration/persistence/repository/test_repository_context.go index c014a74..3e5d1a0 100644 --- a/test/integration/persistence/repository/test_repository_context.go +++ b/test/integration/persistence/repository/test_repository_context.go @@ -113,12 +113,8 @@ func teardownTestDB(t *testing.T, ctx *TestRepositoryContext) { // TestMain setup and teardown for the entire test suite func TestMain(m *testing.M) { - // Set up test context - ctx := setupTestDB(nil) // Run tests code := m.Run() - // Clean up after tests - teardownTestDB(nil, ctx) // Exit with the test result code if code != 0 { fmt.Println("Tests failed.") From c66e3cb5d825b7a1871602d851190583b6aeb27d Mon Sep 17 00:00:00 2001 From: root Date: Thu, 21 Nov 2024 14:36:54 +0000 Subject: [PATCH 14/29] modify connector tests --- .../connector/az_blob_connector_test.go | 24 ++++++++++--------- .../connector/az_vault_connector_test.go | 24 ++++++++++--------- 2 files changed, 26 insertions(+), 22 deletions(-) diff --git a/test/integration/infrastructure/connector/az_blob_connector_test.go b/test/integration/infrastructure/connector/az_blob_connector_test.go index 3b0469e..a1e88c6 100644 --- a/test/integration/infrastructure/connector/az_blob_connector_test.go +++ b/test/integration/infrastructure/connector/az_blob_connector_test.go @@ -51,22 +51,23 @@ func TestUpload(t *testing.T) { // Prepare test file azureTest.createTestFile(t) + // Clean up the test file and blob + defer azureTest.removeTestFile(t) // Upload the file userId := uuid.New().String() - blobs, err := azureTest.Connector.Upload([]string{azureTest.TestFilePath}, userId) + filePaths := []string{azureTest.TestFilePath} + blobs, err := azureTest.Connector.Upload(filePaths, userId) require.NoError(t, err) // Assert that we received one blob metadata assert.Len(t, blobs, 1) blob := blobs[0] assert.NotEmpty(t, blob.ID) - assert.Equal(t, "testfile.txt", blob.Name) + assert.Equal(t, azureTest.TestFilePath, blob.Name) assert.Equal(t, int64(len(azureTest.TestFileContent)), blob.Size) assert.Equal(t, ".txt", blob.Type) - // Clean up the test file and blob - azureTest.removeTestFile(t) err = azureTest.Connector.Delete(blob.ID, blob.Name) require.NoError(t, err) } @@ -78,10 +79,13 @@ func TestDownload(t *testing.T) { // Prepare test file azureTest.createTestFile(t) + // Clean up the test file and blob + defer azureTest.removeTestFile(t) // Upload the file userId := uuid.New().String() - blobs, err := azureTest.Connector.Upload([]string{azureTest.TestFilePath}, userId) + filePaths := []string{azureTest.TestFilePath} + blobs, err := azureTest.Connector.Upload(filePaths, userId) require.NoError(t, err) // Download the uploaded file @@ -92,8 +96,6 @@ func TestDownload(t *testing.T) { // Assert that the downloaded content matches the original content assert.Equal(t, azureTest.TestFileContent, downloadedData) - // Clean up the test file and blob - azureTest.removeTestFile(t) err = azureTest.Connector.Delete(blob.ID, blob.Name) require.NoError(t, err) } @@ -105,10 +107,13 @@ func TestDelete(t *testing.T) { // Prepare test file azureTest.createTestFile(t) + // Clean up the test file and blob + defer azureTest.removeTestFile(t) // Upload the file userId := uuid.New().String() - blobs, err := azureTest.Connector.Upload([]string{azureTest.TestFilePath}, userId) + filePaths := []string{azureTest.TestFilePath} + blobs, err := azureTest.Connector.Upload(filePaths, userId) require.NoError(t, err) // Get the uploaded blob ID @@ -121,7 +126,4 @@ func TestDelete(t *testing.T) { // Try downloading the blob to ensure it was deleted (should fail) _, err = azureTest.Connector.Download(blob.ID, blob.Name) assert.Error(t, err) - - // Clean up the test file - azureTest.removeTestFile(t) } diff --git a/test/integration/infrastructure/connector/az_vault_connector_test.go b/test/integration/infrastructure/connector/az_vault_connector_test.go index ee6dbf8..6bee5b3 100644 --- a/test/integration/infrastructure/connector/az_vault_connector_test.go +++ b/test/integration/infrastructure/connector/az_vault_connector_test.go @@ -52,22 +52,23 @@ func TestAzureVaultConnector_Upload(t *testing.T) { // Prepare test file azureTest.createTestFile(t) + // Clean up the test file and delete the uploaded key + defer azureTest.removeTestFile(t) // Upload the file userId := uuid.New().String() - uploadedKeys, err := azureTest.Connector.Upload([]string{azureTest.TestFilePath}, userId) + filePaths := []string{azureTest.TestFilePath} + uploadedKeys, err := azureTest.Connector.Upload(filePaths, userId) require.NoError(t, err) // Assert that we received key metadata require.Len(t, uploadedKeys, 1) keyMeta := uploadedKeys[0] assert.NotEmpty(t, keyMeta.ID) - assert.Equal(t, "testfile.txt", keyMeta.Type) // Type based on file name + assert.Equal(t, azureTest.TestFilePath, keyMeta.Type) // Type based on file name assert.Equal(t, userId, keyMeta.UserID) assert.WithinDuration(t, time.Now(), keyMeta.DateTimeCreated, time.Second) - // Clean up the test file and delete the uploaded key - azureTest.removeTestFile(t) err = azureTest.Connector.Delete(keyMeta.ID, keyMeta.Type) require.NoError(t, err) } @@ -79,10 +80,13 @@ func TestAzureVaultConnector_Download(t *testing.T) { // Prepare test file azureTest.createTestFile(t) + // Clean up the test file and delete the uploaded key + defer azureTest.removeTestFile(t) // Upload the file userId := uuid.New().String() - uploadedKeys, err := azureTest.Connector.Upload([]string{azureTest.TestFilePath}, userId) + filePaths := []string{azureTest.TestFilePath} + uploadedKeys, err := azureTest.Connector.Upload(filePaths, userId) require.NoError(t, err) // Get the metadata of the uploaded file @@ -95,8 +99,6 @@ func TestAzureVaultConnector_Download(t *testing.T) { // Assert that the downloaded content matches the original content assert.Equal(t, azureTest.TestFileContent, downloadedData) - // Clean up the test file and delete the uploaded key - azureTest.removeTestFile(t) err = azureTest.Connector.Delete(keyMeta.ID, keyMeta.Type) require.NoError(t, err) } @@ -108,10 +110,13 @@ func TestAzureVaultConnector_Delete(t *testing.T) { // Prepare test file azureTest.createTestFile(t) + // Clean up the test file and delete the uploaded key + defer azureTest.removeTestFile(t) // Upload the file userId := uuid.New().String() - uploadedKeys, err := azureTest.Connector.Upload([]string{azureTest.TestFilePath}, userId) + filePaths := []string{azureTest.TestFilePath} + uploadedKeys, err := azureTest.Connector.Upload(filePaths, userId) require.NoError(t, err) // Get the metadata of the uploaded file @@ -124,7 +129,4 @@ func TestAzureVaultConnector_Delete(t *testing.T) { // Try downloading the key to ensure it was deleted (should fail) _, err = azureTest.Connector.Download(keyMeta.ID, keyMeta.Type) assert.Error(t, err) - - // Clean up the test file (key is already deleted) - azureTest.removeTestFile(t) } From 39dfe6952adf88955498b79c42920fe75b5134c8 Mon Sep 17 00:00:00 2001 From: root Date: Thu, 21 Nov 2024 14:37:21 +0000 Subject: [PATCH 15/29] remove obsolete comments --- internal/infrastructure/connector/key_connectors.go | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/internal/infrastructure/connector/key_connectors.go b/internal/infrastructure/connector/key_connectors.go index 03fc837..e9f4ab1 100644 --- a/internal/infrastructure/connector/key_connectors.go +++ b/internal/infrastructure/connector/key_connectors.go @@ -44,11 +44,9 @@ func NewAzureVaultConnector(connectionString string, containerName string) (*Azu return nil, fmt.Errorf("failed to create Azure Blob client: %w", err) } - // Ensure the container exists (this could be a simple placeholder, or it could be updated later to use a dedicated container for keys) _, err = client.CreateContainer(context.Background(), containerName, nil) if err != nil { - // Log container creation failure, but do not fail if container already exists - log.Printf("Failed to create Azure container: %v\n", err) + log.Printf("Failed to create Azure container: %v\n", err) // The container may already exist, so we should not return an error in this case. } return &AzureVaultConnector{ From 11ad9ae8aaabc84c71572a1af4cd4bd14ad2e4e6 Mon Sep 17 00:00:00 2001 From: root Date: Thu, 21 Nov 2024 15:08:58 +0000 Subject: [PATCH 16/29] update and validate member variables of CryptoKeyMeta struct --- docs/diagrams/erd.mmd | 7 ++- internal/domain/keys/models.go | 9 +-- internal/domain/keys/queries.go | 5 +- .../repository/psql_blob_repository_test.go | 12 ++-- .../repository/sqlite_blob_repository_test.go | 12 ++-- .../repository/sqlite_key_repository_test.go | 58 ++++++++++--------- test/unit/domain/blobs/model_test.go | 6 +- test/unit/domain/keys/model_test.go | 6 +- 8 files changed, 66 insertions(+), 49 deletions(-) diff --git a/docs/diagrams/erd.mmd b/docs/diagrams/erd.mmd index 774f779..12a8496 100644 --- a/docs/diagrams/erd.mmd +++ b/docs/diagrams/erd.mmd @@ -1,12 +1,13 @@ erDiagram - CRYPTOGRAPHIC_KEY { + CRYPTO_KEY_META { string id PK + string algorithm string type datetime date_time_created string user_id FK } - BLOB { + BLOB_META { string id PK datetime date_time_created string user_id FK @@ -18,4 +19,4 @@ erDiagram string hash_algorithm } - CRYPTOGRAPHIC_KEY ||--o| BLOB : "associated with" + CRYPTO_KEY_META ||--o| BLOB_META : "associated with" diff --git a/internal/domain/keys/models.go b/internal/domain/keys/models.go index bba959f..7c40ad2 100644 --- a/internal/domain/keys/models.go +++ b/internal/domain/keys/models.go @@ -9,10 +9,11 @@ import ( // CryptoKeyMeta represents the encryption key entity type CryptoKeyMeta struct { - ID string `gorm:"primaryKey" validate:"required,uuid4"` // ID is required and must be a valid UUID - Type string `validate:"required,oneof=AES RSA ECDSA"` // Type is required and must be one of the listed types - DateTimeCreated time.Time `validate:"required"` // DateTimeCreated is required - UserID string `gorm:"index" validate:"required,uuid4"` // UserID is required and must be a valid UUID + ID string `gorm:"primaryKey" validate:"required,uuid4"` // ID is required and must be a valid UUID + Algorithm string `validate:"omitempty,oneof=AES RSA EC"` // Type is required and must be one of the listed types + Type string `validate:"omitempty,oneof=private public symmetric"` // Type is required and must be one of the listed types + DateTimeCreated time.Time `validate:"required"` // DateTimeCreated is required + UserID string `gorm:"index" validate:"required,uuid4"` // UserID is required and must be a valid UUID } // Validate for validating CryptoKeyMeta struct diff --git a/internal/domain/keys/queries.go b/internal/domain/keys/queries.go index 5a897f9..7a9712f 100644 --- a/internal/domain/keys/queries.go +++ b/internal/domain/keys/queries.go @@ -9,8 +9,9 @@ import ( // CryptoKeyQuery represents the parameters used to query encryption keys. type CryptoKeyQuery struct { - Type string `validate:"omitempty,oneof=AES RSA ECDSA"` // Type is optional but if provided, must be one of the listed types (AES, RSA, ECDSA) - DateTimeCreated time.Time `validate:"omitempty,gtefield=DateTimeCreated"` // DateTimeCreated is optional, but can be used for filtering + Algorithm string `validate:"omitempty,oneof=AES RSA EC"` // Type is optional but if provided, must be one of the listed types (AES, RSA, EC) + Type string `validate:"omitempty,oneof=private public symmetric"` // Type is optional but if provided, must be one of the listed types (private-key, public-key, symmetric-key) + DateTimeCreated time.Time `validate:"omitempty,gtefield=DateTimeCreated"` // DateTimeCreated is optional, but can be used for filtering // Pagination properties Limit int `validate:"omitempty,min=1"` // Limit is optional but if provided, should be at least 1 diff --git a/test/integration/persistence/repository/psql_blob_repository_test.go b/test/integration/persistence/repository/psql_blob_repository_test.go index b250755..d90dc3f 100644 --- a/test/integration/persistence/repository/psql_blob_repository_test.go +++ b/test/integration/persistence/repository/psql_blob_repository_test.go @@ -26,7 +26,8 @@ func TestBlobPsqlRepository_Create(t *testing.T) { // Create a valid CryptoKey object cryptographicKey := keys.CryptoKeyMeta{ ID: uuid.New().String(), // Generate valid UUID for ID - Type: "AES", // Example key type + Type: "public", // Example key type + Algorithm: "EC", // Example algorithm DateTimeCreated: time.Now(), // Valid DateTimeCreated time UserID: uuid.New().String(), // Generate valid UUID for UserID } @@ -69,7 +70,8 @@ func TestBlobPsqlRepository_GetById(t *testing.T) { // Create a valid CryptoKey object cryptographicKey := keys.CryptoKeyMeta{ ID: uuid.New().String(), // Generate valid UUID for ID - Type: "AES", // Example key type + Type: "public", // Example key type + Algorithm: "EC", // Example algorithm DateTimeCreated: time.Now(), // Valid DateTimeCreated time UserID: uuid.New().String(), // Generate valid UUID for UserID } @@ -112,7 +114,8 @@ func TestBlobPsqlRepository_UpdateById(t *testing.T) { // Create a valid CryptoKey object cryptographicKey := keys.CryptoKeyMeta{ ID: uuid.New().String(), // Generate valid UUID for ID - Type: "AES", // Example key type + Type: "public", // Example key type + Algorithm: "EC", // Example algorithm DateTimeCreated: time.Now(), // Valid DateTimeCreated time UserID: uuid.New().String(), // Generate valid UUID for UserID } @@ -155,7 +158,8 @@ func TestBlobPsqlRepository_DeleteById(t *testing.T) { // Create a valid CryptoKey object cryptographicKey := keys.CryptoKeyMeta{ ID: uuid.New().String(), // Generate valid UUID for ID - Type: "AES", // Example key type + Type: "public", // Example key type + Algorithm: "EC", // Example algorithm DateTimeCreated: time.Now(), // Valid DateTimeCreated time UserID: uuid.New().String(), // Generate valid UUID for UserID } diff --git a/test/integration/persistence/repository/sqlite_blob_repository_test.go b/test/integration/persistence/repository/sqlite_blob_repository_test.go index 32c1ff0..da6098f 100644 --- a/test/integration/persistence/repository/sqlite_blob_repository_test.go +++ b/test/integration/persistence/repository/sqlite_blob_repository_test.go @@ -26,7 +26,8 @@ func TestBlobInSqliteRepository_Create(t *testing.T) { // Create a valid CryptoKey object cryptographicKey := keys.CryptoKeyMeta{ ID: uuid.New().String(), // Generate valid UUID for ID - Type: "AES", // Example key type + Type: "public", // Example key type + Algorithm: "EC", // Example algorithm DateTimeCreated: time.Now(), // Valid DateTimeCreated time UserID: uuid.New().String(), // Generate valid UUID for UserID } @@ -69,7 +70,8 @@ func TestBlobInSqliteRepository_GetById(t *testing.T) { // Create a valid CryptoKey object cryptographicKey := keys.CryptoKeyMeta{ ID: uuid.New().String(), // Generate valid UUID for ID - Type: "AES", // Example key type + Type: "public", // Example key type + Algorithm: "EC", // Example algorithm DateTimeCreated: time.Now(), // Valid DateTimeCreated time UserID: uuid.New().String(), // Generate valid UUID for UserID } @@ -111,7 +113,8 @@ func TestBlobInSqliteRepository_UpdateById(t *testing.T) { // Create a valid CryptoKey object cryptographicKey := keys.CryptoKeyMeta{ ID: uuid.New().String(), // Generate valid UUID for ID - Type: "AES", // Example key type + Type: "public", // Example key type + Algorithm: "EC", // Example algorithm DateTimeCreated: time.Now(), // Valid DateTimeCreated time UserID: uuid.New().String(), // Generate valid UUID for UserID } @@ -158,7 +161,8 @@ func TestBlobInSqliteRepository_DeleteById(t *testing.T) { // Create a valid CryptoKey object cryptographicKey := keys.CryptoKeyMeta{ ID: uuid.New().String(), // Generate valid UUID for ID - Type: "AES", // Example key type + Type: "public", // Example key type + Algorithm: "EC", // Example algorithm DateTimeCreated: time.Now(), // Valid DateTimeCreated time UserID: uuid.New().String(), // Generate valid UUID for UserID } diff --git a/test/integration/persistence/repository/sqlite_key_repository_test.go b/test/integration/persistence/repository/sqlite_key_repository_test.go index be9548e..aed2fcb 100644 --- a/test/integration/persistence/repository/sqlite_key_repository_test.go +++ b/test/integration/persistence/repository/sqlite_key_repository_test.go @@ -23,23 +23,24 @@ func TestCryptoKeySqliteRepository_Create(t *testing.T) { defer teardownTestDB(t, ctx) // Create a valid CryptoKey object - cryptographicKey := &keys.CryptoKeyMeta{ + cryptoKeyMeta := &keys.CryptoKeyMeta{ ID: uuid.New().String(), // Generate valid UUID for ID - Type: "AES", // Example key type + Type: "public", // Example key type + Algorithm: "EC", // Example algorithm DateTimeCreated: time.Now(), // Valid DateTimeCreated time UserID: uuid.New().String(), // Generate valid UUID for UserID } // Create the cryptographic key in DB - err = ctx.CryptoKeyRepo.Create(cryptographicKey) + err = ctx.CryptoKeyRepo.Create(cryptoKeyMeta) assert.NoError(t, err, "Create should not return an error") // Verify the cryptographic key is created and exists in DB - var createdKey keys.CryptoKeyMeta - err = ctx.DB.First(&createdKey, "id = ?", cryptographicKey.ID).Error + var createdCryptKeyMeta keys.CryptoKeyMeta + err = ctx.DB.First(&createdCryptKeyMeta, "id = ?", cryptoKeyMeta.ID).Error assert.NoError(t, err, "Failed to find created cryptographic key") - assert.Equal(t, cryptographicKey.ID, createdKey.ID, "ID should match") - assert.Equal(t, cryptographicKey.Type, createdKey.Type, "Type should match") + assert.Equal(t, cryptoKeyMeta.ID, createdCryptKeyMeta.ID, "ID should match") + assert.Equal(t, cryptoKeyMeta.Type, createdCryptKeyMeta.Type, "Type should match") } // TestCryptoKeySqliteRepository_GetByID tests the GetByID method of GormCryptoKeyRepository @@ -54,22 +55,23 @@ func TestCryptoKeySqliteRepository_GetByID(t *testing.T) { defer teardownTestDB(t, ctx) // Create a valid CryptoKey object - cryptographicKey := &keys.CryptoKeyMeta{ + cryptoKeyMeta := &keys.CryptoKeyMeta{ ID: uuid.New().String(), // Generate valid UUID for ID - Type: "RSA", // Example key type + Type: "private", // Example key type + Algorithm: "RSA", // Example algorithm DateTimeCreated: time.Now(), // Valid DateTimeCreated time UserID: uuid.New().String(), // Generate valid UUID for UserID } // Create the cryptographic key in DB - err = ctx.CryptoKeyRepo.Create(cryptographicKey) + err = ctx.CryptoKeyRepo.Create(cryptoKeyMeta) assert.NoError(t, err, "Create should not return an error") // Get the cryptographic key by ID - fetchedKey, err := ctx.CryptoKeyRepo.GetByID(cryptographicKey.ID) + fetchedCryptoKeyMeta, err := ctx.CryptoKeyRepo.GetByID(cryptoKeyMeta.ID) assert.NoError(t, err, "GetByID should not return an error") - assert.NotNil(t, fetchedKey, "Fetched cryptographic key should not be nil") - assert.Equal(t, cryptographicKey.ID, fetchedKey.ID, "ID should match") + assert.NotNil(t, fetchedCryptoKeyMeta, "Fetched cryptographic key should not be nil") + assert.Equal(t, cryptoKeyMeta.ID, fetchedCryptoKeyMeta.ID, "ID should match") } // TestCryptoKeySqliteRepository_UpdateByID tests the UpdateByID method of GormCryptoKeyRepository @@ -84,27 +86,28 @@ func TestCryptoKeySqliteRepository_UpdateByID(t *testing.T) { defer teardownTestDB(t, ctx) // Create a valid CryptoKey object - cryptographicKey := &keys.CryptoKeyMeta{ + cryptoKeyMeta := &keys.CryptoKeyMeta{ ID: uuid.New().String(), // Generate valid UUID for ID - Type: "AES", // Example key type + Type: "public", // Example key type + Algorithm: "EC", // Example algorithm DateTimeCreated: time.Now(), // Valid DateTimeCreated time UserID: uuid.New().String(), // Generate valid UUID for UserID } // Create the cryptographic key in DB - err = ctx.CryptoKeyRepo.Create(cryptographicKey) + err = ctx.CryptoKeyRepo.Create(cryptoKeyMeta) assert.NoError(t, err, "Create should not return an error") // Update the cryptographic key's type - cryptographicKey.Type = "ECDSA" - err = ctx.CryptoKeyRepo.UpdateByID(cryptographicKey) + cryptoKeyMeta.Type = "public" + err = ctx.CryptoKeyRepo.UpdateByID(cryptoKeyMeta) assert.NoError(t, err, "UpdateByID should not return an error") // Verify the cryptographic key is updated - var updatedKey keys.CryptoKeyMeta - err = ctx.DB.First(&updatedKey, "id = ?", cryptographicKey.ID).Error + var updatedCryptoKeyMeta keys.CryptoKeyMeta + err = ctx.DB.First(&updatedCryptoKeyMeta, "id = ?", cryptoKeyMeta.ID).Error assert.NoError(t, err, "Failed to find updated cryptographic key") - assert.Equal(t, "ECDSA", updatedKey.Type, "Type should be updated") + assert.Equal(t, cryptoKeyMeta.Type, updatedCryptoKeyMeta.Type, "Type should be updated") } // TestCryptoKeySqliteRepository_DeleteByID tests the DeleteByID method of GormCryptoKeyRepository @@ -114,24 +117,25 @@ func TestCryptoKeySqliteRepository_DeleteByID(t *testing.T) { defer teardownTestDB(t, ctx) // Create a valid CryptoKey object - cryptographicKey := &keys.CryptoKeyMeta{ + cryptoKeyMeta := &keys.CryptoKeyMeta{ ID: uuid.New().String(), // Generate valid UUID for ID - Type: "AES", // Example key type + Type: "public", // Example key type + Algorithm: "EC", // Example algorithm DateTimeCreated: time.Now(), // Valid DateTimeCreated time UserID: uuid.New().String(), // Generate valid UUID for UserID } // Create the cryptographic key in DB - err := ctx.CryptoKeyRepo.Create(cryptographicKey) + err := ctx.CryptoKeyRepo.Create(cryptoKeyMeta) assert.NoError(t, err, "Create should not return an error") // Delete the cryptographic key by ID - err = ctx.CryptoKeyRepo.DeleteByID(cryptographicKey.ID) + err = ctx.CryptoKeyRepo.DeleteByID(cryptoKeyMeta.ID) assert.NoError(t, err, "DeleteByID should not return an error") // Verify the cryptographic key is deleted - var deletedKey keys.CryptoKeyMeta - err = ctx.DB.First(&deletedKey, "id = ?", cryptographicKey.ID).Error + var deletedCryptoKeyMeta keys.CryptoKeyMeta + err = ctx.DB.First(&deletedCryptoKeyMeta, "id = ?", cryptoKeyMeta.ID).Error assert.Error(t, err, "Cryptographic key should be deleted") assert.Equal(t, gorm.ErrRecordNotFound, err, "Error should be 'record not found'") } diff --git a/test/unit/domain/blobs/model_test.go b/test/unit/domain/blobs/model_test.go index 137e413..a7d5271 100644 --- a/test/unit/domain/blobs/model_test.go +++ b/test/unit/domain/blobs/model_test.go @@ -30,7 +30,7 @@ func NewBlobValidationTests() *BlobValidationTests { Type: "text", EncryptionAlgorithm: "AES", HashAlgorithm: "SHA256", - CryptoKey: keys.CryptoKeyMeta{ID: uuid.New().String(), Type: "AES", DateTimeCreated: time.Now(), UserID: uuid.New().String()}, + CryptoKey: keys.CryptoKeyMeta{ID: uuid.New().String(), Algorithm: "AES", Type: "private", DateTimeCreated: time.Now(), UserID: uuid.New().String()}, KeyID: uuid.New().String(), } @@ -43,7 +43,7 @@ func NewBlobValidationTests() *BlobValidationTests { Type: "text", EncryptionAlgorithm: "AES", HashAlgorithm: "SHA256", - CryptoKey: keys.CryptoKeyMeta{ID: uuid.New().String(), Type: "AES", DateTimeCreated: time.Now(), UserID: uuid.New().String()}, + CryptoKey: keys.CryptoKeyMeta{ID: uuid.New().String(), Algorithm: "AES", Type: "private", DateTimeCreated: time.Now(), UserID: uuid.New().String()}, KeyID: uuid.New().String(), } @@ -56,7 +56,7 @@ func NewBlobValidationTests() *BlobValidationTests { Type: "text", EncryptionAlgorithm: "AES", HashAlgorithm: "SHA256", - CryptoKey: keys.CryptoKeyMeta{ID: uuid.New().String(), Type: "AES", DateTimeCreated: time.Now(), UserID: uuid.New().String()}, + CryptoKey: keys.CryptoKeyMeta{ID: uuid.New().String(), Algorithm: "AES", Type: "private", DateTimeCreated: time.Now(), UserID: uuid.New().String()}, KeyID: uuid.New().String(), } diff --git a/test/unit/domain/keys/model_test.go b/test/unit/domain/keys/model_test.go index aa69695..66f6943 100644 --- a/test/unit/domain/keys/model_test.go +++ b/test/unit/domain/keys/model_test.go @@ -14,7 +14,8 @@ func TestCryptoKeyValidation(t *testing.T) { // Valid CryptoKey validKey := keys.CryptoKeyMeta{ ID: uuid.New().String(), // Valid UUID - Type: "AES", // Valid Type + Type: "symmetric", // Valid Type + Algorithm: "AES", // Valid Algorithm DateTimeCreated: time.Now(), UserID: uuid.New().String(), // Valid UserID } @@ -43,7 +44,8 @@ func TestCryptoKeyValidations(t *testing.T) { // Test missing UserID (should fail) invalidKey := keys.CryptoKeyMeta{ ID: uuid.New().String(), // Valid UUID - Type: "AES", // Valid Type + Type: "symmetric", // Valid Type + Algorithm: "AES", // Valid Algorithm DateTimeCreated: time.Now(), UserID: "", // Invalid empty UserID } From 3309bb3784b5013d3f49e1ece4ed4073598d2f49 Mon Sep 17 00:00:00 2001 From: root Date: Thu, 21 Nov 2024 15:14:02 +0000 Subject: [PATCH 17/29] remove redundant check --- internal/app/services/key_services.go | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/internal/app/services/key_services.go b/internal/app/services/key_services.go index 664a97e..9eb2218 100644 --- a/internal/app/services/key_services.go +++ b/internal/app/services/key_services.go @@ -21,12 +21,6 @@ func (s *CryptoKeyUploadService) Upload(filePaths []string, userId string) ([]*k // Step 2: Store the metadata in the database for _, keyMeta := range keyMetas { - // Validate CryptoKeyMeta - if err := keyMeta.Validate(); err != nil { - return nil, fmt.Errorf("invalid key metadata: %w", err) - } - - // Save metadata to DB if err := s.CryptoKeyRepo.Create(keyMeta); err != nil { return nil, fmt.Errorf("failed to create metadata for key of type %s: %w", keyMeta.Type, err) } @@ -43,7 +37,6 @@ type CryptoKeyMetadataService struct { // List retrieves all cryptographic key metadata based on a query. func (s *CryptoKeyMetadataService) List(query *keys.CryptoKeyQuery) ([]*keys.CryptoKeyMeta, error) { - // For now, let's just retrieve all metadata from the database var keyMetas []*keys.CryptoKeyMeta // TBD @@ -52,7 +45,6 @@ func (s *CryptoKeyMetadataService) List(query *keys.CryptoKeyQuery) ([]*keys.Cry // GetByID retrieves the metadata of a cryptographic key by its ID. func (s *CryptoKeyMetadataService) GetByID(keyID string) (*keys.CryptoKeyMeta, error) { - // Retrieve the metadata from the database keyMeta, err := s.CryptoKeyRepo.GetByID(keyID) if err != nil { return nil, fmt.Errorf("failed to retrieve key metadata: %w", err) @@ -78,14 +70,14 @@ type CryptoKeyDownloadService struct { // Download retrieves a cryptographic key by its ID and type. func (s *CryptoKeyDownloadService) Download(keyID string, keyType keys.KeyType) ([]byte, error) { - blobName := "" // Declare the variable outside the blocks + blobName := "" if keyType == keys.AsymmetricPublic { - blobName = "asymmetric-public-key" // Assign to the already declared variable + blobName = "public" } else if keyType == keys.AsymmetricPrivate { - blobName = "asymmetric-private-key" // Assign to the already declared variable + blobName = "private" } else if keyType == keys.Symmetric { - blobName = "symmetric-key" // Assign to the already declared variable + blobName = "symmetric" } else { return nil, fmt.Errorf("unsupported key type: %v", keyType) } @@ -95,6 +87,5 @@ func (s *CryptoKeyDownloadService) Download(keyID string, keyType keys.KeyType) return nil, fmt.Errorf("failed to download key from blob storage: %w", err) } - // Return the metadata and the downloaded content (as a byte slice) return blobData, nil } From b46fafd410e34cd32f108d6fbb0cfcc055f32e24 Mon Sep 17 00:00:00 2001 From: root Date: Thu, 21 Nov 2024 15:32:24 +0000 Subject: [PATCH 18/29] modify signatures in VaultConnector and corresponding test --- .../connector/key_connectors.go | 116 ++++++++---------- .../connector/az_vault_connector_test.go | 42 ++++--- 2 files changed, 74 insertions(+), 84 deletions(-) diff --git a/internal/infrastructure/connector/key_connectors.go b/internal/infrastructure/connector/key_connectors.go index e9f4ab1..28a36b6 100644 --- a/internal/infrastructure/connector/key_connectors.go +++ b/internal/infrastructure/connector/key_connectors.go @@ -17,14 +17,15 @@ import ( // The current implementation uses Azure Blob Storage, but this may be replaced // with Azure Key Vault, AWS KMS, or any other cloud-based key management system in the future. type VaultConnector interface { - // Upload uploads multiple files to the Vault Storage and returns their metadata. - Upload(filePaths []string, userId string) ([]*keys.CryptoKeyMeta, error) + // Upload uploads single file to Azure Blob Storage and returns their metadata. + // In the future, this may be refactored to integrate with more advanced key storage systems like Azure Key Vault. + Upload(filePath, userId, keyType, keyAlgorihm string) (*keys.CryptoKeyMeta, error) // Download retrieves a key's content by its ID and name, and returns the data as a byte slice. - Download(blobId, blobName string) ([]byte, error) + Download(keyId, keyType string) ([]byte, error) // Delete deletes a key from Vault Storage by its ID and Name, and returns any error encountered. - Delete(blobId, blobName string) error + Delete(keyId, keyType string) error } // AzureVaultConnector is a struct that implements the VaultConnector interface using Azure Blob Storage. @@ -55,78 +56,65 @@ func NewAzureVaultConnector(connectionString string, containerName string) (*Azu }, nil } -// Upload uploads multiple files to Azure Blob Storage and returns their metadata. +// Upload uploads single file to Azure Blob Storage and returns their metadata. // In the future, this may be refactored to integrate with more advanced key storage systems like Azure Key Vault. -func (vc *AzureVaultConnector) Upload(filePaths []string, userId string) ([]*keys.CryptoKeyMeta, error) { - var keyMetas []*keys.CryptoKeyMeta - - // Iterate through all file paths and upload each file - for _, filePath := range filePaths { - // Open the file - file, err := os.Open(filePath) - if err != nil { - return nil, fmt.Errorf("failed to open file '%s': %w", filePath, err) - } - defer file.Close() - - // Get file information (name, size, etc.) - fileInfo, err := file.Stat() - if err != nil { - return nil, fmt.Errorf("failed to stat file '%s': %w", filePath, err) - } - - // Read the file content into a buffer - buf := new(bytes.Buffer) - _, err = buf.ReadFrom(file) - if err != nil { - return nil, fmt.Errorf("failed to read file '%s': %w", filePath, err) - } - - // Generate a unique ID for the key - keyID := uuid.New().String() - - // Create metadata for the uploaded key - keyMeta := &keys.CryptoKeyMeta{ - ID: keyID, - Type: fileInfo.Name(), // one of asymmetric-public-key, asymmetric-private-key, symmetric-key - DateTimeCreated: time.Now(), - UserID: userId, - } - - // Construct the full blob name (ID and Name) - fullBlobName := fmt.Sprintf("%s/%s", keyID, fileInfo.Name()) - - // Upload the blob (file) to Azure Blob Storage - _, err = vc.Client.UploadBuffer(context.Background(), vc.ContainerName, fullBlobName, buf.Bytes(), nil) - if err != nil { - return nil, fmt.Errorf("failed to upload blob '%s' to storage: %w", fullBlobName, err) - } - - // Add the metadata to the list - keyMetas = append(keyMetas, keyMeta) +func (vc *AzureVaultConnector) Upload(filePath, userId, keyType, keyAlgorihm string) (*keys.CryptoKeyMeta, error) { + // Open the file + file, err := os.Open(filePath) + if err != nil { + return nil, fmt.Errorf("failed to open file '%s': %w", filePath, err) + } + defer file.Close() + + // Read the file content into a buffer + buf := new(bytes.Buffer) + _, err = buf.ReadFrom(file) + if err != nil { + return nil, fmt.Errorf("failed to read file '%s': %w", filePath, err) + } + + // Generate a unique ID for the key + keyID := uuid.New().String() + + // Create metadata for the uploaded key + keyMeta := &keys.CryptoKeyMeta{ + ID: keyID, + Type: keyType, // one of public, private, symmetric + Algorithm: keyAlgorihm, + DateTimeCreated: time.Now(), + UserID: userId, + } + + // Construct the full blob name (ID and type) + fullKeyName := fmt.Sprintf("%s/%s", keyID, keyType) + + // Upload the blob (file) to Azure Blob Storage + _, err = vc.Client.UploadBuffer(context.Background(), vc.ContainerName, fullKeyName, buf.Bytes(), nil) + if err != nil { + return nil, fmt.Errorf("failed to upload blob '%s' to storage: %w", fullKeyName, err) } // Return the metadata of the uploaded keys - return keyMetas, nil + return keyMeta, nil } // Download retrieves a key's content by its ID and name, and returns the data as a byte slice. -func (vc *AzureVaultConnector) Download(blobId, blobName string) ([]byte, error) { +func (vc *AzureVaultConnector) Download(keyId, keyType string) ([]byte, error) { // Construct the full blob path by combining blob ID and name - fullBlobName := fmt.Sprintf("%s/%s", blobId, blobName) + fullKeyName := fmt.Sprintf("%s/%s", keyId, keyType) // Download the blob from Azure Blob Storage ctx := context.Background() - get, err := vc.Client.DownloadStream(ctx, vc.ContainerName, fullBlobName, nil) + get, err := vc.Client.DownloadStream(ctx, vc.ContainerName, fullKeyName, nil) if err != nil { - return nil, fmt.Errorf("failed to download blob '%s': %w", fullBlobName, err) + return nil, fmt.Errorf("failed to download blob '%s': %w", fullKeyName, err) } // Read the content into a buffer downloadedData := bytes.Buffer{} _, err = downloadedData.ReadFrom(get.Body) if err != nil { - return nil, fmt.Errorf("failed to read data from blob '%s': %w", fullBlobName, err) + return nil, fmt.Errorf("failed to read data from blob '%s': %w", fullKeyName, err) } // Return the downloaded data @@ -134,18 +122,18 @@ func (vc *AzureVaultConnector) Download(blobId, blobName string) ([]byte, error) } // Delete deletes a key from Azure Blob Storage by its ID and Name. -func (vc *AzureVaultConnector) Delete(blobId, blobName string) error { - // Construct the full blob path by combining blob ID and name - fullBlobName := fmt.Sprintf("%s/%s", blobId, blobName) +func (vc *AzureVaultConnector) Delete(keyId, keyType string) error { + // Construct the full blob path by combining blob ID and type + fullKeyName := fmt.Sprintf("%s/%s", keyId, keyType) // Delete the blob from Azure Blob Storage ctx := context.Background() - _, err := vc.Client.DeleteBlob(ctx, vc.ContainerName, fullBlobName, nil) + _, err := vc.Client.DeleteBlob(ctx, vc.ContainerName, fullKeyName, nil) if err != nil { - return fmt.Errorf("failed to delete blob '%s': %w", fullBlobName, err) + return fmt.Errorf("failed to delete blob '%s': %w", fullKeyName, err) } // Log the successful deletion - log.Printf("Deleted blob '%s' from storage.\n", fullBlobName) + log.Printf("Deleted blob '%s' from storage.\n", fullKeyName) return nil } diff --git a/test/integration/infrastructure/connector/az_vault_connector_test.go b/test/integration/infrastructure/connector/az_vault_connector_test.go index 6bee5b3..4315895 100644 --- a/test/integration/infrastructure/connector/az_vault_connector_test.go +++ b/test/integration/infrastructure/connector/az_vault_connector_test.go @@ -57,19 +57,19 @@ func TestAzureVaultConnector_Upload(t *testing.T) { // Upload the file userId := uuid.New().String() - filePaths := []string{azureTest.TestFilePath} - uploadedKeys, err := azureTest.Connector.Upload(filePaths, userId) + filePath := azureTest.TestFilePath + keyAlgorithm := "RSA" + keyType := "private" + cryptoKeyMeta, err := azureTest.Connector.Upload(filePath, userId, keyType, keyAlgorithm) require.NoError(t, err) // Assert that we received key metadata - require.Len(t, uploadedKeys, 1) - keyMeta := uploadedKeys[0] - assert.NotEmpty(t, keyMeta.ID) - assert.Equal(t, azureTest.TestFilePath, keyMeta.Type) // Type based on file name - assert.Equal(t, userId, keyMeta.UserID) - assert.WithinDuration(t, time.Now(), keyMeta.DateTimeCreated, time.Second) - - err = azureTest.Connector.Delete(keyMeta.ID, keyMeta.Type) + assert.NotEmpty(t, cryptoKeyMeta.ID) + assert.Equal(t, keyType, cryptoKeyMeta.Type) + assert.Equal(t, userId, cryptoKeyMeta.UserID) + assert.WithinDuration(t, time.Now(), cryptoKeyMeta.DateTimeCreated, time.Second) + + err = azureTest.Connector.Delete(cryptoKeyMeta.ID, cryptoKeyMeta.Type) require.NoError(t, err) } @@ -85,21 +85,22 @@ func TestAzureVaultConnector_Download(t *testing.T) { // Upload the file userId := uuid.New().String() - filePaths := []string{azureTest.TestFilePath} - uploadedKeys, err := azureTest.Connector.Upload(filePaths, userId) + filePath := azureTest.TestFilePath + keyAlgorithm := "RSA" + keyType := "private" + cryptoKeyMeta, err := azureTest.Connector.Upload(filePath, userId, keyType, keyAlgorithm) require.NoError(t, err) // Get the metadata of the uploaded file - keyMeta := uploadedKeys[0] // Download the uploaded file - downloadedData, err := azureTest.Connector.Download(keyMeta.ID, keyMeta.Type) + downloadedData, err := azureTest.Connector.Download(cryptoKeyMeta.ID, cryptoKeyMeta.Type) require.NoError(t, err) // Assert that the downloaded content matches the original content assert.Equal(t, azureTest.TestFileContent, downloadedData) - err = azureTest.Connector.Delete(keyMeta.ID, keyMeta.Type) + err = azureTest.Connector.Delete(cryptoKeyMeta.ID, cryptoKeyMeta.Type) require.NoError(t, err) } @@ -115,18 +116,19 @@ func TestAzureVaultConnector_Delete(t *testing.T) { // Upload the file userId := uuid.New().String() - filePaths := []string{azureTest.TestFilePath} - uploadedKeys, err := azureTest.Connector.Upload(filePaths, userId) + filePath := azureTest.TestFilePath + keyAlgorithm := "RSA" + keyType := "private" + cryptoKeyMeta, err := azureTest.Connector.Upload(filePath, userId, keyType, keyAlgorithm) require.NoError(t, err) // Get the metadata of the uploaded file - keyMeta := uploadedKeys[0] // Now delete the uploaded key by ID - err = azureTest.Connector.Delete(keyMeta.ID, keyMeta.Type) + err = azureTest.Connector.Delete(cryptoKeyMeta.ID, cryptoKeyMeta.Type) require.NoError(t, err) // Try downloading the key to ensure it was deleted (should fail) - _, err = azureTest.Connector.Download(keyMeta.ID, keyMeta.Type) + _, err = azureTest.Connector.Download(cryptoKeyMeta.ID, cryptoKeyMeta.Type) assert.Error(t, err) } From a95f0956b4554c959a15f07feb10684c0b9b03ba Mon Sep 17 00:00:00 2001 From: root Date: Thu, 21 Nov 2024 15:37:46 +0000 Subject: [PATCH 19/29] remove obsolete comments --- internal/app/services/blob_services.go | 2 -- internal/domain/blobs/models.go | 2 +- internal/domain/blobs/queries.go | 1 - internal/domain/keys/models.go | 2 +- internal/domain/keys/queries.go | 2 +- internal/infrastructure/connector/blob_connectors.go | 2 -- internal/infrastructure/connector/key_connectors.go | 2 -- .../persistence/repository/test_repository_context.go | 1 - 8 files changed, 3 insertions(+), 11 deletions(-) diff --git a/internal/app/services/blob_services.go b/internal/app/services/blob_services.go index 0249ea0..b8b85c3 100644 --- a/internal/app/services/blob_services.go +++ b/internal/app/services/blob_services.go @@ -45,7 +45,6 @@ func (s *BlobUploadService) Upload(filePaths []string, userId string) ([]*blobs. } } - // Return the metadata of uploaded blobs return blobMetas, nil } @@ -127,6 +126,5 @@ func (s *BlobDownloadService) Download(blobID, blobName string) ([]byte, error) return nil, fmt.Errorf("failed to download blob '%s': %w", blobName, err) } - // Return the metadata and content of the downloaded blob return blob, nil } diff --git a/internal/domain/blobs/models.go b/internal/domain/blobs/models.go index 43738e5..acc8ab9 100644 --- a/internal/domain/blobs/models.go +++ b/internal/domain/blobs/models.go @@ -37,5 +37,5 @@ func (b *BlobMeta) Validate() error { } return fmt.Errorf("Validation failed: %v", validationErrors) } - return nil // Return nil if validation passes + return nil } diff --git a/internal/domain/blobs/queries.go b/internal/domain/blobs/queries.go index d21de7e..70154d6 100644 --- a/internal/domain/blobs/queries.go +++ b/internal/domain/blobs/queries.go @@ -49,6 +49,5 @@ func (b *BlobMetaQuery) Validate() error { return fmt.Errorf("Validation failed: %v", validationErrors) } - // Return nil if no validation errors are found return nil } diff --git a/internal/domain/keys/models.go b/internal/domain/keys/models.go index 7c40ad2..27d022b 100644 --- a/internal/domain/keys/models.go +++ b/internal/domain/keys/models.go @@ -31,5 +31,5 @@ func (k *CryptoKeyMeta) Validate() error { } return fmt.Errorf("Validation failed: %v", validationErrors) } - return nil // Return nil if validation passes + return nil } diff --git a/internal/domain/keys/queries.go b/internal/domain/keys/queries.go index 7a9712f..7fce16a 100644 --- a/internal/domain/keys/queries.go +++ b/internal/domain/keys/queries.go @@ -47,5 +47,5 @@ func (k *CryptoKeyQuery) Validate() error { } return fmt.Errorf("Validation failed: %v", validationErrors) } - return nil // Return nil if validation passes + return nil } diff --git a/internal/infrastructure/connector/blob_connectors.go b/internal/infrastructure/connector/blob_connectors.go index d08a311..cefd725 100644 --- a/internal/infrastructure/connector/blob_connectors.go +++ b/internal/infrastructure/connector/blob_connectors.go @@ -119,7 +119,6 @@ func (abc *AzureBlobConnector) Upload(filePaths []string, userId string) ([]*blo blobMeta = append(blobMeta, blob) } - // Return the list of blobs after successful upload. return blobMeta, nil } @@ -164,7 +163,6 @@ func (abc *AzureBlobConnector) Download(blobId, blobName string) ([]byte, error) return nil, fmt.Errorf("failed to close retryReader for blob '%s': %w", fullBlobName, err) } - // Return the buffer containing the downloaded data return downloadedData.Bytes(), nil } diff --git a/internal/infrastructure/connector/key_connectors.go b/internal/infrastructure/connector/key_connectors.go index 28a36b6..e9ccacf 100644 --- a/internal/infrastructure/connector/key_connectors.go +++ b/internal/infrastructure/connector/key_connectors.go @@ -94,7 +94,6 @@ func (vc *AzureVaultConnector) Upload(filePath, userId, keyType, keyAlgorihm str return nil, fmt.Errorf("failed to upload blob '%s' to storage: %w", fullKeyName, err) } - // Return the metadata of the uploaded keys return keyMeta, nil } @@ -117,7 +116,6 @@ func (vc *AzureVaultConnector) Download(keyId, keyType string) ([]byte, error) { return nil, fmt.Errorf("failed to read data from blob '%s': %w", fullKeyName, err) } - // Return the downloaded data return downloadedData.Bytes(), nil } diff --git a/test/integration/persistence/repository/test_repository_context.go b/test/integration/persistence/repository/test_repository_context.go index 3e5d1a0..c06bd85 100644 --- a/test/integration/persistence/repository/test_repository_context.go +++ b/test/integration/persistence/repository/test_repository_context.go @@ -94,7 +94,6 @@ func setupTestDB(t *testing.T) *TestRepositoryContext { blobRepo := &repository.GormBlobRepository{DB: db} cryptoKeyRepo := &repository.GormCryptoKeyRepository{DB: db} - // Return the test context that holds the DB and repositories return &TestRepositoryContext{ DB: db, BlobRepo: blobRepo, From f9c1c90ae5446748b6e46cc82b8b30b6efd1315b Mon Sep 17 00:00:00 2001 From: root Date: Thu, 21 Nov 2024 15:43:07 +0000 Subject: [PATCH 20/29] modify Upload(...) signature --- internal/app/services/key_services.go | 13 +++++-------- internal/domain/keys/contracts.go | 2 +- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/internal/app/services/key_services.go b/internal/app/services/key_services.go index 9eb2218..cad6757 100644 --- a/internal/app/services/key_services.go +++ b/internal/app/services/key_services.go @@ -12,22 +12,19 @@ type CryptoKeyUploadService struct { CryptoKeyRepo repository.CryptoKeyRepository } -func (s *CryptoKeyUploadService) Upload(filePaths []string, userId string) ([]*keys.CryptoKeyMeta, error) { +func (s *CryptoKeyUploadService) Upload(filePath, userId, keyType, keyAlgorihm string) (*keys.CryptoKeyMeta, error) { // Step 1: Upload files to blob storage - keyMetas, err := s.VaultConnector.Upload(filePaths, userId) + keyMeta, err := s.VaultConnector.Upload(filePath, userId, keyType, keyAlgorihm) if err != nil { return nil, fmt.Errorf("failed to upload files: %w", err) } // Step 2: Store the metadata in the database - for _, keyMeta := range keyMetas { - if err := s.CryptoKeyRepo.Create(keyMeta); err != nil { - return nil, fmt.Errorf("failed to create metadata for key of type %s: %w", keyMeta.Type, err) - } + if err := s.CryptoKeyRepo.Create(keyMeta); err != nil { + return nil, fmt.Errorf("failed to create metadata for key of type %s: %w", keyMeta.Type, err) } - // Return metadata - return keyMetas, nil + return keyMeta, nil } // CryptoKeyMetadataService manages cryptographic key metadata. diff --git a/internal/domain/keys/contracts.go b/internal/domain/keys/contracts.go index dc49a1f..f81933f 100644 --- a/internal/domain/keys/contracts.go +++ b/internal/domain/keys/contracts.go @@ -14,7 +14,7 @@ const ( type ICryptoKeyUploadService interface { // Upload uploads cryptographic keys from specified file paths. // It returns a slice of CryptoKeyMeta and any error encountered during the upload process. - Upload(filePaths []string, userId string) ([]*CryptoKeyMeta, error) + Upload(filePath, userId, keyType, keyAlgorihm string) (*CryptoKeyMeta, error) } // ICryptoKeyMetadataService defines methods for managing cryptographic key metadata and deleting keys. From aca7dc040fd7614c25de42d90a49892b73f63e0a Mon Sep 17 00:00:00 2001 From: root Date: Thu, 21 Nov 2024 15:49:53 +0000 Subject: [PATCH 21/29] rename interfaces and structs --- .../internal/commands/aes-commands.go | 4 +- .../internal/commands/ecdsa-commands.go | 18 ++++----- .../internal/commands/rsa-commands.go | 4 +- internal/infrastructure/cryptography/aes.go | 14 +++---- .../cryptography/{ecdsa.go => ec.go} | 24 ++++++------ .../infrastructure/cryptography/pkcs11.go | 4 +- internal/infrastructure/cryptography/rsa.go | 22 +++++------ .../infrastructure/cryptography/aes_test.go | 28 +++++++------- .../infrastructure/cryptography/ecdsa_test.go | 4 +- .../infrastructure/cryptography/rsa_test.go | 38 +++++++++---------- 10 files changed, 80 insertions(+), 80 deletions(-) rename internal/infrastructure/cryptography/{ecdsa.go => ec.go} (86%) diff --git a/cmd/crypto-vault-cli/internal/commands/aes-commands.go b/cmd/crypto-vault-cli/internal/commands/aes-commands.go index 1ac57a4..3d7af43 100644 --- a/cmd/crypto-vault-cli/internal/commands/aes-commands.go +++ b/cmd/crypto-vault-cli/internal/commands/aes-commands.go @@ -24,7 +24,7 @@ func EncryptAESCmd(cmd *cobra.Command, args []string) { log.Fatalf("Error: input, output, and keyDir flags are required\n") } - aes := &cryptography.AESCrypto{} + aes := &cryptography.AES{} // Generate AES Key key, err := aes.GenerateKey(keySize) @@ -85,7 +85,7 @@ func DecryptAESCmd(cmd *cobra.Command, args []string) { log.Fatalf("Error reading encrypted file: %v\n", err) } - aes := &cryptography.AESCrypto{} + aes := &cryptography.AES{} decryptedData, err := aes.Decrypt(encryptedData, key) if err != nil { diff --git a/cmd/crypto-vault-cli/internal/commands/ecdsa-commands.go b/cmd/crypto-vault-cli/internal/commands/ecdsa-commands.go index 9ee45e1..9199d6f 100644 --- a/cmd/crypto-vault-cli/internal/commands/ecdsa-commands.go +++ b/cmd/crypto-vault-cli/internal/commands/ecdsa-commands.go @@ -26,13 +26,13 @@ func SignECCCmd(cmd *cobra.Command, args []string) { } // ECC implementation - ECCrypto := &cryptography.ECCrypto{} + EC := &cryptography.EC{} var privateKey *ecdsa.PrivateKey var publicKey *ecdsa.PublicKey var err error // Generate new ECC keys if no private key is provided - privateKey, publicKey, err = ECCrypto.GenerateKeys(elliptic.P256()) + privateKey, publicKey, err = EC.GenerateKeys(elliptic.P256()) if err != nil { log.Fatalf("Error generating ECC keys: %v\n", err) } @@ -44,7 +44,7 @@ func SignECCCmd(cmd *cobra.Command, args []string) { } // Sign the file content (hash the content before signing) - signature, err := ECCrypto.Sign(fileContent, privateKey) + signature, err := EC.Sign(fileContent, privateKey) if err != nil { log.Fatalf("Error signing file content: %v\n", err) } @@ -57,7 +57,7 @@ func SignECCCmd(cmd *cobra.Command, args []string) { if privateKey != nil && keyDir != "" { privateKeyFilePath := fmt.Sprintf("%s/%s-private_key.pem", keyDir, uniqueID.String()) - err = ECCrypto.SavePrivateKeyToFile(privateKey, privateKeyFilePath) + err = EC.SavePrivateKeyToFile(privateKey, privateKeyFilePath) if err != nil { log.Fatalf("Error saving private key: %v\n", err) } @@ -66,7 +66,7 @@ func SignECCCmd(cmd *cobra.Command, args []string) { if publicKey != nil && keyDir != "" { publicKeyFilePath := fmt.Sprintf("%s/%s-public_key.pem", keyDir, uniqueID.String()) - err = ECCrypto.SavePublicKeyToFile(publicKey, publicKeyFilePath) + err = EC.SavePublicKeyToFile(publicKey, publicKeyFilePath) if err != nil { log.Fatalf("Error saving public key: %v\n", err) } @@ -76,7 +76,7 @@ func SignECCCmd(cmd *cobra.Command, args []string) { // Save the signature to a file in the data folder (optional, based on the input file) if keyDir != "" { signatureFilePath := fmt.Sprintf("%s/%s-signature.sig", keyDir, uniqueID.String()) - err = ECCrypto.SaveSignatureToFile(signatureFilePath, signature) + err = EC.SaveSignatureToFile(signatureFilePath, signature) if err != nil { log.Fatalf("Error saving signature: %v\n", err) } @@ -91,7 +91,7 @@ func VerifyECCCmd(cmd *cobra.Command, args []string) { signatureFile, _ := cmd.Flags().GetString("signature") // Path to signature file // ECC implementation - ECCrypto := &cryptography.ECCrypto{} + EC := &cryptography.EC{} var publicKey *ecdsa.PublicKey var err error @@ -99,7 +99,7 @@ func VerifyECCCmd(cmd *cobra.Command, args []string) { if publicKeyPath == "" { log.Fatalf("Public key is required for ECC signature verification.\n") } else { - publicKey, err = ECCrypto.ReadPublicKey(publicKeyPath, elliptic.P256()) + publicKey, err = EC.ReadPublicKey(publicKeyPath, elliptic.P256()) if err != nil { log.Fatalf("Error reading public key: %v\n", err) } @@ -124,7 +124,7 @@ func VerifyECCCmd(cmd *cobra.Command, args []string) { } // Verify the signature - valid, err := ECCrypto.Verify(fileContent, signature, publicKey) + valid, err := EC.Verify(fileContent, signature, publicKey) if err != nil { log.Fatalf("Error verifying signature: %v\n", err) } diff --git a/cmd/crypto-vault-cli/internal/commands/rsa-commands.go b/cmd/crypto-vault-cli/internal/commands/rsa-commands.go index 2613dd0..a0fe599 100644 --- a/cmd/crypto-vault-cli/internal/commands/rsa-commands.go +++ b/cmd/crypto-vault-cli/internal/commands/rsa-commands.go @@ -25,7 +25,7 @@ func EncryptRSACmd(cmd *cobra.Command, args []string) { // Generate RSA keys if no public key is provided var publicKey *rsa.PublicKey var err error - rsa := &cryptography.RSACrypto{} + rsa := &cryptography.RSA{} uniqueID := uuid.New() // Generate RSA keys @@ -78,7 +78,7 @@ func DecryptRSACmd(cmd *cobra.Command, args []string) { // Generate RSA keys if no private key is provided var privateKey *rsa.PrivateKey var err error - rsa := &cryptography.RSACrypto{} + rsa := &cryptography.RSA{} if privateKeyPath == "" { // Generate RSA keys privKey, _, genErr := rsa.GenerateKeys(2048) diff --git a/internal/infrastructure/cryptography/aes.go b/internal/infrastructure/cryptography/aes.go index 4b902c9..46252bd 100644 --- a/internal/infrastructure/cryptography/aes.go +++ b/internal/infrastructure/cryptography/aes.go @@ -8,15 +8,15 @@ import ( "fmt" ) -// AES Interface -type AES interface { +// IAES Interface +type IAES interface { Encrypt(plainText, key []byte) ([]byte, error) Decrypt(ciphertext, key []byte) ([]byte, error) GenerateKey(keySize int) ([]byte, error) } -// AESCrypto struct that implements the AES interface -type AESCrypto struct{} +// AES struct that implements the IAES interface +type AES struct{} // Pad data to make it a multiple of AES block size func pkcs7Pad(data []byte, blockSize int) []byte { @@ -37,7 +37,7 @@ func pkcs7Unpad(data []byte, blockSize int) ([]byte, error) { } // GenerateRandomAESKey generates a random AES key of the specified size -func (a *AESCrypto) GenerateKey(keySize int) ([]byte, error) { +func (a *AES) GenerateKey(keySize int) ([]byte, error) { key := make([]byte, keySize) _, err := rand.Read(key) if err != nil { @@ -47,7 +47,7 @@ func (a *AESCrypto) GenerateKey(keySize int) ([]byte, error) { } // Encrypt data using AES in CBC mode -func (a *AESCrypto) Encrypt(plainText, key []byte) ([]byte, error) { +func (a *AES) Encrypt(plainText, key []byte) ([]byte, error) { if key == nil { return nil, fmt.Errorf("key key cannot be nil") } @@ -72,7 +72,7 @@ func (a *AESCrypto) Encrypt(plainText, key []byte) ([]byte, error) { } // Decrypt data using AES in CBC mode -func (a *AESCrypto) Decrypt(ciphertext, key []byte) ([]byte, error) { +func (a *AES) Decrypt(ciphertext, key []byte) ([]byte, error) { if key == nil { return nil, fmt.Errorf("key key cannot be nil") } diff --git a/internal/infrastructure/cryptography/ecdsa.go b/internal/infrastructure/cryptography/ec.go similarity index 86% rename from internal/infrastructure/cryptography/ecdsa.go rename to internal/infrastructure/cryptography/ec.go index 89bb520..0cd3576 100644 --- a/internal/infrastructure/cryptography/ecdsa.go +++ b/internal/infrastructure/cryptography/ec.go @@ -12,8 +12,8 @@ import ( "os" ) -// EC Interface -type EC interface { +// IEC Interface +type IEC interface { GenerateKeys(curve elliptic.Curve) (*ecdsa.PrivateKey, *ecdsa.PublicKey, error) Sign(message []byte, privateKey *ecdsa.PrivateKey) ([]byte, error) Verify(message, signature []byte, publicKey *ecdsa.PublicKey) (bool, error) @@ -24,11 +24,11 @@ type EC interface { ReadPublicKey(publicKeyPath string) (*ecdsa.PublicKey, error) } -// ECCrypto struct that implements the EC interface -type ECCrypto struct{} +// EC struct that implements the IEC interface +type EC struct{} // GenerateKeys generates an elliptic curve key pair -func (e *ECCrypto) GenerateKeys(curve elliptic.Curve) (*ecdsa.PrivateKey, *ecdsa.PublicKey, error) { +func (e *EC) GenerateKeys(curve elliptic.Curve) (*ecdsa.PrivateKey, *ecdsa.PublicKey, error) { privateKey, err := ecdsa.GenerateKey(curve, rand.Reader) if err != nil { return nil, nil, fmt.Errorf("failed to generate elliptic curve keys: %v", err) @@ -39,7 +39,7 @@ func (e *ECCrypto) GenerateKeys(curve elliptic.Curve) (*ecdsa.PrivateKey, *ecdsa } // Sign signs a message with the private key -func (e *ECCrypto) Sign(message []byte, privateKey *ecdsa.PrivateKey) ([]byte, error) { +func (e *EC) Sign(message []byte, privateKey *ecdsa.PrivateKey) ([]byte, error) { if privateKey == nil { return nil, fmt.Errorf("private key cannot be nil") } @@ -62,7 +62,7 @@ func (e *ECCrypto) Sign(message []byte, privateKey *ecdsa.PrivateKey) ([]byte, e } // Verify verifies the signature of a message with the public key -func (e *ECCrypto) Verify(message, signature []byte, publicKey *ecdsa.PublicKey) (bool, error) { +func (e *EC) Verify(message, signature []byte, publicKey *ecdsa.PublicKey) (bool, error) { if publicKey == nil { return false, fmt.Errorf("public key cannot be nil") } @@ -81,7 +81,7 @@ func (e *ECCrypto) Verify(message, signature []byte, publicKey *ecdsa.PublicKey) } // SavePrivateKeyToFile saves the private key to a PEM file using encoding/pem -func (e *ECCrypto) SavePrivateKeyToFile(privateKey *ecdsa.PrivateKey, filename string) error { +func (e *EC) SavePrivateKeyToFile(privateKey *ecdsa.PrivateKey, filename string) error { // Marshal private key components (private key 'D' and public key components 'X' and 'Y') privKeyBytes := append(privateKey.D.Bytes(), privateKey.PublicKey.X.Bytes()...) privKeyBytes = append(privKeyBytes, privateKey.PublicKey.Y.Bytes()...) @@ -109,7 +109,7 @@ func (e *ECCrypto) SavePrivateKeyToFile(privateKey *ecdsa.PrivateKey, filename s } // SavePublicKeyToFile saves the public key to a PEM file using encoding/pem -func (e *ECCrypto) SavePublicKeyToFile(publicKey *ecdsa.PublicKey, filename string) error { +func (e *EC) SavePublicKeyToFile(publicKey *ecdsa.PublicKey, filename string) error { pubKeyBytes := append(publicKey.X.Bytes(), publicKey.Y.Bytes()...) // Prepare the PEM block for the public key @@ -135,7 +135,7 @@ func (e *ECCrypto) SavePublicKeyToFile(publicKey *ecdsa.PublicKey, filename stri } // SaveSignatureToFile can be used for storing signature files in hex format -func (e *ECCrypto) SaveSignatureToFile(filename string, data []byte) error { +func (e *EC) SaveSignatureToFile(filename string, data []byte) error { hexData := hex.EncodeToString(data) err := os.WriteFile(filename, []byte(hexData), 0644) if err != nil { @@ -145,7 +145,7 @@ func (e *ECCrypto) SaveSignatureToFile(filename string, data []byte) error { } // ReadPrivateKey reads an ECDSA private key from a PEM file using encoding/pem -func (e *ECCrypto) ReadPrivateKey(privateKeyPath string, curve elliptic.Curve) (*ecdsa.PrivateKey, error) { +func (e *EC) ReadPrivateKey(privateKeyPath string, curve elliptic.Curve) (*ecdsa.PrivateKey, error) { privKeyPEM, err := os.ReadFile(privateKeyPath) if err != nil { return nil, fmt.Errorf("unable to read private key file: %v", err) @@ -178,7 +178,7 @@ func (e *ECCrypto) ReadPrivateKey(privateKeyPath string, curve elliptic.Curve) ( } // ReadPublicKey reads an ECDSA public key from a PEM file using encoding/pem -func (e *ECCrypto) ReadPublicKey(publicKeyPath string, curve elliptic.Curve) (*ecdsa.PublicKey, error) { +func (e *EC) ReadPublicKey(publicKeyPath string, curve elliptic.Curve) (*ecdsa.PublicKey, error) { pubKeyPEM, err := os.ReadFile(publicKeyPath) if err != nil { return nil, fmt.Errorf("unable to read public key file: %v", err) diff --git a/internal/infrastructure/cryptography/pkcs11.go b/internal/infrastructure/cryptography/pkcs11.go index 2eaaaed..61a4619 100644 --- a/internal/infrastructure/cryptography/pkcs11.go +++ b/internal/infrastructure/cryptography/pkcs11.go @@ -7,8 +7,8 @@ import ( "strings" ) -// PKCS11Token defines the operations for working with a PKCS#11 token -type PKCS11Token interface { +// IPKCS11TokenHandler defines the operations for working with a PKCS#11 token +type IPKCS11TokenHandler interface { IsTokenSet() (bool, error) IsObjectSet() (bool, error) InitializeToken(slot string) error diff --git a/internal/infrastructure/cryptography/rsa.go b/internal/infrastructure/cryptography/rsa.go index b46de1f..e910232 100644 --- a/internal/infrastructure/cryptography/rsa.go +++ b/internal/infrastructure/cryptography/rsa.go @@ -10,8 +10,8 @@ import ( "os" ) -// RSA Interface -type RSA interface { +// IRSA Interface +type IRSA interface { Encrypt(plainText []byte, publicKey *rsa.PublicKey) ([]byte, error) Decrypt(ciphertext []byte, privateKey *rsa.PrivateKey) ([]byte, error) GenerateKeys(bits int) (*rsa.PrivateKey, *rsa.PublicKey, error) @@ -21,11 +21,11 @@ type RSA interface { ReadPublicKey(publicKeyPath string) (*rsa.PublicKey, error) } -// RSACrypto struct that implements the RSA interface -type RSACrypto struct{} +// RSA struct that implements the IRSA interface +type RSA struct{} // GenerateRSAKeys generates RSA key pair -func (r *RSACrypto) GenerateKeys(bits int) (*rsa.PrivateKey, *rsa.PublicKey, error) { +func (r *RSA) GenerateKeys(bits int) (*rsa.PrivateKey, *rsa.PublicKey, error) { privateKey, err := rsa.GenerateKey(rand.Reader, bits) if err != nil { return nil, nil, fmt.Errorf("failed to generate RSA keys: %v", err) @@ -35,7 +35,7 @@ func (r *RSACrypto) GenerateKeys(bits int) (*rsa.PrivateKey, *rsa.PublicKey, err } // Encrypt data using RSA public key -func (r *RSACrypto) Encrypt(plainText []byte, publicKey *rsa.PublicKey) ([]byte, error) { +func (r *RSA) Encrypt(plainText []byte, publicKey *rsa.PublicKey) ([]byte, error) { if publicKey == nil { return nil, errors.New("public key cannot be nil") } @@ -48,7 +48,7 @@ func (r *RSACrypto) Encrypt(plainText []byte, publicKey *rsa.PublicKey) ([]byte, } // Decrypt data using RSA private key -func (r *RSACrypto) Decrypt(ciphertext []byte, privateKey *rsa.PrivateKey) ([]byte, error) { +func (r *RSA) Decrypt(ciphertext []byte, privateKey *rsa.PrivateKey) ([]byte, error) { if privateKey == nil { return nil, fmt.Errorf("private key cannot be nil") } @@ -60,7 +60,7 @@ func (r *RSACrypto) Decrypt(ciphertext []byte, privateKey *rsa.PrivateKey) ([]by return decryptedData, nil } -func (r *RSACrypto) SavePrivateKeyToFile(privateKey *rsa.PrivateKey, filename string) error { +func (r *RSA) SavePrivateKeyToFile(privateKey *rsa.PrivateKey, filename string) error { privKeyBytes := x509.MarshalPKCS1PrivateKey(privateKey) privKeyPem := &pem.Block{ Type: "RSA PRIVATE KEY", @@ -81,7 +81,7 @@ func (r *RSACrypto) SavePrivateKeyToFile(privateKey *rsa.PrivateKey, filename st return nil } -func (r *RSACrypto) SavePublicKeyToFile(publicKey *rsa.PublicKey, filename string) error { +func (r *RSA) SavePublicKeyToFile(publicKey *rsa.PublicKey, filename string) error { pubKeyBytes, err := x509.MarshalPKIXPublicKey(publicKey) if err != nil { return fmt.Errorf("failed to marshal public key: %v", err) @@ -107,7 +107,7 @@ func (r *RSACrypto) SavePublicKeyToFile(publicKey *rsa.PublicKey, filename strin } // Read RSA private key from PEM file -func (r *RSACrypto) ReadPrivateKey(privateKeyPath string) (*rsa.PrivateKey, error) { +func (r *RSA) ReadPrivateKey(privateKeyPath string) (*rsa.PrivateKey, error) { privKeyPEM, err := os.ReadFile(privateKeyPath) if err != nil { return nil, fmt.Errorf("unable to read private key file: %v", err) @@ -140,7 +140,7 @@ func (r *RSACrypto) ReadPrivateKey(privateKeyPath string) (*rsa.PrivateKey, erro } // Read RSA public key from PEM file -func (r *RSACrypto) ReadPublicKey(publicKeyPath string) (*rsa.PublicKey, error) { +func (r *RSA) ReadPublicKey(publicKeyPath string) (*rsa.PublicKey, error) { pubKeyPEM, err := os.ReadFile(publicKeyPath) if err != nil { return nil, fmt.Errorf("unable to read public key file: %v", err) diff --git a/test/unit/infrastructure/cryptography/aes_test.go b/test/unit/infrastructure/cryptography/aes_test.go index 6f753f3..c657e5b 100644 --- a/test/unit/infrastructure/cryptography/aes_test.go +++ b/test/unit/infrastructure/cryptography/aes_test.go @@ -10,33 +10,33 @@ import ( // AES struct to encapsulate AES-related test cases type AESTests struct { - AESCrypto *cryptography.AESCrypto + AES *cryptography.AES } // NewAESTests is a constructor that creates a new instance of AESTests func NewAESTests() *AESTests { return &AESTests{ - AESCrypto: &cryptography.AESCrypto{}, + AES: &cryptography.AES{}, } } // TestEncryptDecrypt tests the encryption and decryption functionality func (at *AESTests) TestEncryptDecrypt(t *testing.T) { // Generate a random key of 16 bytes (128-bit AES) - key, err := at.AESCrypto.GenerateKey(16) + key, err := at.AES.GenerateKey(16) assert.NoError(t, err) // Define a plaintext to encrypt and decrypt plainText := []byte("This is a test message.") // Encrypt the plaintext - ciphertext, err := at.AESCrypto.Encrypt(plainText, key) + ciphertext, err := at.AES.Encrypt(plainText, key) assert.NoError(t, err) assert.NotNil(t, ciphertext) assert.Greater(t, len(ciphertext), 0, "Ciphertext should be longer than 0") // Decrypt the ciphertext - decryptedText, err := at.AESCrypto.Decrypt(ciphertext, key) + decryptedText, err := at.AES.Decrypt(ciphertext, key) assert.NoError(t, err) assert.NotNil(t, decryptedText) @@ -51,19 +51,19 @@ func (at *AESTests) TestEncryptionWithInvalidKey(t *testing.T) { plainText := []byte("This is a test.") // Try encrypting with an invalid key - _, err := at.AESCrypto.Encrypt(plainText, key) + _, err := at.AES.Encrypt(plainText, key) assert.Error(t, err) } // TestGenerateKey tests key generation functionality func (at *AESTests) TestGenerateKey(t *testing.T) { // Generate a random AES key with 16 bytes (128-bit AES) - key, err := at.AESCrypto.GenerateKey(16) + key, err := at.AES.GenerateKey(16) assert.NoError(t, err) assert.Equal(t, len(key), 16) // Try generating a 32-byte AES key (256-bit AES) - key256, err := at.AESCrypto.GenerateKey(32) + key256, err := at.AES.GenerateKey(32) assert.NoError(t, err) assert.Equal(t, len(key256), 32) } @@ -71,31 +71,31 @@ func (at *AESTests) TestGenerateKey(t *testing.T) { // TestDecryptWithWrongKey tests decryption with a wrong key func (at *AESTests) TestDecryptWithWrongKey(t *testing.T) { // Generate a random 16-byte AES key - key, err := at.AESCrypto.GenerateKey(16) + key, err := at.AES.GenerateKey(16) assert.NoError(t, err) // Encrypt the data plainText := []byte("Test decryption with wrong key.") - ciphertext, err := at.AESCrypto.Encrypt(plainText, key) + ciphertext, err := at.AES.Encrypt(plainText, key) assert.NoError(t, err) // Generate a new, different key for decryption - anotherKey, err := at.AESCrypto.GenerateKey(16) + anotherKey, err := at.AES.GenerateKey(16) assert.NoError(t, err) // Try to decrypt with the wrong key - _, err = at.AESCrypto.Decrypt(ciphertext, anotherKey) + _, err = at.AES.Decrypt(ciphertext, anotherKey) assert.Error(t, err, "Decryption with the wrong key should fail") } // TestDecryptShortCiphertext tests the case where the ciphertext is too short func (at *AESTests) TestDecryptShortCiphertext(t *testing.T) { // Generate a random key - key, err := at.AESCrypto.GenerateKey(16) + key, err := at.AES.GenerateKey(16) assert.NoError(t, err) // Attempt to decrypt a too-short ciphertext - _, err = at.AESCrypto.Decrypt([]byte("short"), key) + _, err = at.AES.Decrypt([]byte("short"), key) assert.Error(t, err, "Decrypting a ciphertext that's too short should fail") } diff --git a/test/unit/infrastructure/cryptography/ecdsa_test.go b/test/unit/infrastructure/cryptography/ecdsa_test.go index c020127..6fa2b12 100644 --- a/test/unit/infrastructure/cryptography/ecdsa_test.go +++ b/test/unit/infrastructure/cryptography/ecdsa_test.go @@ -14,13 +14,13 @@ import ( ) type ECDSATests struct { - ecc *cryptography.ECCrypto + ecc *cryptography.EC } // NewECDSATests is a constructor that creates a new instance of ECDSATests func NewECDSATests() *ECDSATests { return &ECDSATests{ - ecc: &cryptography.ECCrypto{}, + ecc: &cryptography.EC{}, } } diff --git a/test/unit/infrastructure/cryptography/rsa_test.go b/test/unit/infrastructure/cryptography/rsa_test.go index c7faac5..07026d1 100644 --- a/test/unit/infrastructure/cryptography/rsa_test.go +++ b/test/unit/infrastructure/cryptography/rsa_test.go @@ -11,20 +11,20 @@ import ( // RSATests struct to encapsulate RSA-related test cases type RSATests struct { - RSACrypto *cryptography.RSACrypto + RSA *cryptography.RSA } // NewRSATests is a constructor that creates a new instance of RSATests func NewRSATests() *RSATests { return &RSATests{ - RSACrypto: &cryptography.RSACrypto{}, + RSA: &cryptography.RSA{}, } } // TestGenerateRSAKeys tests the generation of RSA keys func (rt *RSATests) TestGenerateRSAKeys(t *testing.T) { // Generate RSA keys with 2048-bit size - privateKey, publicKey, err := rt.RSACrypto.GenerateKeys(2048) + privateKey, publicKey, err := rt.RSA.GenerateKeys(2048) assert.NoError(t, err, "Error generating RSA keys") assert.NotNil(t, privateKey, "Private key should not be nil") assert.NotNil(t, publicKey, "Public key should not be nil") @@ -37,18 +37,18 @@ func (rt *RSATests) TestGenerateRSAKeys(t *testing.T) { // TestEncryptDecrypt tests the encryption and decryption methods of RSA func (rt *RSATests) TestEncryptDecrypt(t *testing.T) { // Generate RSA keys - privateKey, publicKey, err := rt.RSACrypto.GenerateKeys(2048) + privateKey, publicKey, err := rt.RSA.GenerateKeys(2048) assert.NoError(t, err) // Message to encrypt plainText := []byte("This is a secret message") // Encrypt the message - encryptedData, err := rt.RSACrypto.Encrypt(plainText, publicKey) + encryptedData, err := rt.RSA.Encrypt(plainText, publicKey) assert.NoError(t, err, "Error encrypting data") // Decrypt the message - decryptedData, err := rt.RSACrypto.Decrypt(encryptedData, privateKey) + decryptedData, err := rt.RSA.Decrypt(encryptedData, privateKey) assert.NoError(t, err, "Error decrypting data") // Ensure the decrypted data matches the original message @@ -58,26 +58,26 @@ func (rt *RSATests) TestEncryptDecrypt(t *testing.T) { // TestSaveAndReadKeys tests saving and reading RSA keys to and from files func (rt *RSATests) TestSaveAndReadKeys(t *testing.T) { // Generate RSA keys - privateKey, publicKey, err := rt.RSACrypto.GenerateKeys(2048) + privateKey, publicKey, err := rt.RSA.GenerateKeys(2048) assert.NoError(t, err) // Save keys to files privateKeyFile := "private.pem" publicKeyFile := "public.pem" - err = rt.RSACrypto.SavePrivateKeyToFile(privateKey, privateKeyFile) + err = rt.RSA.SavePrivateKeyToFile(privateKey, privateKeyFile) assert.NoError(t, err, "Error saving private key to file") - err = rt.RSACrypto.SavePublicKeyToFile(publicKey, publicKeyFile) + err = rt.RSA.SavePublicKeyToFile(publicKey, publicKeyFile) assert.NoError(t, err, "Error saving public key to file") // Read the keys back from the files - readPrivateKey, err := rt.RSACrypto.ReadPrivateKey(privateKeyFile) + readPrivateKey, err := rt.RSA.ReadPrivateKey(privateKeyFile) assert.NoError(t, err, "Error reading private key from file") assert.Equal(t, privateKey.N, readPrivateKey.N, "Private key N component should match") assert.Equal(t, privateKey.E, readPrivateKey.E, "Private key E component should match") - readPublicKey, err := rt.RSACrypto.ReadPublicKey(publicKeyFile) + readPublicKey, err := rt.RSA.ReadPublicKey(publicKeyFile) assert.NoError(t, err, "Error reading public key from file") assert.Equal(t, publicKey.N, readPublicKey.N, "Public key N component should match") assert.Equal(t, publicKey.E, readPublicKey.E, "Public key E component should match") @@ -90,42 +90,42 @@ func (rt *RSATests) TestSaveAndReadKeys(t *testing.T) { // TestEncryptWithInvalidKey tests encryption with an invalid public key func (rt *RSATests) TestEncryptWithInvalidKey(t *testing.T) { // Generate RSA keys - _, _, err := rt.RSACrypto.GenerateKeys(2048) + _, _, err := rt.RSA.GenerateKeys(2048) assert.NoError(t, err) // Attempt to encrypt with a nil public key (invalid case) plainText := []byte("This should fail encryption") - _, err = rt.RSACrypto.Encrypt(plainText, nil) + _, err = rt.RSA.Encrypt(plainText, nil) assert.Error(t, err, "Encryption should fail with an invalid public key") // Attempt to decrypt with a nil private key (invalid case) - _, err = rt.RSACrypto.Decrypt(plainText, nil) + _, err = rt.RSA.Decrypt(plainText, nil) assert.Error(t, err, "Decryption should fail with an invalid private key") // Attempt to decrypt with a different private key (invalid case) - _, err = rt.RSACrypto.Decrypt(plainText, &rsa.PrivateKey{}) + _, err = rt.RSA.Decrypt(plainText, &rsa.PrivateKey{}) assert.Error(t, err, "Decryption should fail with an invalid private key") } // TestSavePrivateKeyInvalidPath tests saving a private key to an invalid path func (rt *RSATests) TestSavePrivateKeyInvalidPath(t *testing.T) { // Generate RSA keys - privateKey, _, err := rt.RSACrypto.GenerateKeys(2048) + privateKey, _, err := rt.RSA.GenerateKeys(2048) assert.NoError(t, err) // Try saving the private key to an invalid file path - err = rt.RSACrypto.SavePrivateKeyToFile(privateKey, "/invalid/path/private.pem") + err = rt.RSA.SavePrivateKeyToFile(privateKey, "/invalid/path/private.pem") assert.Error(t, err, "Saving private key to an invalid path should return an error") } // TestSavePublicKeyInvalidPath tests saving a public key to an invalid path func (rt *RSATests) TestSavePublicKeyInvalidPath(t *testing.T) { // Generate RSA keys - _, publicKey, err := rt.RSACrypto.GenerateKeys(2048) + _, publicKey, err := rt.RSA.GenerateKeys(2048) assert.NoError(t, err) // Try saving the public key to an invalid file path - err = rt.RSACrypto.SavePublicKeyToFile(publicKey, "/invalid/path/public.pem") + err = rt.RSA.SavePublicKeyToFile(publicKey, "/invalid/path/public.pem") assert.Error(t, err, "Saving public key to an invalid path should return an error") } From 730a8c11d364dbf60413a61c5a98023647f7f7b2 Mon Sep 17 00:00:00 2001 From: root Date: Thu, 21 Nov 2024 16:01:01 +0000 Subject: [PATCH 22/29] add an integration test for CryptoKeyUploadService's Upload(...) method --- .../app/services/key_services_test.go | 74 +++++++++++ .../app/services/test_repository_context.go | 121 ++++++++++++++++++ 2 files changed, 195 insertions(+) create mode 100644 test/integration/app/services/key_services_test.go create mode 100644 test/integration/app/services/test_repository_context.go diff --git a/test/integration/app/services/key_services_test.go b/test/integration/app/services/key_services_test.go new file mode 100644 index 0000000..176ea57 --- /dev/null +++ b/test/integration/app/services/key_services_test.go @@ -0,0 +1,74 @@ +package services + +import ( + "crypto_vault_service/internal/app/services" + "crypto_vault_service/internal/infrastructure/connector" + "fmt" + "os" + "testing" + + "github.com/google/uuid" + "github.com/stretchr/testify/require" +) + +// Helper function to create a test file +func createTestFile(testFilePath string, testFileContent []byte) error { + err := os.WriteFile(testFilePath, testFileContent, 0644) + if err != nil { + return fmt.Errorf("failed to create test file at %s: %v", testFilePath, err) + } + return nil +} + +// Helper function to remove the test file +func removeTestFile(testFilePath string) error { + err := os.Remove(testFilePath) + if err != nil { + return fmt.Errorf("failed to remove test file at %s: %v", testFilePath, err) + } + return nil +} + +// Test case for successful file upload and metadata creation +func TestCryptoKeyUploadService_Upload_Success(t *testing.T) { + // Set up environment variable + err := os.Setenv("DB_TYPE", "postgres") + require.NoError(t, err, "Error setting environment variable") + + // Set up test context and ensure proper teardown + ctx := setupTestDB(t) + defer teardownTestDB(t, ctx) + + // Initialize Vault Connector + connectionString := "DefaultEndpointsProtocol=http;AccountName=devstoreaccount1;AccountKey=Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==;BlobEndpoint=http://127.0.0.1:10000/devstoreaccount1;" + containerName := "testblobs" + vaultConnector, err := connector.NewAzureVaultConnector(connectionString, containerName) + require.NoError(t, err, "Error creating vault connector") + + // Set up the CryptoKeyUploadService + cryptoKeyUploadService := &services.CryptoKeyUploadService{ + VaultConnector: vaultConnector, + CryptoKeyRepo: ctx.CryptoKeyRepo, + } + + // Prepare test file + testFilePath := "testfile.pem" + testFileContent := []byte("This is a test file content.") + err = createTestFile(testFilePath, testFileContent) + require.NoError(t, err, "Error creating test file") + defer removeTestFile(testFilePath) + + // Call the method under test + userId := uuid.New().String() + keyType := "private" + keyAlgorithm := "EC" + keyMeta, err := cryptoKeyUploadService.Upload(testFilePath, userId, keyType, keyAlgorithm) + + // Assert that no error occurred during the upload + require.NoError(t, err, "Error uploading file") + + // Assert that keyMeta is not nil and contains expected data + require.NotNil(t, keyMeta, "Key metadata should not be nil") + require.NotEmpty(t, keyMeta.ID, "KeyID should not be empty") + require.Equal(t, userId, keyMeta.UserID, "UserID does not match") +} diff --git a/test/integration/app/services/test_repository_context.go b/test/integration/app/services/test_repository_context.go new file mode 100644 index 0000000..83c3fb9 --- /dev/null +++ b/test/integration/app/services/test_repository_context.go @@ -0,0 +1,121 @@ +package services + +import ( + "crypto_vault_service/internal/domain/blobs" + "crypto_vault_service/internal/domain/keys" + "crypto_vault_service/internal/persistence/repository" + "fmt" + "os" + "testing" + + "gorm.io/driver/postgres" + "gorm.io/driver/sqlite" + "gorm.io/gorm" +) + +// TestRepositoryContext struct to hold DB and repositories for each test +type TestRepositoryContext struct { + DB *gorm.DB + BlobRepo *repository.GormBlobRepository + CryptoKeyRepo *repository.GormCryptoKeyRepository +} + +// Setup function to initialize the test DB and repositories +func setupTestDB(t *testing.T) *TestRepositoryContext { + var err error + var db *gorm.DB + + // Check for the DB type to use (SQLite in-memory or PostgreSQL) + dbType := os.Getenv("DB_TYPE") + if dbType == "" { + // Default to SQLite in-memory if DB_TYPE is not set + dbType = "sqlite" + } + + switch dbType { + case "postgres": + // Setup PostgreSQL connection + dsn := "user=postgres password=postgres host=localhost port=5432 sslmode=disable" + if dsn == "" { + t.Fatalf("POSTGRES_DSN environment variable is not set") + } + + db, err = gorm.Open(postgres.Open(dsn), &gorm.Config{}) + if err != nil { + t.Fatalf("Failed to connect to PostgreSQL: %v", err) + } + + // Check if the `blobs` database exists + sqlDB, err := db.DB() + if err != nil { + t.Fatalf("Failed to get raw DB connection: %v", err) + } + + // Query to check if the `blobs` database exists + var dbExists bool + err = sqlDB.QueryRow("SELECT 1 FROM pg_database WHERE datname = 'blobs'").Scan(&dbExists) + if err != nil { + if err.Error() != "sql: no rows in result set" { + t.Fatalf("Failed to check if database exists: %v", err) + } + // The database does not exist, create it + _, err = sqlDB.Exec("CREATE DATABASE blobs") + if err != nil { + t.Fatalf("Failed to create database: %v", err) + } + fmt.Println("Database 'blobs' created successfully.") + } + + // Now, open a connection to the `blobs` database + dsn = "user=postgres password=postgres host=localhost port=5432 dbname=blobs sslmode=disable" + db, err = gorm.Open(postgres.Open(dsn), &gorm.Config{}) + if err != nil { + t.Fatalf("Failed to connect to PostgreSQL database 'blobs': %v", err) + } + + case "sqlite": + // Setup SQLite in-memory connection + db, err = gorm.Open(sqlite.Open(":memory:"), &gorm.Config{}) + if err != nil { + t.Fatalf("Failed to connect to SQLite: %v", err) + } + + default: + t.Fatalf("Unsupported DB_TYPE value: %s", dbType) + } + + // Migrate the schema for Blob and CryptoKey + err = db.AutoMigrate(&blobs.BlobMeta{}, &keys.CryptoKeyMeta{}) + if err != nil { + t.Fatalf("Failed to migrate schema: %v", err) + } + + // Initialize the repositories with the DB instance + blobRepo := &repository.GormBlobRepository{DB: db} + cryptoKeyRepo := &repository.GormCryptoKeyRepository{DB: db} + + return &TestRepositoryContext{ + DB: db, + BlobRepo: blobRepo, + CryptoKeyRepo: cryptoKeyRepo, + } +} + +// Teardown function to clean up after tests (optional, for DB cleanup) +func teardownTestDB(t *testing.T, ctx *TestRepositoryContext) { + sqlDB, err := ctx.DB.DB() + if err != nil { + t.Fatalf("Failed to get DB connection: %v", err) + } + sqlDB.Close() +} + +// TestMain setup and teardown for the entire test suite +func TestMain(m *testing.M) { + // Run tests + code := m.Run() + // Exit with the test result code + if code != 0 { + fmt.Println("Tests failed.") + } +} From f63cff4e84376346db1806c0b1b0cbf072c82610 Mon Sep 17 00:00:00 2001 From: Marvin Gajek Date: Thu, 21 Nov 2024 17:07:45 +0100 Subject: [PATCH 23/29] refactor connector tests --- .../connector/az_blob_connector_test.go | 126 +++++++++--------- .../connector/az_vault_connector_test.go | 119 ++++++++--------- 2 files changed, 115 insertions(+), 130 deletions(-) diff --git a/test/integration/infrastructure/connector/az_blob_connector_test.go b/test/integration/infrastructure/connector/az_blob_connector_test.go index a1e88c6..0ef7336 100644 --- a/test/integration/infrastructure/connector/az_blob_connector_test.go +++ b/test/integration/infrastructure/connector/az_blob_connector_test.go @@ -11,119 +11,115 @@ import ( "github.com/stretchr/testify/require" ) -// Define a struct to represent the test context for Azure Blob Connector tests. -type AzureBlobConnectorTest struct { - Connector *connector.AzureBlobConnector - TestFilePath string - TestFileContent []byte -} - -// Helper function to create a test file -func (abt *AzureBlobConnectorTest) createTestFile(t *testing.T) { - err := os.WriteFile(abt.TestFilePath, abt.TestFileContent, 0644) - require.NoError(t, err) -} - -// Helper function to remove the test file -func (abt *AzureBlobConnectorTest) removeTestFile(t *testing.T) { - err := os.Remove(abt.TestFilePath) - require.NoError(t, err) -} - -// Helper function to create a new AzureBlobConnectorTest instance -func NewAzureBlobConnectorTest(t *testing.T) *AzureBlobConnectorTest { +// TestAzureBlobConnector_Upload tests the Upload method of AzureBlobConnector +func TestAzureBlobConnector_Upload(t *testing.T) { + // Prepare environment and initialize the connector connectionString := "DefaultEndpointsProtocol=http;AccountName=devstoreaccount1;AccountKey=Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==;BlobEndpoint=http://127.0.0.1:10000/devstoreaccount1;" containerName := "testblobs" abc, err := connector.NewAzureBlobConnector(connectionString, containerName) require.NoError(t, err) - return &AzureBlobConnectorTest{ - Connector: abc, - TestFilePath: "testfile.txt", - TestFileContent: []byte("This is a test file content."), - } -} + // Prepare test file content + testFilePath := "testfile.txt" + testFileContent := []byte("This is a test file content.") -// TestUpload tests the Upload method of AzureBlobConnector -func TestUpload(t *testing.T) { - // Initialize test struct - azureTest := NewAzureBlobConnectorTest(t) + // Create test file + err = os.WriteFile(testFilePath, testFileContent, 0644) + require.NoError(t, err) - // Prepare test file - azureTest.createTestFile(t) - // Clean up the test file and blob - defer azureTest.removeTestFile(t) + // Clean up the test file after the test + defer os.Remove(testFilePath) // Upload the file userId := uuid.New().String() - filePaths := []string{azureTest.TestFilePath} - blobs, err := azureTest.Connector.Upload(filePaths, userId) + filePaths := []string{testFilePath} + blobs, err := abc.Upload(filePaths, userId) require.NoError(t, err) // Assert that we received one blob metadata assert.Len(t, blobs, 1) blob := blobs[0] assert.NotEmpty(t, blob.ID) - assert.Equal(t, azureTest.TestFilePath, blob.Name) - assert.Equal(t, int64(len(azureTest.TestFileContent)), blob.Size) + assert.Equal(t, testFilePath, blob.Name) + assert.Equal(t, int64(len(testFileContent)), blob.Size) assert.Equal(t, ".txt", blob.Type) - err = azureTest.Connector.Delete(blob.ID, blob.Name) + // Delete the uploaded blob + err = abc.Delete(blob.ID, blob.Name) require.NoError(t, err) } -// TestDownload tests the Download method of AzureBlobConnector -func TestDownload(t *testing.T) { - // Initialize test struct - azureTest := NewAzureBlobConnectorTest(t) +// TestAzureBlobConnector_Download tests the Download method of AzureBlobConnector +func TestAzureBlobConnector_Download(t *testing.T) { + // Prepare environment and initialize the connector + connectionString := "DefaultEndpointsProtocol=http;AccountName=devstoreaccount1;AccountKey=Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==;BlobEndpoint=http://127.0.0.1:10000/devstoreaccount1;" + containerName := "testblobs" + abc, err := connector.NewAzureBlobConnector(connectionString, containerName) + require.NoError(t, err) + + // Prepare test file content + testFilePath := "testfile.pem" + testFileContent := []byte("This is a test file content.") - // Prepare test file - azureTest.createTestFile(t) - // Clean up the test file and blob - defer azureTest.removeTestFile(t) + // Create test file + err = os.WriteFile(testFilePath, testFileContent, 0644) + require.NoError(t, err) + + // Clean up the test file after the test + defer os.Remove(testFilePath) // Upload the file userId := uuid.New().String() - filePaths := []string{azureTest.TestFilePath} - blobs, err := azureTest.Connector.Upload(filePaths, userId) + filePaths := []string{testFilePath} + blobs, err := abc.Upload(filePaths, userId) require.NoError(t, err) // Download the uploaded file blob := blobs[0] - downloadedData, err := azureTest.Connector.Download(blob.ID, blob.Name) + downloadedData, err := abc.Download(blob.ID, blob.Name) require.NoError(t, err) // Assert that the downloaded content matches the original content - assert.Equal(t, azureTest.TestFileContent, downloadedData) + assert.Equal(t, testFileContent, downloadedData) - err = azureTest.Connector.Delete(blob.ID, blob.Name) + // Delete the uploaded blob + err = abc.Delete(blob.ID, blob.Name) require.NoError(t, err) } -// TestDelete tests the Delete method of AzureBlobConnector -func TestDelete(t *testing.T) { - // Initialize test struct - azureTest := NewAzureBlobConnectorTest(t) +// TestAzureBlobConnector_Delete tests the Delete method of AzureBlobConnector +func TestAzureBlobConnector_Delete(t *testing.T) { + // Prepare environment and initialize the connector + connectionString := "DefaultEndpointsProtocol=http;AccountName=devstoreaccount1;AccountKey=Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==;BlobEndpoint=http://127.0.0.1:10000/devstoreaccount1;" + containerName := "testblobs" + abc, err := connector.NewAzureBlobConnector(connectionString, containerName) + require.NoError(t, err) + + // Prepare test file content + testFilePath := "testfile.pem" + testFileContent := []byte("This is a test file content.") + + // Create test file + err = os.WriteFile(testFilePath, testFileContent, 0644) + require.NoError(t, err) - // Prepare test file - azureTest.createTestFile(t) - // Clean up the test file and blob - defer azureTest.removeTestFile(t) + // Clean up the test file after the test + defer os.Remove(testFilePath) // Upload the file userId := uuid.New().String() - filePaths := []string{azureTest.TestFilePath} - blobs, err := azureTest.Connector.Upload(filePaths, userId) + filePaths := []string{testFilePath} + blobs, err := abc.Upload(filePaths, userId) require.NoError(t, err) // Get the uploaded blob ID blob := blobs[0] // Now delete the uploaded blob by ID - err = azureTest.Connector.Delete(blob.ID, blob.Name) + err = abc.Delete(blob.ID, blob.Name) require.NoError(t, err) // Try downloading the blob to ensure it was deleted (should fail) - _, err = azureTest.Connector.Download(blob.ID, blob.Name) + _, err = abc.Download(blob.ID, blob.Name) assert.Error(t, err) } diff --git a/test/integration/infrastructure/connector/az_vault_connector_test.go b/test/integration/infrastructure/connector/az_vault_connector_test.go index 4315895..ff06df9 100644 --- a/test/integration/infrastructure/connector/az_vault_connector_test.go +++ b/test/integration/infrastructure/connector/az_vault_connector_test.go @@ -1,66 +1,41 @@ package connector import ( - "crypto_vault_service/internal/infrastructure/connector" "os" "testing" "time" + "crypto_vault_service/internal/infrastructure/connector" + "github.com/google/uuid" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) -// Define a struct to represent the test context for Azure Vault Connector tests. -type AzureVaultConnectorTest struct { - Connector *connector.AzureVaultConnector - TestFilePath string - TestFileContent []byte -} - -// Helper function to create a test file -func (abt *AzureVaultConnectorTest) createTestFile(t *testing.T) { - err := os.WriteFile(abt.TestFilePath, abt.TestFileContent, 0644) - require.NoError(t, err) -} - -// Helper function to remove the test file -func (abt *AzureVaultConnectorTest) removeTestFile(t *testing.T) { - err := os.Remove(abt.TestFilePath) - require.NoError(t, err) -} - -// Helper function to create a new AzureVaultConnectorTest instance -func NewAzureVaultConnectorTest(t *testing.T) *AzureVaultConnectorTest { +// TestUpload tests the Upload method of AzureVaultConnector +func TestAzureVaultConnector_Upload(t *testing.T) { + // Prepare environment and initialize the connector connectionString := "DefaultEndpointsProtocol=http;AccountName=devstoreaccount1;AccountKey=Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==;BlobEndpoint=http://127.0.0.1:10000/devstoreaccount1;" containerName := "testblobs" - // Create the Azure Vault Connector abc, err := connector.NewAzureVaultConnector(connectionString, containerName) require.NoError(t, err) - return &AzureVaultConnectorTest{ - Connector: abc, - TestFilePath: "testfile.txt", - TestFileContent: []byte("This is a test file content."), - } -} + // Prepare test file content + testFilePath := "testfile.txt" + testFileContent := []byte("This is a test file content.") -// TestUpload tests the Upload method of AzureVaultConnector -func TestAzureVaultConnector_Upload(t *testing.T) { - // Initialize test struct - azureTest := NewAzureVaultConnectorTest(t) + // Create test file + err = os.WriteFile(testFilePath, testFileContent, 0644) + require.NoError(t, err) - // Prepare test file - azureTest.createTestFile(t) - // Clean up the test file and delete the uploaded key - defer azureTest.removeTestFile(t) + // Clean up the test file after the test + defer os.Remove(testFilePath) // Upload the file userId := uuid.New().String() - filePath := azureTest.TestFilePath keyAlgorithm := "RSA" keyType := "private" - cryptoKeyMeta, err := azureTest.Connector.Upload(filePath, userId, keyType, keyAlgorithm) + cryptoKeyMeta, err := abc.Upload(testFilePath, userId, keyType, keyAlgorithm) require.NoError(t, err) // Assert that we received key metadata @@ -69,66 +44,80 @@ func TestAzureVaultConnector_Upload(t *testing.T) { assert.Equal(t, userId, cryptoKeyMeta.UserID) assert.WithinDuration(t, time.Now(), cryptoKeyMeta.DateTimeCreated, time.Second) - err = azureTest.Connector.Delete(cryptoKeyMeta.ID, cryptoKeyMeta.Type) + // Delete the uploaded key + err = abc.Delete(cryptoKeyMeta.ID, cryptoKeyMeta.Type) require.NoError(t, err) } // TestDownload tests the Download method of AzureVaultConnector func TestAzureVaultConnector_Download(t *testing.T) { - // Initialize test struct - azureTest := NewAzureVaultConnectorTest(t) + // Prepare environment and initialize the connector + connectionString := "DefaultEndpointsProtocol=http;AccountName=devstoreaccount1;AccountKey=Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==;BlobEndpoint=http://127.0.0.1:10000/devstoreaccount1;" + containerName := "testblobs" + abc, err := connector.NewAzureVaultConnector(connectionString, containerName) + require.NoError(t, err) - // Prepare test file - azureTest.createTestFile(t) - // Clean up the test file and delete the uploaded key - defer azureTest.removeTestFile(t) + // Prepare test file content + testFilePath := "testfile.pem" + testFileContent := []byte("This is a test file content.") + + // Create test file + err = os.WriteFile(testFilePath, testFileContent, 0644) + require.NoError(t, err) + + // Clean up the test file after the test + defer os.Remove(testFilePath) // Upload the file userId := uuid.New().String() - filePath := azureTest.TestFilePath keyAlgorithm := "RSA" keyType := "private" - cryptoKeyMeta, err := azureTest.Connector.Upload(filePath, userId, keyType, keyAlgorithm) + cryptoKeyMeta, err := abc.Upload(testFilePath, userId, keyType, keyAlgorithm) require.NoError(t, err) - // Get the metadata of the uploaded file - // Download the uploaded file - downloadedData, err := azureTest.Connector.Download(cryptoKeyMeta.ID, cryptoKeyMeta.Type) + downloadedData, err := abc.Download(cryptoKeyMeta.ID, cryptoKeyMeta.Type) require.NoError(t, err) // Assert that the downloaded content matches the original content - assert.Equal(t, azureTest.TestFileContent, downloadedData) + assert.Equal(t, testFileContent, downloadedData) - err = azureTest.Connector.Delete(cryptoKeyMeta.ID, cryptoKeyMeta.Type) + // Delete the uploaded key + err = abc.Delete(cryptoKeyMeta.ID, cryptoKeyMeta.Type) require.NoError(t, err) } // TestDelete tests the Delete method of AzureVaultConnector func TestAzureVaultConnector_Delete(t *testing.T) { - // Initialize test struct - azureTest := NewAzureVaultConnectorTest(t) + // Prepare environment and initialize the connector + connectionString := "DefaultEndpointsProtocol=http;AccountName=devstoreaccount1;AccountKey=Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==;BlobEndpoint=http://127.0.0.1:10000/devstoreaccount1;" + containerName := "testblobs" + abc, err := connector.NewAzureVaultConnector(connectionString, containerName) + require.NoError(t, err) - // Prepare test file - azureTest.createTestFile(t) - // Clean up the test file and delete the uploaded key - defer azureTest.removeTestFile(t) + // Prepare test file content + testFilePath := "testfile.pem" + testFileContent := []byte("This is a test file content.") + + // Create test file + err = os.WriteFile(testFilePath, testFileContent, 0644) + require.NoError(t, err) + + // Clean up the test file after the test + defer os.Remove(testFilePath) // Upload the file userId := uuid.New().String() - filePath := azureTest.TestFilePath keyAlgorithm := "RSA" keyType := "private" - cryptoKeyMeta, err := azureTest.Connector.Upload(filePath, userId, keyType, keyAlgorithm) + cryptoKeyMeta, err := abc.Upload(testFilePath, userId, keyType, keyAlgorithm) require.NoError(t, err) - // Get the metadata of the uploaded file - // Now delete the uploaded key by ID - err = azureTest.Connector.Delete(cryptoKeyMeta.ID, cryptoKeyMeta.Type) + err = abc.Delete(cryptoKeyMeta.ID, cryptoKeyMeta.Type) require.NoError(t, err) // Try downloading the key to ensure it was deleted (should fail) - _, err = azureTest.Connector.Download(cryptoKeyMeta.ID, cryptoKeyMeta.Type) + _, err = abc.Download(cryptoKeyMeta.ID, cryptoKeyMeta.Type) assert.Error(t, err) } From 6acdf16a50c6eaae2a47c337962b96d1119b1439 Mon Sep 17 00:00:00 2001 From: root Date: Thu, 21 Nov 2024 16:17:04 +0000 Subject: [PATCH 24/29] refactor persistence layer integration tests --- .../repository/psql_blob_repository_test.go | 145 +++-------------- .../repository/sqlite_blob_repository_test.go | 151 ++++-------------- .../repository/sqlite_key_repository_test.go | 16 +- .../repository/test_repository_context.go | 30 +--- 4 files changed, 68 insertions(+), 274 deletions(-) diff --git a/test/integration/persistence/repository/psql_blob_repository_test.go b/test/integration/persistence/repository/psql_blob_repository_test.go index d90dc3f..a08f64a 100644 --- a/test/integration/persistence/repository/psql_blob_repository_test.go +++ b/test/integration/persistence/repository/psql_blob_repository_test.go @@ -1,3 +1,4 @@ +// repository/blobrepository_test.go package repository import ( @@ -9,10 +10,8 @@ import ( "github.com/google/uuid" "github.com/stretchr/testify/assert" - "gorm.io/gorm" ) -// TestBlobPsqlRepository_Create tests the Create method of GormBlobRepository func TestBlobPsqlRepository_Create(t *testing.T) { err := os.Setenv("DB_TYPE", "postgres") if err != nil { @@ -20,28 +19,28 @@ func TestBlobPsqlRepository_Create(t *testing.T) { } // Set up test context - ctx := setupTestDB(t) - defer teardownTestDB(t, ctx) + ctx := SetupTestDB(t) + defer TeardownTestDB(t, ctx) // Create a valid CryptoKey object cryptographicKey := keys.CryptoKeyMeta{ - ID: uuid.New().String(), // Generate valid UUID for ID - Type: "public", // Example key type - Algorithm: "EC", // Example algorithm - DateTimeCreated: time.Now(), // Valid DateTimeCreated time - UserID: uuid.New().String(), // Generate valid UUID for UserID + ID: uuid.New().String(), + Type: "public", + Algorithm: "EC", + DateTimeCreated: time.Now(), + UserID: uuid.New().String(), } - // Create a test Blob object with valid UUIDs and required fields + // Create a test Blob object blob := &blobs.BlobMeta{ - ID: uuid.New().String(), // Generate valid UUID + ID: uuid.New().String(), DateTimeCreated: time.Now(), - UserID: uuid.New().String(), // Generate valid UUID for UserID + UserID: cryptographicKey.UserID, Name: "test-blob", Size: 1024, Type: "text", - CryptoKey: cryptographicKey, // Set the CryptoKey - KeyID: cryptographicKey.ID, // Ensure ID is set + CryptoKey: cryptographicKey, + KeyID: cryptographicKey.ID, } // Call the Create method @@ -56,7 +55,6 @@ func TestBlobPsqlRepository_Create(t *testing.T) { assert.Equal(t, blob.Name, createdBlob.Name, "Name should match") } -// TestBlobPsqlRepository_GetById tests the GetById method of GormBlobRepository func TestBlobPsqlRepository_GetById(t *testing.T) { err := os.Setenv("DB_TYPE", "postgres") if err != nil { @@ -64,29 +62,28 @@ func TestBlobPsqlRepository_GetById(t *testing.T) { } // Set up test context - ctx := setupTestDB(t) - defer teardownTestDB(t, ctx) + ctx := SetupTestDB(t) + defer TeardownTestDB(t, ctx) // Create a valid CryptoKey object cryptographicKey := keys.CryptoKeyMeta{ - ID: uuid.New().String(), // Generate valid UUID for ID - Type: "public", // Example key type - Algorithm: "EC", // Example algorithm - DateTimeCreated: time.Now(), // Valid DateTimeCreated time - UserID: uuid.New().String(), // Generate valid UUID for UserID + ID: uuid.New().String(), + Type: "public", + Algorithm: "EC", + DateTimeCreated: time.Now(), + UserID: uuid.New().String(), } - // Create a test Blob object with valid UUIDs and required fields + // Create a test Blob object blob := &blobs.BlobMeta{ - ID: uuid.New().String(), // Generate valid UUID + ID: uuid.New().String(), DateTimeCreated: time.Now(), - UserID: cryptographicKey.UserID, // Link to valid UserID from CryptoKey + UserID: cryptographicKey.UserID, Name: "test-blob", Size: 1024, Type: "text", - - CryptoKey: cryptographicKey, // Set the CryptoKey - KeyID: cryptographicKey.ID, // Ensure ID is set + CryptoKey: cryptographicKey, + KeyID: cryptographicKey.ID, } // Create the blob in DB @@ -99,95 +96,3 @@ func TestBlobPsqlRepository_GetById(t *testing.T) { assert.NotNil(t, fetchedBlob, "Fetched blob should not be nil") assert.Equal(t, blob.ID, fetchedBlob.ID, "ID should match") } - -// TestBlobPsqlRepository_UpdateById tests the UpdateById method of GormBlobRepository -func TestBlobPsqlRepository_UpdateById(t *testing.T) { - err := os.Setenv("DB_TYPE", "postgres") - if err != nil { - t.Fatalf("Error setting environment variable: %v", err) - } - - // Set up test context - ctx := setupTestDB(t) - defer teardownTestDB(t, ctx) - - // Create a valid CryptoKey object - cryptographicKey := keys.CryptoKeyMeta{ - ID: uuid.New().String(), // Generate valid UUID for ID - Type: "public", // Example key type - Algorithm: "EC", // Example algorithm - DateTimeCreated: time.Now(), // Valid DateTimeCreated time - UserID: uuid.New().String(), // Generate valid UUID for UserID - } - - // Create a test Blob object with valid UUIDs and required fields - blob := &blobs.BlobMeta{ - ID: uuid.New().String(), // Generate valid UUID - DateTimeCreated: time.Now(), - UserID: uuid.New().String(), // Generate valid UUID for UserID - Name: "test-blob", - Size: 1024, - Type: "text", - - CryptoKey: cryptographicKey, // Set the CryptoKey - KeyID: cryptographicKey.ID, // Ensure ID is set - } - - // Create the blob in DB - err = ctx.BlobRepo.Create(blob) - assert.NoError(t, err) - - // Update the blob's name - blob.Name = "updated-blob-name" - err = ctx.BlobRepo.UpdateById(blob) - assert.NoError(t, err) - - // Verify the blob is updated - var updatedBlob blobs.BlobMeta - err = ctx.DB.First(&updatedBlob, "id = ?", blob.ID).Error - assert.NoError(t, err) - assert.Equal(t, "updated-blob-name", updatedBlob.Name, "Name should be updated") -} - -// TestBlobPsqlRepository_DeleteById tests the DeleteById method of GormBlobRepository -func TestBlobPsqlRepository_DeleteById(t *testing.T) { - // Set up test context - ctx := setupTestDB(t) - defer teardownTestDB(t, ctx) - - // Create a valid CryptoKey object - cryptographicKey := keys.CryptoKeyMeta{ - ID: uuid.New().String(), // Generate valid UUID for ID - Type: "public", // Example key type - Algorithm: "EC", // Example algorithm - DateTimeCreated: time.Now(), // Valid DateTimeCreated time - UserID: uuid.New().String(), // Generate valid UUID for UserID - } - - // Create a test Blob object with valid UUIDs and required fields - blob := &blobs.BlobMeta{ - ID: uuid.New().String(), // Generate valid UUID - DateTimeCreated: time.Now(), - UserID: uuid.New().String(), // Generate valid UUID for UserID - Name: "test-blob", - Size: 1024, - Type: "text", - - CryptoKey: cryptographicKey, // Set the CryptoKey - KeyID: cryptographicKey.ID, // Ensure ID is set - } - - // Create the blob in DB - err := ctx.BlobRepo.Create(blob) - assert.NoError(t, err) - - // Delete the blob - err = ctx.BlobRepo.DeleteById(blob.ID) - assert.NoError(t, err) - - // Verify the blob is deleted - var deletedBlob blobs.BlobMeta - err = ctx.DB.First(&deletedBlob, "id = ?", blob.ID).Error - assert.Error(t, err, "Blob should be deleted") - assert.Equal(t, gorm.ErrRecordNotFound, err, "Error should be 'record not found'") -} diff --git a/test/integration/persistence/repository/sqlite_blob_repository_test.go b/test/integration/persistence/repository/sqlite_blob_repository_test.go index da6098f..ecdf572 100644 --- a/test/integration/persistence/repository/sqlite_blob_repository_test.go +++ b/test/integration/persistence/repository/sqlite_blob_repository_test.go @@ -1,3 +1,4 @@ +// repository/blobrepository_test.go package repository import ( @@ -9,39 +10,37 @@ import ( "github.com/google/uuid" "github.com/stretchr/testify/assert" - "gorm.io/gorm" ) -// TestBlobInSqliteRepository_Create tests the Create method of GormBlobRepository -func TestBlobInSqliteRepository_Create(t *testing.T) { +func TestBlobSqliteRepository_Create(t *testing.T) { err := os.Setenv("DB_TYPE", "sqlite") if err != nil { t.Fatalf("Error setting environment variable: %v", err) } // Set up test context - ctx := setupTestDB(t) - defer teardownTestDB(t, ctx) + ctx := SetupTestDB(t) + defer TeardownTestDB(t, ctx) // Create a valid CryptoKey object cryptographicKey := keys.CryptoKeyMeta{ - ID: uuid.New().String(), // Generate valid UUID for ID - Type: "public", // Example key type - Algorithm: "EC", // Example algorithm - DateTimeCreated: time.Now(), // Valid DateTimeCreated time - UserID: uuid.New().String(), // Generate valid UUID for UserID + ID: uuid.New().String(), + Type: "public", + Algorithm: "EC", + DateTimeCreated: time.Now(), + UserID: uuid.New().String(), } - // Create a test Blob object with valid UUIDs and required fields + // Create a test Blob object blob := &blobs.BlobMeta{ - ID: uuid.New().String(), // Generate valid UUID + ID: uuid.New().String(), DateTimeCreated: time.Now(), - UserID: uuid.New().String(), // Generate valid UUID for UserID + UserID: cryptographicKey.UserID, Name: "test-blob", Size: 1024, Type: "text", - CryptoKey: cryptographicKey, // Set the CryptoKey - KeyID: cryptographicKey.ID, // Ensure ID is set + CryptoKey: cryptographicKey, + KeyID: cryptographicKey.ID, } // Call the Create method @@ -56,36 +55,35 @@ func TestBlobInSqliteRepository_Create(t *testing.T) { assert.Equal(t, blob.Name, createdBlob.Name, "Name should match") } -// TestBlobInSqliteRepository_GetById tests the GetById method of GormBlobRepository -func TestBlobInSqliteRepository_GetById(t *testing.T) { +func TestBlobSqliteRepository_GetById(t *testing.T) { err := os.Setenv("DB_TYPE", "sqlite") if err != nil { t.Fatalf("Error setting environment variable: %v", err) } // Set up test context - ctx := setupTestDB(t) - defer teardownTestDB(t, ctx) + ctx := SetupTestDB(t) + defer TeardownTestDB(t, ctx) // Create a valid CryptoKey object cryptographicKey := keys.CryptoKeyMeta{ - ID: uuid.New().String(), // Generate valid UUID for ID - Type: "public", // Example key type - Algorithm: "EC", // Example algorithm - DateTimeCreated: time.Now(), // Valid DateTimeCreated time - UserID: uuid.New().String(), // Generate valid UUID for UserID + ID: uuid.New().String(), + Type: "public", + Algorithm: "EC", + DateTimeCreated: time.Now(), + UserID: uuid.New().String(), } - // Create a test Blob object with valid UUIDs and required fields + // Create a test Blob object blob := &blobs.BlobMeta{ - ID: uuid.New().String(), // Generate valid UUID + ID: uuid.New().String(), DateTimeCreated: time.Now(), - UserID: cryptographicKey.UserID, // Link to valid UserID from CryptoKey + UserID: cryptographicKey.UserID, Name: "test-blob", Size: 1024, Type: "text", - CryptoKey: cryptographicKey, // Set the CryptoKey - KeyID: cryptographicKey.ID, // Ensure ID is set + CryptoKey: cryptographicKey, + KeyID: cryptographicKey.ID, } // Create the blob in DB @@ -98,98 +96,3 @@ func TestBlobInSqliteRepository_GetById(t *testing.T) { assert.NotNil(t, fetchedBlob, "Fetched blob should not be nil") assert.Equal(t, blob.ID, fetchedBlob.ID, "ID should match") } - -// TestBlobInSqliteRepository_UpdateById tests the UpdateById method of GormBlobRepository -func TestBlobInSqliteRepository_UpdateById(t *testing.T) { - err := os.Setenv("DB_TYPE", "sqlite") - if err != nil { - t.Fatalf("Error setting environment variable: %v", err) - } - - // Set up test context - ctx := setupTestDB(t) - defer teardownTestDB(t, ctx) - - // Create a valid CryptoKey object - cryptographicKey := keys.CryptoKeyMeta{ - ID: uuid.New().String(), // Generate valid UUID for ID - Type: "public", // Example key type - Algorithm: "EC", // Example algorithm - DateTimeCreated: time.Now(), // Valid DateTimeCreated time - UserID: uuid.New().String(), // Generate valid UUID for UserID - } - - // Create a test Blob object with valid UUIDs and required fields - blob := &blobs.BlobMeta{ - ID: uuid.New().String(), // Generate valid UUID - DateTimeCreated: time.Now(), - UserID: uuid.New().String(), // Generate valid UUID for UserID - Name: "test-blob", - Size: 1024, - Type: "text", - CryptoKey: cryptographicKey, // Set the CryptoKey - KeyID: cryptographicKey.ID, // Ensure ID is set - } - - // Create the blob in DB - err = ctx.BlobRepo.Create(blob) - assert.NoError(t, err) - - // Update the blob's name - blob.Name = "updated-blob-name" - err = ctx.BlobRepo.UpdateById(blob) - assert.NoError(t, err) - - // Verify the blob is updated - var updatedBlob blobs.BlobMeta - err = ctx.DB.First(&updatedBlob, "id = ?", blob.ID).Error - assert.NoError(t, err) - assert.Equal(t, "updated-blob-name", updatedBlob.Name, "Name should be updated") -} - -// TestBlobInSqliteRepository_DeleteById tests the DeleteById method of GormBlobRepository -func TestBlobInSqliteRepository_DeleteById(t *testing.T) { - err := os.Setenv("DB_TYPE", "sqlite") - if err != nil { - t.Fatalf("Error setting environment variable: %v", err) - } - - // Set up test context - ctx := setupTestDB(t) - defer teardownTestDB(t, ctx) - - // Create a valid CryptoKey object - cryptographicKey := keys.CryptoKeyMeta{ - ID: uuid.New().String(), // Generate valid UUID for ID - Type: "public", // Example key type - Algorithm: "EC", // Example algorithm - DateTimeCreated: time.Now(), // Valid DateTimeCreated time - UserID: uuid.New().String(), // Generate valid UUID for UserID - } - - // Create a test Blob object with valid UUIDs and required fields - blob := &blobs.BlobMeta{ - ID: uuid.New().String(), // Generate valid UUID - DateTimeCreated: time.Now(), - UserID: uuid.New().String(), // Generate valid UUID for UserID - Name: "test-blob", - Size: 1024, - Type: "text", - CryptoKey: cryptographicKey, // Set the CryptoKey - KeyID: cryptographicKey.ID, // Ensure ID is set - } - - // Create the blob in DB - err = ctx.BlobRepo.Create(blob) - assert.NoError(t, err) - - // Delete the blob - err = ctx.BlobRepo.DeleteById(blob.ID) - assert.NoError(t, err) - - // Verify the blob is deleted - var deletedBlob blobs.BlobMeta - err = ctx.DB.First(&deletedBlob, "id = ?", blob.ID).Error - assert.Error(t, err, "Blob should be deleted") - assert.Equal(t, gorm.ErrRecordNotFound, err, "Error should be 'record not found'") -} diff --git a/test/integration/persistence/repository/sqlite_key_repository_test.go b/test/integration/persistence/repository/sqlite_key_repository_test.go index aed2fcb..0548ff8 100644 --- a/test/integration/persistence/repository/sqlite_key_repository_test.go +++ b/test/integration/persistence/repository/sqlite_key_repository_test.go @@ -19,8 +19,8 @@ func TestCryptoKeySqliteRepository_Create(t *testing.T) { } // Set up test context - ctx := setupTestDB(t) - defer teardownTestDB(t, ctx) + ctx := SetupTestDB(t) + defer TeardownTestDB(t, ctx) // Create a valid CryptoKey object cryptoKeyMeta := &keys.CryptoKeyMeta{ @@ -51,8 +51,8 @@ func TestCryptoKeySqliteRepository_GetByID(t *testing.T) { } // Set up test context - ctx := setupTestDB(t) - defer teardownTestDB(t, ctx) + ctx := SetupTestDB(t) + defer TeardownTestDB(t, ctx) // Create a valid CryptoKey object cryptoKeyMeta := &keys.CryptoKeyMeta{ @@ -82,8 +82,8 @@ func TestCryptoKeySqliteRepository_UpdateByID(t *testing.T) { } // Set up test context - ctx := setupTestDB(t) - defer teardownTestDB(t, ctx) + ctx := SetupTestDB(t) + defer TeardownTestDB(t, ctx) // Create a valid CryptoKey object cryptoKeyMeta := &keys.CryptoKeyMeta{ @@ -113,8 +113,8 @@ func TestCryptoKeySqliteRepository_UpdateByID(t *testing.T) { // TestCryptoKeySqliteRepository_DeleteByID tests the DeleteByID method of GormCryptoKeyRepository func TestCryptoKeySqliteRepository_DeleteByID(t *testing.T) { // Set up test context - ctx := setupTestDB(t) - defer teardownTestDB(t, ctx) + ctx := SetupTestDB(t) + defer TeardownTestDB(t, ctx) // Create a valid CryptoKey object cryptoKeyMeta := &keys.CryptoKeyMeta{ diff --git a/test/integration/persistence/repository/test_repository_context.go b/test/integration/persistence/repository/test_repository_context.go index c06bd85..10fca05 100644 --- a/test/integration/persistence/repository/test_repository_context.go +++ b/test/integration/persistence/repository/test_repository_context.go @@ -13,28 +13,25 @@ import ( "gorm.io/gorm" ) -// TestRepositoryContext struct to hold DB and repositories for each test type TestRepositoryContext struct { DB *gorm.DB BlobRepo *repository.GormBlobRepository CryptoKeyRepo *repository.GormCryptoKeyRepository } -// Setup function to initialize the test DB and repositories -func setupTestDB(t *testing.T) *TestRepositoryContext { +// SetupTestDB initializes the test database and repositories based on the DB_TYPE environment variable +func SetupTestDB(t *testing.T) *TestRepositoryContext { var err error var db *gorm.DB - // Check for the DB type to use (SQLite in-memory or PostgreSQL) dbType := os.Getenv("DB_TYPE") if dbType == "" { - // Default to SQLite in-memory if DB_TYPE is not set - dbType = "sqlite" + dbType = "sqlite" // Default to SQLite in-memory if DB_TYPE is not set } switch dbType { case "postgres": - // Setup PostgreSQL connection + // PostgreSQL setup dsn := "user=postgres password=postgres host=localhost port=5432 sslmode=disable" if dsn == "" { t.Fatalf("POSTGRES_DSN environment variable is not set") @@ -45,7 +42,7 @@ func setupTestDB(t *testing.T) *TestRepositoryContext { t.Fatalf("Failed to connect to PostgreSQL: %v", err) } - // Check if the `blobs` database exists + // Ensure the `blobs` database exists sqlDB, err := db.DB() if err != nil { t.Fatalf("Failed to get raw DB connection: %v", err) @@ -66,7 +63,7 @@ func setupTestDB(t *testing.T) *TestRepositoryContext { fmt.Println("Database 'blobs' created successfully.") } - // Now, open a connection to the `blobs` database + // Open the connection to `blobs` database dsn = "user=postgres password=postgres host=localhost port=5432 dbname=blobs sslmode=disable" db, err = gorm.Open(postgres.Open(dsn), &gorm.Config{}) if err != nil { @@ -74,7 +71,6 @@ func setupTestDB(t *testing.T) *TestRepositoryContext { } case "sqlite": - // Setup SQLite in-memory connection db, err = gorm.Open(sqlite.Open(":memory:"), &gorm.Config{}) if err != nil { t.Fatalf("Failed to connect to SQLite: %v", err) @@ -101,21 +97,11 @@ func setupTestDB(t *testing.T) *TestRepositoryContext { } } -// Teardown function to clean up after tests (optional, for DB cleanup) -func teardownTestDB(t *testing.T, ctx *TestRepositoryContext) { +// TeardownTestDB closes the DB connection after the test +func TeardownTestDB(t *testing.T, ctx *TestRepositoryContext) { sqlDB, err := ctx.DB.DB() if err != nil { t.Fatalf("Failed to get DB connection: %v", err) } sqlDB.Close() } - -// TestMain setup and teardown for the entire test suite -func TestMain(m *testing.M) { - // Run tests - code := m.Run() - // Exit with the test result code - if code != 0 { - fmt.Println("Tests failed.") - } -} From b2c3a3782bb1f9e0435d714577b9ed3569358971 Mon Sep 17 00:00:00 2001 From: root Date: Thu, 21 Nov 2024 16:31:52 +0000 Subject: [PATCH 25/29] remove enum, modify Download(...) signature and logic --- internal/app/services/key_services.go | 16 ++-------------- internal/domain/keys/contracts.go | 12 +----------- 2 files changed, 3 insertions(+), 25 deletions(-) diff --git a/internal/app/services/key_services.go b/internal/app/services/key_services.go index cad6757..a2c1527 100644 --- a/internal/app/services/key_services.go +++ b/internal/app/services/key_services.go @@ -66,20 +66,8 @@ type CryptoKeyDownloadService struct { } // Download retrieves a cryptographic key by its ID and type. -func (s *CryptoKeyDownloadService) Download(keyID string, keyType keys.KeyType) ([]byte, error) { - blobName := "" - - if keyType == keys.AsymmetricPublic { - blobName = "public" - } else if keyType == keys.AsymmetricPrivate { - blobName = "private" - } else if keyType == keys.Symmetric { - blobName = "symmetric" - } else { - return nil, fmt.Errorf("unsupported key type: %v", keyType) - } - - blobData, err := s.VaultConnector.Download(keyID, blobName) +func (s *CryptoKeyDownloadService) Download(keyID, keyType string) ([]byte, error) { + blobData, err := s.VaultConnector.Download(keyID, keyType) if err != nil { return nil, fmt.Errorf("failed to download key from blob storage: %w", err) } diff --git a/internal/domain/keys/contracts.go b/internal/domain/keys/contracts.go index f81933f..5603c20 100644 --- a/internal/domain/keys/contracts.go +++ b/internal/domain/keys/contracts.go @@ -1,15 +1,5 @@ package keys -// KeyType defines a custom type for key types based on an integer. -type KeyType int - -// Enum-like values for different key types, using iota to generate sequential values. -const ( - AsymmetricPublic KeyType = iota // Public key in asymmetric cryptography (e.g., RSA, ECDSA) - AsymmetricPrivate // Private key in asymmetric cryptography (e.g., RSA, ECDSA) - Symmetric // Symmetric key (e.g., AES) -) - // ICryptoKeyUploadService defines methods for uploading cryptographic keys. type ICryptoKeyUploadService interface { // Upload uploads cryptographic keys from specified file paths. @@ -36,5 +26,5 @@ type ICryptoKeyMetadataService interface { type ICryptoKeyDownloadService interface { // Download retrieves a cryptographic key by its ID and type. // It returns the CryptoKeyMeta, the key data as a byte slice, and any error encountered during the download process. - Download(keyID string, keyType KeyType) ([]byte, error) + Download(keyID, keyType string) ([]byte, error) } From c85f47344b0aeb29abe8f5c46b5ad9098197992c Mon Sep 17 00:00:00 2001 From: Marvin Gajek Date: Thu, 21 Nov 2024 17:32:13 +0100 Subject: [PATCH 26/29] increase code coverage on key services --- .../app/services/key_services_test.go | 137 ++++++++++++++++++ 1 file changed, 137 insertions(+) diff --git a/test/integration/app/services/key_services_test.go b/test/integration/app/services/key_services_test.go index 176ea57..685970e 100644 --- a/test/integration/app/services/key_services_test.go +++ b/test/integration/app/services/key_services_test.go @@ -2,13 +2,16 @@ package services import ( "crypto_vault_service/internal/app/services" + "crypto_vault_service/internal/domain/keys" "crypto_vault_service/internal/infrastructure/connector" "fmt" "os" "testing" + "time" "github.com/google/uuid" "github.com/stretchr/testify/require" + "gorm.io/gorm" ) // Helper function to create a test file @@ -72,3 +75,137 @@ func TestCryptoKeyUploadService_Upload_Success(t *testing.T) { require.NotEmpty(t, keyMeta.ID, "KeyID should not be empty") require.Equal(t, userId, keyMeta.UserID, "UserID does not match") } + +// Test case for successful retrieval of cryptographic key metadata by ID +func TestCryptoKeyMetadataService_GetByID_Success(t *testing.T) { + // Set up environment variable + err := os.Setenv("DB_TYPE", "postgres") + require.NoError(t, err, "Error setting environment variable") + + // Set up test context and ensure proper teardown + ctx := setupTestDB(t) + defer teardownTestDB(t, ctx) + + // Create a key metadata instance in the database for testing + cryptoKeyMeta := &keys.CryptoKeyMeta{ + ID: uuid.New().String(), + Type: "public", + Algorithm: "EC", + DateTimeCreated: time.Now(), + UserID: uuid.New().String(), + } + + // Store the cryptographic key metadata in the database + err = ctx.CryptoKeyRepo.Create(cryptoKeyMeta) + require.NoError(t, err, "Error creating test cryptographic key metadata") + + // Set up the CryptoKeyMetadataService + cryptoKeyMetadataService := &services.CryptoKeyMetadataService{ + CryptoKeyRepo: ctx.CryptoKeyRepo, + } + + // Call the method under test + fetchedCryptoKeyMeta, err := cryptoKeyMetadataService.GetByID(cryptoKeyMeta.ID) + + // Assert that no error occurred during retrieval + require.NoError(t, err, "Error retrieving cryptographic key metadata") + + // Assert that the fetched metadata matches the original + require.NotNil(t, fetchedCryptoKeyMeta, "Fetched cryptographic key metadata should not be nil") + require.Equal(t, cryptoKeyMeta.ID, fetchedCryptoKeyMeta.ID, "ID should match") + require.Equal(t, cryptoKeyMeta.Type, fetchedCryptoKeyMeta.Type, "Type should match") + require.Equal(t, cryptoKeyMeta.Algorithm, fetchedCryptoKeyMeta.Algorithm, "Algorithm should match") +} + +// Test case for successful deletion of cryptographic key metadata by ID +func TestCryptoKeyMetadataService_DeleteByID_Success(t *testing.T) { + // Set up environment variable + err := os.Setenv("DB_TYPE", "postgres") + require.NoError(t, err, "Error setting environment variable") + + // Set up test context and ensure proper teardown + ctx := setupTestDB(t) + defer teardownTestDB(t, ctx) + + // Create a key metadata instance in the database for testing + cryptoKeyMeta := &keys.CryptoKeyMeta{ + ID: uuid.New().String(), + Type: "private", + Algorithm: "RSA", + DateTimeCreated: time.Now(), + UserID: uuid.New().String(), + } + + // Store the cryptographic key metadata in the database + err = ctx.CryptoKeyRepo.Create(cryptoKeyMeta) + require.NoError(t, err, "Error creating test cryptographic key metadata") + + // Set up the CryptoKeyMetadataService + cryptoKeyMetadataService := &services.CryptoKeyMetadataService{ + CryptoKeyRepo: ctx.CryptoKeyRepo, + } + + // Call the method under test + err = cryptoKeyMetadataService.DeleteByID(cryptoKeyMeta.ID) + + // Assert that no error occurred during deletion + require.NoError(t, err, "Error deleting cryptographic key metadata") + + // Verify the metadata is deleted + var deletedCryptoKeyMeta keys.CryptoKeyMeta + err = ctx.DB.First(&deletedCryptoKeyMeta, "id = ?", cryptoKeyMeta.ID).Error + require.Error(t, err, "Cryptographic key metadata should be deleted") + require.Equal(t, gorm.ErrRecordNotFound, err, "Error should be 'record not found'") +} + +// Test case for successful download of cryptographic key +func TestCryptoKeyDownloadService_Download_Success(t *testing.T) { + // Set up environment variable + err := os.Setenv("DB_TYPE", "postgres") + require.NoError(t, err, "Error setting environment variable") + + // Set up test context and ensure proper teardown + ctx := setupTestDB(t) + defer teardownTestDB(t, ctx) + + // Initialize Vault Connector + connectionString := "DefaultEndpointsProtocol=http;AccountName=devstoreaccount1;AccountKey=Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==;BlobEndpoint=http://127.0.0.1:10000/devstoreaccount1;" + containerName := "testblobs" + vaultConnector, err := connector.NewAzureVaultConnector(connectionString, containerName) + require.NoError(t, err, "Error creating vault connector") + + // Set up the CryptoKeyUploadService + cryptoKeyUploadService := &services.CryptoKeyUploadService{ + VaultConnector: vaultConnector, + CryptoKeyRepo: ctx.CryptoKeyRepo, + } + + // Prepare test file + testFilePath := "testfile.pem" + testFileContent := []byte("This is a test file content.") + err = createTestFile(testFilePath, testFileContent) + require.NoError(t, err, "Error creating test file") + defer removeTestFile(testFilePath) + + // Call the method under test + userId := uuid.New().String() + keyType := "private" + keyAlgorithm := "EC" + cryptoKeyMeta, err := cryptoKeyUploadService.Upload(testFilePath, userId, keyType, keyAlgorithm) + require.NoError(t, err, "Error uploading file") + + // Set up the CryptoKeyDownloadService + cryptoKeyDownloadService := &services.CryptoKeyDownloadService{ + VaultConnector: vaultConnector, + } + + // Call the method under test + blobData, err := cryptoKeyDownloadService.Download(cryptoKeyMeta.ID, keyType) + + // Assert that no error occurred during download + require.NoError(t, err, "Error downloading cryptographic key") + + // Assert that blobData is not nil or empty + require.NotNil(t, blobData, "Downloaded key data should not be nil") + require.NotEmpty(t, blobData, "Downloaded key data should not be empty") +} From 40449ed753f1460d15c599134368c09278369a38 Mon Sep 17 00:00:00 2001 From: root Date: Thu, 21 Nov 2024 16:41:10 +0000 Subject: [PATCH 27/29] fix linter findings --- test/integration/app/services/key_services_test.go | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/test/integration/app/services/key_services_test.go b/test/integration/app/services/key_services_test.go index 685970e..fbc21bd 100644 --- a/test/integration/app/services/key_services_test.go +++ b/test/integration/app/services/key_services_test.go @@ -59,7 +59,10 @@ func TestCryptoKeyUploadService_Upload_Success(t *testing.T) { testFileContent := []byte("This is a test file content.") err = createTestFile(testFilePath, testFileContent) require.NoError(t, err, "Error creating test file") - defer removeTestFile(testFilePath) + defer func() { + err := removeTestFile(testFilePath) + require.NoError(t, err, "Error deleting test file") + }() // Call the method under test userId := uuid.New().String() @@ -185,7 +188,10 @@ func TestCryptoKeyDownloadService_Download_Success(t *testing.T) { testFileContent := []byte("This is a test file content.") err = createTestFile(testFilePath, testFileContent) require.NoError(t, err, "Error creating test file") - defer removeTestFile(testFilePath) + defer func() { + err := removeTestFile(testFilePath) + require.NoError(t, err, "Error deleting test file") + }() // Call the method under test userId := uuid.New().String() From 7da7a1cf0b53875b1eaaa83ee5f336d5cbe90109 Mon Sep 17 00:00:00 2001 From: root Date: Thu, 21 Nov 2024 16:55:55 +0000 Subject: [PATCH 28/29] add folder dedicated to helpers for e.g. mocks, DB setup --- test/{unit/app/services => helpers}/mocks.go | 2 +- .../test_db_context.go} | 10 +- .../app/services/key_services_test.go | 17 +-- .../app/services/test_repository_context.go | 121 ------------------ .../repository/psql_blob_repository_test.go | 10 +- .../repository/sqlite_blob_repository_test.go | 10 +- .../repository/sqlite_key_repository_test.go | 18 +-- .../app/services/blob_services_mock_test.go | 12 +- 8 files changed, 44 insertions(+), 156 deletions(-) rename test/{unit/app/services => helpers}/mocks.go (99%) rename test/{integration/persistence/repository/test_repository_context.go => helpers/test_db_context.go} (93%) delete mode 100644 test/integration/app/services/test_repository_context.go diff --git a/test/unit/app/services/mocks.go b/test/helpers/mocks.go similarity index 99% rename from test/unit/app/services/mocks.go rename to test/helpers/mocks.go index e5f0b6c..6010f5a 100644 --- a/test/unit/app/services/mocks.go +++ b/test/helpers/mocks.go @@ -1,4 +1,4 @@ -package services +package helpers import ( "crypto_vault_service/internal/domain/blobs" diff --git a/test/integration/persistence/repository/test_repository_context.go b/test/helpers/test_db_context.go similarity index 93% rename from test/integration/persistence/repository/test_repository_context.go rename to test/helpers/test_db_context.go index 10fca05..7eeacc1 100644 --- a/test/integration/persistence/repository/test_repository_context.go +++ b/test/helpers/test_db_context.go @@ -1,4 +1,4 @@ -package repository +package helpers import ( "crypto_vault_service/internal/domain/blobs" @@ -13,14 +13,14 @@ import ( "gorm.io/gorm" ) -type TestRepositoryContext struct { +type TestDBContext struct { DB *gorm.DB BlobRepo *repository.GormBlobRepository CryptoKeyRepo *repository.GormCryptoKeyRepository } // SetupTestDB initializes the test database and repositories based on the DB_TYPE environment variable -func SetupTestDB(t *testing.T) *TestRepositoryContext { +func SetupTestDB(t *testing.T) *TestDBContext { var err error var db *gorm.DB @@ -90,7 +90,7 @@ func SetupTestDB(t *testing.T) *TestRepositoryContext { blobRepo := &repository.GormBlobRepository{DB: db} cryptoKeyRepo := &repository.GormCryptoKeyRepository{DB: db} - return &TestRepositoryContext{ + return &TestDBContext{ DB: db, BlobRepo: blobRepo, CryptoKeyRepo: cryptoKeyRepo, @@ -98,7 +98,7 @@ func SetupTestDB(t *testing.T) *TestRepositoryContext { } // TeardownTestDB closes the DB connection after the test -func TeardownTestDB(t *testing.T, ctx *TestRepositoryContext) { +func TeardownTestDB(t *testing.T, ctx *TestDBContext) { sqlDB, err := ctx.DB.DB() if err != nil { t.Fatalf("Failed to get DB connection: %v", err) diff --git a/test/integration/app/services/key_services_test.go b/test/integration/app/services/key_services_test.go index fbc21bd..0b617a4 100644 --- a/test/integration/app/services/key_services_test.go +++ b/test/integration/app/services/key_services_test.go @@ -4,6 +4,7 @@ import ( "crypto_vault_service/internal/app/services" "crypto_vault_service/internal/domain/keys" "crypto_vault_service/internal/infrastructure/connector" + "crypto_vault_service/test/helpers" "fmt" "os" "testing" @@ -39,8 +40,8 @@ func TestCryptoKeyUploadService_Upload_Success(t *testing.T) { require.NoError(t, err, "Error setting environment variable") // Set up test context and ensure proper teardown - ctx := setupTestDB(t) - defer teardownTestDB(t, ctx) + ctx := helpers.SetupTestDB(t) + defer helpers.TeardownTestDB(t, ctx) // Initialize Vault Connector connectionString := "DefaultEndpointsProtocol=http;AccountName=devstoreaccount1;AccountKey=Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==;BlobEndpoint=http://127.0.0.1:10000/devstoreaccount1;" @@ -86,8 +87,8 @@ func TestCryptoKeyMetadataService_GetByID_Success(t *testing.T) { require.NoError(t, err, "Error setting environment variable") // Set up test context and ensure proper teardown - ctx := setupTestDB(t) - defer teardownTestDB(t, ctx) + ctx := helpers.SetupTestDB(t) + defer helpers.TeardownTestDB(t, ctx) // Create a key metadata instance in the database for testing cryptoKeyMeta := &keys.CryptoKeyMeta{ @@ -127,8 +128,8 @@ func TestCryptoKeyMetadataService_DeleteByID_Success(t *testing.T) { require.NoError(t, err, "Error setting environment variable") // Set up test context and ensure proper teardown - ctx := setupTestDB(t) - defer teardownTestDB(t, ctx) + ctx := helpers.SetupTestDB(t) + defer helpers.TeardownTestDB(t, ctx) // Create a key metadata instance in the database for testing cryptoKeyMeta := &keys.CryptoKeyMeta{ @@ -168,8 +169,8 @@ func TestCryptoKeyDownloadService_Download_Success(t *testing.T) { require.NoError(t, err, "Error setting environment variable") // Set up test context and ensure proper teardown - ctx := setupTestDB(t) - defer teardownTestDB(t, ctx) + ctx := helpers.SetupTestDB(t) + defer helpers.TeardownTestDB(t, ctx) // Initialize Vault Connector connectionString := "DefaultEndpointsProtocol=http;AccountName=devstoreaccount1;AccountKey=Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==;BlobEndpoint=http://127.0.0.1:10000/devstoreaccount1;" diff --git a/test/integration/app/services/test_repository_context.go b/test/integration/app/services/test_repository_context.go deleted file mode 100644 index 83c3fb9..0000000 --- a/test/integration/app/services/test_repository_context.go +++ /dev/null @@ -1,121 +0,0 @@ -package services - -import ( - "crypto_vault_service/internal/domain/blobs" - "crypto_vault_service/internal/domain/keys" - "crypto_vault_service/internal/persistence/repository" - "fmt" - "os" - "testing" - - "gorm.io/driver/postgres" - "gorm.io/driver/sqlite" - "gorm.io/gorm" -) - -// TestRepositoryContext struct to hold DB and repositories for each test -type TestRepositoryContext struct { - DB *gorm.DB - BlobRepo *repository.GormBlobRepository - CryptoKeyRepo *repository.GormCryptoKeyRepository -} - -// Setup function to initialize the test DB and repositories -func setupTestDB(t *testing.T) *TestRepositoryContext { - var err error - var db *gorm.DB - - // Check for the DB type to use (SQLite in-memory or PostgreSQL) - dbType := os.Getenv("DB_TYPE") - if dbType == "" { - // Default to SQLite in-memory if DB_TYPE is not set - dbType = "sqlite" - } - - switch dbType { - case "postgres": - // Setup PostgreSQL connection - dsn := "user=postgres password=postgres host=localhost port=5432 sslmode=disable" - if dsn == "" { - t.Fatalf("POSTGRES_DSN environment variable is not set") - } - - db, err = gorm.Open(postgres.Open(dsn), &gorm.Config{}) - if err != nil { - t.Fatalf("Failed to connect to PostgreSQL: %v", err) - } - - // Check if the `blobs` database exists - sqlDB, err := db.DB() - if err != nil { - t.Fatalf("Failed to get raw DB connection: %v", err) - } - - // Query to check if the `blobs` database exists - var dbExists bool - err = sqlDB.QueryRow("SELECT 1 FROM pg_database WHERE datname = 'blobs'").Scan(&dbExists) - if err != nil { - if err.Error() != "sql: no rows in result set" { - t.Fatalf("Failed to check if database exists: %v", err) - } - // The database does not exist, create it - _, err = sqlDB.Exec("CREATE DATABASE blobs") - if err != nil { - t.Fatalf("Failed to create database: %v", err) - } - fmt.Println("Database 'blobs' created successfully.") - } - - // Now, open a connection to the `blobs` database - dsn = "user=postgres password=postgres host=localhost port=5432 dbname=blobs sslmode=disable" - db, err = gorm.Open(postgres.Open(dsn), &gorm.Config{}) - if err != nil { - t.Fatalf("Failed to connect to PostgreSQL database 'blobs': %v", err) - } - - case "sqlite": - // Setup SQLite in-memory connection - db, err = gorm.Open(sqlite.Open(":memory:"), &gorm.Config{}) - if err != nil { - t.Fatalf("Failed to connect to SQLite: %v", err) - } - - default: - t.Fatalf("Unsupported DB_TYPE value: %s", dbType) - } - - // Migrate the schema for Blob and CryptoKey - err = db.AutoMigrate(&blobs.BlobMeta{}, &keys.CryptoKeyMeta{}) - if err != nil { - t.Fatalf("Failed to migrate schema: %v", err) - } - - // Initialize the repositories with the DB instance - blobRepo := &repository.GormBlobRepository{DB: db} - cryptoKeyRepo := &repository.GormCryptoKeyRepository{DB: db} - - return &TestRepositoryContext{ - DB: db, - BlobRepo: blobRepo, - CryptoKeyRepo: cryptoKeyRepo, - } -} - -// Teardown function to clean up after tests (optional, for DB cleanup) -func teardownTestDB(t *testing.T, ctx *TestRepositoryContext) { - sqlDB, err := ctx.DB.DB() - if err != nil { - t.Fatalf("Failed to get DB connection: %v", err) - } - sqlDB.Close() -} - -// TestMain setup and teardown for the entire test suite -func TestMain(m *testing.M) { - // Run tests - code := m.Run() - // Exit with the test result code - if code != 0 { - fmt.Println("Tests failed.") - } -} diff --git a/test/integration/persistence/repository/psql_blob_repository_test.go b/test/integration/persistence/repository/psql_blob_repository_test.go index a08f64a..c8e9e94 100644 --- a/test/integration/persistence/repository/psql_blob_repository_test.go +++ b/test/integration/persistence/repository/psql_blob_repository_test.go @@ -4,6 +4,8 @@ package repository import ( "crypto_vault_service/internal/domain/blobs" "crypto_vault_service/internal/domain/keys" + "crypto_vault_service/test/helpers" + "os" "testing" "time" @@ -19,8 +21,8 @@ func TestBlobPsqlRepository_Create(t *testing.T) { } // Set up test context - ctx := SetupTestDB(t) - defer TeardownTestDB(t, ctx) + ctx := helpers.SetupTestDB(t) + defer helpers.TeardownTestDB(t, ctx) // Create a valid CryptoKey object cryptographicKey := keys.CryptoKeyMeta{ @@ -62,8 +64,8 @@ func TestBlobPsqlRepository_GetById(t *testing.T) { } // Set up test context - ctx := SetupTestDB(t) - defer TeardownTestDB(t, ctx) + ctx := helpers.SetupTestDB(t) + defer helpers.TeardownTestDB(t, ctx) // Create a valid CryptoKey object cryptographicKey := keys.CryptoKeyMeta{ diff --git a/test/integration/persistence/repository/sqlite_blob_repository_test.go b/test/integration/persistence/repository/sqlite_blob_repository_test.go index ecdf572..4c80758 100644 --- a/test/integration/persistence/repository/sqlite_blob_repository_test.go +++ b/test/integration/persistence/repository/sqlite_blob_repository_test.go @@ -4,6 +4,8 @@ package repository import ( "crypto_vault_service/internal/domain/blobs" "crypto_vault_service/internal/domain/keys" + "crypto_vault_service/test/helpers" + "os" "testing" "time" @@ -19,8 +21,8 @@ func TestBlobSqliteRepository_Create(t *testing.T) { } // Set up test context - ctx := SetupTestDB(t) - defer TeardownTestDB(t, ctx) + ctx := helpers.SetupTestDB(t) + defer helpers.TeardownTestDB(t, ctx) // Create a valid CryptoKey object cryptographicKey := keys.CryptoKeyMeta{ @@ -62,8 +64,8 @@ func TestBlobSqliteRepository_GetById(t *testing.T) { } // Set up test context - ctx := SetupTestDB(t) - defer TeardownTestDB(t, ctx) + ctx := helpers.SetupTestDB(t) + defer helpers.TeardownTestDB(t, ctx) // Create a valid CryptoKey object cryptographicKey := keys.CryptoKeyMeta{ diff --git a/test/integration/persistence/repository/sqlite_key_repository_test.go b/test/integration/persistence/repository/sqlite_key_repository_test.go index 0548ff8..9a2342c 100644 --- a/test/integration/persistence/repository/sqlite_key_repository_test.go +++ b/test/integration/persistence/repository/sqlite_key_repository_test.go @@ -2,6 +2,8 @@ package repository import ( "crypto_vault_service/internal/domain/keys" + "crypto_vault_service/test/helpers" + "os" "testing" "time" @@ -19,8 +21,8 @@ func TestCryptoKeySqliteRepository_Create(t *testing.T) { } // Set up test context - ctx := SetupTestDB(t) - defer TeardownTestDB(t, ctx) + ctx := helpers.SetupTestDB(t) + defer helpers.TeardownTestDB(t, ctx) // Create a valid CryptoKey object cryptoKeyMeta := &keys.CryptoKeyMeta{ @@ -51,8 +53,8 @@ func TestCryptoKeySqliteRepository_GetByID(t *testing.T) { } // Set up test context - ctx := SetupTestDB(t) - defer TeardownTestDB(t, ctx) + ctx := helpers.SetupTestDB(t) + defer helpers.TeardownTestDB(t, ctx) // Create a valid CryptoKey object cryptoKeyMeta := &keys.CryptoKeyMeta{ @@ -82,8 +84,8 @@ func TestCryptoKeySqliteRepository_UpdateByID(t *testing.T) { } // Set up test context - ctx := SetupTestDB(t) - defer TeardownTestDB(t, ctx) + ctx := helpers.SetupTestDB(t) + defer helpers.TeardownTestDB(t, ctx) // Create a valid CryptoKey object cryptoKeyMeta := &keys.CryptoKeyMeta{ @@ -113,8 +115,8 @@ func TestCryptoKeySqliteRepository_UpdateByID(t *testing.T) { // TestCryptoKeySqliteRepository_DeleteByID tests the DeleteByID method of GormCryptoKeyRepository func TestCryptoKeySqliteRepository_DeleteByID(t *testing.T) { // Set up test context - ctx := SetupTestDB(t) - defer TeardownTestDB(t, ctx) + ctx := helpers.SetupTestDB(t) + defer helpers.TeardownTestDB(t, ctx) // Create a valid CryptoKey object cryptoKeyMeta := &keys.CryptoKeyMeta{ diff --git a/test/unit/app/services/blob_services_mock_test.go b/test/unit/app/services/blob_services_mock_test.go index 8cc9f8a..464f6e8 100644 --- a/test/unit/app/services/blob_services_mock_test.go +++ b/test/unit/app/services/blob_services_mock_test.go @@ -3,6 +3,8 @@ package services import ( "crypto_vault_service/internal/app/services" "crypto_vault_service/internal/domain/blobs" + "crypto_vault_service/test/helpers" + "fmt" "testing" @@ -12,8 +14,8 @@ import ( func TestBlobUploadService_Upload(t *testing.T) { // Prepare mock dependencies - mockBlobConnector := new(MockBlobConnector) - mockBlobRepository := new(MockBlobRepository) + mockBlobConnector := new(helpers.MockBlobConnector) + mockBlobRepository := new(helpers.MockBlobRepository) // Initialize the service with mock dependencies service := services.NewBlobUploadService(mockBlobConnector, mockBlobRepository) @@ -73,8 +75,8 @@ func TestBlobUploadService_Upload(t *testing.T) { func TestBlobMetadataService(t *testing.T) { // Prepare mock dependencies - mockBlobConnector := new(MockBlobConnector) - mockBlobRepository := new(MockBlobRepository) + mockBlobConnector := new(helpers.MockBlobConnector) + mockBlobRepository := new(helpers.MockBlobRepository) // Initialize the service with mock dependencies metadataService := services.NewBlobMetadataService(mockBlobRepository, mockBlobConnector) @@ -104,7 +106,7 @@ func TestBlobMetadataService(t *testing.T) { func TestBlobDownloadService(t *testing.T) { // Prepare mock dependencies - mockBlobConnector := new(MockBlobConnector) + mockBlobConnector := new(helpers.MockBlobConnector) // Initialize the service with mock dependencies downloadService := services.NewBlobDownloadService(mockBlobConnector) From e2adaff60ba4c5e297172a36c41d8a3c098305bf Mon Sep 17 00:00:00 2001 From: root Date: Thu, 21 Nov 2024 17:09:17 +0000 Subject: [PATCH 29/29] refactor db context helper to consider unique database names --- test/helpers/test_db_context.go | 60 +++++++++++++------ .../app/services/key_services_test.go | 40 +++++-------- .../repository/psql_blob_repository_test.go | 21 ++----- .../repository/sqlite_blob_repository_test.go | 21 ++----- .../repository/sqlite_key_repository_test.go | 34 ++++------- 5 files changed, 78 insertions(+), 98 deletions(-) diff --git a/test/helpers/test_db_context.go b/test/helpers/test_db_context.go index 7eeacc1..2e6a176 100644 --- a/test/helpers/test_db_context.go +++ b/test/helpers/test_db_context.go @@ -8,6 +8,7 @@ import ( "os" "testing" + "github.com/google/uuid" "gorm.io/driver/postgres" "gorm.io/driver/sqlite" "gorm.io/gorm" @@ -37,37 +38,33 @@ func SetupTestDB(t *testing.T) *TestDBContext { t.Fatalf("POSTGRES_DSN environment variable is not set") } + // Connect to PostgreSQL without specifying a database (so we can create one if necessary) db, err = gorm.Open(postgres.Open(dsn), &gorm.Config{}) if err != nil { t.Fatalf("Failed to connect to PostgreSQL: %v", err) } - // Ensure the `blobs` database exists + // Generate a unique database name using UUID + uniqueDBName := "blobs_" + uuid.New().String() + + // Ensure the unique `blobs` database exists, create if necessary sqlDB, err := db.DB() if err != nil { t.Fatalf("Failed to get raw DB connection: %v", err) } - // Query to check if the `blobs` database exists - var dbExists bool - err = sqlDB.QueryRow("SELECT 1 FROM pg_database WHERE datname = 'blobs'").Scan(&dbExists) + // Create the new database + _, err = sqlDB.Exec(fmt.Sprintf("CREATE DATABASE %s", uniqueDBName)) if err != nil { - if err.Error() != "sql: no rows in result set" { - t.Fatalf("Failed to check if database exists: %v", err) - } - // The database does not exist, create it - _, err = sqlDB.Exec("CREATE DATABASE blobs") - if err != nil { - t.Fatalf("Failed to create database: %v", err) - } - fmt.Println("Database 'blobs' created successfully.") + t.Fatalf("Failed to create database '%s': %v", uniqueDBName, err) } + fmt.Printf("Database '%s' created successfully.\n", uniqueDBName) - // Open the connection to `blobs` database - dsn = "user=postgres password=postgres host=localhost port=5432 dbname=blobs sslmode=disable" + // Now that the unique `blobs` database is created, connect to it + dsn = fmt.Sprintf("user=postgres password=postgres host=localhost port=5432 dbname=%s sslmode=disable", uniqueDBName) db, err = gorm.Open(postgres.Open(dsn), &gorm.Config{}) if err != nil { - t.Fatalf("Failed to connect to PostgreSQL database 'blobs': %v", err) + t.Fatalf("Failed to connect to PostgreSQL database '%s': %v", uniqueDBName, err) } case "sqlite": @@ -97,11 +94,36 @@ func SetupTestDB(t *testing.T) *TestDBContext { } } -// TeardownTestDB closes the DB connection after the test -func TeardownTestDB(t *testing.T, ctx *TestDBContext) { +// TeardownTestDB closes the DB connection and cleans up the database after the test +func TeardownTestDB(t *testing.T, ctx *TestDBContext, dbType string) { sqlDB, err := ctx.DB.DB() if err != nil { t.Fatalf("Failed to get DB connection: %v", err) } - sqlDB.Close() + + // If using PostgreSQL, drop the unique database created during the test + if dbType == "postgres" { + // Get the database name from the DSN or context (you might store it during DB setup) + databaseName := ctx.DB.Migrator().CurrentDatabase() + + // Close the current DB connection before dropping the database + sqlDB.Close() + + // Connect again to PostgreSQL without specifying a database (connect to the default one) + dsn := "user=postgres password=postgres host=localhost port=5432 sslmode=disable" + db, err := gorm.Open(postgres.Open(dsn), &gorm.Config{}) + if err != nil { + t.Fatalf("Failed to reconnect to PostgreSQL: %v", err) + } + + // Drop the unique database + tx := db.Exec(fmt.Sprintf("DROP DATABASE IF EXISTS %s", databaseName)) + if tx.Error != nil { + t.Fatalf("Failed to drop database '%s': %v", databaseName, tx.Error) + } + fmt.Printf("Database '%s' dropped successfully.\n", databaseName) + } else { + // For SQLite, no need to drop the in-memory database, just close the connection + sqlDB.Close() + } } diff --git a/test/integration/app/services/key_services_test.go b/test/integration/app/services/key_services_test.go index 0b617a4..c093e01 100644 --- a/test/integration/app/services/key_services_test.go +++ b/test/integration/app/services/key_services_test.go @@ -35,13 +35,10 @@ func removeTestFile(testFilePath string) error { // Test case for successful file upload and metadata creation func TestCryptoKeyUploadService_Upload_Success(t *testing.T) { - // Set up environment variable - err := os.Setenv("DB_TYPE", "postgres") - require.NoError(t, err, "Error setting environment variable") - - // Set up test context and ensure proper teardown + // Set up test context ctx := helpers.SetupTestDB(t) - defer helpers.TeardownTestDB(t, ctx) + dbType := "sqlite" + defer helpers.TeardownTestDB(t, ctx, dbType) // Initialize Vault Connector connectionString := "DefaultEndpointsProtocol=http;AccountName=devstoreaccount1;AccountKey=Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==;BlobEndpoint=http://127.0.0.1:10000/devstoreaccount1;" @@ -82,13 +79,10 @@ func TestCryptoKeyUploadService_Upload_Success(t *testing.T) { // Test case for successful retrieval of cryptographic key metadata by ID func TestCryptoKeyMetadataService_GetByID_Success(t *testing.T) { - // Set up environment variable - err := os.Setenv("DB_TYPE", "postgres") - require.NoError(t, err, "Error setting environment variable") - - // Set up test context and ensure proper teardown + // Set up test context ctx := helpers.SetupTestDB(t) - defer helpers.TeardownTestDB(t, ctx) + dbType := "sqlite" + defer helpers.TeardownTestDB(t, ctx, dbType) // Create a key metadata instance in the database for testing cryptoKeyMeta := &keys.CryptoKeyMeta{ @@ -100,7 +94,7 @@ func TestCryptoKeyMetadataService_GetByID_Success(t *testing.T) { } // Store the cryptographic key metadata in the database - err = ctx.CryptoKeyRepo.Create(cryptoKeyMeta) + err := ctx.CryptoKeyRepo.Create(cryptoKeyMeta) require.NoError(t, err, "Error creating test cryptographic key metadata") // Set up the CryptoKeyMetadataService @@ -123,13 +117,10 @@ func TestCryptoKeyMetadataService_GetByID_Success(t *testing.T) { // Test case for successful deletion of cryptographic key metadata by ID func TestCryptoKeyMetadataService_DeleteByID_Success(t *testing.T) { - // Set up environment variable - err := os.Setenv("DB_TYPE", "postgres") - require.NoError(t, err, "Error setting environment variable") - - // Set up test context and ensure proper teardown + // Set up test context ctx := helpers.SetupTestDB(t) - defer helpers.TeardownTestDB(t, ctx) + dbType := "sqlite" + defer helpers.TeardownTestDB(t, ctx, dbType) // Create a key metadata instance in the database for testing cryptoKeyMeta := &keys.CryptoKeyMeta{ @@ -141,7 +132,7 @@ func TestCryptoKeyMetadataService_DeleteByID_Success(t *testing.T) { } // Store the cryptographic key metadata in the database - err = ctx.CryptoKeyRepo.Create(cryptoKeyMeta) + err := ctx.CryptoKeyRepo.Create(cryptoKeyMeta) require.NoError(t, err, "Error creating test cryptographic key metadata") // Set up the CryptoKeyMetadataService @@ -164,13 +155,10 @@ func TestCryptoKeyMetadataService_DeleteByID_Success(t *testing.T) { // Test case for successful download of cryptographic key func TestCryptoKeyDownloadService_Download_Success(t *testing.T) { - // Set up environment variable - err := os.Setenv("DB_TYPE", "postgres") - require.NoError(t, err, "Error setting environment variable") - - // Set up test context and ensure proper teardown + // Set up test context ctx := helpers.SetupTestDB(t) - defer helpers.TeardownTestDB(t, ctx) + dbType := "sqlite" + defer helpers.TeardownTestDB(t, ctx, dbType) // Initialize Vault Connector connectionString := "DefaultEndpointsProtocol=http;AccountName=devstoreaccount1;AccountKey=Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==;BlobEndpoint=http://127.0.0.1:10000/devstoreaccount1;" diff --git a/test/integration/persistence/repository/psql_blob_repository_test.go b/test/integration/persistence/repository/psql_blob_repository_test.go index c8e9e94..3b1b65e 100644 --- a/test/integration/persistence/repository/psql_blob_repository_test.go +++ b/test/integration/persistence/repository/psql_blob_repository_test.go @@ -6,7 +6,6 @@ import ( "crypto_vault_service/internal/domain/keys" "crypto_vault_service/test/helpers" - "os" "testing" "time" @@ -15,14 +14,10 @@ import ( ) func TestBlobPsqlRepository_Create(t *testing.T) { - err := os.Setenv("DB_TYPE", "postgres") - if err != nil { - t.Fatalf("Error setting environment variable: %v", err) - } - // Set up test context ctx := helpers.SetupTestDB(t) - defer helpers.TeardownTestDB(t, ctx) + dbType := "postgres" + defer helpers.TeardownTestDB(t, ctx, dbType) // Create a valid CryptoKey object cryptographicKey := keys.CryptoKeyMeta{ @@ -46,7 +41,7 @@ func TestBlobPsqlRepository_Create(t *testing.T) { } // Call the Create method - err = ctx.BlobRepo.Create(blob) + err := ctx.BlobRepo.Create(blob) assert.NoError(t, err, "Create should not return an error") // Verify the blob is created and exists in DB @@ -58,14 +53,10 @@ func TestBlobPsqlRepository_Create(t *testing.T) { } func TestBlobPsqlRepository_GetById(t *testing.T) { - err := os.Setenv("DB_TYPE", "postgres") - if err != nil { - t.Fatalf("Error setting environment variable: %v", err) - } - // Set up test context ctx := helpers.SetupTestDB(t) - defer helpers.TeardownTestDB(t, ctx) + dbType := "postgres" + defer helpers.TeardownTestDB(t, ctx, dbType) // Create a valid CryptoKey object cryptographicKey := keys.CryptoKeyMeta{ @@ -89,7 +80,7 @@ func TestBlobPsqlRepository_GetById(t *testing.T) { } // Create the blob in DB - err = ctx.BlobRepo.Create(blob) + err := ctx.BlobRepo.Create(blob) assert.NoError(t, err, "Create should not return an error") // Get the blob by ID diff --git a/test/integration/persistence/repository/sqlite_blob_repository_test.go b/test/integration/persistence/repository/sqlite_blob_repository_test.go index 4c80758..a09731c 100644 --- a/test/integration/persistence/repository/sqlite_blob_repository_test.go +++ b/test/integration/persistence/repository/sqlite_blob_repository_test.go @@ -6,7 +6,6 @@ import ( "crypto_vault_service/internal/domain/keys" "crypto_vault_service/test/helpers" - "os" "testing" "time" @@ -15,14 +14,10 @@ import ( ) func TestBlobSqliteRepository_Create(t *testing.T) { - err := os.Setenv("DB_TYPE", "sqlite") - if err != nil { - t.Fatalf("Error setting environment variable: %v", err) - } - // Set up test context ctx := helpers.SetupTestDB(t) - defer helpers.TeardownTestDB(t, ctx) + dbType := "sqlite" + defer helpers.TeardownTestDB(t, ctx, dbType) // Create a valid CryptoKey object cryptographicKey := keys.CryptoKeyMeta{ @@ -46,7 +41,7 @@ func TestBlobSqliteRepository_Create(t *testing.T) { } // Call the Create method - err = ctx.BlobRepo.Create(blob) + err := ctx.BlobRepo.Create(blob) assert.NoError(t, err, "Create should not return an error") // Verify the blob is created and exists in DB @@ -58,14 +53,10 @@ func TestBlobSqliteRepository_Create(t *testing.T) { } func TestBlobSqliteRepository_GetById(t *testing.T) { - err := os.Setenv("DB_TYPE", "sqlite") - if err != nil { - t.Fatalf("Error setting environment variable: %v", err) - } - // Set up test context ctx := helpers.SetupTestDB(t) - defer helpers.TeardownTestDB(t, ctx) + dbType := "sqlite" + defer helpers.TeardownTestDB(t, ctx, dbType) // Create a valid CryptoKey object cryptographicKey := keys.CryptoKeyMeta{ @@ -89,7 +80,7 @@ func TestBlobSqliteRepository_GetById(t *testing.T) { } // Create the blob in DB - err = ctx.BlobRepo.Create(blob) + err := ctx.BlobRepo.Create(blob) assert.NoError(t, err, "Create should not return an error") // Get the blob by ID diff --git a/test/integration/persistence/repository/sqlite_key_repository_test.go b/test/integration/persistence/repository/sqlite_key_repository_test.go index 9a2342c..e0de2cc 100644 --- a/test/integration/persistence/repository/sqlite_key_repository_test.go +++ b/test/integration/persistence/repository/sqlite_key_repository_test.go @@ -4,7 +4,6 @@ import ( "crypto_vault_service/internal/domain/keys" "crypto_vault_service/test/helpers" - "os" "testing" "time" @@ -15,14 +14,10 @@ import ( // TestCryptoKeySqliteRepository_Create tests the Create method of GormCryptoKeyRepository func TestCryptoKeySqliteRepository_Create(t *testing.T) { - err := os.Setenv("DB_TYPE", "sqlite") - if err != nil { - t.Fatalf("Error setting environment variable: %v", err) - } - // Set up test context ctx := helpers.SetupTestDB(t) - defer helpers.TeardownTestDB(t, ctx) + dbType := "sqlite" + defer helpers.TeardownTestDB(t, ctx, dbType) // Create a valid CryptoKey object cryptoKeyMeta := &keys.CryptoKeyMeta{ @@ -34,7 +29,7 @@ func TestCryptoKeySqliteRepository_Create(t *testing.T) { } // Create the cryptographic key in DB - err = ctx.CryptoKeyRepo.Create(cryptoKeyMeta) + err := ctx.CryptoKeyRepo.Create(cryptoKeyMeta) assert.NoError(t, err, "Create should not return an error") // Verify the cryptographic key is created and exists in DB @@ -47,14 +42,10 @@ func TestCryptoKeySqliteRepository_Create(t *testing.T) { // TestCryptoKeySqliteRepository_GetByID tests the GetByID method of GormCryptoKeyRepository func TestCryptoKeySqliteRepository_GetByID(t *testing.T) { - err := os.Setenv("DB_TYPE", "sqlite") - if err != nil { - t.Fatalf("Error setting environment variable: %v", err) - } - // Set up test context ctx := helpers.SetupTestDB(t) - defer helpers.TeardownTestDB(t, ctx) + dbType := "sqlite" + defer helpers.TeardownTestDB(t, ctx, dbType) // Create a valid CryptoKey object cryptoKeyMeta := &keys.CryptoKeyMeta{ @@ -66,7 +57,7 @@ func TestCryptoKeySqliteRepository_GetByID(t *testing.T) { } // Create the cryptographic key in DB - err = ctx.CryptoKeyRepo.Create(cryptoKeyMeta) + err := ctx.CryptoKeyRepo.Create(cryptoKeyMeta) assert.NoError(t, err, "Create should not return an error") // Get the cryptographic key by ID @@ -78,14 +69,10 @@ func TestCryptoKeySqliteRepository_GetByID(t *testing.T) { // TestCryptoKeySqliteRepository_UpdateByID tests the UpdateByID method of GormCryptoKeyRepository func TestCryptoKeySqliteRepository_UpdateByID(t *testing.T) { - err := os.Setenv("DB_TYPE", "sqlite") - if err != nil { - t.Fatalf("Error setting environment variable: %v", err) - } - // Set up test context ctx := helpers.SetupTestDB(t) - defer helpers.TeardownTestDB(t, ctx) + dbType := "sqlite" + defer helpers.TeardownTestDB(t, ctx, dbType) // Create a valid CryptoKey object cryptoKeyMeta := &keys.CryptoKeyMeta{ @@ -97,7 +84,7 @@ func TestCryptoKeySqliteRepository_UpdateByID(t *testing.T) { } // Create the cryptographic key in DB - err = ctx.CryptoKeyRepo.Create(cryptoKeyMeta) + err := ctx.CryptoKeyRepo.Create(cryptoKeyMeta) assert.NoError(t, err, "Create should not return an error") // Update the cryptographic key's type @@ -116,7 +103,8 @@ func TestCryptoKeySqliteRepository_UpdateByID(t *testing.T) { func TestCryptoKeySqliteRepository_DeleteByID(t *testing.T) { // Set up test context ctx := helpers.SetupTestDB(t) - defer helpers.TeardownTestDB(t, ctx) + dbType := "sqlite" + defer helpers.TeardownTestDB(t, ctx, dbType) // Create a valid CryptoKey object cryptoKeyMeta := &keys.CryptoKeyMeta{