Migrate db, auth to mcdsl; remove mcias client dependency
- db.Open: delegate to mcdsl/db.Open - db.Migrate: convert to mcdsl/db.Migration format, delegate - auth: type aliases for TokenInfo/Authenticator/Config from mcdsl, re-export error sentinels, Logout helper - cmd/server: construct auth.Authenticator from Config (not mcias.Client) - server/routes.go logout: use auth.Logout(authenticator, token) - grpcserver/auth.go: same logout pattern, fix Login return type (time.Time not string) - webserver: replace mcias.Client with mcdsl/auth for service token validation; resolveUser degrades to raw UUID (TODO: restore when mcias client library is properly tagged) - Dockerfiles: bump to golang:1.25-alpine, remove gcc/musl-dev, add VERSION build arg - Deploy: add docker-compose-rift.yml with localhost-only port mapping - Remove git.wntrmute.dev/kyle/mcias/clients/go dependency entirely - All tests pass, net -185 lines Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -3,41 +3,13 @@ package db
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
_ "modernc.org/sqlite"
|
||||
mcdsldb "git.wntrmute.dev/kyle/mcdsl/db"
|
||||
)
|
||||
|
||||
// Open opens or creates a SQLite database at the given path with secure
|
||||
// file permissions (0600) and WAL mode enabled.
|
||||
// Open opens or creates a SQLite database at the given path with the
|
||||
// standard Metacircular pragmas (WAL, FK, busy timeout) and 0600
|
||||
// permissions.
|
||||
func Open(path string) (*sql.DB, error) {
|
||||
// Ensure the file has restrictive permissions if it doesn't exist yet.
|
||||
if _, err := os.Stat(path); os.IsNotExist(err) {
|
||||
f, err := os.OpenFile(path, os.O_CREATE|os.O_WRONLY, 0600) //nolint:gosec
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("db: create file: %w", err)
|
||||
}
|
||||
_ = f.Close()
|
||||
}
|
||||
|
||||
db, err := sql.Open("sqlite", path)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("db: open: %w", err)
|
||||
}
|
||||
|
||||
// Enable WAL mode and foreign keys.
|
||||
pragmas := []string{
|
||||
"PRAGMA journal_mode=WAL",
|
||||
"PRAGMA foreign_keys=ON",
|
||||
"PRAGMA busy_timeout=5000",
|
||||
}
|
||||
for _, p := range pragmas {
|
||||
if _, err := db.Exec(p); err != nil {
|
||||
_ = db.Close()
|
||||
return nil, fmt.Errorf("db: pragma %q: %w", p, err)
|
||||
}
|
||||
}
|
||||
|
||||
return db, nil
|
||||
return mcdsldb.Open(path)
|
||||
}
|
||||
|
||||
@@ -2,14 +2,16 @@ package db
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"fmt"
|
||||
|
||||
mcdsldb "git.wntrmute.dev/kyle/mcdsl/db"
|
||||
)
|
||||
|
||||
// migrations is an ordered list of SQL DDL statements. Each index is the
|
||||
// migration version (1-based).
|
||||
var migrations = []string{
|
||||
// Version 1: initial schema
|
||||
`CREATE TABLE IF NOT EXISTS seal_config (
|
||||
// Migrations is the ordered list of metacrypt schema migrations.
|
||||
var Migrations = []mcdsldb.Migration{
|
||||
{
|
||||
Version: 1,
|
||||
Name: "initial schema",
|
||||
SQL: `CREATE TABLE IF NOT EXISTS seal_config (
|
||||
id INTEGER PRIMARY KEY CHECK (id = 1),
|
||||
encrypted_mek BLOB NOT NULL,
|
||||
kdf_salt BLOB NOT NULL,
|
||||
@@ -24,56 +26,22 @@ var migrations = []string{
|
||||
value BLOB NOT NULL,
|
||||
created_at DATETIME NOT NULL DEFAULT (datetime('now')),
|
||||
updated_at DATETIME NOT NULL DEFAULT (datetime('now'))
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS schema_migrations (
|
||||
version INTEGER PRIMARY KEY,
|
||||
applied_at DATETIME NOT NULL DEFAULT (datetime('now'))
|
||||
);`,
|
||||
|
||||
// Version 2: barrier key registry for per-engine DEKs
|
||||
`CREATE TABLE IF NOT EXISTS barrier_keys (
|
||||
},
|
||||
{
|
||||
Version: 2,
|
||||
Name: "barrier key registry",
|
||||
SQL: `CREATE TABLE IF NOT EXISTS barrier_keys (
|
||||
key_id TEXT PRIMARY KEY,
|
||||
version INTEGER NOT NULL DEFAULT 1,
|
||||
encrypted_dek BLOB NOT NULL,
|
||||
created_at DATETIME NOT NULL DEFAULT (datetime('now')),
|
||||
rotated_at DATETIME NOT NULL DEFAULT (datetime('now'))
|
||||
);`,
|
||||
},
|
||||
}
|
||||
|
||||
// Migrate applies all pending migrations.
|
||||
func Migrate(db *sql.DB) error {
|
||||
// Ensure the migrations table exists (bootstrap).
|
||||
if _, err := db.Exec(`CREATE TABLE IF NOT EXISTS schema_migrations (
|
||||
version INTEGER PRIMARY KEY,
|
||||
applied_at DATETIME NOT NULL DEFAULT (datetime('now'))
|
||||
)`); err != nil {
|
||||
return fmt.Errorf("db: create migrations table: %w", err)
|
||||
}
|
||||
|
||||
var current int
|
||||
row := db.QueryRow("SELECT COALESCE(MAX(version), 0) FROM schema_migrations")
|
||||
if err := row.Scan(¤t); err != nil {
|
||||
return fmt.Errorf("db: get migration version: %w", err)
|
||||
}
|
||||
|
||||
for i := current; i < len(migrations); i++ {
|
||||
version := i + 1
|
||||
tx, err := db.Begin()
|
||||
if err != nil {
|
||||
return fmt.Errorf("db: begin migration %d: %w", version, err)
|
||||
}
|
||||
if _, err := tx.Exec(migrations[i]); err != nil {
|
||||
_ = tx.Rollback()
|
||||
return fmt.Errorf("db: migration %d: %w", version, err)
|
||||
}
|
||||
if _, err := tx.Exec("INSERT INTO schema_migrations (version) VALUES (?)", version); err != nil {
|
||||
_ = tx.Rollback()
|
||||
return fmt.Errorf("db: record migration %d: %w", version, err)
|
||||
}
|
||||
if err := tx.Commit(); err != nil {
|
||||
return fmt.Errorf("db: commit migration %d: %w", version, err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
func Migrate(database *sql.DB) error {
|
||||
return mcdsldb.Migrate(database, Migrations)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user