Authorization

Flaxon provides role-based and permission-based authorization through decorators and utility functions.

Defining Roles

from flaxon.security import Role, register_role

admin_role = register_role(
    name="admin",
    permissions=["read", "write", "delete", "manage_users"],
    description="Administrator with full access",
)

moderator_role = register_role(
    name="moderator",
    permissions=["read", "write", "delete"],
    description="Moderator with limited access",
)

user_role = register_role(
    name="user",
    permissions=["read"],
    description="Regular user with read-only access",
)

Role Hierarchy

moderator = register_role(
    name="moderator",
    permissions=["write", "delete"],
    parent=user_role,  # Inherits all user permissions
)

admin = register_role(
    name="admin",
    permissions=["manage_users"],
    parent=moderator,  # Inherits all moderator permissions
)

Permission-Based Authorization

from flaxon.security import permission_required, Permission

register_permission("read", "Read data")
register_permission("write", "Write data")
register_permission("delete", "Delete data")

@app.get("/api/users")
@permission_required("read")
async def list_users():
    return [{"id": 1, "name": "Alice"}]

@app.post("/api/users")
@permission_required("write")
async def create_user():
    return {"created": True}

@app.delete("/api/users/<int:user_id>")
@permission_required("delete")
async def delete_user(user_id: int):
    return {"deleted": True}

Role-Based Authorization

from flaxon.security import role_required

@app.get("/admin/dashboard")
@role_required("admin")
async def admin_dashboard():
    return {"admin": True}

@app.get("/moderator/reports")
@role_required("moderator")
async def moderator_reports():
    return {"reports": []}

Combining Roles and Permissions

from flaxon.security import authorize

@app.delete("/api/users/<int:user_id>")
@authorize(permission="delete", role="admin")
async def delete_user(user_id: int):
    return {"deleted": True}

Permission Checking in Functions

from flaxon.security import AuthorizationChecker

async def get_user_data(request):
    checker = AuthorizationChecker(getattr(request, "user", None))

    if checker.has_permission("read"):
        return await db.fetch_all("SELECT * FROM users")

    raise HTTPException(403, "Insufficient permissions")

Multiple Permissions

@app.post("/api/bulk")
@login_required
async def bulk_operation(request):
    user = getattr(request, "user")
    checker = AuthorizationChecker(user)

    # Require any of the specified permissions
    checker.require_any_permission("write", "admin")

    # Or require all permissions
    checker.require_all_permissions("write", "read")

    return {"success": True}

Resource-Level Authorization

@app.get("/users/<int:user_id>")
async def get_user(request, user_id: int):
    user = getattr(request, "user")

    # Check if user owns the resource or is admin
    if user.id != user_id and "admin" not in user.roles:
        raise HTTPException(403, "Cannot access this user")

    return await db.fetch_one("SELECT * FROM users WHERE id = $1", user_id)
Tip

Use AuthorizationChecker for complex permission logic inside functions.