Files
Gondulf/docs/decisions/0004-phase-2-implementation-decisions.md
Phil Skentelbery 6f06aebf40 docs: add Phase 2 domain verification design and clarifications
Add comprehensive Phase 2 documentation:
- Complete design document for two-factor domain verification
- Implementation guide with code examples
- ADR for implementation decisions (ADR-0004)
- ADR for rel="me" email discovery (ADR-008)
- Phase 1 impact assessment
- All 23 clarification questions answered
- Updated architecture docs (indieauth-protocol, security)
- Updated ADR-005 with rel="me" approach
- Updated backlog with technical debt items

Design ready for Phase 2 implementation.

Generated with Claude Code https://claude.com/claude-code

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-20 13:05:09 -07:00

98 lines
4.3 KiB
Markdown

# 0004. Phase 2 Implementation Decisions
Date: 2024-11-20
## Status
Accepted
## Context
The Developer has raised 8 categories of implementation questions for Phase 2 that require architectural decisions. These decisions need to balance simplicity with functionality while providing clear direction for implementation.
## Decisions
### 1. Rate Limiting Implementation
**Decision**: Implement actual rate limiting with in-memory storage in Phase 2.
**Rationale**: Security features should be real from the start, not stubs. In-memory is simplest.
**Implementation**:
- Use a simple dictionary with domain as key, list of timestamps as value
- Clean up old timestamps on each check (older than 1 hour)
- Store in `RateLimiter` service as instance variable
- No persistence needed - resets on restart is acceptable
### 2. Authorization Code Metadata Structure
**Decision**: Use Phase 1's `CodeStorage` service with complete structure from the start.
**Rationale**: Reuse existing infrastructure, avoid future migrations.
**Implementation**:
- Include `used` field (boolean, default False) even though Phase 3 consumes it
- Store epoch integers for timestamps (simpler than datetime objects)
- Use same `CodeStorage` from Phase 1 with authorization code keys
### 3. HTML Template Implementation
**Decision**: Use Jinja2 templates with separate template files.
**Rationale**: Jinja2 is standard, maintainable, and allows for future template customization.
**Implementation**:
- Templates in `src/gondulf/templates/`
- Create `base.html` for shared layout
- Individual templates: `verify_email.html`, `verify_totp.html`, `authorize.html`, `error.html`
- Pass minimal context to templates
### 4. Database Migration Timing
**Decision**: Apply migration 002 immediately as part of Phase 2 setup.
**Rationale**: Keep database schema current with code expectations.
**Implementation**:
- Run migration before any Phase 2 code execution
- New code assumes 'two_factor' column exists
- Migration updates existing rows (if any) to have 'two_factor' = false
### 5. Client Validation Helper Functions
**Decision**: Implement as standalone functions in a shared utility module.
**Rationale**: Functions over classes when no state is needed. Simpler to test and understand.
**Implementation**:
- Create `src/gondulf/utils/validation.py`
- Functions: `mask_email()`, `validate_redirect_uri()`, `normalize_client_id()`
- Full subdomain validation now (not a stub) - security should be complete
### 6. Error Response Format Consistency
**Decision**: Use format appropriate to the endpoint type.
**Rationale**: Follow OAuth 2.0 patterns and user experience expectations.
**Implementation**:
- Verification endpoints (`/verify/email`, `/verify/totp`): JSON responses, always 200 OK
- Authorization endpoint errors before user interaction: HTML error page
- Authorization endpoint errors after client validation: OAuth redirect with error
- Token endpoint (Phase 3): Always JSON
### 7. Dependency Injection Pattern
**Decision**: Create `dependencies.py` with singleton services instantiated at startup.
**Rationale**: Simpler than per-request instantiation, consistent with Phase 1 pattern.
**Implementation**:
- All services instantiated once in `dependencies.py`
- Services read configuration at instantiation
- FastAPI dependency injection provides same instance to all requests
- Pattern: `get_code_storage()`, `get_rate_limiter()`, etc.
### 8. Test Organization for Authorization Endpoint
**Decision**: Separate test files per major endpoint with shared fixtures module.
**Rationale**: Easier to navigate and maintain as tests grow.
**Implementation**:
- `tests/test_verification_endpoints.py` - email and TOTP verification
- `tests/test_authorization_endpoint.py` - authorization flow
- `tests/conftest.py` - shared fixtures for common scenarios
- Test complete flows, not sub-endpoints in isolation
## Consequences
### Positive
- Clear, consistent patterns across the codebase
- Real security from the start (no stubs)
- Reuse of existing Phase 1 infrastructure
- Standard, maintainable template approach
- Simple service architecture
### Negative
- Slightly more upfront work than stub implementations
- In-memory rate limiting loses state on restart
- Templates add a dependency (Jinja2)
### Neutral
- Following established patterns from other web frameworks
- Committing to specific implementation choices early