Skip to content

Commit

Permalink
Merge pull request #18 from MGTheTrain/opt/general
Browse files Browse the repository at this point in the history
Refactoring and increasing code coverage
  • Loading branch information
MGTheTrain authored Nov 21, 2024
2 parents 995e4f8 + e2adaff commit c44bf2b
Show file tree
Hide file tree
Showing 33 changed files with 779 additions and 828 deletions.
24 changes: 21 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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
docker-compose down -v
4 changes: 2 additions & 2 deletions cmd/crypto-vault-cli/internal/commands/aes-commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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 {
Expand Down
18 changes: 9 additions & 9 deletions cmd/crypto-vault-cli/internal/commands/ecdsa-commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
Expand All @@ -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)
}
Expand All @@ -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)
}
Expand All @@ -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)
}
Expand All @@ -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)
}
Expand All @@ -91,15 +91,15 @@ 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

// Read the public key
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)
}
Expand All @@ -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)
}
Expand Down
4 changes: 2 additions & 2 deletions cmd/crypto-vault-cli/internal/commands/rsa-commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)
Expand Down
7 changes: 4 additions & 3 deletions docs/diagrams/erd.mmd
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -18,4 +19,4 @@ erDiagram
string hash_algorithm
}

CRYPTOGRAPHIC_KEY ||--o| BLOB : "associated with"
CRYPTO_KEY_META ||--o| BLOB_META : "associated with"
28 changes: 13 additions & 15 deletions internal/app/services/blob_services.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,28 +25,27 @@ 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
Expand All @@ -66,27 +65,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)
}
Expand All @@ -98,9 +97,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
Expand All @@ -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
}
56 changes: 8 additions & 48 deletions internal/app/services/key_services.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,51 +5,26 @@ import (
"crypto_vault_service/internal/infrastructure/connector"
"crypto_vault_service/internal/persistence/repository"
"fmt"
"time"

"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(filePath, userId, keyType, keyAlgorihm string) (*keys.CryptoKeyMeta, error) {
// Step 1: Upload files to blob storage
userId := uuid.New().String()
blobMeta, 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
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)
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.
Expand All @@ -59,7 +34,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

Expand All @@ -68,7 +42,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)
Expand All @@ -93,24 +66,11 @@ 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

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)
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)
}

// Return the metadata and the downloaded content (as a byte slice)
return blobData, nil
}
2 changes: 1 addition & 1 deletion internal/domain/blobs/models.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
1 change: 0 additions & 1 deletion internal/domain/blobs/queries.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Loading

0 comments on commit c44bf2b

Please sign in to comment.