Documentation
¶
Overview ¶
Package storage provides the persistence layer for the skladka service. It implements a PostgreSQL-based storage backend with support for:
- Storing and retrieving pastes with metadata
- Managing paste visibility (public/private)
- Handling paste expiration
- Reference generation and validation
- Content encryption for private pastes
The package uses sqlc for type-safe SQL queries and includes metrics for monitoring database operations. It also integrates with the application's observability stack for logging and tracing.
Example usage:
db, err := storage.NewPostgresStorage(ctx, cfg)
if err != nil {
return fmt.Errorf("failed to initialize storage: %w", err)
}
paste, err := db.GetPaste(ctx, reference)
if err != nil {
return fmt.Errorf("failed to retrieve paste: %w", err)
}
Index ¶
- type Cipher
- type PostgresStorage
- func (s *PostgresStorage) CreatePaste(ctx context.Context, paste paste.Paste) (reference string, err error)
- func (s *PostgresStorage) CreateSession(ctx context.Context, ssn auth.Session) (err error)
- func (s *PostgresStorage) CreateUser(ctx context.Context, user auth.User) (err error)
- func (s *PostgresStorage) DecryptPaste(ctx context.Context, paste *paste.Paste) (err error)
- func (s *PostgresStorage) DeletePaste(ctx context.Context, ref string) (err error)
- func (s *PostgresStorage) EncryptPaste(ctx context.Context, paste *paste.Paste) (err error)
- func (s *PostgresStorage) GetPaste(ctx context.Context, ref string) (paste paste.Paste, err error)
- func (s *PostgresStorage) GetPasteWithPassword(ctx context.Context, ref, password string) (*paste.Paste, error)
- func (s *PostgresStorage) GetSessionByToken(ctx context.Context, token string) (session auth.Session, err error)
- func (s *PostgresStorage) GetUserByUsername(ctx context.Context, username string) (user auth.User, err error)
- func (s *PostgresStorage) ListPastes(ctx context.Context) (pastes []paste.Paste, err error)
- func (s *PostgresStorage) ListUserPastes(ctx context.Context, username string) (pastes []paste.Paste, err error)
- func (s *PostgresStorage) UpdateUserAvatar(ctx context.Context, user auth.User) (err error)
- func (s *PostgresStorage) UpdateUserCredentials(ctx context.Context, user auth.User) (err error)
- type PostgresStorageOption
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type PostgresStorage ¶
type PostgresStorage struct {
// contains filtered or unexported fields
}
func NewPostgresStorage ¶
func NewPostgresStorage(ctx context.Context, cfg config.Config, opts ...PostgresStorageOption) (*PostgresStorage, error)
Example ¶
package main
import (
"context"
"github.com/aexvir/skladka/internal/config"
"github.com/aexvir/skladka/internal/errors"
"github.com/aexvir/skladka/internal/storage"
)
func main() error {
ctx := context.Background()
db, err := storage.NewPostgresStorage(
ctx,
config.Config{
Postgres: config.Postgres{},
},
)
if err != nil {
return errors.Wrap(err, "failed to initialize storage")
}
_, err = db.GetPaste(ctx, "abc123")
return nil
}
func (*PostgresStorage) CreatePaste ¶
func (s *PostgresStorage) CreatePaste(ctx context.Context, paste paste.Paste) (reference string, err error)
CreatePaste stores a new paste in the database. It generates a unique reference identifier, encrypts the paste content and title if needed, and hashes any provided password.
Returns:
- reference: The unique reference string used to identify the paste
- err: Any error that occurred during the operation
The method will attempt to generate a unique reference up to 10 times before failing.
func (*PostgresStorage) CreateSession ¶
CreateSession creates a new user session in the database with the provided auth.Session data. Returns an error if the database operation fails.
func (*PostgresStorage) CreateUser ¶
CreateUser creates a new user in the database with the provided auth.User data.
func (*PostgresStorage) DecryptPaste ¶
DecryptPaste decrypts both the title and content of a paste using the storage's cipher. The decryption is done in-place, modifying the provided paste object directly.
The method will attempt to decrypt both fields even if one fails, then return any errors that occurred during either operation joined together.
func (*PostgresStorage) DeletePaste ¶
func (s *PostgresStorage) DeletePaste(ctx context.Context, ref string) (err error)
func (*PostgresStorage) EncryptPaste ¶
EncryptPaste encrypts both the title and content of a paste using the storage's cipher. The encryption is done in-place, modifying the provided paste object directly.
The method will attempt to encrypt both fields even if one fails, then return any errors that occurred during either operation.
func (*PostgresStorage) GetPaste ¶
GetPaste retrieves a paste from the database using its reference identifier. It fetches the encrypted paste data and decrypts it before returning.
Returns:
- paste.Paste: The decrypted paste if found
- error: Any error that occurred during fetching or decryption
If the paste cannot be found or decrypted, returns an empty paste and the error.
func (*PostgresStorage) GetPasteWithPassword ¶
func (s *PostgresStorage) GetPasteWithPassword(ctx context.Context, ref, password string) (*paste.Paste, error)
GetPasteWithPassword retrieves a password-protected paste from storage and verifies the provided password. It first fetches the paste using the reference identifier, then checks if it's password protected and verifies the supplied password matches.
Returns:
- *paste.Paste: The paste if found and password verified, nil if password invalid
- error: Error if paste not found, has no password, or other errors occur
func (*PostgresStorage) GetSessionByToken ¶
func (s *PostgresStorage) GetSessionByToken(ctx context.Context, token string) (session auth.Session, err error)
GetSessionByToken retrieves a session from the database using the provided token string. Returns the session data as an auth.Session object if found, or an error if the token is invalid or the session cannot be retrieved.
func (*PostgresStorage) GetUserByUsername ¶
func (s *PostgresStorage) GetUserByUsername(ctx context.Context, username string) (user auth.User, err error)
GetUserByUsername retrieves a user from the database by their username. It returns the user data as an auth.User object and any error that occurred during the operation.
func (*PostgresStorage) ListPastes ¶
ListPastes retrieves all public pastes from the database and decrypts their contents.
This method: 1. Fetches all public pastes from the database 2. Converts each database row to domain model 3. Attempts to decrypt the content and title of each paste 4. Skips any pastes that fail decryption
Returns: - []paste.Paste: Slice containing all successfully retrieved and decrypted public pastes - error: Any error encountered while fetching pastes from the database
func (*PostgresStorage) ListUserPastes ¶
func (s *PostgresStorage) ListUserPastes(ctx context.Context, username string) (pastes []paste.Paste, err error)
ListUserPastes retrieves all pastes from the database that belong to the specified user. It fetches the encrypted paste data and decrypts it before returning.
Returns:
- []paste.Paste: The decrypted pastes if found
- error: Any error that occurred during fetching or decryption
func (*PostgresStorage) UpdateUserAvatar ¶
UpdateUserAvatar updates the avatar image data for a user in the database. Returns an error if the database update operation fails.
func (*PostgresStorage) UpdateUserCredentials ¶
UpdateUserCredentials updates the stored credentials for a user in the database. It expects the auth.User object to have the new value for Credentials already set. Returns an error if the update operation fails.
type PostgresStorageOption ¶
type PostgresStorageOption func(*PostgresStorage)