Add user delete process
This commit is contained in:
@@ -336,3 +336,73 @@ analytics_tier_required = require_subscription_tier(['professional', 'enterprise
|
||||
enterprise_tier_required = require_subscription_tier(['enterprise'])
|
||||
admin_role_required = require_user_role(['admin', 'owner'])
|
||||
owner_role_required = require_user_role(['owner'])
|
||||
|
||||
|
||||
def service_only_access(func: Callable) -> Callable:
|
||||
"""
|
||||
Decorator to restrict endpoint access to service-to-service calls only
|
||||
|
||||
This decorator validates that:
|
||||
1. The request has a valid service token (type='service' in JWT)
|
||||
2. The token is from an authorized internal service
|
||||
|
||||
Usage:
|
||||
@router.delete("/tenant/{tenant_id}")
|
||||
@service_only_access
|
||||
async def delete_tenant_data(
|
||||
tenant_id: str,
|
||||
current_user: dict = Depends(get_current_user_dep),
|
||||
db = Depends(get_db)
|
||||
):
|
||||
# Service-only logic here
|
||||
|
||||
The decorator expects current_user to be injected via get_current_user_dep
|
||||
dependency, which should already contain the user/service context from JWT.
|
||||
"""
|
||||
|
||||
@wraps(func)
|
||||
async def wrapper(*args, **kwargs):
|
||||
# Get current user from kwargs (injected by get_current_user_dep)
|
||||
current_user = kwargs.get('current_user')
|
||||
|
||||
if not current_user:
|
||||
# Try to find in args
|
||||
for arg in args:
|
||||
if isinstance(arg, dict) and 'user_id' in arg:
|
||||
current_user = arg
|
||||
break
|
||||
|
||||
if not current_user:
|
||||
logger.error("Service-only access: current user not found in request context")
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_401_UNAUTHORIZED,
|
||||
detail="Authentication required"
|
||||
)
|
||||
|
||||
# Check if this is a service token
|
||||
user_type = current_user.get('type', '')
|
||||
is_service = current_user.get('is_service', False)
|
||||
|
||||
if user_type != 'service' and not is_service:
|
||||
logger.warning(
|
||||
"Service-only access denied: not a service token",
|
||||
user_id=current_user.get('user_id'),
|
||||
user_type=user_type,
|
||||
is_service=is_service
|
||||
)
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_403_FORBIDDEN,
|
||||
detail="This endpoint is only accessible to internal services"
|
||||
)
|
||||
|
||||
# Log successful service access
|
||||
service_name = current_user.get('service', current_user.get('user_id', 'unknown'))
|
||||
logger.info(
|
||||
"Service-only access granted",
|
||||
service=service_name,
|
||||
endpoint=func.__name__
|
||||
)
|
||||
|
||||
return await func(*args, **kwargs)
|
||||
|
||||
return wrapper
|
||||
|
||||
Reference in New Issue
Block a user