Version 0.2.0

Changes:
- forbid to overwrite secrets of other users
- add some logs of success
- add validation on code (length 50)
- use same limiter for POST requests
This commit is contained in:
2026-08-17 21:13:15 +00:03
parent 6ee80f1c8f
commit 1ccf40396f
16 changed files with 184 additions and 38 deletions

View File

@@ -8,6 +8,7 @@ import (
)
var ErrNotFound = errors.New("secret not found")
var ErrForbidden = errors.New("code owned by another user")
type SecretsRepository struct {
db *sql.DB
@@ -29,14 +30,35 @@ func (r *SecretsRepository) Get(ctx context.Context, code string) (string, error
return value, nil
}
func (r *SecretsRepository) Set(ctx context.Context, code, value string) error {
_, err := r.db.ExecContext(ctx, `
INSERT INTO secrets (code, value, updated_at)
VALUES (?, ?, CURRENT_TIMESTAMP)
ON CONFLICT(code) DO UPDATE SET value = excluded.value, updated_at = CURRENT_TIMESTAMP
`, code, value)
// Set stores value under code, owned by user. If code already exists and is
// owned by a different user, it returns ErrForbidden and leaves the stored
// value untouched.
func (r *SecretsRepository) Set(ctx context.Context, code, value, user string) error {
tx, err := r.db.BeginTx(ctx, nil)
if err != nil {
return fmt.Errorf("could not begin transaction: %w", err)
}
defer func() { _ = tx.Rollback() }()
var owner string
err = tx.QueryRowContext(ctx, "SELECT user FROM secrets WHERE code = ?", code).Scan(&owner)
if err != nil && !errors.Is(err, sql.ErrNoRows) {
return fmt.Errorf("could not check secret owner: %w", err)
}
if !errors.Is(err, sql.ErrNoRows) && owner != user {
return ErrForbidden
}
if _, err := tx.ExecContext(ctx, `
INSERT INTO secrets (code, value, user, created_at, updated_at)
VALUES (?, ?, ?, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)
ON CONFLICT(code) DO UPDATE SET value = excluded.value, updated_at = CURRENT_TIMESTAMP
`, code, value, user); err != nil {
return fmt.Errorf("could not set secret: %w", err)
}
if err := tx.Commit(); err != nil {
return fmt.Errorf("could not commit transaction: %w", err)
}
return nil
}