mirror of
https://github.com/maziggy/bambuddy.git
synced 2026-10-22 03:49:18 +02:00
feat(auth): manual LDAP user provisioning from the UI (#1298)
Reporter @Fuechslein flagged that disabling LDAP auto-provision left admins
with no UI path to onboard new users — the create-user form had zero LDAP
awareness and the only workaround was hand-editing the database.
Add a Local / LDAP tab toggle to the create-user modal (hidden when LDAP is
disabled). The LDAP tab is a debounced directory search (≥2 chars, 300ms)
that returns up to 25 matches via the service-account bind, annotated with
already_provisioned so existing usernames render disabled. Clicking
"Provision user" re-resolves via the service bind and creates the user
through the same _provision_ldap_user helper the auto-provision login path
uses, so group mapping, default-group fallback, and email sync are identical
regardless of which path created the user.
The picker component is shared across all four create-user modal paths
(UsersPage basic + advanced, SettingsPage basic + advanced).
Two ldap3 schema-check workarounds were needed for OpenLDAP installs:
- Open the search connection with check_names=False so ldap3 doesn't reject
the cross-schema OR filter (sAMAccountName/displayName are AD-only)
- Request attributes=["*"] because ldap3's build_attribute_selection
validates each named attribute against the server schema regardless of
check_names, and only the * wildcard is in its hard-coded exclusion list
Login/lookup paths keep check_names=True so typos in user_filter still fail
loudly.
Backend
- New routes: GET /auth/ldap/search, POST /auth/ldap/provision (both gated
by USERS_CREATE; 503 details include ldap3 exception class + message)
- Extract _open_service_connection + _extract_user_info helpers so
authenticate_ldap_user, lookup_ldap_user, and search_ldap_users share the
bind and attribute-extraction logic
Frontend
- New LdapUserPicker component (debounced search, result list, provision
mutation, already-provisioned guard, error surface)
- Tab toggle wired into UsersPage and SettingsPage modals, plus
CreateUserAdvancedAuthModal props
- 14 i18n keys added to en.ts (other locales fall back to English)
This commit is contained in:
@@ -2911,6 +2911,14 @@ export interface LDAPTestResponse {
|
||||
message: string;
|
||||
}
|
||||
|
||||
export interface LDAPSearchResult {
|
||||
username: string;
|
||||
email: string | null;
|
||||
display_name: string | null;
|
||||
dn: string;
|
||||
already_provisioned: boolean;
|
||||
}
|
||||
|
||||
export interface SetupResponse {
|
||||
auth_enabled: boolean;
|
||||
admin_created?: boolean;
|
||||
@@ -2973,6 +2981,13 @@ export const api = {
|
||||
request<LDAPTestResponse>('/auth/ldap/test', {
|
||||
method: 'POST',
|
||||
}),
|
||||
searchLDAPDirectory: (q: string) =>
|
||||
request<LDAPSearchResult[]>(`/auth/ldap/search?q=${encodeURIComponent(q)}`),
|
||||
provisionLDAPUser: (username: string) =>
|
||||
request<UserResponse>('/auth/ldap/provision', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({ username }),
|
||||
}),
|
||||
forgotPassword: (data: ForgotPasswordRequest) =>
|
||||
request<ForgotPasswordResponse>('/auth/forgot-password', {
|
||||
method: 'POST',
|
||||
|
||||
Reference in New Issue
Block a user