### Install Dependencies with uv Source: https://github.com/fernaper/fastapi-oauth-rbac/blob/main/AGENTS.md Use this command to install project dependencies and set up the virtual environment. ```bash uv sync ``` -------------------------------- ### Initialize FastAPIOAuthRBAC in FastAPI App Source: https://github.com/fernaper/fastapi-oauth-rbac/blob/main/README.md Quick start example demonstrating the minimal setup for initializing the FastAPIOAuthRBAC library with a FastAPI application. Includes including authentication and dashboard routes. ```python from fastapi import FastAPI from fastapi_oauth_rbac import FastAPIOAuthRBAC app = FastAPI() # Initialize with default settings or your own Settings object auth = FastAPIOAuthRBAC(app) # Explicitly include the routes you want auth.include_auth_router() auth.include_dashboard() ``` -------------------------------- ### Install FastAPI-OAuth-RBAC Source: https://github.com/fernaper/fastapi-oauth-rbac/blob/main/docs/getting-started.md Install the library using pip. Choose the appropriate command based on your database needs. ```bash pip install fastapi-oauth-rbac ``` ```bash pip install "fastapi-oauth-rbac[sqlite]" ``` ```bash pip install "fastapi-oauth-rbac[postgres]" ``` ```bash uv add fastapi-oauth-rbac --extra sqlite ``` -------------------------------- ### Install FastAPIOAuthRBAC using uv Source: https://context7.com/fernaper/fastapi-oauth-rbac/llms.txt Install the library using the 'uv' package manager, including the extra for SQLite support. ```bash uv add fastapi-oauth-rbac --extra sqlite ``` -------------------------------- ### Install FastAPIOAuthRBAC with PostgreSQL Support Source: https://github.com/fernaper/fastapi-oauth-rbac/blob/main/README.md Command to install the fastapi-oauth-rbac library with support for PostgreSQL databases. ```bash pip install "fastapi-oauth-rbac[postgres]" ``` -------------------------------- ### Install FastAPIOAuthRBAC with SQLite Support Source: https://github.com/fernaper/fastapi-oauth-rbac/blob/main/README.md Command to install the fastapi-oauth-rbac library with support for asynchronous SQLite databases. ```bash pip install "fastapi-oauth-rbac[sqlite]" ``` -------------------------------- ### Configure FastAPIOAuthRBAC settings via .env file Source: https://context7.com/fernaper/fastapi-oauth-rbac/llms.txt Example of how to configure FastAPIOAuthRBAC settings using a .env file. Environment variables should be prefixed with FORBAC_. ```dotenv # .env FORBAC_DATABASE_URL=sqlite+aiosqlite:///./app.db FORBAC_JWT_SECRET_KEY=super-secret-key FORBAC_JWT_ALGORITHM=HS256 FORBAC_ACCESS_TOKEN_EXPIRE_MINUTES=30 FORBAC_REFRESH_TOKEN_EXPIRE_DAYS=7 FORBAC_ADMIN_EMAIL=admin@example.com FORBAC_ADMIN_PASSWORD=admin123 FORBAC_SIGNUP_ENABLED=true FORBAC_VERIFY_EMAIL_ENABLED=false FORBAC_REQUIRE_VERIFIED_LOGIN=false FORBAC_AUTH_REVOCATION_ENABLED=false FORBAC_AUDIT_ENABLED=true FORBAC_DASHBOARD_ENABLED=true FORBAC_DASHBOARD_PATH=/auth/dashboard FORBAC_GOOGLE_OAUTH_CLIENT_ID=xxx.apps.googleusercontent.com FORBAC_GOOGLE_OAUTH_CLIENT_SECRET=GOCSPX-xxx FORBAC_GOOGLE_OAUTH_REDIRECT_URI=https://myapp.com/auth/google/callback ``` -------------------------------- ### Initialize FastAPIOAuthRBAC with minimal settings Source: https://context7.com/fernaper/fastapi-oauth-rbac/llms.txt Initialize the FastAPIOAuthRBAC class with a FastAPI application instance. This minimal setup reads configuration from environment variables prefixed with FORBAC_. ```python from fastapi import FastAPI from fastapi_oauth_rbac import FastAPIOAuthRBAC, Settings app = FastAPI(title="My App") # Minimal — reads config from env vars prefixed FORBAC_ auth = FastAPIOAuthRBAC(app) auth.include_auth_router() # mounts /auth/login, /signup, /logout, /me, /refresh, … auth.include_dashboard() # mounts glassmorphism admin UI at /auth/dashboard ``` -------------------------------- ### Multi-Tenancy Example Source: https://context7.com/fernaper/fastapi-oauth-rbac/llms.txt Illustrates how the RBACManager handles multi-tenancy by automatically filtering roles based on the user's tenant ID, preventing cross-tenant access. ```APIDOC ## GET /global-data ### Description Retrieves global data, accessible by any user with the 'data:read' permission, regardless of tenant. ### Method GET ### Endpoint /global-data ### Parameters None ### Request Example None ### Response #### Success Response (200) - **message** (string) - A message indicating global data access. #### Response Example ```json { "message": "Global data" } ``` ## GET /org-secret ### Description Retrieves organization-specific secrets. Access is restricted to users whose assigned roles match their tenant ID. ### Method GET ### Endpoint /org-secret ### Parameters None ### Request Example None ### Response #### Success Response (200) - **secret** (string) - The organization-specific secret. #### Response Example ```json { "secret": "Secret for org_a" } ``` ``` -------------------------------- ### Query Active Admin Users with Roles Source: https://context7.com/fernaper/fastapi-oauth-rbac/llms.txt Example of querying active users and filtering them by role name using SQLAlchemy. ```python from fastapi_oauth_rbac.database.models import ( User, Role, Permission, AuditLog, UserBaseMixin, Base, ) from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy import select from sqlalchemy.orm import selectinload async def get_admin_users(db: AsyncSession): stmt = ( select(User) .options(selectinload(User.roles)) .where(User.is_active == True) ) result = await db.execute(stmt) users = result.scalars().all() return [u for u in users if any(r.name == "admin" for r in u.roles)] ``` -------------------------------- ### Custom Email Exporter with SendGrid Source: https://context7.com/fernaper/fastapi-oauth-rbac/llms.txt Implement a custom email exporter by subclassing `BaseEmailExporter`. This example shows integration with SendGrid for sending verification and password reset emails. ```python from fastapi_oauth_rbac import BaseEmailExporter, FastAPIOAuthRBAC import httpx class SendGridExporter(BaseEmailExporter): SENDGRID_API_KEY = "SG.xxx" async def send_verification_email(self, user, token: str): verify_url = f"https://myapp.com/verify?token={token}" async with httpx.AsyncClient() as client: await client.post( "https://api.sendgrid.com/v3/mail/send", headers={"Authorization": f"Bearer {self.SENDGRID_API_KEY}"}, json={ "to": [{"email": user.email}], "from": {"email": "noreply@myapp.com"}, "subject": "Verify your email", "content": [{"type": "text/plain", "value": f"Click: {verify_url}"}] }, ) async def send_password_reset_email(self, user, token: str): reset_url = f"https://myapp.com/reset?token={token}" async with httpx.AsyncClient() as client: await client.post( "https://api.sendgrid.com/v3/mail/send", headers={"Authorization": f"Bearer {self.SENDGRID_API_KEY}"}, json={ "to": [{"email": user.email}], "from": {"email": "noreply@myapp.com"}, "subject": "Reset your password", "content": [{"type": "text/plain", "value": f"Click: {reset_url}"}] }, ) app = FastAPI() auth = FastAPIOAuthRBAC(app, email_exporter=SendGridExporter()) auth.include_auth_router() ``` -------------------------------- ### Password Reset Flow Source: https://context7.com/fernaper/fastapi-oauth-rbac/llms.txt Manages the password reset process, starting with requesting a reset token via email and then confirming the reset with the token and new password. ```APIDOC ## POST /auth/forgot-password — Initiate Password Reset ### Description Initiates the password reset process by sending a reset token to the user's email. ### Method POST ### Endpoint /auth/forgot-password ### Request Body - **email** (string) - Required - The email address of the user requesting a password reset. ### Request Example ```bash curl -X POST http://localhost:8000/auth/forgot-password \ -H "Content-Type: application/json" \ -d '"alice@example.com"' ``` ### Response #### Success Response (200) - **message** (string) - Confirmation message indicating that a reset link will be sent if the email is registered. - **debug_token** (string) - A debug token (optional, for development/testing purposes). ## POST /auth/reset-password — Confirm Password Reset ### Description Completes the password reset process by accepting a token and a new password. ### Method POST ### Endpoint /auth/reset-password ### Request Body - **token** (string) - Required - The password reset token received via email. - **new_password** (string) - Required - The new password for the user. ### Request Example ```bash curl -X POST http://localhost:8000/auth/reset-password \ -H "Content-Type: application/json" \ -d '{"token": "eyJ...", "new_password": "NewSecurePass456"}' ``` ### Response #### Success Response (200) - **message** (string) - Confirmation message indicating the password has been reset successfully. ``` -------------------------------- ### Get Current User Profile with curl Source: https://context7.com/fernaper/fastapi-oauth-rbac/llms.txt Retrieve the authenticated user's profile information, including email, verification status, roles, and permissions, using a bearer token. ```bash curl http://localhost:8000/auth/me \ -H "Authorization: Bearer " # Response: # { # "email": "alice@example.com", # "is_active": true, # "is_verified": true, # "roles": ["user", "editor"], # "permissions": ["content:read", "content:update", "users:read"] ``` -------------------------------- ### User Registration with httpx Source: https://context7.com/fernaper/fastapi-oauth-rbac/llms.txt Programmatically register a new user using `httpx`. The `tenant_id` is optional for global users. ```python import httpx async with httpx.AsyncClient(base_url="http://localhost:8000") as client: r = await client.post("/auth/signup", json={ "email": "alice@example.com", "password": "SecurePass123", "tenant_id": "org_a", # optional — omit for global users }) print(r.json()) # {'message': 'User created successfully', 'email': 'alice@example.com'} ``` -------------------------------- ### Initialize FastAPIOAuthRBAC Source: https://github.com/fernaper/fastapi-oauth-rbac/blob/main/docs/api-reference.md Instantiate the main class with optional user model, settings, and email exporter. ```python FastAPIOAuthRBAC( app: FastAPI, user_model: Optional[Type] = None, settings: Optional[Settings] = None, email_exporter: Optional[BaseEmailExporter] = None, ) ``` -------------------------------- ### User Registration with POST /auth/signup Source: https://context7.com/fernaper/fastapi-oauth-rbac/llms.txt Use this endpoint to create a new user, assigning the default 'user' role. It triggers the `post_signup` hook and can optionally send a verification email. ```bash curl -X POST http://localhost:8000/auth/signup \ -H "Content-Type: application/json" \ -d '{"email": "alice@example.com", "password": "SecurePass123", "tenant_id": "org_a"}' # Response: {"message": "User created successfully", "email": "alice@example.com"} ``` -------------------------------- ### Get Current User Profile Source: https://context7.com/fernaper/fastapi-oauth-rbac/llms.txt Retrieves the profile information for the currently authenticated user, including their email, verification status, roles, and permissions. ```APIDOC ## GET /auth/me — Current User Profile ### Description Returns the authenticated user's email, verification status, roles, and resolved permission set (including inherited and wildcard-expanded permissions). ### Method GET ### Endpoint /auth/me ### Parameters #### Query Parameters None #### Headers - **Authorization** (string) - Required - Bearer token for authentication (e.g., `Bearer `) ### Response #### Success Response (200) - **email** (string) - The user's email address. - **is_active** (boolean) - Indicates if the user account is active. - **is_verified** (boolean) - Indicates if the user's email has been verified. - **roles** (array of strings) - A list of roles assigned to the user. - **permissions** (array of strings) - A list of permissions granted to the user. ### Response Example ```json { "email": "alice@example.com", "is_active": true, "is_verified": true, "roles": ["user", "editor"], "permissions": ["content:read", "content:update", "users:read"] } ``` ``` -------------------------------- ### auth.add_role() - Custom Role Registration Source: https://context7.com/fernaper/fastapi-oauth-rbac/llms.txt Register custom roles with specific permissions before the application lifespan seeds the database. This ensures custom roles are available from the start. ```APIDOC ## auth.add_role() — Custom Role Registration ### Description Registers application-specific roles with explicit permissions before the lifespan seeds the database. This ensures custom roles are available from the start. ### Usage ```python from fastapi import FastAPI from fastapi_oauth_rbac import FastAPIOAuthRBAC app = FastAPI() auth = FastAPIOAuthRBAC(app) # Register before include_auth_router so roles exist on first startup auth.add_role( name="editor", description="Can read and update content", permissions=["content:read", "content:update"], ) auth.add_role( name="content_manager", description="Full access to content resources", permissions=["content:*"], # prefix wildcard: matches content:read, content:update, … ) auth.add_role( name="billing_admin", description="Full billing access", permissions=["billing:*", "invoices:*"], ) auth.include_auth_router() auth.include_dashboard() ``` ``` -------------------------------- ### Create a Tenant User Source: https://github.com/fernaper/fastapi-oauth-rbac/blob/main/docs/multi-tenancy.md Assign a `tenant_id` when creating a new user to associate them with a specific organization. ```python user = User(email="user@org1.com", tenant_id="org_123") db.add(user) ``` -------------------------------- ### Initiate Google OAuth Login (Vanilla JS) Source: https://github.com/fernaper/fastapi-oauth-rbac/blob/main/docs/frontend-integration.md Use this function to redirect the user to Google's OAuth consent screen. Ensure `REDIRECT_URI` and `GOOGLE_CLIENT_ID` are correctly configured. ```javascript const GOOGLE_CLIENT_ID = 'YOUR_GOOGLE_CLIENT_ID'; // Ensure this URI is registered in Google Cloud Console const REDIRECT_URI = 'http://localhost:3000/callback'; // 1. Initiate Login function loginWithGoogle() { const rootUrl = 'https://accounts.google.com/o/oauth2/v2/auth'; const options = { redirect_uri: REDIRECT_URI, client_id: GOOGLE_CLIENT_ID, access_type: 'offline', response_type: 'code', prompt: 'consent', scope: [ 'https://www.googleapis.com/auth/userinfo.profile', 'https://www.googleapis.com/auth/userinfo.email', ].join(' '), }; const qs = new URLSearchParams(options); window.location.href = `${rootUrl}?${qs.toString()}`; } ``` -------------------------------- ### FastAPIOAuthRBAC Initialization Source: https://github.com/fernaper/fastapi-oauth-rbac/blob/main/docs/api-reference.md Initialize the FastAPIOAuthRBAC class with optional user model, settings, and email exporter. ```APIDOC ## FastAPIOAuthRBAC Initialization ### Description Initializes the main entry point for the library, attaching it to a FastAPI application. ### Parameters - `app` (FastAPI) - The FastAPI instance to attach to. - `user_model` (Optional[Type]) - Your custom SQLAlchemy user model. Defaults to internal `User`. - `settings` (Optional[Settings]) - A `Settings` object for configuration. If not provided, it loads from environment variables with `FORBAC_` prefix. - `email_exporter` (Optional[BaseEmailExporter]) - Custom email service implementation. ``` -------------------------------- ### Get Current User Dependency Source: https://github.com/fernaper/fastapi-oauth-rbac/blob/main/docs/api-reference.md Use the get_current_user dependency to retrieve the authenticated user from a JWT token. It raises a 401 Unauthorized error if the token is missing or invalid. ```python from fastapi import Depends from fastapi_oauth_rbac import get_current_user, User @app.get("/users/me") async def read_me(user: User = Depends(get_current_user)): return user ``` -------------------------------- ### Configure Google OAuth with FastAPI Source: https://context7.com/fernaper/fastapi-oauth-rbac/llms.txt Set up Google OAuth integration in FastAPI by providing client ID, secret, and redirect URI. Ensure these are set in your .env file. ```dotenv # .env settings required for Google OAuth # FORBAC_GOOGLE_OAUTH_CLIENT_ID=xxx.apps.googleusercontent.com # FORBAC_GOOGLE_OAUTH_CLIENT_SECRET=GOCSPX-xxx # FORBAC_GOOGLE_OAUTH_REDIRECT_URI=http://localhost:8000/auth/google/callback ``` ```python from fastapi_oauth_rbac import FastAPIOAuthRBAC, Settings settings = Settings( GOOGLE_OAUTH_CLIENT_ID="xxx.apps.googleusercontent.com", GOOGLE_OAUTH_CLIENT_SECRET="GOCSPX-xxx", GOOGLE_OAUTH_REDIRECT_URI="http://localhost:8000/auth/google/callback", ) auth = FastAPIOAuthRBAC(app, settings=settings) auth.include_auth_router() ``` -------------------------------- ### POST /auth/signup - User Registration Source: https://context7.com/fernaper/fastapi-oauth-rbac/llms.txt Creates a new user in the system and assigns the default 'user' role. This endpoint also triggers the `post_signup` hook and can optionally send a verification email. ```APIDOC ## `POST /auth/signup` — User Registration Creates a new user and assigns the default `user` role. Fires `post_signup` hook and optionally sends a verification email. ### Request Body - **email** (string) - Required - The email address of the new user. - **password** (string) - Required - The password for the new user. - **tenant_id** (string) - Optional - The ID of the tenant the user belongs to. Omit for global users. ### Request Example (curl) ```bash curl -X POST http://localhost:8000/auth/signup \ -H "Content-Type: application/json" \ -d '{"email": "alice@example.com", "password": "SecurePass123", "tenant_id": "org_a"}' ``` ### Request Example (Python httpx) ```python import httpx async with httpx.AsyncClient(base_url="http://localhost:8000") as client: r = await client.post("/auth/signup", json={ "email": "alice@example.com", "password": "SecurePass123", "tenant_id": "org_a", # optional — omit for global users }) print(r.json()) ``` ### Response Example ```json { "message": "User created successfully", "email": "alice@example.com" } ``` ``` -------------------------------- ### Initialize FastAPIOAuthRBAC Source: https://github.com/fernaper/fastapi-oauth-rbac/blob/main/docs/README.md Basic initialization of the FastAPIOAuthRBAC library with a FastAPI application. This includes including the authentication router and the admin dashboard. Configuration can be done via environment variables or explicit settings. ```python from fastapi import FastAPI from fastapi_oauth_rbac import FastAPIOAuthRBAC app = FastAPI() # Initialize (environment variables prefixed with FORBAC_ or explicit settings) auth = FastAPIOAuthRBAC(app) auth.include_auth_router() auth.include_dashboard() ``` -------------------------------- ### Register Post Signup Event Hook Source: https://github.com/fernaper/fastapi-oauth-rbac/blob/main/docs/api-reference.md Register a callback function to be executed after a user signs up. Available events include post_signup, post_login, post_password_reset, and post_email_verify. ```python auth = FastAPIOAuthRBAC(app) @auth.hooks.register("post_signup") async def welcome_user(user, **kwargs): print(f"Welcome {user.email}!") ``` -------------------------------- ### Testing Protected Routes with AuthTestClient Source: https://context7.com/fernaper/fastapi-oauth-rbac/llms.txt Demonstrates how to use `AuthTestClient` to simulate authenticated and unauthorized access to protected API routes during testing. ```APIDOC ## GET /protected ### Description A protected endpoint that requires the 'reports:read' permission. ### Method GET ### Endpoint /protected ### Parameters None ### Request Example None ### Response #### Success Response (200) - **data** (string) - A message indicating secret data. #### Response Example ```json { "data": "secret" } ``` ``` -------------------------------- ### include_auth_router Source: https://github.com/fernaper/fastapi-oauth-rbac/blob/main/docs/api-reference.md Mounts the authentication endpoints for login, signup, logout, and user profile. ```APIDOC ## include_auth_router() ### Description Mounts the authentication endpoints (`/login`, `/signup`, `/logout`, `/me`) to the FastAPI application. ### Method `FastAPIOAuthRBAC.include_auth_router()` ``` -------------------------------- ### FastAPIOAuthRBAC Initialization Source: https://context7.com/fernaper/fastapi-oauth-rbac/llms.txt Initialize the FastAPIOAuthRBAC class with an optional custom user model, settings object, and email exporter. This bootstraps the database schema, seeds default roles and an admin user, and wraps the app's lifespan automatically. ```APIDOC ## FastAPIOAuthRBAC Initialization ### Description Initialize the FastAPIOAuthRBAC class with an optional custom user model, settings object, and email exporter. This bootstraps the database schema, seeds default roles and an admin user, and wraps the app's lifespan automatically. ### Usage ```python from fastapi import FastAPI from fastapi_oauth_rbac import FastAPIOAuthRBAC, Settings app = FastAPI(title="My App") # Minimal initialization (reads config from env vars prefixed FORBAC_) auth = FastAPIOAuthRBAC(app) auth.include_auth_router() # mounts /auth/login, /signup, /logout, /me, /refresh, … auth.include_dashboard() # mounts glassmorphism admin UI at /auth/dashboard # Initialization with explicit settings custom_settings = Settings( DATABASE_URL="postgresql+asyncpg://user:pass@localhost/mydb", JWT_SECRET_KEY="change-me-in-production", ADMIN_EMAIL="superadmin@myapp.com", ADMIN_PASSWORD="StrongP@ss1", SIGNUP_ENABLED=True, VERIFY_EMAIL_ENABLED=True, REQUIRE_VERIFIED_LOGIN=True, AUDIT_ENABLED=True, DASHBOARD_PATH="/admin", ) auth = FastAPIOAuthRBAC(app, settings=custom_settings) auth.include_auth_router() auth.include_dashboard(path="/admin") ``` ``` -------------------------------- ### Initialize FastAPIOAuthRBAC with explicit settings Source: https://context7.com/fernaper/fastapi-oauth-rbac/llms.txt Initialize the FastAPIOAuthRBAC class with explicit settings provided via a Settings object. This allows programmatic configuration of database URL, JWT secrets, admin credentials, and feature flags. ```python # ── OR pass explicit settings ────────────────────────────────────────────── custom_settings = Settings( DATABASE_URL="postgresql+asyncpg://user:pass@localhost/mydb", JWT_SECRET_KEY="change-me-in-production", ADMIN_EMAIL="superadmin@myapp.com", ADMIN_PASSWORD="StrongP@ss1", SIGNUP_ENABLED=True, VERIFY_EMAIL_ENABLED=True, REQUIRE_VERIFIED_LOGIN=True, AUDIT_ENABLED=True, DASHBOARD_PATH="/admin", ) auth = FastAPIOAuthRBAC(app, settings=custom_settings) auth.include_auth_router() auth.include_dashboard(path="/admin") ``` -------------------------------- ### Run Tests with Coverage Source: https://github.com/fernaper/fastapi-oauth-rbac/blob/main/AGENTS.md Run all tests and generate a code coverage report for the fastapi_oauth_rbac module. This helps identify areas that need more test coverage. ```bash uv run pytest --cov=fastapi_oauth_rbac ``` -------------------------------- ### Permission Checks with OR, AND, and NOT Source: https://context7.com/fernaper/fastapi-oauth-rbac/llms.txt Demonstrates how to define route dependencies using various permission logic operators. Ensure the `requires_permission` decorator is imported. ```python from fastapi import FastAPI from fastapi_oauth_rbac import requires_permission, Or, And, Not app = FastAPI() # OR: either permission is sufficient @app.get("/reports", dependencies=[requires_permission(Or("reports:read", "admin:access"))]) async def get_reports(): return {"data": "reports"} # AND (via list shorthand): BOTH permissions required @app.post("/users", dependencies=[requires_permission(["users:write", "roles:manage"])]) async def create_user(): return {"status": "created"} # NOT: user must NOT have the guest flag @app.get("/premium", dependencies=[requires_permission(Not("guest:access"))]) async def premium(): return {"tier": "premium"} # Complex nested: (billing:read OR admin:access) AND NOT suspended:flag complex_req = And( Or("billing:read", "admin:access"), Not("suspended:flag"), ) @app.get("/invoices", dependencies=[requires_permission(complex_req)]) async def invoices(): return {"invoices": []} ``` -------------------------------- ### Password Login and Token Usage with httpx Source: https://context7.com/fernaper/fastapi-oauth-rbac/llms.txt Authenticate a user and use the obtained access token for subsequent requests. The response includes access and refresh tokens. ```python import httpx async with httpx.AsyncClient(base_url="http://localhost:8000") as client: r = await client.post("/auth/login", data={ "username": "alice@example.com", "password": "SecurePass123", }) tokens = r.json() access_token = tokens["access_token"] # Use in subsequent requests r2 = await client.get("/me", headers={"Authorization": f"Bearer {access_token}"}) print(r2.json()) # {'email': 'alice@example.com', 'roles': ['user'], 'permissions': ['users:read', ...]} ``` -------------------------------- ### Register custom roles with permissions Source: https://context7.com/fernaper/fastapi-oauth-rbac/llms.txt Register custom roles and their associated permissions using `auth.add_role()` before including the authentication router. This ensures roles are available on the first application startup. ```python from fastapi import FastAPI from fastapi_oauth_rbac import FastAPIOAuthRBAC app = FastAPI() auth = FastAPIOAuthRBAC(app) # Register before include_auth_router so roles exist on first startup auth.add_role( name="editor", description="Can read and update content", permissions=["content:read", "content:update"], ) auth.add_role( name="content_manager", description="Full access to content resources", permissions=["content:*"], # prefix wildcard: matches content:read, content:update, … ) auth.add_role( name="billing_admin", description="Full billing access", permissions=["billing:*", "invoices:*"], ) auth.include_auth_router() auth.include_dashboard() ``` -------------------------------- ### Basic AuthTestClient Usage Source: https://github.com/fernaper/fastapi-oauth-rbac/blob/main/docs/testing.md Use AuthTestClient to log in as a specific user with defined scopes and then make requests to protected routes. ```python from fastapi.testclient import TestClient from fastapi_oauth_rbac.testing import AuthTestClient from my_app import app client = TestClient(app) auth_client = AuthTestClient(client) def test_protected_route(): # Login as a user with specific permissions auth_client.login_as("user@example.com", scopes=["users:read"]) response = client.get("/users/me") assert response.status_code == 200 ``` -------------------------------- ### Inject Settings Object for FastAPI OAuth RBAC Source: https://github.com/fernaper/fastapi-oauth-rbac/blob/main/docs/configuration.md Demonstrates loading settings from environment variables or providing explicit values via a Settings object during initialization. Use explicit values for dynamic configurations or testing. ```python from fastapi_oauth_rbac import FastAPIOAuthRBAC, Settings # Load settings from environment (default behavior) auth = FastAPIOAuthRBAC(app) # OR provide explicit values custom_settings = Settings( DATABASE_URL="postgresql+asyncpg://user:pass@localhost/db", JWT_SECRET_KEY="my-super-secret-key", SIGNUP_ENABLED=False ) auth = FastAPIOAuthRBAC(app, settings=custom_settings) ``` -------------------------------- ### Manual Header Generation with AuthTestClient Source: https://github.com/fernaper/fastapi-oauth-rbac/blob/main/docs/testing.md Generate authentication headers manually for requests when you need more control over the request process. ```python from fastapi_oauth_rbac.testing import AuthTestClient auth = AuthTestClient(None) headers = auth.get_auth_headers("admin@example.com", scopes=["*"]) response = client.get("/admin/config", headers=headers) ``` -------------------------------- ### Settings Configuration Source: https://context7.com/fernaper/fastapi-oauth-rbac/llms.txt Configure FastAPIOAuthRBAC settings either via a .env file or environment variables prefixed with FORBAC_. Programmatic overrides are also supported. ```APIDOC ## Settings Configuration ### Description Configure FastAPIOAuthRBAC settings either via a .env file or environment variables prefixed with `FORBAC_`. Programmatic overrides are also supported. ### Environment Variables Example ```env FORBAC_DATABASE_URL=sqlite+aiosqlite:///./app.db FORBAC_JWT_SECRET_KEY=super-secret-key FORBAC_JWT_ALGORITHM=HS256 FORBAC_ACCESS_TOKEN_EXPIRE_MINUTES=30 FORBAC_REFRESH_TOKEN_EXPIRE_DAYS=7 FORBAC_ADMIN_EMAIL=admin@example.com FORBAC_ADMIN_PASSWORD=admin123 FORBAC_SIGNUP_ENABLED=true FORBAC_VERIFY_EMAIL_ENABLED=false FORBAC_REQUIRE_VERIFIED_LOGIN=false FORBAC_AUTH_REVOCATION_ENABLED=false FORBAC_AUDIT_ENABLED=true FORBAC_DASHBOARD_ENABLED=true FORBAC_DASHBOARD_PATH=/auth/dashboard FORBAC_GOOGLE_OAUTH_CLIENT_ID=xxx.apps.googleusercontent.com FORBAC_GOOGLE_OAUTH_CLIENT_SECRET=GOCSPX-xxx FORBAC_GOOGLE_OAUTH_REDIRECT_URI=https://myapp.com/auth/google/callback ``` ### Programmatic Override Example ```python from fastapi_oauth_rbac import Settings # Programmatic override (useful for tests) settings = Settings( DATABASE_URL="sqlite+aiosqlite:///:memory:", JWT_SECRET_KEY="test-secret", ADMIN_EMAIL="test@example.com", ADMIN_PASSWORD="testpass", SIGNUP_ENABLED=True, AUDIT_ENABLED=False, ) ``` ``` -------------------------------- ### Run All Tests with pytest Source: https://github.com/fernaper/fastapi-oauth-rbac/blob/main/AGENTS.md Execute all tests in the project using pytest. Ensure all tests pass before submitting changes. ```bash uv run pytest ``` -------------------------------- ### Create Scoped Roles Source: https://github.com/fernaper/fastapi-oauth-rbac/blob/main/docs/multi-tenancy.md Define roles with a specific `tenant_id` to limit their visibility and applicability to users within that tenant. ```python org1_role = Role(name="OrgManager", tenant_id="org_123", permissions=[...]) db.add(org1_role) ``` -------------------------------- ### Multi-Tenancy with RBAC Source: https://context7.com/fernaper/fastapi-oauth-rbac/llms.txt Illustrates how `FastAPIOAuthRBAC` handles multi-tenancy by automatically filtering roles based on user `tenant_id`. Ensure `FastAPIOAuthRBAC`, `User`, `Role`, `Permission`, `Base`, `requires_permission`, and `get_current_user` are imported. ```python from fastapi import FastAPI, Depends from fastapi_oauth_rbac import FastAPIOAuthRBAC, User, Role, Permission, Base, requires_permission, get_current_user app = FastAPI() auth = FastAPIOAuthRBAC(app) auth.include_auth_router() # Roles and users provisioned at startup: # viewer_role (tenant_id=None) — global, available to all tenants # org_a_role (tenant_id='org_a') — only for org_a users # org_b_role (tenant_id='org_b') — only for org_b users # # alice (tenant_id='org_a') assigned [viewer_role, org_a_role] # bob (tenant_id='org_b') assigned [viewer_role, org_a_role] ← org_a_role ignored for bob @app.get("/global-data", dependencies=[requires_permission("data:read")]) async def global_data(): # Accessible by alice and bob (viewer_role is global) return {"message": "Global data"} @app.get("/org-secret", dependencies=[requires_permission("org:secret")]) async def org_secret(user: User = Depends(get_current_user)): # Only alice passes — bob's org_a_role is filtered out because bob.tenant_id != 'org_a' return {"secret": f"Secret for {user.tenant_id}"} # At signup, pass tenant_id: # POST /auth/signup {"email": "carol@org_b.com", "password": "...", "tenant_id": "org_b"} ``` -------------------------------- ### Handle Google OAuth Callback (Vanilla JS) Source: https://github.com/fernaper/fastapi-oauth-rbac/blob/main/docs/frontend-integration.md This function should be called on your callback page (`/callback`). It extracts the authorization `code` from the URL, sends it to the backend to exchange for tokens, and stores the tokens in `localStorage`. Handle potential errors during the fetch operation. ```javascript // 2. Handle Callback (on /callback page) async function handleCallback() { const urlParams = new URLSearchParams(window.location.search); const code = urlParams.get('code'); if (code) { try { const response = await fetch('http://localhost:8000/auth/google/exchange', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ code: code, redirect_uri: REDIRECT_URI }), }); const data = await response.json(); if (response.ok) { localStorage.setItem('access_token', data.access_token); console.log('Google Login Successful', data); } else { console.error('Google Login FAILED', data); } } catch (err) { console.error(err); } } } ``` -------------------------------- ### Registering Event Hooks for Identity Events Source: https://context7.com/fernaper/fastapi-oauth-rbac/llms.txt Use the `auth.hooks` system to register asynchronous callbacks for key identity events like signup, login, password reset, and email verification. Handlers can be registered using decorators or direct registration. ```python from fastapi import FastAPI from fastapi_oauth_rbac import FastAPIOAuthRBAC app = FastAPI() auth = FastAPIOAuthRBAC(app) @auth.hooks.register("post_signup") async def on_signup(user, **kwargs): # Send welcome email, create a Profile record, subscribe to newsletter, etc. print(f"New user registered: {user.email} (tenant: {user.tenant_id})") @auth.hooks.register("post_login") async def on_login(user, **kwargs): # Track analytics, update last_login timestamp, etc. print(f"Login event for {user.email}") @auth.hooks.register("post_password_reset") async def on_reset(user, **kwargs): print(f"Password was reset for {user.email}") @auth.hooks.register("post_email_verify") async def on_verify(user, **kwargs): # Unlock premium features, send a welcome gift, etc. print(f"Email verified: {user.email}") auth.include_auth_router() ``` -------------------------------- ### Testing Protected Routes with AuthTestClient Source: https://context7.com/fernaper/fastapi-oauth-rbac/llms.txt Demonstrates using `AuthTestClient` to simulate authenticated and unauthorized access to protected FastAPI routes during testing. Requires `pytest`, `TestClient`, `FastAPI`, `FastAPIOAuthRBAC`, `requires_permission`, and `AuthTestClient` imports. ```python import pytest from fastapi.testclient import TestClient from fastapi import FastAPI from fastapi_oauth_rbac import FastAPIOAuthRBAC, requires_permission from fastapi_oauth_rbac.testing import AuthTestClient app = FastAPI() auth = FastAPIOAuthRBAC(app) auth.include_auth_router() @app.get("/protected", dependencies=[requires_permission("reports:read")]) async def protected(): return {"data": "secret"} @pytest.fixture def test_client(): return AuthTestClient(TestClient(app)) def test_authorized_access(test_client): client = test_client.login_as( email="tester@example.com", scopes=["reports:read", "users:read"], ) response = client.get("/protected") assert response.status_code == 200 assert response.json() == {"data": "secret"} def test_forbidden_access(test_client): client = test_client.login_as( email="limited@example.com", scopes=[], # no permissions ) response = client.get("/protected") assert response.status_code == 403 def test_unauthenticated(test_client): response = test_client.client.get("/protected") # no token set assert response.status_code == 401 ``` -------------------------------- ### Password Reset Flow with curl Source: https://context7.com/fernaper/fastapi-oauth-rbac/llms.txt Initiate a password reset by requesting a token via email, then confirm the reset with the token and a new password. ```bash # Step 1: Request reset curl -X POST http://localhost:8000/auth/forgot-password \ -H "Content-Type: application/json" \ -d '"alice@example.com"' # Response: {"message": "If the email is registered, you will receive a reset link", "debug_token": "eyJ..."} # Step 2: Confirm reset curl -X POST http://localhost:8000/auth/reset-password \ -H "Content-Type: application/json" \ -d '{"token": "eyJ...", "new_password": "NewSecurePass456"}' # Response: {"message": "Password reset successfully"} ``` -------------------------------- ### Basic FastAPI-OAuth-RBAC Integration Source: https://github.com/fernaper/fastapi-oauth-rbac/blob/main/docs/getting-started.md Initialize FastAPIOAuthRBAC with your FastAPI app. It can load settings from environment variables or a custom Settings object. ```python from fastapi import FastAPI from fastapi_oauth_rbac import FastAPIOAuthRBAC, Settings app = FastAPI() # Initialize with default settings (loads from .env) auth = FastAPIOAuthRBAC(app) # OR pass explicit settings # custom_settings = Settings(DATABASE_URL="...", ...) # auth = FastAPIOAuthRBAC(app, settings=custom_settings) # Add the essential authentication routes (login, logout, signup, /me) auth.include_auth_router() # Add the Admin Dashboard (Explicitly required) auth.include_dashboard() ``` -------------------------------- ### include_dashboard Source: https://github.com/fernaper/fastapi-oauth-rbac/blob/main/docs/api-reference.md Mounts the administrative dashboard for managing users and roles. ```APIDOC ## include_dashboard() ### Description Mounts the admin dashboard for administrative tasks. ### Method `FastAPIOAuthRBAC.include_dashboard()` ``` -------------------------------- ### Refresh Access Token with httpx Source: https://context7.com/fernaper/fastapi-oauth-rbac/llms.txt Use httpx to send a refresh token and obtain a new access token. The refresh token can be sent automatically via cookies. ```python import httpx async with httpx.AsyncClient(base_url="http://localhost:8000") as client: # Refresh token can also be sent via cookie automatically r = await client.post("/auth/refresh", json=refresh_token_string) new_tokens = r.json() print(new_tokens["access_token"]) ``` -------------------------------- ### Extend User Model with Custom Fields Source: https://context7.com/fernaper/fastapi-oauth-rbac/llms.txt Customize the user model by subclassing `UserBaseMixin` and `Base` to add application-specific fields like phone, bio, and avatar URL. ```python from typing import Optional from sqlalchemy import String from sqlalchemy.orm import Mapped, mapped_column, relationship from fastapi import FastAPI, Depends from fastapi_oauth_rbac import FastAPIOAuthRBAC, UserBaseMixin, Base, get_current_user from fastapi_oauth_rbac.database.models import user_roles, Role class MyUser(Base, UserBaseMixin): __tablename__ = "users" phone: Mapped[Optional[str]] = mapped_column(String(20)) bio: Mapped[Optional[str]] = mapped_column(String(500)) avatar_url: Mapped[Optional[str]] = mapped_column(String(512)) # Re-declare roles relationship when overriding the model roles: Mapped[list[Role]] = relationship(secondary=user_roles) app = FastAPI() auth = FastAPIOAuthRBAC(app, user_model=MyUser) auth.include_auth_router() @app.get("/profile") async def profile(user: MyUser = Depends(get_current_user)): return { "email": user.email, "phone": user.phone, "bio": user.bio, "avatar_url": user.avatar_url, } ``` -------------------------------- ### Audit Logging with AuditManager Source: https://context7.com/fernaper/fastapi-oauth-rbac/llms.txt Shows how to use the `AuditManager` within a route handler to log application-level actions, including actor details, action type, target, and IP address. ```APIDOC ## DELETE /users/{target_email} ### Description Deletes a user and logs the action using `AuditManager`. Requires 'users:delete' permission. ### Method DELETE ### Endpoint /users/{target_email} ### Parameters #### Path Parameters - **target_email** (string) - Required - The email of the user to delete. ### Request Example None ### Response #### Success Response (200) - **deleted** (string) - The email of the deleted user. #### Response Example ```json { "deleted": "user@example.com" } ``` ``` -------------------------------- ### Include Dashboard in FastAPI App Source: https://github.com/fernaper/fastapi-oauth-rbac/blob/main/docs/dashboard.md Call `.include_dashboard()` on your `FastAPIOAuthRBAC` instance to enable the built-in admin dashboard. The `path` parameter is optional for customizing the dashboard's URL. ```python auth = FastAPIOAuthRBAC(app) auth.include_dashboard(path="/custom/admin") ``` -------------------------------- ### Vanilla JavaScript Standard Login Source: https://github.com/fernaper/fastapi-oauth-rbac/blob/main/docs/frontend-integration.md Use this function with native fetch API for standard email/password login. It sends credentials as form data and stores access/refresh tokens in localStorage. ```javascript async function login(email, password) { const formData = new FormData(); formData.append('username', email); // Note: OAuth2 expects 'username', not 'email' formData.append('password', password); try { const response = await fetch('http://localhost:8000/auth/login', { method: 'POST', body: formData, }); if (!response.ok) { const errorData = await response.json(); throw new Error(errorData.detail || 'Login failed'); } const data = await response.json(); // Store the tokens securely localStorage.setItem('access_token', data.access_token); localStorage.setItem('refresh_token', data.refresh_token); console.log('Login successful!', data); return data; } catch (error) { console.error('Error logging in:', error); } } ``` -------------------------------- ### Custom Audit Logging with AuditManager Source: https://context7.com/fernaper/fastapi-oauth-rbac/llms.txt Shows how to use `AuditManager` within route handlers to log application-level actions. Requires `FastAPI`, `Depends`, `Request`, `AsyncSession`, `FastAPIOAuthRBAC`, `get_current_user`, `requires_permission`, `AuditManager`, `User`, and `get_db` imports. ```python from fastapi import FastAPI, Depends, Request from sqlalchemy.ext.asyncio import AsyncSession from fastapi_oauth_rbac import FastAPIOAuthRBAC, get_current_user, requires_permission from fastapi_oauth_rbac.core.audit import AuditManager from fastapi_oauth_rbac.database.models import User from fastapi_oauth_rbac.database.session import get_db app = FastAPI() auth = FastAPIOAuthRBAC(app) auth.include_auth_router() @app.delete( "/users/{target_email}", dependencies=[requires_permission("users:delete")], ) async def delete_user( target_email: str, request: Request, actor: User = Depends(get_current_user), db: AsyncSession = Depends(get_db), ): # … perform deletion logic … audit = AuditManager(db) await audit.log( actor_email=actor.email, action="USER_DELETED", target=target_email, details=f"Deleted by {actor.email}", ip_address=request.client.host if request.client else None, enabled=True, ) return {"deleted": target_email} ``` -------------------------------- ### Password Login with POST /auth/login Source: https://context7.com/fernaper/fastapi-oauth-rbac/llms.txt Authenticate users via the OAuth2 password flow. This endpoint returns JWT access and refresh tokens and sets corresponding cookies. ```bash curl -X POST http://localhost:8000/auth/login \ -H "Content-Type: application/x-www-form-urlencoded" \ -d "username=alice@example.com&password=SecurePass123" # Response: # { # "access_token": "eyJhbGci...", # "refresh_token": "eyJhbGci...", # "token_type": "bearer" # } ``` -------------------------------- ### Google OAuth Login Button (React) Source: https://github.com/fernaper/fastapi-oauth-rbac/blob/main/docs/frontend-integration.md A React component that renders a button to initiate the Google OAuth flow. It uses `window.location.assign` to redirect the user. Ensure `GOOGLE_CLIENT_ID` and `REDIRECT_URI` are configured. ```jsx import React, { useEffect } from 'react'; import { useSearchParams, useNavigate } from 'react-router-dom'; // Configuration const GOOGLE_CLIENT_ID = 'YOUR_GOOGLE_CLIENT_ID'; const REDIRECT_URI = 'http://localhost:3000/oauth/callback'; const BACKEND_URL = 'http://localhost:8000'; export const GoogleLoginButton = () => { const handleLogin = () => { const rootUrl = 'https://accounts.google.com/o/oauth2/v2/auth'; const options = { redirect_uri: REDIRECT_URI, client_id: GOOGLE_CLIENT_ID, access_type: 'offline', response_type: 'code', prompt: 'consent', scope: [ 'https://www.googleapis.com/auth/userinfo.profile', 'https://www.googleapis.com/auth/userinfo.email', ].join(' '), }; const qs = new URLSearchParams(options); window.location.assign(`${rootUrl}?${qs.toString()}`); }; return ( ); }; ``` -------------------------------- ### Reset User Password via CLI Source: https://context7.com/fernaper/fastapi-oauth-rbac/llms.txt Command-line utility to reset a user's password directly in the database. Ensure the database URL is set in the environment. ```bash # Ensure the library is on PYTHONPATH and FORBAC_DATABASE_URL is set export FORBAC_DATABASE_URL="sqlite+aiosqlite:///./sql_app.db" export PYTHONPATH=$PYTHONPATH:$(pwd)/src python -m fastapi_oauth_rbac.main set-password "admin@example.com" "NewSecureP@ss99" # Output: Successfully updated password for admin@example.com. ``` -------------------------------- ### Custom User Model with FastAPI-OAuth-RBAC Source: https://github.com/fernaper/fastapi-oauth-rbac/blob/main/docs/getting-started.md Define a custom SQLAlchemy user model that inherits from UserBaseMixin or includes its fields, then pass it during initialization. ```python from fastapi_oauth_rbac import UserBaseMixin, Base class MyUser(Base, UserBaseMixin): __tablename__ = "my_custom_users" phone: str = Column(String) # Pass it during initialization auth = FastAPIOAuthRBAC(app, user_model=MyUser) ```