KolektivComputer / KolektivComputer/kalendee

LDAP M2: auto-provisioning, user_identities, and admin visibility

Open
#10 0 comments 0 reactions 1 assignee Claimed by @LizAinslie View on GitHub
c/enhancement c/feature t/server
Dominant language
Kotlin
Stars
0
Forks
0
Avg merge
11h 20m
Merged PRs (30d)
23

Description

## Context

M2 turns a successful directory bind into a local Kalendee user on first login and records where the account came from. A shared `user_identities` table maps (`source`, `subject`) to a user and is also the natural home for OAuth identity links, and admins need to see the account source. Directory-backed accounts must not pretend they can change local passwords.

## Tasks

- [ ] Migration: `user_identities` (`user_id`, `source`, `subject`, `email`, timestamps; `UNIQUE(source, subject)`) — design alongside the OAuth identity storage from `feat/oauth-foundation`
- [ ] First-login provisioning: create the user with a random unguessable password hash, verified email from the directory, collision-safe username generation
- [ ] Repeat logins resolve to the existing user via `user_identities` (no duplicates, case-normalized)
- [ ] `authSource` (`local` | `ldap` | `google` | `microsoft`) surfaced in admin user list/detail
- [ ] Hide/disable password change and reset fields for directory accounts (UI + server guard)
- [ ] Account deletion cascades through `user_identities`
- [ ] Tests: first/repeat login, username collision, admin source display, password-field guard

## References

- #9 (LDAP M1) — `UserDirectory` seam
- `server/src/main/kotlin/dev/kolektiv/kalendee/auth/AuthService.kt`
- `server/src/main/kotlin/dev/kolektiv/kalendee/organizations/OrganizationService.kt` — member identity shape
- `server/pack/src/pages/kalendee/admin/+page.svelte`
- `server/src/main/resources/db/migration/V17__external_calendars.sql` — OAuth connection model
- `docs/external-calendars.md` — identity edge cases (unverified email, duplicate usernames, first-user admin)

## Dependencies

- **Depends on #9 (LDAP M1).**
- Identity table coordinates with the OAuth foundation on `feat/oauth-foundation` (currently being restored) so both sources share one model.
- #11 (M3) builds on provisioning.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.