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
+39
View File
@@ -57,6 +57,14 @@ interface SetupState {
oidcIssuerUrl: string;
oidcClientId: string;
oidcClientSecret: string;
oidcAccessControlMethod: string;
oidcAccessGroupClaim: string;
oidcAccessGroupValue: string;
oidcAllowedEmails: string;
oidcAllowedUsernames: string;
oidcAdminClaimEnabled: boolean;
oidcAdminClaimName: string;
oidcAdminClaimValue: string;
// Manual registration config
requireAdminApproval: boolean;
@@ -114,6 +122,14 @@ export default function SetupWizard() {
oidcIssuerUrl: '',
oidcClientId: '',
oidcClientSecret: '',
oidcAccessControlMethod: 'open',
oidcAccessGroupClaim: 'groups',
oidcAccessGroupValue: '',
oidcAllowedEmails: '',
oidcAllowedUsernames: '',
oidcAdminClaimEnabled: false,
oidcAdminClaimName: 'groups',
oidcAdminClaimValue: '',
// Manual registration config
requireAdminApproval: true,
@@ -231,11 +247,26 @@ export default function SetupWizard() {
// OIDC configuration
if (state.authMethod === 'oidc' || state.authMethod === 'both') {
// Helper function to parse comma-separated strings into JSON arrays
const parseCommaSeparatedToArray = (str: string): string => {
if (!str || str.trim() === '') return '[]';
const items = str.split(',').map(s => s.trim()).filter(s => s.length > 0);
return JSON.stringify(items);
};
payload.oidc = {
provider_name: state.oidcProviderName,
issuer_url: state.oidcIssuerUrl,
client_id: state.oidcClientId,
client_secret: state.oidcClientSecret,
access_control_method: state.oidcAccessControlMethod,
access_group_claim: state.oidcAccessGroupClaim,
access_group_value: state.oidcAccessGroupValue,
allowed_emails: parseCommaSeparatedToArray(state.oidcAllowedEmails),
allowed_usernames: parseCommaSeparatedToArray(state.oidcAllowedUsernames),
admin_claim_enabled: state.oidcAdminClaimEnabled ? 'true' : 'false',
admin_claim_name: state.oidcAdminClaimName,
admin_claim_value: state.oidcAdminClaimValue,
};
}
@@ -392,6 +423,14 @@ export default function SetupWizard() {
oidcIssuerUrl={state.oidcIssuerUrl}
oidcClientId={state.oidcClientId}
oidcClientSecret={state.oidcClientSecret}
oidcAccessControlMethod={state.oidcAccessControlMethod}
oidcAccessGroupClaim={state.oidcAccessGroupClaim}
oidcAccessGroupValue={state.oidcAccessGroupValue}
oidcAllowedEmails={state.oidcAllowedEmails}
oidcAllowedUsernames={state.oidcAllowedUsernames}
oidcAdminClaimEnabled={state.oidcAdminClaimEnabled}
oidcAdminClaimName={state.oidcAdminClaimName}
oidcAdminClaimValue={state.oidcAdminClaimValue}
onUpdate={updateField}
onNext={() => goToStep(currentStepNumber + 1)}
onBack={() => goToStep(currentStepNumber - 1)}