Add comprehensive OIDC access control and admin role mapping

Implements full OIDC configuration UI and backend support for access control and admin permissions.

**Access Control Features:**
- Open access (anyone can log in)
- Group/claim based access (require specific group membership)
- Allowed list (whitelist specific emails/usernames)
- Admin approval (manual approval required for new users)

**Admin Role Mapping:**
- Automatic admin role assignment based on OIDC claims
- Configurable claim name and value (default: groups claim)
- First user always becomes admin
- Dynamic role updates on each login

**Setup Wizard:**
- Updated OIDCConfigStep with comprehensive OIDC settings
- Access control method selector with conditional fields
- Admin role mapping configuration with examples
- Improved UX with clear sections and helpful descriptions

**Admin Settings:**
- Expanded OIDC section with all new configuration options
- Proper JSON array handling for allowed emails/usernames
- Visual organization matching setup wizard

**Backend:**
- Updated setup complete API to persist new OIDC fields
- Updated OIDC settings API for all new configuration
- Updated settings GET endpoint to return new fields with defaults
- Proper comma-separated to JSON array conversion

**Documentation:**
- Comprehensive OIDC section in auth.md
- Configuration examples and use cases
- Clear distinction between access control and admin roles
- Default values documented

All changes tested and ready for production use.
This commit is contained in:
Claude
2025-12-21 18:43:39 +00:00
committed by kikootwo
parent a3ba192fbd
commit 5a9b6b4b46
7 changed files with 730 additions and 31 deletions
+23 -1
View File
@@ -11,7 +11,21 @@ export async function PUT(request: NextRequest) {
return requireAdmin(req, async () => {
try {
const body = await request.json();
const { enabled, providerName, issuerUrl, clientId, clientSecret } = body;
const {
enabled,
providerName,
issuerUrl,
clientId,
clientSecret,
accessControlMethod,
accessGroupClaim,
accessGroupValue,
allowedEmails,
allowedUsernames,
adminClaimEnabled,
adminClaimName,
adminClaimValue,
} = body;
const { getConfigService } = await import('@/lib/services/config.service');
const configService = getConfigService();
@@ -22,6 +36,14 @@ export async function PUT(request: NextRequest) {
{ key: 'oidc.provider_name', value: providerName || '' },
{ key: 'oidc.issuer_url', value: issuerUrl || '' },
{ key: 'oidc.client_id', value: clientId || '' },
{ key: 'oidc.access_control_method', value: accessControlMethod || 'open' },
{ key: 'oidc.access_group_claim', value: accessGroupClaim || 'groups' },
{ key: 'oidc.access_group_value', value: accessGroupValue || '' },
{ key: 'oidc.allowed_emails', value: allowedEmails || '[]' },
{ key: 'oidc.allowed_usernames', value: allowedUsernames || '[]' },
{ key: 'oidc.admin_claim_enabled', value: adminClaimEnabled ? 'true' : 'false' },
{ key: 'oidc.admin_claim_name', value: adminClaimName || 'groups' },
{ key: 'oidc.admin_claim_value', value: adminClaimValue || '' },
];
// Only update client secret if provided (not masked)
+8
View File
@@ -43,6 +43,14 @@ export async function GET(request: NextRequest) {
issuerUrl: configMap.get('oidc.issuer_url') || '',
clientId: configMap.get('oidc.client_id') || '',
clientSecret: maskValue('client_secret', configMap.get('oidc.client_secret')),
accessControlMethod: configMap.get('oidc.access_control_method') || 'open',
accessGroupClaim: configMap.get('oidc.access_group_claim') || 'groups',
accessGroupValue: configMap.get('oidc.access_group_value') || '',
allowedEmails: configMap.get('oidc.allowed_emails') || '[]',
allowedUsernames: configMap.get('oidc.allowed_usernames') || '[]',
adminClaimEnabled: configMap.get('oidc.admin_claim_enabled') === 'true',
adminClaimName: configMap.get('oidc.admin_claim_name') || 'groups',
adminClaimValue: configMap.get('oidc.admin_claim_value') || '',
},
registration: {
enabled: configMap.get('auth.registration_enabled') === 'true',