PythonmediumPython

Authentication and Authorization Decorator

Add authentication and role-based authorization to functions.

01

The problem

You need to secure functions with authentication and role-based access control.

02

The solution

Python
import functools
from typing import Callable, List

class User:
    def __init__(self, username: str, roles: List[str]):
        self.username = username
        self.roles = set(roles)
    
    def has_role(self, role: str) -> bool:
        return role in self.roles

def require_auth(required_roles: List[str] = None):
    """Decorator to require authentication and authorization."""
    def decorator(func: Callable) -> Callable:
        @functools.wraps(func)
        def wrapper(user: User, *args, **kwargs):
            # Check if user is authenticated
            if user is None:
                raise PermissionError("Authentication required")
            
            # Check if user has required roles
            if required_roles:
                if not any(user.has_role(role) for role in required_roles):
                    raise PermissionError(
                        f"Insufficient permissions. Required roles: {required_roles}"
                    )
            
            return func(user, *args, **kwargs)
        return wrapper
    return decorator

03

Parameters

required_roleslist

List of required user roles

04

Put it to work

Example
# Define users
admin = User("admin", ["admin", "editor"])
editor = User("editor", ["editor"])
viewer = User("viewer", ["viewer"])

@require_auth(required_roles=["admin"])
def delete_user(current_user: User, user_id: int):
    return f"User {user_id} deleted by {current_user.username}"

# Admin can delete users
try:
    print(delete_user(admin, 123))
except PermissionError as e:
    print(e)

# Editor cannot delete users
try:
    print(delete_user(editor, 123))
except PermissionError as e:
    print(f"Permission denied: {e}")