File size: 7,154 Bytes
50a7bf0
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
"""

Example integration of user management utilities with FastAPI dependencies.



This module demonstrates how to integrate the user management utilities

with FastAPI dependency injection for authentication and authorization.

"""

from typing import Optional
from fastapi import Depends, HTTPException, status, Request
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials

from .user_utils import (
    create_auth_context,
    validate_user_permission,
    get_session_cache
)
from ..models.user import AuthenticationContext, UserPermissions
from ..core.auth import get_clerk_manager, AuthenticationError, AuthorizationError

# Security scheme for Bearer token authentication
security = HTTPBearer()


async def get_current_user(

    credentials: HTTPAuthorizationCredentials = Depends(security)

) -> AuthenticationContext:
    """

    FastAPI dependency to get current authenticated user.

    

    This dependency extracts the Bearer token from the Authorization header,

    validates it with Clerk, and returns the complete authentication context.

    

    Args:

        credentials: HTTP Bearer credentials from FastAPI security

        

    Returns:

        AuthenticationContext with user, session, and permissions

        

    Raises:

        HTTPException: If authentication fails

    """
    try:
        token = credentials.credentials
        
        # Check session cache first
        cache = get_session_cache()
        cached_context = cache.get(token)
        
        if cached_context and cached_context.is_authenticated:
            return cached_context
        
        # Create new authentication context
        auth_context = await create_auth_context(token)
        
        # Cache the context
        cache.set(token, auth_context)
        
        return auth_context
        
    except Exception as e:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail=f"Authentication failed: {str(e)}",
            headers={"WWW-Authenticate": "Bearer"}
        )


async def get_verified_user(

    current_user: AuthenticationContext = Depends(get_current_user)

) -> AuthenticationContext:
    """

    FastAPI dependency to get verified user only.

    

    This dependency ensures the user has verified their email address.

    

    Args:

        current_user: Current authenticated user context

        

    Returns:

        AuthenticationContext for verified user

        

    Raises:

        HTTPException: If user is not verified

    """
    if not current_user.is_verified:
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN,
            detail="Email verification required"
        )
    
    return current_user


async def get_admin_user(

    current_user: AuthenticationContext = Depends(get_current_user)

) -> AuthenticationContext:
    """

    FastAPI dependency to get admin user only.

    

    This dependency ensures the user has admin privileges.

    

    Args:

        current_user: Current authenticated user context

        

    Returns:

        AuthenticationContext for admin user

        

    Raises:

        HTTPException: If user is not admin

    """
    if not current_user.permissions.role.value == "admin":
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN,
            detail="Admin privileges required"
        )
    
    return current_user


def require_permission(permission: str):
    """

    Create a FastAPI dependency that requires specific permission.

    

    Args:

        permission: Required permission string

        

    Returns:

        FastAPI dependency function

    """
    async def permission_dependency(

        current_user: AuthenticationContext = Depends(get_current_user)

    ) -> AuthenticationContext:
        """Check if user has required permission."""
        if not current_user.can_perform_action(permission):
            raise HTTPException(
                status_code=status.HTTP_403_FORBIDDEN,
                detail=f"Permission required: {permission}"
            )
        
        return current_user
    
    return permission_dependency


async def check_rate_limits(

    current_user: AuthenticationContext = Depends(get_current_user)

) -> AuthenticationContext:
    """

    FastAPI dependency to check user rate limits.

    

    This dependency validates that the user hasn't exceeded their rate limits

    for API usage.

    

    Args:

        current_user: Current authenticated user context

        

    Returns:

        AuthenticationContext if rate limits are not exceeded

        

    Raises:

        HTTPException: If rate limits are exceeded

    """
    # This is a placeholder implementation
    # In a real system, you would check against Redis or database
    
    permissions = current_user.permissions
    
    # Example rate limit check (would be implemented with Redis)
    current_concurrent_jobs = 0  # Would fetch from Redis
    current_daily_jobs = 0       # Would fetch from database
    
    if current_concurrent_jobs >= permissions.max_concurrent_jobs:
        raise HTTPException(
            status_code=status.HTTP_429_TOO_MANY_REQUESTS,
            detail="Maximum concurrent jobs exceeded",
            headers={"Retry-After": "300"}
        )
    
    if current_daily_jobs >= permissions.max_daily_jobs:
        raise HTTPException(
            status_code=status.HTTP_429_TOO_MANY_REQUESTS,
            detail="Daily job limit exceeded",
            headers={"Retry-After": "86400"}  # 24 hours
        )
    
    return current_user


# Example usage in FastAPI endpoints:

"""

from fastapi import APIRouter, Depends

from .auth_integration_example import (

    get_current_user, 

    get_verified_user, 

    get_admin_user,

    require_permission,

    check_rate_limits

)



router = APIRouter()



@router.get("/profile")

async def get_user_profile(

    current_user: AuthenticationContext = Depends(get_current_user)

):

    '''Get current user profile.'''

    return {

        "user": current_user.user,

        "permissions": current_user.permissions

    }



@router.post("/videos/generate")

async def generate_video(

    request: VideoGenerationRequest,

    current_user: AuthenticationContext = Depends(get_verified_user),

    _rate_check: AuthenticationContext = Depends(check_rate_limits)

):

    '''Generate video - requires verified user and rate limit check.'''

    # Implementation here

    pass



@router.get("/admin/system/health")

async def get_system_health(

    current_user: AuthenticationContext = Depends(get_admin_user)

):

    '''Get system health - admin only.'''

    # Implementation here

    pass



@router.post("/jobs/{job_id}/cancel")

async def cancel_job(

    job_id: str,

    current_user: AuthenticationContext = Depends(require_permission("cancel_jobs"))

):

    '''Cancel job - requires specific permission.'''

    # Implementation here

    pass

"""