Phase 2: Subsonic REST API framework (auth, response formatting, error handling, routing) plus user permission model

This commit is contained in:
2026-08-22 23:58:54 -05:00
parent f81c8704a5
commit b5e2bf01e2
26 changed files with 1772 additions and 75 deletions
+34
View File
@@ -0,0 +1,34 @@
-- Phase 2: Subsonic REST API support.
--
-- Adds the Subsonic permission model to users, per-user music folder
-- restrictions, and a recoverable (encrypted, not plaintext) copy of the
-- password for legacy token/salt authentication (t = md5(password+salt)),
-- which is mathematically impossible to verify against a one-way Argon2id
-- hash alone.
ALTER TABLE users ADD COLUMN role_settings INTEGER NOT NULL DEFAULT 1;
ALTER TABLE users ADD COLUMN role_stream INTEGER NOT NULL DEFAULT 1;
ALTER TABLE users ADD COLUMN role_download INTEGER NOT NULL DEFAULT 1;
ALTER TABLE users ADD COLUMN role_upload INTEGER NOT NULL DEFAULT 0;
ALTER TABLE users ADD COLUMN role_playlist INTEGER NOT NULL DEFAULT 1;
ALTER TABLE users ADD COLUMN role_cover_art INTEGER NOT NULL DEFAULT 1;
ALTER TABLE users ADD COLUMN role_comment INTEGER NOT NULL DEFAULT 1;
ALTER TABLE users ADD COLUMN role_podcast INTEGER NOT NULL DEFAULT 0;
ALTER TABLE users ADD COLUMN role_share INTEGER NOT NULL DEFAULT 1;
ALTER TABLE users ADD COLUMN role_jukebox INTEGER NOT NULL DEFAULT 0;
ALTER TABLE users ADD COLUMN role_video_conversion INTEGER NOT NULL DEFAULT 0;
-- Encrypted (AES-GCM, server-side key) copy of the current password,
-- refreshed whenever the plaintext is available (login, password set/
-- change). Never store the plaintext itself. NULL for accounts with no
-- local password (external-auth-only), which therefore cannot use
-- Subsonic token/password authentication until a local password is set.
ALTER TABLE users ADD COLUMN subsonic_auth_secret TEXT;
-- Per-user music folder restriction. No rows for a user means
-- unrestricted (sees every folder) -- the common case.
CREATE TABLE user_music_folders (
user_id TEXT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
music_folder_id TEXT NOT NULL REFERENCES music_folders(id) ON DELETE CASCADE,
PRIMARY KEY (user_id, music_folder_id)
);