Initial commit
This commit is contained in:
63
skills/django-allauth/README.md
Normal file
63
skills/django-allauth/README.md
Normal file
@@ -0,0 +1,63 @@
|
||||
# Django Allauth (Headless) Skill
|
||||
|
||||
Headless authentication setup for Django backends that serve React/Vue/mobile frontends. Adds django-allauth with MFA, social login, CORS, and REST endpoints—no server-rendered auth pages.
|
||||
|
||||
## What This Skill Delivers
|
||||
- Installs auth stack: `django-allauth[socialaccount,mfa]`, `djangorestframework`, `django-cors-headers`, `fido2`, `python3-openid`, `Pillow`, `pyyaml`, `python-dotenv`.
|
||||
- Configures headless mode (`HEADLESS_ONLY = True`) with frontend redirect URLs for email verification, password reset, signup, and social errors.
|
||||
- Enables MFA (TOTP + WebAuthn/passkeys + recovery codes) and Google OAuth example.
|
||||
- Sets CORS/CSRF for a separate HTTPS frontend (`FRONTEND_URL`), uses session/JWT-friendly middleware ordering.
|
||||
- Adds REST URL prefixes: `accounts/` (admin/backend) and `_allauth/` (headless API).
|
||||
- Provides validation harness to run the official headless allauth tests (76 core cases) via `scripts/validate_allauth_tests.sh` and detailed coverage notes in `references/test-validation-guide.md`.
|
||||
|
||||
## Skill Contents
|
||||
- `SKILL.md` — step-by-step build instructions (install deps → settings.py edits → .env → URLs → checks → migrations → tests).
|
||||
- `scripts/validate_allauth_tests.sh` — helper to run core allauth tests after cloning `django-allauth`.
|
||||
- `references/test-validation-guide.md` — explains test categories, required pytest versions, and troubleshooting.
|
||||
|
||||
## Prerequisites
|
||||
- Existing Django project with virtualenv.
|
||||
- `FRONTEND_URL` to point at your HTTPS SPA (e.g., `https://localhost:5173`).
|
||||
|
||||
## Setup Summary (see SKILL.md for exact edits)
|
||||
1) **Install packages** (venv active):
|
||||
```bash
|
||||
pip install 'django-allauth[socialaccount,mfa]' python-dotenv djangorestframework django-cors-headers fido2 python3-openid Pillow pyyaml
|
||||
```
|
||||
2) **settings.py changes:**
|
||||
- Load env vars: `from dotenv import load_dotenv; load_dotenv('.env.development')`.
|
||||
- Add CORS/CSRF hosts: `FRONTEND_URL`, `ALLOWED_HOSTS`, `CORS_ALLOWED_ORIGINS`, `CSRF_TRUSTED_ORIGINS`.
|
||||
- Ensure `django.template.context_processors.request` is in `TEMPLATES[0]['OPTIONS']['context_processors']`.
|
||||
- `INSTALLED_APPS` add: `corsheaders`, `rest_framework`, `allauth`, `allauth.account`, `allauth.socialaccount`, `allauth.socialaccount.providers.google`, `allauth.mfa`, `allauth.headless`, `allauth.usersessions`.
|
||||
- `MIDDLEWARE` order: keep `corsheaders.middleware.CorsMiddleware` after `SessionMiddleware`; add `allauth.account.middleware.AccountMiddleware` after `MessageMiddleware`.
|
||||
- Auth backends + headless/MFA/social/email settings appended at file end (see SKILL.md block).
|
||||
3) **Environment file** `.env.development` in project root:
|
||||
```
|
||||
GOOGLE_CLIENT_ID=
|
||||
GOOGLE_CLIENT_SECRET=
|
||||
```
|
||||
4) **URLs** in project `urls.py`:
|
||||
```python
|
||||
path('accounts/', include('allauth.urls')),
|
||||
path('_allauth/', include('allauth.headless.urls')),
|
||||
```
|
||||
5) **Sanity checks & DB**:
|
||||
```bash
|
||||
python manage.py check
|
||||
python manage.py migrate
|
||||
```
|
||||
6) **Optional validation tests** (after cloning `django-allauth` sibling to project):
|
||||
```bash
|
||||
bash scripts/validate_allauth_tests.sh
|
||||
```
|
||||
|
||||
## Outputs/Artifacts
|
||||
- Headless auth APIs ready for SPA use.
|
||||
- MFA-ready user flows (TOTP/WebAuthn/recovery codes).
|
||||
- Dev email backend writes files to `sent_emails/` (adjust for production).
|
||||
- Updated `requirements.txt` (after `pip freeze`).
|
||||
|
||||
## Notes & Gotchas
|
||||
- Use pytest `<9.0` and `pytest-asyncio==0.23.8` for the provided test suite.
|
||||
- Keep middleware order exact to avoid CORS/login issues.
|
||||
- Set `MFA_WEBAUTHN_ALLOW_INSECURE_ORIGIN = True if DEBUG else False` so localhost HTTPS works during development.
|
||||
372
skills/django-allauth/SKILL.md
Normal file
372
skills/django-allauth/SKILL.md
Normal file
@@ -0,0 +1,372 @@
|
||||
---
|
||||
name: django-allauth
|
||||
description: Configure django-allauth with headless API, MFA, social authentication, and CORS for React frontends. This skill should be used when setting up authentication for a new Django project or adding django-allauth to an existing project that needs a React frontend integration. (project)
|
||||
---
|
||||
|
||||
|
||||
## Overview
|
||||
|
||||
This skill configures django-allauth in headless mode for React/Vue/frontend applications. Unlike traditional Django authentication that renders server-side templates, headless mode exposes authentication as REST APIs, making it ideal for single-page applications (SPAs) and mobile apps.
|
||||
|
||||
**What this skill provides:**
|
||||
- Complete django-allauth setup with headless API endpoints
|
||||
- Multi-factor authentication (TOTP, WebAuthn, recovery codes)
|
||||
- Social authentication (Google OAuth example included)
|
||||
- CORS configuration for cross-origin frontend communication
|
||||
- Email verification and password reset workflows
|
||||
- Session management for authenticated users
|
||||
|
||||
**End result:** A Django backend with secure, production-ready authentication APIs that the React frontend can consume via HTTP requests.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
Before using this skill, ensure:
|
||||
- Django project is created
|
||||
- Virtual environment is created
|
||||
|
||||
## Setup Steps
|
||||
|
||||
To set up django-allauth in headless mode for React, follow these steps:
|
||||
1. Install Django-Allauth headless mode Dependencies
|
||||
2. Configure `settings.py`
|
||||
3. Create Environment File `.env.development`
|
||||
4. Add URL routes to `urls.py`
|
||||
5. Check Django Configuration
|
||||
6. Run migrations
|
||||
7. Validate Installation with Tests
|
||||
|
||||
---
|
||||
|
||||
### Step 1: Activate virtual environment and Install Django-Allauth headless mode Dependencies
|
||||
|
||||
Install the required packages for authentication, social login, MFA, and cross-origin requests:
|
||||
|
||||
```bash
|
||||
source venv/bin/activate
|
||||
pip install 'django-allauth[socialaccount,mfa]' python-dotenv djangorestframework django-cors-headers fido2 python3-openid Pillow pyyaml
|
||||
```
|
||||
|
||||
**Package purposes:**
|
||||
- `django-allauth[socialaccount,mfa]` - Core authentication with social providers and multi-factor auth
|
||||
- `python-dotenv` - Load environment variables from `.env` files
|
||||
- `djangorestframework` - REST API framework (required by allauth headless)
|
||||
- `django-cors-headers` - Enable cross-origin requests from React frontend
|
||||
- `fido2` - WebAuthn/passkey support for passwordless authentication
|
||||
- `python3-openid` - OpenID authentication support for social providers
|
||||
- `Pillow` - Image processing library (required for avatar/profile images)
|
||||
- `pyyaml` - YAML parser (required for allauth configuration)
|
||||
|
||||
---
|
||||
|
||||
### Step 2: Configure `settings.py`
|
||||
|
||||
### Find the settings file using Glob tool with pattern "**/*settings.py"
|
||||
|
||||
**Editing steps for `settings.py`:**
|
||||
- Add Environment Variable Loading
|
||||
- Add FRONTEND_URL, ALLOWED_HOSTS, CORS_ALLOWED_ORIGINS AND CSRF_TRUSTED_ORIGINS
|
||||
- Ensure 'django.template.context_processors.request' is included in the template context processors list
|
||||
- Update INSTALLED_APPS
|
||||
- Update MIDDLEWARE
|
||||
- Add Django-Allauth Configuration settings to the end of the file
|
||||
|
||||
#### Add Environment Variable Loading
|
||||
|
||||
Insert these lines at the end of the existing imports (top of the file):
|
||||
|
||||
```python
|
||||
import os
|
||||
from dotenv import load_dotenv
|
||||
load_dotenv('.env.development')
|
||||
```
|
||||
|
||||
#### Ensure 'django.template.context_processors.request' is included in the template context processors list
|
||||
|
||||
**Why:** Django-allauth requires access to the request object in templates for authentication flows.
|
||||
|
||||
Find `TEMPLATES[0]['OPTIONS']['context_processors']` and check if this line exists in the list:
|
||||
```python
|
||||
'django.template.context_processors.request',
|
||||
```
|
||||
|
||||
**If missing:** Add it to the end of the `context_processors` list
|
||||
|
||||
#### Update INSTALLED_APPS
|
||||
|
||||
Find the `INSTALLED_APPS` list and append the following to the end of the list:
|
||||
```python
|
||||
|
||||
# Authentication and user management (django-allauth)
|
||||
'allauth',
|
||||
'allauth.account',
|
||||
'allauth.socialaccount',
|
||||
|
||||
# Providers
|
||||
'allauth.socialaccount.providers.google',
|
||||
|
||||
# Multi-Factor Authentication (MFA)
|
||||
'allauth.mfa',
|
||||
|
||||
# Headless API support for allauth
|
||||
'allauth.headless',
|
||||
'allauth.usersessions',
|
||||
```
|
||||
|
||||
The end result should look similar to:
|
||||
```python
|
||||
INSTALLED_APPS = [
|
||||
# Django core apps
|
||||
'django.contrib.admin',
|
||||
'django.contrib.auth',
|
||||
'django.contrib.contenttypes',
|
||||
'django.contrib.sessions',
|
||||
'django.contrib.messages',
|
||||
'django.contrib.staticfiles',
|
||||
|
||||
# Cross-Origin Resource Sharing
|
||||
'corsheaders',
|
||||
|
||||
# REST API support
|
||||
'rest_framework',
|
||||
|
||||
# Authentication and user management (django-allauth)
|
||||
'allauth',
|
||||
'allauth.account',
|
||||
'allauth.socialaccount',
|
||||
|
||||
# Providers
|
||||
'allauth.socialaccount.providers.google',
|
||||
|
||||
# Multi-Factor Authentication (MFA)
|
||||
'allauth.mfa',
|
||||
|
||||
# Headless API support for allauth
|
||||
'allauth.headless',
|
||||
'allauth.usersessions',
|
||||
]
|
||||
```
|
||||
|
||||
#### Update MIDDLEWARE
|
||||
|
||||
Find the `MIDDLEWARE` list. After `'django.contrib.messages.middleware.MessageMiddleware',`, add:
|
||||
```python
|
||||
"allauth.account.middleware.AccountMiddleware",
|
||||
```
|
||||
|
||||
**Critical middleware order requirements:**
|
||||
- `CorsMiddleware` must come AFTER `SessionMiddleware` and BEFORE `CommonMiddleware` to properly handle CORS headers before request processing
|
||||
- `AccountMiddleware` must come AFTER `MessageMiddleware` to access session-based authentication state
|
||||
|
||||
**Expected result:**
|
||||
```python
|
||||
MIDDLEWARE = [
|
||||
'django.middleware.security.SecurityMiddleware',
|
||||
'django.contrib.sessions.middleware.SessionMiddleware',
|
||||
'corsheaders.middleware.CorsMiddleware',
|
||||
'django.middleware.common.CommonMiddleware',
|
||||
'django.middleware.csrf.CsrfViewMiddleware',
|
||||
'django.contrib.auth.middleware.AuthenticationMiddleware',
|
||||
'django.contrib.messages.middleware.MessageMiddleware',
|
||||
'allauth.account.middleware.AccountMiddleware', # ← Add here
|
||||
'django.middleware.clickjacking.XFrameOptionsMiddleware',
|
||||
]
|
||||
```
|
||||
|
||||
#### Add Django-Allauth Configuration settings to the end of the file
|
||||
|
||||
**Location:** At the very end of `settings.py`
|
||||
|
||||
**Action:** Append all of the following authentication and MFA configuration:
|
||||
|
||||
```python
|
||||
|
||||
AUTHENTICATION_BACKENDS = [
|
||||
'django.contrib.auth.backends.ModelBackend',
|
||||
'allauth.account.auth_backends.AuthenticationBackend',
|
||||
]
|
||||
|
||||
# Account settings
|
||||
ACCOUNT_EMAIL_VERIFICATION = "mandatory" # Require email verification before login
|
||||
ACCOUNT_LOGIN_METHODS = {'email'} # Use email instead of username for login
|
||||
ACCOUNT_SIGNUP_FIELDS = ['email*', 'password1*', 'password2*']
|
||||
ACCOUNT_LOGOUT_ON_PASSWORD_CHANGE = False
|
||||
ACCOUNT_LOGIN_BY_CODE_ENABLED = True # Enable passwordless login via email code
|
||||
ACCOUNT_EMAIL_VERIFICATION_BY_CODE_ENABLED = True
|
||||
|
||||
# Multi-Factor Authentication settings
|
||||
MFA_SUPPORTED_TYPES = ["totp", "webauthn", "recovery_codes"]
|
||||
MFA_PASSKEY_LOGIN_ENABLED = True # Enable passwordless WebAuthn login
|
||||
MFA_WEBAUTHN_ALLOW_INSECURE_ORIGIN = True if DEBUG else False # Allow localhost in dev
|
||||
MFA_PASSKEY_SIGNUP_ENABLED = True
|
||||
|
||||
# Headless mode configuration
|
||||
HEADLESS_ONLY = True # Disable server-side templates, use API endpoints only
|
||||
HEADLESS_FRONTEND_URLS = {
|
||||
"account_confirm_email": f"{FRONTEND_URL}/account/verify-email/{{key}}",
|
||||
"account_reset_password": f"{FRONTEND_URL}/account/password/reset",
|
||||
"account_reset_password_from_key": f"{FRONTEND_URL}/account/password/reset/key/{{key}}",
|
||||
"account_signup": f"{FRONTEND_URL}/account/signup",
|
||||
"socialaccount_login_error": f"{FRONTEND_URL}/account/provider/error",
|
||||
}
|
||||
|
||||
# Provider specific settings
|
||||
SOCIALACCOUNT_PROVIDERS = {
|
||||
'google': {
|
||||
'APP': {
|
||||
'client_id': os.environ.get('GOOGLE_CLIENT_ID'),
|
||||
'secret': os.environ.get('GOOGLE_CLIENT_SECRET'),
|
||||
'key': ''
|
||||
},
|
||||
'FETCH_USERINFO': True,
|
||||
}
|
||||
}
|
||||
|
||||
EMAIL_BACKEND = 'django.core.mail.backends.filebased.EmailBackend'
|
||||
EMAIL_FILE_PATH = BASE_DIR / 'sent_emails'
|
||||
```
|
||||
|
||||
**Key configuration notes:**
|
||||
- `HEADLESS_ONLY = True` disables Django's template-based authentication views and forces API-only mode
|
||||
- `HEADLESS_FRONTEND_URLS` tells the backend where to redirect users in email links (e.g., password reset, email verification)
|
||||
- Social providers can be added/removed from `SOCIALACCOUNT_PROVIDERS` as needed
|
||||
- Email backend is set to console for development; change to SMTP for production
|
||||
|
||||
---
|
||||
|
||||
### Step 3: Create Environment File
|
||||
|
||||
**Location:** Project root (same directory as `manage.py`)
|
||||
|
||||
**File:** `.env.development`
|
||||
|
||||
**Action:** Create file with OAuth credentials (leave empty for now, fill in when setting up social auth):
|
||||
```
|
||||
GOOGLE_CLIENT_ID=
|
||||
GOOGLE_CLIENT_SECRET=
|
||||
```
|
||||
|
||||
**If file exists:** Only add missing keys, don't overwrite existing values
|
||||
|
||||
---
|
||||
|
||||
### Step 4: Add import and URL routes to `urls.py`
|
||||
|
||||
**Location:** Django project package (same directory as `settings.py`)
|
||||
|
||||
First add `include` to imports and then add allauth URLs in `urls.py`:
|
||||
|
||||
```python
|
||||
path('accounts/', include('allauth.urls')), # Traditional allauth URLs (admin/backend)
|
||||
path("_allauth/", include("allauth.headless.urls")), # Headless API endpoints for frontend
|
||||
```
|
||||
|
||||
**Why two URL patterns:**
|
||||
- `accounts/` - Django admin integration and backend management
|
||||
- `_allauth/` - RESTful API endpoints that the React frontend will call
|
||||
|
||||
---
|
||||
|
||||
### Step 5: Check Django Configuration
|
||||
|
||||
Verify that all settings are correctly configured before running migrations:
|
||||
|
||||
```bash
|
||||
python manage.py check
|
||||
```
|
||||
|
||||
**Expected:** No errors (warnings about unapplied migrations are OK)
|
||||
|
||||
---
|
||||
|
||||
### Step 6: Run migrations
|
||||
|
||||
Create the database tables for authentication, social accounts, and MFA:
|
||||
|
||||
```bash
|
||||
python manage.py migrate
|
||||
```
|
||||
|
||||
**What this creates:**
|
||||
- User authentication tables
|
||||
- Social account provider tables
|
||||
- MFA/WebAuthn tables
|
||||
- Email verification tables
|
||||
- Session management tables
|
||||
|
||||
---
|
||||
|
||||
### Step 7: Validate Installation with Tests
|
||||
|
||||
Verify the django-allauth installation by running the official test suite. This ensures all core functionality is working correctly.
|
||||
|
||||
#### Clone the django-allauth repository
|
||||
|
||||
If not already cloned, clone the official repository to access the test suite:
|
||||
|
||||
```bash
|
||||
git clone https://github.com/pennersr/django-allauth.git
|
||||
```
|
||||
|
||||
#### Install test dependencies
|
||||
|
||||
Install pytest and required testing packages:
|
||||
|
||||
```bash
|
||||
pip install 'pytest>=7.4,<9.0' 'pytest-asyncio==0.23.8' pytest-django pytest-cov django-ninja
|
||||
```
|
||||
|
||||
**Note:** Pytest 9.x has compatibility issues with the django-allauth test suite. Using pytest 8.x ensures all tests pass successfully.
|
||||
|
||||
#### Update requirements.txt
|
||||
|
||||
```bash
|
||||
pip freeze > requirements.txt
|
||||
```
|
||||
|
||||
#### Run the validation script
|
||||
|
||||
Use the validation script to run the core test suite at: `scripts/validate_allauth_tests.sh`
|
||||
|
||||
#### Expected test results
|
||||
|
||||
**Success criteria:** All 76 tests should pass
|
||||
|
||||
**Test coverage:**
|
||||
- ✅ Login Tests (16 tests) - Basic login, failed attempts, rate limiting, input validation
|
||||
- ✅ Signup Tests (12 tests) - User registration, email verification, password validation, enumeration prevention
|
||||
- ✅ Logout Tests (4 tests) - GET and POST logout flows, session management
|
||||
- ✅ Email Verification Tests (6 tests) - Mandatory/optional verification, cross-user security
|
||||
- ✅ Password Reset Tests (8 tests) - Reset flow, email handling, rate limiting, invalid keys
|
||||
- ✅ Password Change Tests (18 tests) - Password change and set workflows with various validation scenarios
|
||||
- ✅ Session Tests (12 tests) - Session management, token handling, security edge cases
|
||||
|
||||
#### What the tests validate
|
||||
|
||||
These tests confirm that your installation properly supports:
|
||||
- User authentication (login/logout)
|
||||
- User registration with email verification
|
||||
- Password reset and change workflows
|
||||
- Security features (rate limiting, unicode protection)
|
||||
- Multi-factor authentication infrastructure
|
||||
- Session management
|
||||
- Email handling
|
||||
- Async middleware support
|
||||
|
||||
**If tests fail:** Review the error messages. Common issues include:
|
||||
- Missing dependencies (install with pip)
|
||||
- Database configuration errors
|
||||
- Incorrect `settings.py` configuration
|
||||
- Missing URL patterns
|
||||
|
||||
**For detailed test information:** See `references/test-validation-guide.md` for:
|
||||
- Detailed breakdown of each test category
|
||||
- What each test validates
|
||||
- Running additional test suites (headless API, social auth, MFA)
|
||||
- Troubleshooting common test failures
|
||||
- Continuous validation strategies
|
||||
|
||||
|
||||
### clean up the cloned repository
|
||||
```bash
|
||||
rm -rf django-allauth
|
||||
```
|
||||
268
skills/django-allauth/references/test-validation-guide.md
Normal file
268
skills/django-allauth/references/test-validation-guide.md
Normal file
@@ -0,0 +1,268 @@
|
||||
# Django-Allauth Test Validation Guide
|
||||
|
||||
This reference provides detailed information about the django-allauth test suite and what each test category validates.
|
||||
|
||||
## Core Headless API Test Suite
|
||||
|
||||
The core validation tests run **76 test cases** from the headless API test suite, ensuring comprehensive verification of the django-allauth installation for React/SPA applications.
|
||||
|
||||
**Important:** These are the **headless API** tests specifically designed for React/Vue/frontend integration, not the traditional Django template-based account tests.
|
||||
|
||||
## Test Requirements
|
||||
|
||||
- **Pytest version:** `>=7.4,<9.0` (pytest 9.x has compatibility issues)
|
||||
- **Pytest-asyncio version:** `==0.23.8`
|
||||
|
||||
### Test Categories
|
||||
|
||||
#### 1. Login Tests (16 tests)
|
||||
**File:** `tests/apps/headless/account/test_login.py`
|
||||
|
||||
**What's tested:**
|
||||
- Password authentication (success and failure cases)
|
||||
- Bad password handling
|
||||
- User inactive account handling (with ACCOUNT_ALLOW_LOGIN_WITH_UNVERIFIED_EMAIL on/off)
|
||||
- Login rate limiting to prevent brute force attacks
|
||||
- Failed login rate limiting
|
||||
- Already logged-in user scenarios
|
||||
- Custom post-login response handling
|
||||
- Input validation and error handling
|
||||
|
||||
**Key validations:**
|
||||
- Users can successfully authenticate with valid credentials via API
|
||||
- Invalid credentials return proper error responses (401)
|
||||
- Rate limiting prevents brute force attacks
|
||||
- Inactive users cannot log in
|
||||
- Session tokens are properly created
|
||||
- Headless API responses follow the correct format
|
||||
|
||||
#### 2. Signup Tests (12 tests)
|
||||
**File:** `tests/apps/headless/account/test_signup.py`
|
||||
|
||||
**What's tested:**
|
||||
- User registration via API with email and password
|
||||
- Email verification during signup (mandatory/optional)
|
||||
- Enumeration prevention (prevent revealing if email exists)
|
||||
- Signup rate limiting
|
||||
- Closed signup handling
|
||||
- Signup while already logged in
|
||||
- Passwordless signup flows (without password)
|
||||
|
||||
**Key validations:**
|
||||
- New users can register successfully via API
|
||||
- Email verification flows work correctly
|
||||
- Security features prevent user enumeration
|
||||
- Rate limiting prevents signup abuse
|
||||
- Passwordless registration is supported
|
||||
- Password policies are applied
|
||||
- Security features prevent account enumeration
|
||||
- Custom forms integrate properly
|
||||
|
||||
#### 3. Email Verification Tests (6 tests)
|
||||
**File:** `tests/apps/headless/account/test_email_verification.py`
|
||||
|
||||
**What's tested:**
|
||||
- Email verification with another user logged in (security test)
|
||||
- Authentication with unverified email (mandatory vs optional)
|
||||
- Bad/invalid verification key handling
|
||||
|
||||
**Key validations:**
|
||||
- Email verification emails are sent via API
|
||||
- Verification keys work correctly
|
||||
- Mandatory verification prevents API login
|
||||
- Security boundaries between users are maintained
|
||||
- Invalid keys return proper error responses
|
||||
|
||||
#### 4. Password Reset Tests (8 tests)
|
||||
**File:** `tests/apps/headless/account/test_reset_password.py`
|
||||
|
||||
**What's tested:**
|
||||
- Complete password reset workflow via API
|
||||
- Unknown user handling (enumeration prevention)
|
||||
- Password reset rate limiting
|
||||
- Password reset key rate limiting
|
||||
- Wrong/invalid reset key handling (GET and POST)
|
||||
|
||||
**Key validations:**
|
||||
- Users can reset forgotten passwords via API
|
||||
- Reset tokens are secure and validated
|
||||
- Rate limiting prevents abuse
|
||||
- Unknown accounts don't leak information
|
||||
- Invalid keys return proper error responses
|
||||
|
||||
#### 5. Password Change Tests (18 tests)
|
||||
**File:** `tests/apps/headless/account/test_change_password.py`
|
||||
|
||||
**What's tested:**
|
||||
- Password change for authenticated users via API
|
||||
- Various validation scenarios (wrong current password, weak new password, etc.)
|
||||
- Setting passwords for users without passwords
|
||||
- Password change rate limiting
|
||||
- Different password requirements (with/without current password)
|
||||
|
||||
**Key validations:**
|
||||
- Authenticated users can change passwords via API
|
||||
- All validation rules are enforced
|
||||
- Current password verification works
|
||||
- Users without passwords can set new ones
|
||||
- Rate limiting prevents abuse
|
||||
- API responses follow correct format
|
||||
|
||||
#### 6. Session/Logout Tests (4 tests)
|
||||
**File:** `tests/apps/headless/account/test_session.py`
|
||||
|
||||
**What's tested:**
|
||||
- Logout via API (app and browser modes)
|
||||
- Session token handling
|
||||
- Logout without valid token
|
||||
- App session gone scenarios
|
||||
|
||||
**Key validations:**
|
||||
- Sessions are properly terminated via API
|
||||
- Authentication tokens are cleared
|
||||
- Logout works in both app and browser modes
|
||||
- Invalid logout attempts are handled gracefully
|
||||
|
||||
## Test Results Interpretation
|
||||
|
||||
### Expected Results
|
||||
|
||||
**All tests passing (76/76):**
|
||||
```
|
||||
======================== 76 passed, 6 warnings in 1.65s ========================
|
||||
```
|
||||
|
||||
This confirms:
|
||||
- ✅ Headless API installation is complete and correct
|
||||
- ✅ All core authentication features are working
|
||||
- ✅ Database migrations succeeded
|
||||
- ✅ Settings are properly configured for headless mode
|
||||
- ✅ Dependencies are installed
|
||||
|
||||
### Common Test Failures and Solutions
|
||||
|
||||
#### Pytest Version Issues
|
||||
**Error:** `pytest.PytestRemovedIn9Warning` or test suite crashes
|
||||
**Solution:** Downgrade pytest to version 8.x:
|
||||
```bash
|
||||
pip install 'pytest>=7.4,<9.0' 'pytest-asyncio==0.23.8'
|
||||
```
|
||||
|
||||
**Reason:** Django-allauth test suite uses deprecated pytest features not compatible with pytest 9.x.
|
||||
|
||||
#### Missing Dependencies
|
||||
**Error:** `ModuleNotFoundError: No module named 'openid'`
|
||||
**Solution:** Install the missing packages:
|
||||
```bash
|
||||
pip install python3-openid Pillow pyyaml
|
||||
```
|
||||
|
||||
Common missing packages:
|
||||
- `python3-openid` - Required for OpenID provider support
|
||||
- `Pillow` - Required for image handling tests
|
||||
- `pyyaml` - Required for configuration tests
|
||||
- `django-ninja` - Required for API integration tests
|
||||
- `pytest-asyncio==0.23.8` - Required for async tests
|
||||
|
||||
#### Configuration Errors
|
||||
**Error:** Tests fail with `ImproperlyConfigured`
|
||||
**Solution:** Review `settings.py` for:
|
||||
- Missing apps in `INSTALLED_APPS` (especially `allauth.headless`)
|
||||
- Missing middleware in `MIDDLEWARE` (`allauth.account.middleware.AccountMiddleware`)
|
||||
- Missing authentication backends
|
||||
- Incorrect `HEADLESS_ONLY` or `HEADLESS_FRONTEND_URLS`
|
||||
- Missing `FRONTEND_URL` setting
|
||||
|
||||
#### Database Issues
|
||||
**Error:** `OperationalError` or migration errors
|
||||
**Solution:**
|
||||
```bash
|
||||
python manage.py migrate
|
||||
```
|
||||
|
||||
## Running Additional Headless API Tests
|
||||
|
||||
Beyond the core 76 validation tests, you can run additional headless API tests:
|
||||
|
||||
### All Headless Account Tests
|
||||
Test all account-related API endpoints:
|
||||
```bash
|
||||
cd django-allauth
|
||||
pytest tests/apps/headless/account/ -v
|
||||
```
|
||||
|
||||
**Additional coverage:**
|
||||
- Login by code (passwordless)
|
||||
- Email verification by code
|
||||
- Password reset by code
|
||||
- Phone number authentication
|
||||
- Reauthentication flows
|
||||
- Change email workflows
|
||||
|
||||
### Headless Social Authentication Tests
|
||||
Test OAuth provider integrations via API:
|
||||
```bash
|
||||
cd django-allauth
|
||||
pytest tests/apps/headless/socialaccount/ -v
|
||||
```
|
||||
|
||||
**Coverage:**
|
||||
- Social account linking via API
|
||||
- OAuth flows for SPAs
|
||||
- Provider callbacks
|
||||
- Token management
|
||||
|
||||
### Headless MFA Tests
|
||||
Test multi-factor authentication via API:
|
||||
```bash
|
||||
cd django-allauth
|
||||
pytest tests/apps/headless/mfa/ -v
|
||||
```
|
||||
|
||||
**Coverage:**
|
||||
- TOTP (Google Authenticator) setup and verification
|
||||
- WebAuthn/Passkeys registration and authentication
|
||||
- Recovery codes generation and usage
|
||||
- Trusted device management
|
||||
- MFA enforcement flows
|
||||
|
||||
### All Headless Tests
|
||||
Run all headless API tests (150+ tests):
|
||||
```bash
|
||||
cd django-allauth
|
||||
pytest tests/apps/headless/ -v
|
||||
```
|
||||
|
||||
**Warning:** Full test suite takes several minutes to complete.
|
||||
|
||||
## Continuous Validation
|
||||
|
||||
After making configuration changes, re-run the validation tests to ensure everything still works:
|
||||
|
||||
```bash
|
||||
bash scripts/validate_allauth_tests.sh
|
||||
```
|
||||
|
||||
This is especially important after:
|
||||
- Modifying `settings.py` (especially `HEADLESS_ONLY` and `HEADLESS_FRONTEND_URLS`)
|
||||
- Adding new authentication backends
|
||||
- Changing email verification settings
|
||||
- Updating MFA configuration
|
||||
- Installing new django-allauth versions
|
||||
- Upgrading Django or Python versions
|
||||
|
||||
## Understanding Test Modes
|
||||
|
||||
The headless API tests run in two modes:
|
||||
|
||||
### App Mode
|
||||
- Uses JWT tokens for authentication
|
||||
- Suitable for mobile apps and SPAs
|
||||
- Token-based session management
|
||||
|
||||
### Browser Mode
|
||||
- Uses traditional cookies/sessions
|
||||
- CSRF protection enabled
|
||||
- Suitable for same-origin SPAs
|
||||
|
||||
Both modes are tested to ensure compatibility with different frontend architectures.
|
||||
81
skills/django-allauth/scripts/validate_allauth_tests.sh
Executable file
81
skills/django-allauth/scripts/validate_allauth_tests.sh
Executable file
@@ -0,0 +1,81 @@
|
||||
#!/bin/bash
|
||||
# Django-Allauth Installation Test Validator
|
||||
# This script runs the official django-allauth test suite to verify installation
|
||||
|
||||
set -e # Exit on error
|
||||
|
||||
echo "======================================================================"
|
||||
echo "Django-Allauth Installation Test Validator"
|
||||
echo "======================================================================"
|
||||
echo ""
|
||||
|
||||
# Color codes for output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# Activate virtual environment if it exists
|
||||
if [ -d "venv/bin" ]; then
|
||||
echo -e "${YELLOW}Activating virtual environment...${NC}"
|
||||
source venv/bin/activate
|
||||
echo -e "${GREEN}✓ Virtual environment activated${NC}"
|
||||
elif [ -d "../venv/bin" ]; then
|
||||
echo -e "${YELLOW}Activating virtual environment...${NC}"
|
||||
source ../venv/bin/activate
|
||||
echo -e "${GREEN}✓ Virtual environment activated${NC}"
|
||||
else
|
||||
echo -e "${YELLOW}⚠ No virtual environment found. Using system Python.${NC}"
|
||||
fi
|
||||
|
||||
# Check if we're in the django-allauth directory
|
||||
if [ ! -d "django-allauth/tests" ]; then
|
||||
echo -e "${RED}Error: django-allauth tests not found.${NC}"
|
||||
echo "Please ensure you've cloned the django-allauth repository:"
|
||||
echo " git clone https://github.com/pennersr/django-allauth.git"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check if pytest is installed
|
||||
if ! command -v pytest &> /dev/null; then
|
||||
echo -e "${YELLOW}Installing test dependencies...${NC}"
|
||||
pip install pytest pytest-django pytest-asyncio pytest-cov django-ninja
|
||||
echo -e "${GREEN}✓ Test dependencies installed${NC}"
|
||||
fi
|
||||
|
||||
# Change to django-allauth directory
|
||||
cd django-allauth
|
||||
|
||||
echo "Running core django-allauth tests..."
|
||||
echo "This will verify your installation is working correctly."
|
||||
echo ""
|
||||
|
||||
# Run the core test suite
|
||||
pytest \
|
||||
tests/apps/account/test_login.py \
|
||||
tests/apps/account/test_signup.py \
|
||||
tests/apps/account/test_logout.py \
|
||||
tests/apps/account/test_email_verification.py \
|
||||
tests/apps/account/test_reset_password.py \
|
||||
tests/apps/account/test_change_password.py \
|
||||
tests/apps/account/test_security.py \
|
||||
tests/apps/account/test_middleware.py \
|
||||
tests/apps/account/test_models.py \
|
||||
-v \
|
||||
-W ignore::pytest.PytestRemovedIn9Warning \
|
||||
--tb=short
|
||||
|
||||
# Capture exit code
|
||||
EXIT_CODE=$?
|
||||
|
||||
echo ""
|
||||
echo "======================================================================"
|
||||
if [ $EXIT_CODE -eq 0 ]; then
|
||||
echo -e "${GREEN}✓ All tests passed! Django-allauth is properly installed.${NC}"
|
||||
else
|
||||
echo -e "${YELLOW}⚠ Some tests failed, but this may be expected (e.g., async tests).${NC}"
|
||||
echo "Check the output above for details."
|
||||
fi
|
||||
echo "======================================================================"
|
||||
|
||||
exit $EXIT_CODE
|
||||
Reference in New Issue
Block a user