storage

package
v0.0.0-...-8a2022e Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 27, 2025 License: MIT Imports: 23 Imported by: 0

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

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Cipher

type Cipher struct {
	// contains filtered or unexported fields
}

func NewCipher

func NewCipher(key, salt string) *Cipher

func (*Cipher) Decrypt

func (c *Cipher) Decrypt(encrypted string) (string, error)

func (*Cipher) Encrypt

func (c *Cipher) Encrypt(plaintext string) (string, error)

func (*Cipher) Hash

func (c *Cipher) Hash(value string) string

func (*Cipher) Verify

func (c *Cipher) Verify(password, encoded string) bool

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

func (s *PostgresStorage) CreateSession(ctx context.Context, ssn auth.Session) (err error)

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

func (s *PostgresStorage) CreateUser(ctx context.Context, user auth.User) (err error)

CreateUser creates a new user in the database with the provided auth.User data.

func (*PostgresStorage) DecryptPaste

func (s *PostgresStorage) DecryptPaste(ctx context.Context, paste *paste.Paste) (err error)

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

func (s *PostgresStorage) EncryptPaste(ctx context.Context, paste *paste.Paste) (err error)

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

func (s *PostgresStorage) GetPaste(ctx context.Context, ref string) (paste paste.Paste, err error)

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

func (s *PostgresStorage) ListPastes(ctx context.Context) (pastes []paste.Paste, err error)

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

func (s *PostgresStorage) UpdateUserAvatar(ctx context.Context, user auth.User) (err error)

UpdateUserAvatar updates the avatar image data for a user in the database. Returns an error if the database update operation fails.

func (*PostgresStorage) UpdateUserCredentials

func (s *PostgresStorage) UpdateUserCredentials(ctx context.Context, user auth.User) (err error)

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)

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL