Add authentication, authorization, and team-scoped access control
Implement email/password auth with JWT sessions and API key auth for sandbox lifecycle. Users get a default team on signup; sandboxes, snapshots, and API keys are scoped to teams. - Add user, team, users_teams, and team_api_keys tables (goose migrations) - Add JWT middleware (Bearer token) for user management endpoints - Add API key middleware (X-API-Key header, SHA-256 hashed) for sandbox ops - Add signup/login handlers with transactional user+team creation - Add API key CRUD endpoints (create/list/delete) - Replace owner_id with team_id on sandboxes and templates - Update all handlers to use team-scoped queries - Add godotenv for .env file loading - Update OpenAPI spec and test UI with auth flows
This commit is contained in:
46
db/migrations/20260313210608_auth.sql
Normal file
46
db/migrations/20260313210608_auth.sql
Normal file
@ -0,0 +1,46 @@
|
||||
-- +goose Up
|
||||
|
||||
CREATE TABLE users (
|
||||
id TEXT PRIMARY KEY,
|
||||
email TEXT NOT NULL UNIQUE,
|
||||
password_hash TEXT NOT NULL,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
||||
);
|
||||
|
||||
CREATE TABLE teams (
|
||||
id TEXT PRIMARY KEY,
|
||||
name TEXT NOT NULL,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
||||
);
|
||||
|
||||
CREATE TABLE users_teams (
|
||||
user_id TEXT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||||
team_id TEXT NOT NULL REFERENCES teams(id) ON DELETE CASCADE,
|
||||
is_default BOOLEAN NOT NULL DEFAULT TRUE,
|
||||
role TEXT NOT NULL DEFAULT 'owner',
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
PRIMARY KEY (team_id, user_id)
|
||||
);
|
||||
|
||||
CREATE INDEX idx_users_teams_user ON users_teams(user_id);
|
||||
|
||||
CREATE TABLE team_api_keys (
|
||||
id TEXT PRIMARY KEY,
|
||||
team_id TEXT NOT NULL REFERENCES teams(id) ON DELETE CASCADE,
|
||||
name TEXT NOT NULL DEFAULT '',
|
||||
key_hash TEXT NOT NULL UNIQUE,
|
||||
key_prefix TEXT NOT NULL DEFAULT '',
|
||||
created_by TEXT NOT NULL REFERENCES users(id),
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
last_used TIMESTAMPTZ
|
||||
);
|
||||
|
||||
CREATE INDEX idx_team_api_keys_team ON team_api_keys(team_id);
|
||||
|
||||
-- +goose Down
|
||||
|
||||
DROP TABLE team_api_keys;
|
||||
DROP TABLE users_teams;
|
||||
DROP TABLE teams;
|
||||
DROP TABLE users;
|
||||
31
db/migrations/20260313210611_team_ownership.sql
Normal file
31
db/migrations/20260313210611_team_ownership.sql
Normal file
@ -0,0 +1,31 @@
|
||||
-- +goose Up
|
||||
|
||||
ALTER TABLE sandboxes
|
||||
ADD COLUMN team_id TEXT NOT NULL DEFAULT '';
|
||||
|
||||
UPDATE sandboxes SET team_id = owner_id WHERE owner_id != '';
|
||||
|
||||
ALTER TABLE sandboxes
|
||||
DROP COLUMN owner_id;
|
||||
|
||||
ALTER TABLE templates
|
||||
ADD COLUMN team_id TEXT NOT NULL DEFAULT '';
|
||||
|
||||
CREATE INDEX idx_sandboxes_team ON sandboxes(team_id);
|
||||
CREATE INDEX idx_templates_team ON templates(team_id);
|
||||
|
||||
-- +goose Down
|
||||
|
||||
ALTER TABLE sandboxes
|
||||
ADD COLUMN owner_id TEXT NOT NULL DEFAULT '';
|
||||
|
||||
UPDATE sandboxes SET owner_id = team_id WHERE team_id != '';
|
||||
|
||||
ALTER TABLE sandboxes
|
||||
DROP COLUMN team_id;
|
||||
|
||||
ALTER TABLE templates
|
||||
DROP COLUMN team_id;
|
||||
|
||||
DROP INDEX IF EXISTS idx_sandboxes_team;
|
||||
DROP INDEX IF EXISTS idx_templates_team;
|
||||
Reference in New Issue
Block a user