mirror of
https://github.com/warmbly/warmbly.git
synced 2026-09-05 00:01:49 +00:00
Mailboxes, integration tokens, and message content are organization assets. Keying their DEK by the connecting user meant offboarding that user made every ciphertext they created unreadable. Migration 000039 drops user_encrypted_keys and creates organization_encrypted_keys keyed by organization_id. The new table has no FK on purpose: platform secrets live under the zero UUID (no organizations row), and DEK rows must never cascade-delete because a lost DEK is unrecoverable. Pre-production, so there is no data migration; ciphertexts sealed under the old per-user DEKs are abandoned with the table.
64 lines
1.7 KiB
Go
64 lines
1.7 KiB
Go
package encryptedkeys
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
|
|
"github.com/google/uuid"
|
|
"github.com/jackc/pgx/v5"
|
|
"github.com/jackc/pgx/v5/pgconn"
|
|
"github.com/warmbly/warmbly/internal/infrastructure/db"
|
|
)
|
|
|
|
// PostgresStore stores encrypted DEKs in the organization_encrypted_keys
|
|
// table. Only the backend uses this impl directly; workers reach DEKs via the
|
|
// HTTP store (which proxies through the backend).
|
|
type PostgresStore struct {
|
|
db *db.DB
|
|
}
|
|
|
|
func NewPostgres(d *db.DB) *PostgresStore {
|
|
return &PostgresStore{db: d}
|
|
}
|
|
|
|
func (s *PostgresStore) Name() string { return "postgres" }
|
|
|
|
func (s *PostgresStore) Put(ctx context.Context, orgID uuid.UUID, encryptedDEKB64 string) error {
|
|
const q = `
|
|
INSERT INTO organization_encrypted_keys (organization_id, encrypted_data_key)
|
|
VALUES ($1, $2)
|
|
`
|
|
_, err := s.db.Exec(ctx, q, orgID, encryptedDEKB64)
|
|
if err != nil {
|
|
var pgErr *pgconn.PgError
|
|
if errors.As(err, &pgErr) && pgErr.Code == "23505" { // unique_violation
|
|
return ErrAlreadyExists
|
|
}
|
|
return fmt.Errorf("encryptedkeys.postgres: put: %w", err)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (s *PostgresStore) Get(ctx context.Context, orgID uuid.UUID) (string, error) {
|
|
const q = `SELECT encrypted_data_key FROM organization_encrypted_keys WHERE organization_id = $1`
|
|
var out string
|
|
err := s.db.QueryRow(ctx, q, orgID).Scan(&out)
|
|
if err != nil {
|
|
if errors.Is(err, pgx.ErrNoRows) {
|
|
return "", nil
|
|
}
|
|
return "", fmt.Errorf("encryptedkeys.postgres: get: %w", err)
|
|
}
|
|
return out, nil
|
|
}
|
|
|
|
func (s *PostgresStore) Delete(ctx context.Context, orgID uuid.UUID) error {
|
|
const q = `DELETE FROM organization_encrypted_keys WHERE organization_id = $1`
|
|
_, err := s.db.Exec(ctx, q, orgID)
|
|
if err != nil {
|
|
return fmt.Errorf("encryptedkeys.postgres: delete: %w", err)
|
|
}
|
|
return nil
|
|
}
|