feat: OIDC SSO provider support (Keycloak, Azure AD, custom)
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
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
This commit is contained in:
59
migrations/014_oidc_provider.sql
Normal file
59
migrations/014_oidc_provider.sql
Normal file
@ -0,0 +1,59 @@
|
||||
-- 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);
|
||||
Reference in New Issue
Block a user