### User Signup Endpoint Example Source: https://context7.com/shashstormer/authtuna/llms.txt Demonstrates how to register a new user using the AuthTuna signup endpoint. The process includes automatic email verification if enabled and logs an audit event. The example uses httpx to make a POST request to the /auth/signup endpoint. ```python import httpx # POST /auth/signup response = httpx.post("http://localhost:8000/auth/signup", json={ "username": "johndoe", "email": "john@example.com", "password": "SecureP@ssw0rd!" }) print(response.json()) # If EMAIL_ENABLED=true: # {"message": "User created. A verification email has been sent."} # If EMAIL_ENABLED=false: # {"message": "User created and logged in successfully."} # (Session cookie is automatically set) ``` -------------------------------- ### Install AuthTuna Dependencies Source: https://github.com/shashstormer/authtuna/blob/master/readme.md Install the necessary packages including AuthTuna, FastAPI, Uvicorn, and database drivers. ```bash pip install authtuna fastapi uvicorn[standard] asyncpg aiosqlite python-dotenv ``` -------------------------------- ### User Login Endpoint Example Source: https://context7.com/shashstormer/authtuna/llms.txt Shows how to authenticate a user via the AuthTuna login endpoint. It accepts username/email and password, returning a session cookie on success or an MFA token if MFA is enabled for the user. The example uses httpx to make a POST request to the /auth/login endpoint. ```python import httpx # POST /auth/login response = httpx.post("http://localhost:8000/auth/login", json={ "username_or_email": "johndoe", "password": "SecureP@ssw0rd!" }) print(response.json()) # Without MFA: {"message": "Login successful."} # With MFA: {"mfa_required": true, "mfa_token": "abc123..."} # The session cookie is automatically set on successful login # Cookie name: session_token (configurable via SESSION_TOKEN_NAME) ``` -------------------------------- ### Start Next.js Development Server Source: https://github.com/shashstormer/authtuna/blob/master/docs_v2/README.md Commands to initiate the local development server for the Next.js application. Supports npm, yarn, pnpm, and bun package managers. ```bash npm run dev yarn dev pnpm dev bun dev ``` -------------------------------- ### Complete AuthTuna FastAPI Application Example Source: https://context7.com/shashstormer/authtuna/llms.txt A full example of integrating AuthTuna into a FastAPI application. It showcases initialization, public and protected endpoints, permission and role-based access control, and multi-tenant support with scoped permissions. It also demonstrates automatic API key authentication. ```python from fastapi import FastAPI, Depends, HTTPException from authtuna import init_app from authtuna.integrations.fastapi_integration import ( get_current_user, PermissionChecker, RoleChecker, auth_service ) from authtuna.core.database import User app = FastAPI(title="AuthTuna Example API") # Initialize AuthTuna (adds all routes, middleware, etc.) init_app(app) # Public endpoint @app.get("/") async def root(): return {"message": "Welcome to the API"} # Protected endpoint - requires authentication @app.get("/me") async def get_current_user_info(user: User = Depends(get_current_user)): roles = await auth_service.roles.get_user_roles_with_scope(user.id) return { "id": user.id, "username": user.username, "email": user.email, "roles": roles } # Permission-based protection @app.get("/admin/users") async def list_users(user: User = Depends(PermissionChecker("users:manage"))): users = await auth_service.users.list(skip=0, limit=50) return {"users": [{"id": u.id, "username": u.username} for u in users]} # Role-based protection @app.post("/admin/roles") async def create_role( name: str, description: str, user: User = Depends(RoleChecker("Admin")) ): new_role = await auth_service.roles.create(name=name, description=description) return {"role": {"name": new_role.name, "id": new_role.id}} # Scoped permissions for multi-tenant @app.get("/orgs/{org_id}/projects") async def list_org_projects( org_id: str, user: User = Depends(PermissionChecker("projects:read", scope_from_path="org_id")) ): # User must have projects:read in scope "org:{org_id}" return {"org_id": org_id, "projects": [...]} # API key authentication works automatically @app.get("/api/data") async def get_data(user: User = Depends(get_current_user)): # Works with both session cookies AND API keys return {"data": "sensitive information", "user": user.username} if __name__ == "__main__": import uvicorn uvicorn.run(app, host="0.0.0.0", port=8000) ``` -------------------------------- ### Configure AuthTuna with Environment Variables Source: https://context7.com/shashstormer/authtuna/llms.txt Demonstrates how to configure AuthTuna using environment variables or a .env file. Settings are loaded via Pydantic for validation. Includes examples for API base URL, encryption keys, database URI, email, OAuth, MFA, and Passkeys. ```bash # .env file API_BASE_URL=https://api.example.com FERNET_KEYS=["your-base64-fernet-key-here"] DEFAULT_DATABASE_URI=postgresql+asyncpg://user:pass@localhost/authdb JWT_SECRET_KEY=your-super-secret-jwt-key ENCRYPTION_PRIMARY_KEY=your-encryption-key # Email settings (optional) EMAIL_ENABLED=true SMTP_HOST=smtp.example.com SMTP_PORT=587 SMTP_USERNAME=noreply@example.com SMTP_PASSWORD=smtp-password # OAuth settings (optional) GOOGLE_CLIENT_ID=your-google-client-id GOOGLE_CLIENT_SECRET=your-google-client-secret GITHUB_CLIENT_ID=your-github-client-id GITHUB_CLIENT_SECRET=your-github-client-secret # MFA and Passkeys MFA_ENABLED=true PASSKEYS_ENABLED=true WEBAUTHN_RP_ID=example.com WEBAUTHN_ORIGIN=https://example.com ``` -------------------------------- ### Organization and Team Management with Authtuna Source: https://context7.com/shashstormer/authtuna/llms.txt Provides examples for creating and managing multi-tenant organizations and teams. This includes inviting users, accepting invitations, retrieving members, and assigning roles within organizations and teams. It also shows how to fetch a user's organizations and teams. ```python org = await auth_service.orgs.create_organization( name="Acme Corp", owner=current_user, ip_address="192.168.1.100" ) # Owner automatically gets "OrgOwner" role in scope "org:{org.id}" await auth_service.orgs.invite_to_organization( org_id=org.id, invitee_email="jane@example.com", role_name="OrgMember", inviter=current_user, ip_address="192.168.1.100" ) # Sends email if EMAIL_ENABLED, otherwise auto-joins org = await auth_service.orgs.accept_organization_invite( token_id="invite-token-id", ip_address="192.168.1.100" ) members = await auth_service.orgs.get_org_members(org_id=org.id) # Returns: [{"user_id": "...", "username": "...", "email": "...", "joined_at": ...}] team = await auth_service.orgs.create_team( name="Engineering", org_id=org.id, creator=current_user, ip_address="192.168.1.100" ) # Creator gets "TeamLead" role in scope "team:{team.id}" await auth_service.orgs.invite_to_team( team_id=team.id, invitee_email="bob@example.com", role_name="TeamMember", inviter=current_user, ip_address="192.168.1.100" ) user_orgs = await auth_service.orgs.get_user_orgs(user.id) user_teams = await auth_service.orgs.get_user_teams(user.id, org_id=org.id) ``` -------------------------------- ### 2-Factor Authentication Setup API Source: https://github.com/shashstormer/authtuna/blob/master/authtuna/templates/pages/mfa_setup.html This section covers the API endpoints related to setting up and verifying 2-Factor Authentication. ```APIDOC ## POST /mfa/verify ### Description Verifies the provided 2-Factor Authentication code and enables MFA for the user's account. If successful, it returns recovery codes. ### Method POST ### Endpoint /mfa/verify ### Parameters #### Request Body - **setup_token** (string) - Required - The token generated during the MFA setup process. - **code** (string) - Required - The 6-digit verification code from the authenticator app. ### Request Example ```json { "setup_token": "your_setup_token_here", "code": "123456" } ``` ### Response #### Success Response (200) - **recovery_codes** (array of strings) - A list of recovery codes to be saved by the user. #### Response Example ```json { "recovery_codes": [ "code1", "code2", "code3" ] } ``` #### Error Response (400) - **detail** (string) - A message indicating the reason for verification failure. #### Error Response Example ```json { "detail": "Invalid verification code." } ``` ``` -------------------------------- ### Configure and Manage MFA Source: https://context7.com/shashstormer/authtuna/llms.txt Handles the setup of TOTP-based MFA, including QR code generation, verification, recovery code management, and disabling MFA. ```python from authtuna.integrations import auth_service secret, provisioning_uri = await auth_service.mfa.setup_totp(user=current_user, issuer_name="MyApp") recovery_codes = await auth_service.mfa.verify_and_enable_totp(user=current_user, code="123456") is_valid = await auth_service.mfa.verify_recovery_code(user=current_user, code="ABC-DEF-GHI", db=db_session) await auth_service.mfa.disable_mfa(user=current_user) ``` -------------------------------- ### Advanced Guide & Patterns Source: https://github.com/shashstormer/authtuna/blob/master/readme.md This section covers advanced patterns such as multi-tenant applications and database integration with AuthTuna. ```APIDOC ## Advanced Guide & Patterns ### Multi-Tenant Applications AuthTuna supports multi-tenant applications by allowing organization-scoped permissions. You can define permissions that are specific to an organization, often determined by path parameters. ```python # Organization-scoped permissions @app.get("/orgs/{org_id}/projects") async def list_org_projects( org_id: str, user=Depends(PermissionChecker("projects:read", scope_from_path="org_id")) ): # User must have projects:read permission in this org projects = await get_projects_for_org(org_id, user.id) return {"projects": projects} ``` ### Database Integration AuthTuna is designed to work with any asynchronous SQLAlchemy-supported database. You can configure the database URI to connect to your preferred database system. **Example Database URIs:** - **PostgreSQL**: `postgresql+asyncpg://user:pass@localhost/dbname` - **SQLite (default)**: `sqlite+aiosqlite:///./authtuna.db` ```python # Example configuration (typically set as an environment variable or in a config file) DEFAULT_DATABASE_URI=postgresql+asyncpg://user:pass@localhost/dbname ``` ``` -------------------------------- ### Integrate AuthTuna with FastAPI Source: https://github.com/shashstormer/authtuna/blob/master/readme.md Shows the installation of dependencies, registration of the database session middleware, and usage of dependency injection for user authentication. ```bash pip install authtuna fastapi uvicorn[standard] ``` ```python from authtuna.middlewares.session import DatabaseSessionMiddleware from authtuna.integrations.fastapi_integration import get_current_user from fastapi import Depends app.add_middleware(DatabaseSessionMiddleware) @app.get("/me") async def me(user=Depends(get_current_user)): return {"id": user.id, "username": user.username} ``` -------------------------------- ### Configure Database URI for AuthTuna Source: https://github.com/shashstormer/authtuna/blob/master/readme.md Examples of database connection strings for AuthTuna, supporting PostgreSQL and SQLite via SQLAlchemy. ```text # PostgreSQL DEFAULT_DATABASE_URI=postgresql+asyncpg://user:pass@localhost/dbname # SQLite DEFAULT_DATABASE_URI=sqlite+aiosqlite:///./authtuna.db ``` -------------------------------- ### Implement Multi-Factor Authentication Source: https://github.com/shashstormer/authtuna/blob/master/readme.md Handles the TOTP setup flow, including generating a QR code URL and verifying the initial MFA code for a user. ```python from authtuna.integrations import auth_service # Start MFA setup for user secret, url = await auth_service.mfa.setup_totp(user_id, "App Name") print(url) # Complete setup with verification code await auth_service.mfa.verify_and_enable_totp(user_id, verification_code="123456") # Verify MFA code during login is_valid = await auth_service.mfa.verify_code(user_id, code="123456") ``` -------------------------------- ### User Logout Endpoint Example Source: https://context7.com/shashstormer/authtuna/llms.txt Demonstrates how to terminate a user's current session and delete the associated session cookie using the AuthTuna logout endpoint. This endpoint supports both GET and POST methods. ```python import httpx # POST /auth/logout (or GET) response = httpx.post("http://localhost:8000/auth/logout") print(response.json()) # Expected output: {"message": "Logout successful."} ``` -------------------------------- ### Manage Permissions via Auth Service Source: https://github.com/shashstormer/authtuna/blob/master/readme.md Provides examples for creating new permissions or using get_or_create for idempotent operations within the AuthTuna permission manager. ```python from authtuna.integrations import auth_service permission_manager = auth_service.permissions new_permission = await permission_manager.create( name="posts:create", description="Allows users to create new blog posts" ) permission, created = await permission_manager.get_or_create( name="posts:publish", defaults={"description": "Allows publishing posts to make them public"} ) ``` -------------------------------- ### Manage Roles and Permissions with AuthTuna Source: https://github.com/shashstormer/authtuna/blob/master/readme.md Shows how to create roles, add permissions to roles, assign roles to users, and remove roles from users using the AuthTuna role manager. Includes examples for audit logging and scope management. ```python from authtuna.integrations import auth_service role_manager = auth_service.roles # Create a new role new_role = await role_manager.create( name="editor", description="Content editor with publishing rights" ) # Add permissions to role await role_manager.add_permission_to_role( role_name="editor", permission_name="posts:create" ) await role_manager.add_permission_to_role( role_name="editor", permission_name="posts:edit", adder_id="system" # this is for audit logging. ) # Assign role to user await role_manager.assign_to_user( user_id=user.id, role_name="editor", assigner_id=admin_id, # This checks if the assigner can assign or not, you need to correctly setup the role with either hierarchy or using grantable allow. scope="org:project1", # either set this or set global, default = none to prevent misconfiguration ) # Remove role from user await role_manager.remove_from_user( user_id=user.id, role_name="editor", remover_id=admin_id ) ``` -------------------------------- ### Audit Trail and Event Logging with Authtuna Source: https://context7.com/shashstormer/authtuna/llms.txt Shows how to query and manage the audit trail for security monitoring and compliance. Examples include fetching events for a specific user and filtering events by type, such as login failures or user creation. Common event types are listed. ```python events = await auth_service.audit.get_events_for_user( user_id=user.id, skip=0, limit=25 ) for event in events: print(f"{event.timestamp}: {event.event_type} - {event.details}") login_failures = await auth_service.audit.get_events_by_type( event_type="LOGIN_FAILED", skip=0, limit=100 ) # Event types include: # - USER_CREATED, USER_UPDATED, USER_DELETED # - USER_SUSPENDED, USER_UNSUSPENDED # - LOGIN_ATTEMPT, LOGIN_SUCCESS, LOGIN_FAILED # - LOGIN_RATE_LIMITED, PASSWORD_CHANGED # - SESSION_CREATED, SESSIONS_TERMINATED_ALL # - MFA_VALIDATION_ATTEMPT, MFA_VALIDATION_SUCCESS # - ROLE_ASSIGNED, ROLE_REMOVED # - API_KEY_CREATED, API_KEY_DELETED # - ORG_CREATED, ORG_JOINED, TEAM_CREATED ``` -------------------------------- ### Perform User Operations with AuthTuna Source: https://github.com/shashstormer/authtuna/blob/master/readme.md Provides examples for common user management operations such as retrieving, updating, suspending, unsuspending, deleting, and listing users. Utilizes the 'auth_service.users' manager. ```python # Get user by ID user = await user_manager.get_by_id(user_id) # Get user by email user = await user_manager.get_by_email("john@example.com") # Update user updated_user = await user_manager.update( user_id, {"first_name": "John", "last_name": "Smith"} ) # Suspend user await user_manager.suspend_user(user_id, admin_id, "Violation of terms") # Unsuspend user await user_manager.unsuspend_user(user_id, admin_id, "Appeal approved") # Delete user (soft delete) await user_manager.delete(user_id) # List users with pagination users = await user_manager.list(skip=0, limit=50) ``` -------------------------------- ### GET /me Source: https://context7.com/shashstormer/authtuna/llms.txt Retrieves the profile information for the currently authenticated user. ```APIDOC ## GET /me ### Description Fetches the current user's profile details using the session or bearer token. ### Method GET ### Endpoint /me ### Response #### Success Response (200) - **user_id** (string) - Unique user identifier - **username** (string) - User username - **email** (string) - User email - **is_active** (boolean) - Account status #### Response Example { "user_id": "123", "username": "jdoe", "email": "jdoe@example.com", "is_active": true } ``` -------------------------------- ### Create Users with AuthTuna Source: https://github.com/shashstormer/authtuna/blob/master/readme.md Demonstrates how to create new users using the AuthTuna user manager, including options for adding metadata. Requires the 'authtuna.integrations' module. ```python from authtuna.integrations import auth_service user_manager = auth_service.users # Create a new user new_user = await user_manager.create( email="john@example.com", username="johndoe", password="secure_password_123" ) # Create user with additional metadata user_with_meta = await user_manager.create( email="jane@example.com", username="janedoe", password="secure_password_123", first_name="Jane", last_name="Doe", is_active=True ) ``` -------------------------------- ### Initialize AuthTuna Settings Programmatically Source: https://github.com/shashstormer/authtuna/blob/master/readme.md Demonstrates how to use init_settings to manually inject configuration, useful for cloud environments or secret managers. This bypasses default environment variable loading when AUTHTUNA_NO_ENV is set. ```python from authtuna.core.config import init_settings def fetch_secrets(): import os return { "API_BASE_URL": os.environ.get("API_BASE_URL"), "FERNET_KEYS": os.environ.get("FERNET_KEYS") } init_settings(**fetch_secrets()) ``` -------------------------------- ### Initialize User Details and Roles (JavaScript) Source: https://github.com/shashstormer/authtuna/blob/master/authtuna/templates/pages/admin_user_detail.html Sets up an event listener to fetch user details and roles when the DOM is fully loaded. This ensures that the necessary data is available upon page initialization. ```javascript document.addEventListener('DOMContentLoaded', fetchUserDetailsAndRoles); ``` -------------------------------- ### Initialize Application Data and Event Listeners Source: https://github.com/shashstormer/authtuna/blob/master/authtuna/templates/pages/admin_dashboard.html This script initializes the application by fetching roles and users from the backend upon DOM content load. It also sets up event listeners for search functionality and role creation forms to ensure a responsive UI. ```javascript async function fetchInitialData() { try { const roles = await apiRequest('/roles'); renderRoles(roles); const users = await apiRequest('/users/search'); renderUsers(users); } catch (error) { showToast(error.message, true); } } document.addEventListener('DOMContentLoaded', () => { userSearchInput.addEventListener('input', handleSearch); createRoleForm.addEventListener('submit', handleCreateRole); fetchInitialData(); handleSearch(); }); ``` -------------------------------- ### User Logout Endpoint Source: https://context7.com/shashstormer/authtuna/llms.txt Terminate the current user session and delete the session cookie. Works with both GET and POST methods. ```APIDOC ## User Logout Endpoint ### Description Terminate the current user session and delete the session cookie. Works with both GET and POST methods. ### Method GET, POST ### Endpoint /auth/logout ### Response #### Success Response (200) - **message** (string) - Indicates successful logout. #### Response Example ```json { "message": "Logout successful." } ``` ``` -------------------------------- ### POST /passkeys/login-options Source: https://github.com/shashstormer/authtuna/blob/master/authtuna/templates/pages/mfa_challenge.html Retrieves the necessary options from the server to initiate a passkey-based authentication. ```APIDOC ## POST /passkeys/login-options ### Description Requests the authentication options required by the browser to start a passkey-based login flow. ### Method POST ### Endpoint /passkeys/login-options ### Parameters No parameters are required for this endpoint. ### Request Example ```json {} ``` ### Response #### Success Response (200) - **challenge** (string) - The challenge generated by the server for the authentication. - **rpId** (string) - The Relying Party ID. - **user** (object) - User information (if available). - **id** (string) - User ID. - **name** (string) - User's display name. - **displayName** (string) - User's display name. - **timeout** (number) - The timeout for the authentication request. - **attestation** (string) - The attestation type. #### Response Example ```json { "challenge": "some_base64_encoded_challenge", "rpId": "yourdomain.com", "user": { "id": "user_id_bytes", "name": "username", "displayName": "User Name" }, "timeout": 60000, "attestation": "none" } ``` ``` -------------------------------- ### POST /auth/signup Source: https://context7.com/shashstormer/authtuna/llms.txt Register new users with automatic email verification (if enabled) or immediate login. The signup process creates the user, logs an audit event, and triggers post-creation hooks. ```APIDOC ## POST /auth/signup ### Description Register new users with automatic email verification (if enabled) or immediate login. The signup process creates the user, logs an audit event, and triggers post-creation hooks. ### Method POST ### Endpoint /auth/signup ### Parameters #### Request Body - **username** (string) - Required - The username for the new user. - **email** (string) - Required - The email address for the new user. - **password** (string) - Required - The password for the new user. ### Request Example ```json { "username": "johndoe", "email": "john@example.com", "password": "SecureP@ssw0rd!" } ``` ### Response #### Success Response (200) - **message** (string) - Indicates the result of the signup operation. #### Response Example ```json { "message": "User created. A verification email has been sent." } ``` #### Response Example (No Email Verification) ```json { "message": "User created and logged in successfully." } ``` ``` -------------------------------- ### Programmatic Configuration with init_settings Source: https://context7.com/shashstormer/authtuna/llms.txt For advanced scenarios like Docker, cloud deployments, or secrets managers, use init_settings() to configure AuthTuna programmatically at startup. ```APIDOC ## Programmatic Configuration with init_settings For advanced scenarios like Docker, cloud deployments, or secrets managers, use init_settings() to configure AuthTuna programmatically at startup. ```python from authtuna.core.config import init_settings import os def fetch_secrets_from_vault(): # Fetch from AWS Secrets Manager, HashiCorp Vault, etc. return { "API_BASE_URL": os.environ.get("API_BASE_URL"), "FERNET_KEYS": [os.environ.get("FERNET_KEY")], "DEFAULT_DATABASE_URI": os.environ.get("DATABASE_URL"), "JWT_SECRET_KEY": os.environ.get("JWT_SECRET"), "EMAIL_ENABLED": True, "SMTP_HOST": os.environ.get("SMTP_HOST"), } # Initialize settings before creating the app init_settings(**fetch_secrets_from_vault()) from fastapi import FastAPI from authtuna import init_app app = FastAPI() init_app(app) ``` ``` -------------------------------- ### Define RBAC Permissions and Roles Source: https://github.com/shashstormer/authtuna/blob/master/readme.md Demonstrates how to initialize custom permissions and organize them into roles like Editor, Moderator, and Viewer using the auth_service integration. ```python from authtuna.integrations import auth_service # Create permissions await auth_service.permissions.get_or_create("posts:create", {"description": "Create blog posts"}) await auth_service.permissions.get_or_create("posts:read", {"description": "Read blog posts"}) await auth_service.permissions.get_or_create("posts:update", {"description": "Update blog posts"}) await auth_service.permissions.get_or_create("posts:delete", {"description": "Update blog posts"}) await auth_service.permissions.get_or_create("posts:publish", {"description": "Publish blog posts"}) await auth_service.permissions.get_or_create("comments:moderate", {"description": "Moderate comments"}) # Create Editor role editor_role = await auth_service.roles.create("editor", "Content editor") await auth_service.roles.add_permission_to_role("editor", "posts:create") await auth_service.roles.add_permission_to_role("editor", "posts:read") await auth_service.roles.add_permission_to_role("editor", "posts:update") await auth_service.roles.add_permission_to_role("editor", "posts:publish") # Create Moderator role moderator_role = await auth_service.roles.create("moderator", "Comment moderator") await auth_service.roles.add_permission_to_role("moderator", "posts:read") await auth_service.roles.add_permission_to_role("moderator", "comments:moderate") # Create Viewer role viewer_role = await auth_service.roles.create("viewer", "Content viewer") await auth_service.roles.add_permission_to_role("viewer", "posts:read") ``` -------------------------------- ### Verify MFA Token and Handle Recovery Codes Source: https://github.com/shashstormer/authtuna/blob/master/authtuna/templates/pages/mfa_setup.html Handles the form submission for MFA verification via a fetch request. Upon success, it hides the setup view and displays the generated recovery codes. ```javascript const verifyForm = document.getElementById('verify-form'); const messageBox = document.getElementById('message-box'); if (verifyForm) { verifyForm.addEventListener('submit', async (e) => { e.preventDefault(); const token = document.getElementById('setup-token').value; const code = document.getElementById('mfa-code').value; try { const response = await fetch('/mfa/verify', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ setup_token: token, code: code }) }); const data = await response.json(); if (response.ok) { document.getElementById('setup-view').classList.add('hidden'); const recoveryView = document.getElementById('recovery-view'); const recoveryList = document.getElementById('recovery-codes-list'); recoveryList.innerHTML = ''; data.recovery_codes.forEach(code => { const codeEl = document.createElement('div'); codeEl.textContent = code; recoveryList.appendChild(codeEl); }); recoveryView.classList.remove('hidden'); } else { messageBox.textContent = data.detail || 'Verification failed.'; messageBox.className = 'text-center text-sm font-medium text-red-500'; messageBox.classList.remove('hidden'); } } catch (error) { messageBox.textContent = 'Network error. Please try again.'; messageBox.className = 'text-center text-sm font-medium text-red-500'; messageBox.classList.remove('hidden'); } }); } ``` -------------------------------- ### Manage API Keys with AuthTuna Source: https://github.com/shashstormer/authtuna/blob/master/readme.md Demonstrates how to programmatically create, list, and revoke API keys for users. The create method returns a plaintext key that must be handled securely. ```python from authtuna.integrations import auth_service # Create API key for user api_key = await auth_service.api_keys.create_key( user_id=user.id, name="My API Key", key_type="secret", scopes=["Admin:global", "Projects:{sm_org_ig}"], valid_seconds=31536000 ) # List user's API keys keys = await auth_service.api_keys.get_all_keys_for_user(user.id) # Revoke API key await auth_service.api_keys.delete_key(key_id) ``` -------------------------------- ### Implement Conditional 2FA UI Logic Source: https://github.com/shashstormer/authtuna/blob/master/authtuna/templates/dashboard/settings.html This Jinja2 template snippet conditionally renders the Two-Factor Authentication status based on the user object's mfa_enabled property. It provides either a disable action or a link to the setup flow. ```jinja2 {% if user.mfa_enabled %} 2FA is currently enabled on your account. Disable Two-Factor Authentication {% else %} Protect your account with an extra layer of security using an authenticator app. [Setup Two-Factor Authentication](/mfa/setup) {% endif %} ``` -------------------------------- ### Sample Backend Code with AuthTuna Source: https://github.com/shashstormer/authtuna/blob/master/readme.md This section provides a sample FastAPI backend application demonstrating how to integrate AuthTuna for authentication, authorization, and API key support. ```APIDOC ## Sample Backend Code with AuthTuna This example demonstrates a FastAPI application integrated with AuthTuna. ### Initialization Initialize AuthTuna using `init_app(app)` to automatically add routes, middleware, and configurations. ```python from fastapi import FastAPI, Depends, HTTPException from authtuna import init_app from authtuna.integrations.fastapi_integration import ( get_current_user, PermissionChecker, RoleChecker ) app = FastAPI(title="AuthTuna Example API") # Initialize AuthTuna (adds all routes, middleware, etc.) init_app(app) ``` ### Endpoints - **Public Endpoint**: Accessible without authentication. ```python @app.get("/") async def root(): return {"message": "Welcome to AuthTuna API"} ``` - **Protected Endpoint (User Info)**: Requires authentication. Returns information about the currently logged-in user. ```python @app.get("/me") async def get_current_user_info(user=Depends(get_current_user)): return { "id": user.id, "username": user.username, "email": user.email, "roles": [role.name for role in user.roles] } ``` - **Permission-Based Protection**: Requires a specific permission (e.g., `users:manage`). ```python @app.get("/admin/users") async def list_users(user=Depends(PermissionChecker("users:manage"))): # Only users with users:manage permission users = await get_all_users() return {"users": users} ``` - **Role-Based Protection**: Requires a specific role (e.g., `admin`). ```python @app.post("/admin/roles") async def create_role(role_data: dict, user=Depends(RoleChecker("admin"))): # Only admin role new_role = await create_role_in_db(role_data) return {"role": new_role} ``` - **Scoped Permissions**: Protects access to resources based on specific scopes, using path parameters to determine the scope. ```python @app.get("/projects/{project_id}") async def get_project( project_id: str, user=Depends(PermissionChecker("projects:read", scope_from_path="project_id")) ): # Check if user can read this specific project project = await get_project_by_id(project_id) return {"project": project} ``` - **API Key Support**: This endpoint works with both session cookies and API keys for authentication. ```python @app.get("/api/data") async def get_data(user=Depends(get_current_user)): # Works with both session cookies and API keys data = await fetch_data_for_user(user.id) return {"data": data} ``` ### Running the Application ```python if __name__ == "__main__": import uvicorn uvicorn.run(app, host="0.0.0.0", port=8000) ``` ``` -------------------------------- ### AuthTuna Configuration Options Source: https://github.com/shashstormer/authtuna/blob/master/readme.md AuthTuna supports configuration through environment variables, a .env file, or a custom initialization function. This section lists common configuration variables. ```APIDOC ## AuthTuna Configuration Options AuthTuna can be configured using environment variables, a `.env` file, or by exporting variables in your shell. For advanced scenarios, you can use a secrets manager or a custom `init_settings` function. ### Environment Variables | Variable Name | Description | Required | Default | |---|---|---|---| | `GITHUB_CLIENT_ID` | GitHub OAuth client ID. | If GitHub SSO | | | `GITHUB_CLIENT_SECRET` | GitHub OAuth client secret. | If GitHub SSO | | | `GITHUB_REDIRECT_URI` | GitHub OAuth redirect URI. | If GitHub SSO | | | `RPC_ENABLED` | Enable or disable RPC. | No | `False` | | `RPC_AUTOSTART` | Automatically start the RPC server. | No | `True` | | `RPC_TOKEN` | RPC authentication token. | No | `changeme-secure-token` | | `RPC_TLS_CERT_FILE` | Path to the RPC TLS certificate file. | If RPC TLS | | | `RPC_TLS_KEY_FILE` | Path to the RPC TLS key file. | If RPC TLS | | | `RPC_ADDRESS` | RPC server address. | No | `[::]:50051` | | `WEBAUTHN_ENABLED` | Enable or disable WebAuthn. | No | `False` | | `WEBAUTHN_RP_ID` | WebAuthn relying party ID. | No | `localhost` | | `WEBAUTHN_RP_NAME` | WebAuthn relying party name. | No | `AuthTuna` | | `WEBAUTHN_ORIGIN` | WebAuthn origin URL. | No | `http://localhost:8000` | | `STRATEGY` | Authentication strategy (`COOKIE` or `BEARER`). | No | `COOKIE` | **See [core/config.py](authtuna/core/config.py) for ALL options.** ### Setting Configuration - Place your config in a `.env` file (see above). - Or export them in your shell: `export API_BASE_URL="https://api.mysite.com"`, etc. - If you want to use a custom file: `ENV_FILE_NAME=".myenv"` ### Using a Secrets Manager or Custom `init_settings` - For ultimate flexibility (Docker, cloud, Vault, AWS, etc), call `init_settings()` at app startup: ```python from authtuna.core.config import init_settings def fetch_secrets(): # Example: fetch from AWS, Vault, or any source import os return { "API_BASE_URL": os.environ.get("API_BASE_URL"), "FERNET_KEYS": os.environ.get("FERNET_KEYS"), # ...add your secrets here... } init_settings(**fetch_secrets()) ``` - If you set `AUTHTUNA_NO_ENV=true`, AuthTuna will **not** auto-load from env and will require explicit `init_settings()`. ``` -------------------------------- ### Manage API Keys with Authtuna Source: https://context7.com/shashstormer/authtuna/llms.txt Demonstrates how to create, validate, list, and delete API keys using the Authtuna service. Master keys have dynamic user role inheritance and cannot have explicit scopes. Key validation returns user information if the token is valid. ```python master_key = await auth_service.api.create_key( user_id=user.id, name="Master Key", key_type="master", valid_seconds=86400 # 1 day ) # Master keys cannot have explicit scopes validated_key = await auth_service.api.validate_key( token="sk_xxxx.yyyyyyyyyyyyyyy" ) if validated_key: print(f"Valid key for user: {validated_key.user_id}") keys = await auth_service.api.get_all_keys_for_user(user.id) await auth_service.api.delete_key(key_id=api_key.id) await auth_service.api.extend_key_expiration( key_id=api_key.id, expire_time=time.time() + 31536000 # Unix timestamp ) ``` -------------------------------- ### Configure Multi-Tenant Scoped Permissions Source: https://github.com/shashstormer/authtuna/blob/master/readme.md Illustrates how to enforce organization-scoped permissions in a multi-tenant application using path parameters. ```python @app.get("/orgs/{org_id}/projects") async def list_org_projects( org_id: str, user=Depends(PermissionChecker("projects:read", scope_from_path="org_id")) ): return await get_projects_for_org(org_id, user.id) ``` -------------------------------- ### Manage Users Programmatically Source: https://context7.com/shashstormer/authtuna/llms.txt Demonstrates using the UserManager service to create, retrieve, and update user records programmatically. ```python from authtuna.integrations import auth_service # Create a new user new_user = await auth_service.users.create( email="jane@example.com", username="janedoe", password="SecurePassword123!", ip_address="192.168.1.100" ) # Update user updated_user = await auth_service.users.update( user_id=new_user.id, update_data={"username": "jane_doe_updated"}, ip_address="192.168.1.100" ) ``` -------------------------------- ### Integrate Social Login (SSO) Source: https://context7.com/shashstormer/authtuna/llms.txt Shows how to programmatically register or link a user account using OAuth provider data from services like Google or GitHub. ```python from authtuna.integrations import auth_service user, social_account = await auth_service.register_social_user( email="john@gmail.com", provider="google", provider_user_id="google-user-id-123", token_data={"access_token": "ya29.xxxxx", "refresh_token": "1//xxxxx", "token_type": "Bearer", "expires_at": 1699999999}, ip_address="192.168.1.100", username_candidate="John Doe" ) ``` -------------------------------- ### Implement Login with MFA Flow Source: https://context7.com/shashstormer/authtuna/llms.txt Demonstrates the two-step login process where an initial login attempt returns an MFA token if enabled, followed by a secondary validation step using a TOTP code. ```python from authtuna.integrations import auth_service from authtuna.core.database import Token, Session user, result = await auth_service.login( username_or_email="johndoe", password="SecurePassword123!", ip_address="192.168.1.100", region="US", device="Chrome on Windows" ) if isinstance(result, Token): mfa_token = result.id session = await auth_service.validate_mfa_login( mfa_token=mfa_token, code="123456", ip_address="192.168.1.100", device_data={"region": "US", "device": "Chrome on Windows"} ) else: session = result ``` -------------------------------- ### Manage Passkeys with JavaScript Source: https://github.com/shashstormer/authtuna/blob/master/authtuna/templates/dashboard/settings.html This script handles the loading, adding, and removing of passkeys for user authentication. It fetches the list of registered passkeys, displays them, and provides functionality to remove individual passkeys after a confirmation prompt. It also initiates the passkey registration process. ```javascript // --- Passkey Logic --- const passkeyMessageBox = document.getElementById('passkey-message-box'); const passkeyList = document.getElementById('passkey-list'); async function loadPasskeys() { try { const response = await fetch('/passkeys/'); if (!response.ok) throw new Error('Failed to load passkeys.'); const passkeys = await response.json(); passkeyList.innerHTML = passkeys.map(key => `
${key.name}
No passkeys registered yet.
'; } catch (error) { showMessage(passkeyMessageBox, error.message, 'error'); } } async function removePasskey(credentialId) { showModal('Remove this Passkey?', 'You will no longer be able to use this passkey to sign in. This action cannot be undone.', async () => { try { const response = await fetch(`/passkeys/${credentialId}`, { method: 'DELETE' }); if (response.ok) { showMessage(passkeyMessageBox, 'Passkey removed successfully.', 'success'); loadPasskeys(); } else { const data = await response.json(); throw new Error(data.detail || 'Failed to remove passkey.'); } } catch (error) { showMessage(passkeyMessageBox, error.message, 'error'); } }); } document.getElementById('add-passkey-button').addEventListener('click', async () => { const button = document.getElementById('add-passkey-button'); button.disabled = true; try { const optionsResp = await fetch('/passkeys/register-' ``` -------------------------------- ### Handle Logic by Authentication Method Source: https://github.com/shashstormer/authtuna/blob/master/COOKIE_BEARER.md Illustrates how to resolve the token method at runtime to execute specific logic depending on whether the user is authenticated via cookie or bearer token. ```python from authtuna.integrations.fastapi_integration import resolve_token_method @router.get("/mixed") async def mixed_endpoint( request: Request, user: User = Depends(get_current_user) ): token_method = resolve_token_method(request) if token_method == "COOKIE": return {"view": "full_ui", "user": user.username} elif token_method == "BEARER": return {"data": {"user_id": user.id}} else: raise HTTPException(401) ``` -------------------------------- ### Configuration with Environment Variables Source: https://context7.com/shashstormer/authtuna/llms.txt Configure AuthTuna using environment variables or a .env file. All settings are loaded via Pydantic for validation and type safety. ```APIDOC ## Configuration with Environment Variables Configure AuthTuna using environment variables or a .env file. All settings are loaded via Pydantic for validation and type safety. ```bash # .env file API_BASE_URL=https://api.example.com FERNET_KEYS=["your-base64-fernet-key-here"] DEFAULT_DATABASE_URI=postgresql+asyncpg://user:pass@localhost/authdb JWT_SECRET_KEY=your-super-secret-jwt-key ENCRYPTION_PRIMARY_KEY=your-encryption-key # Email settings (optional) EMAIL_ENABLED=true SMTP_HOST=smtp.example.com SMTP_PORT=587 SMTP_USERNAME=noreply@example.com SMTP_PASSWORD=smtp-password # OAuth settings (optional) GOOGLE_CLIENT_ID=your-google-client-id GOOGLE_CLIENT_SECRET=your-google-client-secret GITHUB_CLIENT_ID=your-github-client-id GITHUB_CLIENT_SECRET=your-github-client-secret # MFA and Passkeys MFA_ENABLED=true PASSKEYS_ENABLED=true WEBAUTHN_RP_ID=example.com WEBAUTHN_ORIGIN=https://example.com ``` ``` -------------------------------- ### Open Create API Key Modal (JavaScript) Source: https://github.com/shashstormer/authtuna/blob/master/authtuna/templates/dashboard/settings.html Handles the click event for the 'Create API Key' button. It resets the API key form, clears any previous descriptions, hides the scopes container, and makes the API key creation modal visible with a slight delay for animation. ```javascript document.getElementById('create-api-key-button').addEventListener('click', () => { document.getElementById('api-key-form').reset(); document.getElementById('scopes-container').classList.add('hidden'); document.getElementById('key-type-description').textContent = ''; apiKeyModal.classList.remove('hidden'); setTimeout(() => apiKeyModal.classList.remove('opacity-0'), 10); }); ``` -------------------------------- ### Manage Theme and Styling (JavaScript) Source: https://github.com/shashstormer/authtuna/blob/master/authtuna/templates/pages/reset_password.html This JavaScript code manages the website's theme (light/dark mode) and applies corresponding CSS styles. It utilizes `localStorage` to persist user theme preferences and `window.matchMedia` to detect system preferences. The `setTheme` function toggles a 'dark' class on the root element, and `toggleTheme` provides a user-initiated theme switch. It includes CSS for gradient animations and basic body styling. ```JavaScript function setTheme(theme) { document.documentElement.classList.toggle('dark', theme === 'dark'); localStorage.setItem('theme', theme); } document.addEventListener('DOMContentLoaded', () => { const storedTheme = localStorage.getItem('theme'); const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches; setTheme(storedTheme || (prefersDark ? 'dark' : 'light')); }); function toggleTheme() { const isDark = document.documentElement.classList.contains('dark'); setTheme(isDark ? 'light' : 'dark'); } ``` ```CSS body { font-family: 'Poppins', sans-serif; background-size: 400% 400%; animation: gradientAnimation 15s ease infinite; transition: background 0.5s ease-in-out; } @keyframes gradientAnimation { 0% { background-position: 0% 50%; } 50% { background-position: 100% 50%; } 100% { background-position: 0% 50%; } } ``` -------------------------------- ### Register Passkey with SimpleWebAuthn Source: https://github.com/shashstormer/authtuna/blob/master/authtuna/templates/dashboard/settings.html Handles the registration flow for a new passkey. It fetches registration options from the server, triggers the browser's WebAuthn registration, and sends the response back for verification. ```javascript const optionsResp = await fetch('/passkeys/options', { method: 'POST' }); if (!optionsResp.ok) throw new Error('Could not get registration options.'); const options = await optionsResp.json(); const registrationResp = await SimpleWebAuthnBrowser.startRegistration(options); const nickname = prompt("Please enter a name for this passkey:", `Passkey on ${new Date().toLocaleDateString()}`); if (!nickname) throw new Error("Registration cancelled."); const verificationResp = await fetch('/passkeys/register', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ name: nickname, registration_response: registrationResp }) }); if (!verificationResp.ok) throw new Error('Server verification failed.'); ``` -------------------------------- ### Minimal FastAPI Integration Source: https://github.com/shashstormer/authtuna/blob/master/readme.md Initialize a FastAPI application with AuthTuna's database session middleware and a protected endpoint using dependency injection. ```python from fastapi import FastAPI, Depends from authtuna.middlewares.session import DatabaseSessionMiddleware from authtuna.integrations.fastapi_integration import get_current_user app = FastAPI() app.add_middleware(DatabaseSessionMiddleware) @app.get("/me") async def me(user=Depends(get_current_user)): return {"id": user.id, "username": user.username, "email": user.email} ```