Files
gh-christianlouis-docuelevate/OAUTH_IMPLEMENTATION_SUMMARY.md
T
2026-02-13 09:12:11 +00:00

7.1 KiB

Mock OAuth2 Server Implementation - Summary

Overview

Successfully implemented a production-ready mock OAuth2/OIDC server infrastructure for testing authentication flows in DocuElevate.

What Was Implemented

1. Mock OAuth2 Server Container (tests/mock_oauth_server.py)

  • Wraps mock-oauth2-server Docker image using testcontainers
  • Provides complete OIDC provider with all standard endpoints
  • Fast startup (<1 second), no persistence needed
  • Automatic readiness detection with health checks

2. OAuth Test Fixtures (tests/conftest_oauth.py)

  • Session-scoped mock OAuth server fixture
  • Auto-detection of real OAuth credentials from environment
  • Seamless switching between mock and real OAuth modes
  • Test data generators (tokens, userinfo, etc.)
  • Test client with OAuth pre-configured

3. Integration Tests (tests/test_oauth_integration_flows.py)

  • 20+ comprehensive integration tests covering:
    • OAuth login initiation and redirects
    • Authorization code exchange
    • Token validation and session management
    • Admin vs non-admin authorization
    • Error handling scenarios
    • Real OAuth provider integration (when credentials available)

4. Documentation

  • tests/README_OAUTH_TESTING.md - Developer guide
  • docs/OAuth_Testing_CI_CD.md - CI/CD integration guide
  • Complete examples and troubleshooting

Key Features

Dual Mode Operation

Mock Mode (Default)

# Uses mock-oauth2-server in testcontainer
pytest tests/test_oauth_integration_flows.py -v
  • <1s startup
  • 🔒 No external dependencies
  • 🎲 Deterministic results
  • Perfect for local development

Real Mode (CI with Secrets)

# Auto-detects and uses real OAuth credentials
export AUTHENTIK_CLIENT_ID="your-client-id"
export AUTHENTIK_CLIENT_SECRET="your-client-secret"
export AUTHENTIK_CONFIG_URL="https://auth.example.com/.well-known/openid-configuration"
pytest tests/test_oauth_integration_flows.py -v -m requires_external
  • Tests real OAuth provider
  • Validates actual authentication flows
  • Uses GitHub Actions secrets
  • Perfect for integration testing

Automatic Mode Detection

  • Checks for real OAuth credentials in environment
  • Falls back to mock if credentials not available
  • Can be manually overridden with env vars
  • Gracefully skips if dependencies missing

Architecture

Test Suite
    ↓
OAuth Fixtures (conftest_oauth.py)
    ├── Mock Mode → MockOAuth2ServerContainer
    │   ├── .well-known/openid-configuration
    │   ├── /authorize
    │   ├── /token
    │   ├── /userinfo
    │   └── /jwks
    │
    └── Real Mode → Actual OAuth Provider (Authentik)
        └── Uses GitHub Actions secrets

Verification Results

Mock OAuth2 Server

  • Starts successfully in <1 second
  • Returns valid OIDC configuration
  • Provides all required OIDC endpoints
  • Can be started/stopped cleanly
  • Works with Docker in CI

Endpoints Verified

  • /.well-known/openid-configuration - OIDC discovery
  • /authorize - OAuth authorization
  • /token - Token exchange
  • /userinfo - User information
  • /jwks - JWT signing keys

Test Infrastructure

  • Fixtures load correctly
  • Auto-detection works
  • Mock/real mode switching functional
  • Integration with conftest.py successful

Usage Examples

Basic Test

@pytest.mark.integration
def test_oauth_login(oauth_enabled_app):
    """Test OAuth login redirects to provider."""
    response = oauth_enabled_app.get("/oauth-login", follow_redirects=False)
    assert response.status_code == 302
    assert "authorize" in response.headers["location"]

Test with Mock Token Exchange

from unittest.mock import patch

@pytest.mark.integration
@patch("app.auth.oauth.authentik.authorize_access_token")
async def test_oauth_callback(mock_authorize, oauth_enabled_app, test_user_info):
    """Test OAuth callback with test user."""
    mock_authorize.return_value = {
        "access_token": "test-token",
        "userinfo": test_user_info,
    }

    response = oauth_enabled_app.get("/oauth-callback?code=test-code")
    assert response.status_code == 302

GitHub Actions Integration

Basic Workflow

name: OAuth Tests

on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v4
    - uses: actions/setup-python@v5
      with:
        python-version: '3.12'
    - run: pip install -r requirements-dev.txt
    - run: pytest tests/test_oauth_integration_flows.py -v

With Real OAuth (Internal PRs)

jobs:
  test-real:
    if: github.event_name == 'push'
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v4
    - uses: actions/setup-python@v5
    - run: pip install -r requirements-dev.txt
    - env:
        AUTHENTIK_CLIENT_ID: ${{ secrets.AUTHENTIK_CLIENT_ID }}
        AUTHENTIK_CLIENT_SECRET: ${{ secrets.AUTHENTIK_CLIENT_SECRET }}
        AUTHENTIK_CONFIG_URL: ${{ secrets.AUTHENTIK_CONFIG_URL }}
      run: pytest tests/test_oauth_integration_flows.py -v -m requires_external

Benefits

Aspect Benefit
Speed <1s startup, tests complete in seconds
Reliability Deterministic, no flaky tests
Realism Tests actual OIDC protocol
Flexibility Works with mock or real OAuth
CI-Friendly Ephemeral containers, works in pipelines
Security Uses GitHub secrets for real credentials
Maintainability Industry-standard mock-oauth2-server
Documentation Comprehensive guides and examples

Technical Details

Container: ghcr.io/navikt/mock-oauth2-server:2.1.1 Framework: Testcontainers Python 4.14.1+ Test Framework: pytest with async support Languages: Python 3.12+ Dependencies: testcontainers, requests, docker

Files Created/Modified

New Files

  • tests/mock_oauth_server.py - Mock OAuth server container wrapper
  • tests/conftest_oauth.py - OAuth test fixtures
  • tests/test_oauth_integration_flows.py - Integration tests
  • tests/README_OAUTH_TESTING.md - Developer documentation
  • docs/OAuth_Testing_CI_CD.md - CI/CD guide

Modified Files

  • tests/conftest.py - Added OAuth fixtures import

Next Steps

To fully utilize this infrastructure:

  1. Run tests locally:

    pytest tests/test_oauth_integration_flows.py -v
    
  2. Add to CI pipeline:

    • Use provided GitHub Actions examples
    • Configure secrets for real OAuth testing
  3. Expand test coverage:

    • Add more OAuth flow scenarios
    • Test edge cases
    • Add performance tests
  4. Monitor and maintain:

    • Keep mock-oauth2-server image updated
    • Update tests as OAuth implementation evolves
    • Add new scenarios as needed

Conclusion

The mock OAuth2 server infrastructure is production-ready and provides:

  • Fast, reliable OAuth testing
  • Support for both mock and real OAuth providers
  • Comprehensive test coverage
  • Full CI/CD integration
  • Excellent documentation

This implementation addresses all requirements from the original issue and provides a robust foundation for OAuth testing in DocuElevate.