52 lines
3.4 KiB
Markdown
52 lines
3.4 KiB
Markdown
# Phase 005 Execution
|
|
|
|
## Scope
|
|
- Added lightweight internal authentication without passwords.
|
|
- Added database-backed monthly access keys with lazy auto-rotation.
|
|
- Added random browser tokens stored in encrypted cookies and mapped to users through server-side session records.
|
|
- Required identification for all application pages except the identify flow and Rails health check.
|
|
- Replaced temporary `Unknown User` event attribution with the active identified user.
|
|
- Added request and model specs for authenticated and unauthenticated flows.
|
|
|
|
## Changes
|
|
- Added `AccessKey` model and migration.
|
|
- Added `UserSession` model and migration.
|
|
- Added `Current` for request-local user/session access.
|
|
- Added `SessionsController` with identify, create session, and logout behavior.
|
|
- Added `/identify`, `POST /identify`, and `DELETE /session` routes.
|
|
- Added `app/views/sessions/new.html.erb` for the “Identify yourself” page.
|
|
- Updated the application layout to show the identified user and a logout button on authenticated pages.
|
|
- Updated `ApplicationController` to lazily rotate access keys, load the encrypted-cookie auth token, and require identification by default.
|
|
- Updated fuel and maintenance entry creation to set `updated_by_user` from `Current.user`.
|
|
- Removed the temporary `Unknown User` seed and replaced it with initial `AccessKey.current` creation.
|
|
- Updated vehicle, home, and session request/system specs for the new authentication requirements.
|
|
|
|
## Decisions
|
|
- Access keys are stored in plaintext in the database so the server manager can retrieve the current key with `AccessKey.current.raw_key` from Rails console.
|
|
- Browser clients store only a random auth token in an encrypted cookie.
|
|
- The database stores only token digests, not raw session tokens.
|
|
- `AccessKey.rotate!` invalidates all active sessions by deleting `UserSession` records.
|
|
- Auto-rotation is lazy and runs during normal requests when enabled and expired.
|
|
- Default auto-rotation frequency is 30 days.
|
|
- Auto-rotation can be disabled and re-enabled with `AccessKey.current.disable_auto_rotation!` and `AccessKey.current.enable_auto_rotation!`.
|
|
- The rotation frequency can be changed with `AccessKey.current.update!(auto_rotation_frequency_days: days)`.
|
|
- Existing users are matched by normalized email and require an exact stored-name match.
|
|
- `/up` remains publicly accessible for health checks.
|
|
- `DELETE /session` uses the `logout_path` helper because `session_path` is already used for `POST /identify`.
|
|
|
|
## Console API
|
|
```ruby
|
|
AccessKey.current.raw_key
|
|
AccessKey.rotate!
|
|
AccessKey.current.disable_auto_rotation!
|
|
AccessKey.current.enable_auto_rotation!
|
|
AccessKey.current.auto_rotation_frequency_days
|
|
AccessKey.current.update!(auto_rotation_frequency_days: 60)
|
|
```
|
|
|
|
## Verification
|
|
- Passed: `bundle exec rspec spec/models/access_key_spec.rb spec/models/user_session_spec.rb spec/requests/sessions_spec.rb spec/requests/vehicles_spec.rb`
|
|
- Passed: `bundle exec rspec`
|
|
- Passed: `bin/rubocop app/models/access_key.rb app/models/user_session.rb app/models/current.rb app/models/user.rb app/controllers/application_controller.rb app/controllers/sessions_controller.rb app/controllers/fuel_entries_controller.rb app/controllers/maintenance_entries_controller.rb spec/models/access_key_spec.rb spec/models/user_session_spec.rb spec/requests/sessions_spec.rb spec/requests/vehicles_spec.rb spec/requests/home_spec.rb spec/system/home_spec.rb db/seeds.rb`
|
|
- Passed after lint cleanup: `bundle exec rspec`
|