All checks were successful
CI Pipeline / Rust Format Check (push) Successful in 4s
CI Pipeline / Clippy Lints (push) Successful in 52s
CI Pipeline / Rust Unit Tests (push) Successful in 1m11s
CI Pipeline / Security Audit (push) Successful in 5s
CI Pipeline / Frontend Lint & Type Check (push) Successful in 15s
CI Pipeline / Build .deb & Release (push) Has been skipped
- Refactored azure_sso.rs to sso.rs with generic OIDC provider support - Added OIDC discovery URL lookup with 1hr TTL caching - Added PKCE for all providers, client_secret optional for public clients - Added /api/v1/auth/sso/login and /api/v1/auth/sso/callback routes - Added /api/v1/auth/azure/* backward-compatible routes - Added POST /settings/sso/discover and POST /settings/sso/test endpoints - Frontend: Provider dropdown (Keycloak/Azure AD/Custom OIDC) - Frontend: Auto-fill discovery URL for Keycloak - Frontend: Discover Endpoints and Test Connection buttons - Frontend: Dynamic SSO button based on provider display name - Made migration 014 idempotent with DO blocks and IF NOT EXISTS - Fixed debian/install to use /usr/local/bin/ for binaries - Fixed frontend file path in .deb package - Reset admin password on dev server - Fixed database permissions for oidc_config table
60 lines
2.5 KiB
SQL
60 lines
2.5 KiB
SQL
-- 014_oidc_provider.sql
|
|
-- Migrate from Azure AD-specific SSO to generic OIDC provider support
|
|
-- Supports Keycloak, Azure AD, and custom OIDC providers
|
|
|
|
-- Add new auth_provider enum values for Keycloak and generic OIDC
|
|
-- Use DO blocks with exception handling for idempotency
|
|
DO $$
|
|
BEGIN
|
|
IF NOT EXISTS (SELECT 1 FROM pg_enum e JOIN pg_type t ON e.enumtypid = t.oid WHERE t.typname = 'auth_provider' AND e.enumlabel = 'keycloak') THEN
|
|
ALTER TYPE auth_provider ADD VALUE 'keycloak';
|
|
END IF;
|
|
IF NOT EXISTS (SELECT 1 FROM pg_enum e JOIN pg_type t ON e.enumtypid = t.oid WHERE t.typname = 'auth_provider' AND e.enumlabel = 'oidc') THEN
|
|
ALTER TYPE auth_provider ADD VALUE 'oidc';
|
|
END IF;
|
|
END
|
|
$$;
|
|
|
|
-- Add oidc_sub column for Keycloak/custom OIDC subject IDs
|
|
ALTER TABLE users ADD COLUMN IF NOT EXISTS oidc_sub TEXT;
|
|
CREATE INDEX IF NOT EXISTS idx_users_oidc_sub ON users (oidc_sub) WHERE oidc_sub IS NOT NULL;
|
|
|
|
-- Create oidc_config table (replaces azure_sso_config)
|
|
CREATE TABLE IF NOT EXISTS oidc_config (
|
|
id INTEGER PRIMARY KEY DEFAULT 1 CHECK (id = 1),
|
|
enabled BOOLEAN NOT NULL DEFAULT FALSE,
|
|
provider_type TEXT NOT NULL DEFAULT 'azure' CHECK (provider_type IN ('keycloak', 'azure', 'custom')),
|
|
display_name TEXT NOT NULL DEFAULT 'Azure AD',
|
|
discovery_url TEXT NOT NULL DEFAULT '',
|
|
client_id TEXT NOT NULL DEFAULT '',
|
|
-- Empty string for public clients (Keycloak); non-empty for confidential clients (Azure AD)
|
|
client_secret TEXT NOT NULL DEFAULT '',
|
|
redirect_uri TEXT NOT NULL DEFAULT '',
|
|
scopes TEXT NOT NULL DEFAULT 'openid profile email',
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
);
|
|
|
|
-- Migrate data from azure_sso_config if it has a row and oidc_config is empty
|
|
INSERT INTO oidc_config (enabled, provider_type, display_name, discovery_url, client_id, client_secret, redirect_uri, scopes)
|
|
SELECT
|
|
az.enabled,
|
|
'azure',
|
|
'Azure AD',
|
|
CASE
|
|
WHEN az.tenant_id IS NOT NULL AND az.tenant_id != ''
|
|
THEN 'https://login.microsoftonline.com/' || az.tenant_id || '/v2.0/.well-known/openid-configuration'
|
|
ELSE ''
|
|
END,
|
|
az.client_id,
|
|
az.client_secret,
|
|
az.redirect_uri,
|
|
az.scopes
|
|
FROM azure_sso_config az
|
|
WHERE az.id = 1
|
|
ON CONFLICT (id) DO NOTHING;
|
|
|
|
-- Ensure a default row exists if no data was migrated
|
|
INSERT INTO oidc_config (enabled, provider_type, display_name)
|
|
SELECT FALSE, 'azure', 'Azure AD'
|
|
WHERE NOT EXISTS (SELECT 1 FROM oidc_config WHERE id = 1);
|