Create users table and OmniAuth integration #32

Open
opened 2026-06-08 03:20:36 +00:00 by ldraney · 0 comments
Owner

Type

Feature

Lineage

Follow-up from spike #16 (docs/auth.md — Schema Design + Routes + Controller sections). Depends on #31 (Keycloak provisioning).

Repo

ldraney/palinks

User Story

As a visitor
I want to log in via Keycloak
So that I can access member-tier links and features

Context

The auth flow: visitor clicks login -> redirected to Keycloak -> OIDC callback -> user found-or-created in local DB -> session set. The users table stores keycloak_sub (stable OIDC subject ID), email, role (refreshed from token on each login), and preferences JSONB (for per-user feature flag overrides). The spike doc has complete code sketches for OmniAuth initializer, SessionsController, and ApplicationController helpers.

File Targets

  • Gemfile — add omniauth-keycloak, omniauth-rails_csrf_protection
  • db/migrate/xxx_create_users.rb — users table migration
  • app/models/user.rb — new model
  • config/initializers/omniauth.rb — Keycloak OIDC strategy
  • config/routes.rb — add OmniAuth callback routes, logout
  • app/controllers/sessions_controller.rb — new controller (create, destroy, failure)
  • app/controllers/application_controller.rb — add current_user, logged_in?, current_role helpers
  • app/views/ — add login/logout button to layout

Feature Flag

None — core auth infrastructure, not a toggleable feature.

Acceptance Criteria

  • Users table created with keycloak_sub (unique), email, role, preferences
  • Login button visible on page
  • Clicking login redirects to Keycloak
  • Successful auth creates/updates user and sets session
  • current_user and current_role helpers work in controllers and views
  • Logout clears session
  • Role extracted from Keycloak realm_access.roles in ID token

Test Expectations

  • Unit test: User model validations
  • Unit test: SessionsController#create finds or creates user
  • Integration test: full OmniAuth callback flow (mock auth hash)
  • Run: bundle exec rails test

Constraints

  • keycloak_sub is the stable identifier (not email)
  • Role is cached locally, refreshed on each login
  • No user registration in Rails — Keycloak owns identity
  • Depends on #31 (Keycloak provisioning) for secrets

Checklist

  • PR opened
  • Tests pass
  • No unrelated changes
  • project-palinks — project page
  • docs/auth.md — full design spec
  • #31 — Keycloak provisioning (dependency)
### Type Feature ### Lineage Follow-up from spike #16 (`docs/auth.md` — Schema Design + Routes + Controller sections). Depends on #31 (Keycloak provisioning). ### Repo `ldraney/palinks` ### User Story As a visitor I want to log in via Keycloak So that I can access member-tier links and features ### Context The auth flow: visitor clicks login -> redirected to Keycloak -> OIDC callback -> user found-or-created in local DB -> session set. The `users` table stores `keycloak_sub` (stable OIDC subject ID), email, role (refreshed from token on each login), and preferences JSONB (for per-user feature flag overrides). The spike doc has complete code sketches for OmniAuth initializer, SessionsController, and ApplicationController helpers. ### File Targets - `Gemfile` — add `omniauth-keycloak`, `omniauth-rails_csrf_protection` - `db/migrate/xxx_create_users.rb` — users table migration - `app/models/user.rb` — new model - `config/initializers/omniauth.rb` — Keycloak OIDC strategy - `config/routes.rb` — add OmniAuth callback routes, logout - `app/controllers/sessions_controller.rb` — new controller (create, destroy, failure) - `app/controllers/application_controller.rb` — add current_user, logged_in?, current_role helpers - `app/views/` — add login/logout button to layout ### Feature Flag None — core auth infrastructure, not a toggleable feature. ### Acceptance Criteria - [ ] Users table created with keycloak_sub (unique), email, role, preferences - [ ] Login button visible on page - [ ] Clicking login redirects to Keycloak - [ ] Successful auth creates/updates user and sets session - [ ] `current_user` and `current_role` helpers work in controllers and views - [ ] Logout clears session - [ ] Role extracted from Keycloak realm_access.roles in ID token ### Test Expectations - [ ] Unit test: User model validations - [ ] Unit test: SessionsController#create finds or creates user - [ ] Integration test: full OmniAuth callback flow (mock auth hash) - Run: `bundle exec rails test` ### Constraints - `keycloak_sub` is the stable identifier (not email) - Role is cached locally, refreshed on each login - No user registration in Rails — Keycloak owns identity - Depends on #31 (Keycloak provisioning) for secrets ### Checklist - [ ] PR opened - [ ] Tests pass - [ ] No unrelated changes ### Related - `project-palinks` — project page - `docs/auth.md` — full design spec - #31 — Keycloak provisioning (dependency)
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
ldraney/palinks#32
No description provided.