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.