diff --git a/api/api_test.go b/api/api_test.go index bd18157..a020141 100644 --- a/api/api_test.go +++ b/api/api_test.go @@ -75,7 +75,7 @@ func TestCreateEntry(t *testing.T) { secretStore := secret.NewSecretStorage(connection, aes.New(key)) ctx := context.Background() - entry, err := secretStore.GetAndDelete(ctx, savedUUID) + entry, err := secretStore.Read(ctx, savedUUID) if err != nil { t.Fatal(err) @@ -120,7 +120,7 @@ func TestCreateEntryJSON(t *testing.T) { secretStore := secret.NewSecretStorage(connection, aes.New(key)) ctx := context.Background() - entry, err := secretStore.GetAndDelete(ctx, encode.UUID) + entry, err := secretStore.Read(ctx, encode.UUID) if err != nil { t.Fatal(err) @@ -202,7 +202,7 @@ func TestCreateEntryForm(t *testing.T) { secretStore := secret.NewSecretStorage(connection, aes.New(key)) ctx := context.Background() - entry, err := secretStore.GetAndDelete(ctx, savedUUID) + entry, err := secretStore.Read(ctx, savedUUID) if err != nil { t.Fatal("Getting entry", err) @@ -287,7 +287,7 @@ func TestGetEntry(t *testing.T) { } ctx := context.Background() - connection.Create(ctx, testCase.UUID, encryptedData, time.Second*10, 1) + connection.Write(ctx, testCase.UUID, encryptedData, time.Second*10, 1) req := httptest.NewRequest(http.MethodGet, fmt.Sprintf("http://example.com/%s/%s", testCase.UUID, hex.EncodeToString(rsakey)), nil) w := httptest.NewRecorder() @@ -335,7 +335,7 @@ func TestGetEntryJSON(t *testing.T) { } ctx := context.Background() - connection.Create(ctx, testCase.UUID, encryptedData, time.Second*10, 1) + connection.Write(ctx, testCase.UUID, encryptedData, time.Second*10, 1) req := httptest.NewRequest("GET", fmt.Sprintf("http://example.com/%s/%s", testCase.UUID, hex.EncodeToString(rsakey)), nil) req.Header.Add("Accept", "application/json") @@ -427,7 +427,7 @@ func TestCreateEntryWithExpiration(t *testing.T) { secretStore := secret.NewSecretStorage(connection, aes.New(decodedKey)) ctx := context.Background() - entry, err := secretStore.GetAndDelete(ctx, savedUUID) + entry, err := secretStore.Read(ctx, savedUUID) if err != nil { t.Fatal(err) @@ -493,7 +493,7 @@ func TestCreateEntryWithMaxReads(t *testing.T) { secretStore := secret.NewSecretStorage(connection, aes.New(decodedKey)) ctx := context.Background() - entry, err := secretStore.GetMeta(ctx, savedUUID) + entry, err := secretStore.ReadMeta(ctx, savedUUID) if err != nil { t.Fatal(err) diff --git a/api/create_handler.go b/api/create_handler.go index 29da1df..5b19d82 100644 --- a/api/create_handler.go +++ b/api/create_handler.go @@ -78,7 +78,7 @@ func (c CreateHandler) Handle(w http.ResponseWriter, r *http.Request) { UUID := uuid.NewUUIDString() ctx := context.Background() - err = secretStore.Create(ctx, UUID, data.body, data.expiration, data.maxReads) + err = secretStore.Write(ctx, UUID, data.body, data.expiration, data.maxReads) if err != nil { log.Println("Create secret failed", err) @@ -86,7 +86,7 @@ func (c CreateHandler) Handle(w http.ResponseWriter, r *http.Request) { return } - entry, err := secretStore.GetMeta(ctx, UUID) + entry, err := secretStore.ReadMeta(ctx, UUID) if err != nil { log.Println("Getting meta failed", err, UUID) http.Error(w, "Internal error", http.StatusInternalServerError) diff --git a/api/get_handler.go b/api/get_handler.go index f1bbba3..5748710 100644 --- a/api/get_handler.go +++ b/api/get_handler.go @@ -56,7 +56,7 @@ func handleGetSecret(entryStorage storage.Verifyable, UUID, keyString string) (* secretStore := secret.NewSecretStorage(entryStorage, aesencrypter.New(key)) ctx := context.Background() - return secretStore.GetAndDelete(ctx, UUID) + return secretStore.Read(ctx, UUID) } func sendGetSecretResponse(entry *entries.Entry, keyString string, w http.ResponseWriter, r *http.Request) { diff --git a/storage/integration/integration_test.go b/storage/integration/integration_test.go index 47179cc..f32fb35 100644 --- a/storage/integration/integration_test.go +++ b/storage/integration/integration_test.go @@ -36,15 +36,15 @@ func TestStorages(t *testing.T) { for name, storage := range storages { t.Run(name, func(t *testing.T) { - t.Run("GetMeta", func(t *testing.T) { + t.Run("ReadMeta", func(t *testing.T) { UUID := uuid.NewUUIDString() - err := storage.Create(ctx, UUID, []byte("foo"), time.Second*-10, 1) + err := storage.Write(ctx, UUID, []byte("foo"), time.Second*-10, 1) if err != nil { t.Fatal(err) } - data, err := storage.GetMeta(ctx, UUID) + data, err := storage.ReadMeta(ctx, UUID) if data != nil { t.Errorf("Expected expired data to be nil") @@ -54,15 +54,15 @@ func TestStorages(t *testing.T) { t.Errorf("Expected expire error but got %v", err) } }) - t.Run("GetAndDelete", func(t *testing.T) { + t.Run("Read", func(t *testing.T) { UUID := uuid.NewUUIDString() - err := storage.Create(ctx, UUID, []byte("foo"), time.Second*-10, 1) + err := storage.Write(ctx, UUID, []byte("foo"), time.Second*-10, 1) if err != nil { t.Fatal(err) } - data, err := storage.GetAndDelete(ctx, UUID) + data, err := storage.Read(ctx, UUID) if data != nil { t.Errorf("Expected expired data to be nil") @@ -74,7 +74,7 @@ func TestStorages(t *testing.T) { }) t.Run("Delete", func(t *testing.T) { UUID := uuid.NewUUIDString() - err := storage.Create(ctx, UUID, []byte("foo"), time.Second*-10, 1) + err := storage.Write(ctx, UUID, []byte("foo"), time.Second*-10, 1) if err != nil { t.Fatal(err) @@ -86,20 +86,20 @@ func TestStorages(t *testing.T) { t.Error(err) } - retMeta, err := storage.GetMeta(ctx, UUID) + retMeta, err := storage.ReadMeta(ctx, UUID) if err != entries.ErrEntryNotFound { - t.Errorf("Storage GetMeta should return an entry not found error, but returned %v", err) + t.Errorf("Storage ReadMeta should return an entry not found error, but returned %v", err) } if retMeta != nil { t.Errorf("Expected to not be able to retreive deleted item, but got: %v", retMeta) } - ret, err := storage.GetAndDelete(ctx, UUID) + ret, err := storage.Read(ctx, UUID) if err != entries.ErrEntryNotFound { - t.Errorf("Storage GetAndDelete should return an entry not found error, but returned %v", err) + t.Errorf("Storage Read should return an entry not found error, but returned %v", err) } if ret != nil { @@ -129,7 +129,7 @@ func TestStorages(t *testing.T) { } for _, item := range items { - err := storage.Create(ctx, item.UUID, item.Value, item.Expire, 1) + err := storage.Write(ctx, item.UUID, item.Value, item.Expire, 1) if err != nil { t.Fatal(err) @@ -141,7 +141,7 @@ func TestStorages(t *testing.T) { t.Error(err) } - ret, err := storage.GetMeta(ctx, item.UUID) + ret, err := storage.ReadMeta(ctx, item.UUID) if item.ShouldExpire { if err != entries.ErrEntryNotFound { diff --git a/storage/postgresql/postgresql_storage.go b/storage/postgresql/postgresql_storage.go index 410400c..fd3a4b7 100644 --- a/storage/postgresql/postgresql_storage.go +++ b/storage/postgresql/postgresql_storage.go @@ -25,8 +25,8 @@ func (s Storage) Close() error { return s.db.Close() } -// Create stores a new entry in database -func (s Storage) Create(ctx context.Context, UUID string, entry []byte, expire time.Duration, remainingReads int) error { +// Write stores a new entry in database +func (s Storage) Write(ctx context.Context, UUID string, entry []byte, expire time.Duration, remainingReads int) error { now := time.Now() k, err := key.NewGeneratedKey() if err != nil { @@ -38,10 +38,10 @@ func (s Storage) Create(ctx context.Context, UUID string, entry []byte, expire t return err } -// GetMeta to get entry metadata (without the actual secret) +// ReadMeta to get entry metadata (without the actual secret) // returns the metadata if the secret not expired yet // does not update read count -func (s Storage) GetMeta(ctx context.Context, UUID string) (*entries.EntryMeta, error) { +func (s Storage) ReadMeta(ctx context.Context, UUID string) (*entries.EntryMeta, error) { tx, err := s.db.BeginTx(ctx, nil) if err != nil { return nil, err @@ -200,11 +200,11 @@ func (s Storage) Get(ctx context.Context, UUID string) (*entries.Entry, error) { }, nil } -// GetAndDelete to get entry including the actual secret then delete it +// Read to get entry including the actual secret then delete it // returns the data if the secret not expired yet // updates read count // deletes the data after the read -func (s Storage) GetAndDelete(ctx context.Context, UUID string) (*entries.Entry, error) { +func (s Storage) Read(ctx context.Context, UUID string) (*entries.Entry, error) { tx, err := s.db.BeginTx(ctx, nil) if err != nil { return nil, err diff --git a/storage/postgresql/postgresql_storage_test.go b/storage/postgresql/postgresql_storage_test.go index a6c2096..72d56c0 100644 --- a/storage/postgresql/postgresql_storage_test.go +++ b/storage/postgresql/postgresql_storage_test.go @@ -10,7 +10,7 @@ import ( "github.com/Ajnasz/sekret.link/uuid" ) -// func TestPostgresqlStorageCreateGet(t *testing.T) { +// func TestPostgresqlStorageWriteGet(t *testing.T) { // psqlConn := testhelper.GetPSQLTestConn() // storage := NewStorage(psqlConn) // t.Cleanup(func() { @@ -24,7 +24,7 @@ import ( // t.Run(testCase, func(t *testing.T) { // UUID := uuid.NewUUIDString() -// err := storage.Create(UUID, []byte("foo"), time.Second*10, 1) +// err := storage.Write(UUID, []byte("foo"), time.Second*10, 1) // if err != nil { // t.Fatal(err) @@ -42,7 +42,7 @@ import ( // } // } -func TestPostgresqlStorageCreateGetAndDelete(t *testing.T) { +func TestPostgresqlStorageWrite(t *testing.T) { psqlConn := testhelper.GetPSQLTestConn() storage := NewStorage(psqlConn) t.Cleanup(func() { @@ -84,12 +84,12 @@ func TestPostgresqlStorageCreateGetAndDelete(t *testing.T) { UUID := uuid.NewUUIDString() ctx := context.Background() - err := storage.Create(ctx, UUID, []byte(testCase.Secret), time.Second*10, testCase.Reads) + err := storage.Write(ctx, UUID, []byte(testCase.Secret), time.Second*10, testCase.Reads) if err != nil { t.Fatal(err) } - res, err := storage.GetAndDelete(ctx, UUID) + res, err := storage.Read(ctx, UUID) if err != nil { t.Fatal(err) } @@ -145,7 +145,7 @@ func TestPostgresqlStorageVerifyDelete(t *testing.T) { for _, testCase := range testCases { ctx := context.Background() - err := storage.Create(ctx, testCase.UUID, []byte("foo"), time.Second*10, 1) + err := storage.Write(ctx, testCase.UUID, []byte("foo"), time.Second*10, 1) if err != testCase.ExpectedErr { t.Error(err) } diff --git a/storage/secret/secret_storage.go b/storage/secret/secret_storage.go index d67cbec..14a9361 100644 --- a/storage/secret/secret_storage.go +++ b/storage/secret/secret_storage.go @@ -21,20 +21,20 @@ func NewSecretStorage(v storage.Verifyable, e encrypter.Encrypter) *SecretStorag return &SecretStorage{v, e} } -// Create stores the encrypted secret in the VerifyStorage -func (s SecretStorage) Create(ctx context.Context, UUID string, entry []byte, expire time.Duration, remainingReads int) error { +// Write stores the encrypted secret in the VerifyStorage +func (s SecretStorage) Write(ctx context.Context, UUID string, entry []byte, expire time.Duration, remainingReads int) error { encrypted, err := s.encrypter.Encrypt(entry) if err != nil { return err } - return s.internalStorage.Create(ctx, UUID, encrypted, expire, remainingReads) + return s.internalStorage.Write(ctx, UUID, encrypted, expire, remainingReads) } -// GetMeta returns the entry's metadata -func (s SecretStorage) GetMeta(ctx context.Context, UUID string) (*entries.EntryMeta, error) { - entryMeta, err := s.internalStorage.GetMeta(ctx, UUID) +// ReadMeta returns the entry's metadata +func (s SecretStorage) ReadMeta(ctx context.Context, UUID string) (*entries.EntryMeta, error) { + entryMeta, err := s.internalStorage.ReadMeta(ctx, UUID) if err != nil { return nil, err @@ -47,9 +47,9 @@ func (s SecretStorage) GetMeta(ctx context.Context, UUID string) (*entries.Entry return entryMeta, nil } -// GetAndDelete deletes the secret from VerifyStorage -func (s SecretStorage) GetAndDelete(ctx context.Context, UUID string) (*entries.Entry, error) { - entry, err := s.internalStorage.GetAndDelete(ctx, UUID) +// Read deletes the secret from VerifyStorage +func (s SecretStorage) Read(ctx context.Context, UUID string) (*entries.Entry, error) { + entry, err := s.internalStorage.Read(ctx, UUID) if err != nil { return nil, err diff --git a/storage/secret/secret_storage_test.go b/storage/secret/secret_storage_test.go index 008be47..bd5c514 100644 --- a/storage/secret/secret_storage_test.go +++ b/storage/secret/secret_storage_test.go @@ -30,13 +30,13 @@ func TestSecretStorage(t *testing.T) { UUID := uuid.NewUUIDString() ctx := context.Background() - err := storage.Create(ctx, UUID, []byte(testData), time.Second*10, 1) + err := storage.Write(ctx, UUID, []byte(testData), time.Second*10, 1) if err != nil { t.Fatal(err) } - data, err := storage.GetAndDelete(ctx, UUID) + data, err := storage.Read(ctx, UUID) if err != nil { t.Fatal(err) diff --git a/storage/storage.go b/storage/storage.go index 6976828..c64fb16 100644 --- a/storage/storage.go +++ b/storage/storage.go @@ -7,12 +7,15 @@ import ( "github.com/Ajnasz/sekret.link/entries" ) +type Transform = func(*entries.Entry) (*entries.Entry, error) + // Reader interface to get stored entry type Reader interface { - GetAndDelete(context.Context, string) (*entries.Entry, error) - GetMeta(context.Context, string) (*entries.EntryMeta, error) - // Get(UUID string) (*entries.Entry, error) - // Closes connection to data storage, like database + // Read reads the secret and deletes from the underlying storage in one step + Read(context.Context, string) (*entries.Entry, error) + // ReadMeta reads secret meta data from the storage + ReadMeta(context.Context, string) (*entries.EntryMeta, error) + // Close Closes connection to data storage, like database // Executed on application shutdown Close() error } @@ -20,7 +23,7 @@ type Reader interface { // Writer interface to store and delete entry type Writer interface { // Writes the secret into the remote data storege - Create(ctx context.Context, UUID string, entry []byte, expiration time.Duration, maxReads int) error + Write(ctx context.Context, UUID string, entry []byte, expiration time.Duration, maxReads int) error Delete(context.Context, string) error DeleteExpired(context.Context) error // Closes connection to data storage, like database