Spaces:
Running
Running
File size: 6,761 Bytes
5ccd893 | 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 | """
Auth Controller
Handles authentication, profile, and activity-log operations.
Sits between routes and the AuthService.
"""
import logging
from typing import Dict, Any
from services.auth_service import AuthService
from models.auth_model import (
LoginRequest, SignUpRequest, ProfileUpdate, ActivityLogEntry
)
from utils import create_error_response, create_success_response
logger = logging.getLogger(__name__)
class AuthController:
"""Controller for all auth-related endpoints"""
def __init__(self, auth_service: AuthService):
self.auth_service = auth_service
# ββ Auth ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
def login(self, data: Dict[str, Any]) -> Dict[str, Any]:
req = LoginRequest(
email=data.get("email", ""),
password=data.get("password", ""),
)
errors = req.validate()
if errors:
return create_error_response("Validation failed", {"errors": errors})
ok, result = self.auth_service.sign_in(req.email, req.password)
if not ok:
return create_error_response(result.get("error", "Login failed"))
# Log the login activity
self.auth_service.log_activity(
user_id=result["user"]["id"],
activity_type="login",
description=f"User logged in: {req.email}",
device_info=data.get("device_info"),
)
return create_success_response(result, "Login successful")
def signup(self, data: Dict[str, Any]) -> Dict[str, Any]:
req = SignUpRequest(
email=data.get("email", ""),
password=data.get("password", ""),
full_name=data.get("full_name", ""),
organization=data.get("organization"),
purpose=data.get("purpose"),
)
errors = req.validate()
if errors:
return create_error_response("Validation failed", {"errors": errors})
ok, result = self.auth_service.sign_up(
email=req.email,
password=req.password,
full_name=req.full_name,
organization=req.organization,
purpose=req.purpose,
)
if not ok:
return create_error_response(result.get("error", "Signup failed"))
# Log the signup activity
self.auth_service.log_activity(
user_id=result["user"]["id"],
activity_type="signup",
description=f"New user registered: {req.email}",
device_info=data.get("device_info"),
)
return create_success_response(result, "Account created successfully")
def logout(self, access_token: str, user_id: str) -> Dict[str, Any]:
self.auth_service.sign_out(access_token)
self.auth_service.log_activity(
user_id=user_id,
activity_type="logout",
description="User logged out",
)
return create_success_response(None, "Logged out")
def get_me(self, access_token: str) -> Dict[str, Any]:
"""Verify token and return current user info."""
ok, user = self.auth_service.verify_token(access_token)
if not ok or not user:
return create_error_response("Invalid or expired token")
return create_success_response({"user": user})
def refresh(self, data: Dict[str, Any]) -> Dict[str, Any]:
refresh_token = data.get("refresh_token", "")
if not refresh_token:
return create_error_response("refresh_token is required")
ok, result = self.auth_service.refresh_session(refresh_token)
if not ok:
return create_error_response(result.get("error", "Refresh failed"))
return create_success_response(result, "Session refreshed")
def resend_verification(self, data: Dict[str, Any]) -> Dict[str, Any]:
email = data.get("email", "").strip()
if not email:
return create_error_response("Email is required")
ok, err = self.auth_service.resend_verification_email(email)
if not ok:
return create_error_response(err or "Failed to resend verification email")
return create_success_response(None, "Verification email sent")
# ββ Profile βββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
def get_profile(self, user_id: str) -> Dict[str, Any]:
profile = self.auth_service.get_profile(user_id)
if not profile:
return create_error_response("Profile not found")
return create_success_response({"profile": profile})
def update_profile(self, user_id: str, data: Dict[str, Any]) -> Dict[str, Any]:
update = ProfileUpdate(
full_name=data.get("full_name"),
organization=data.get("organization"),
purpose=data.get("purpose"),
)
fields = update.to_dict()
if not fields:
return create_error_response("No fields to update")
ok, err = self.auth_service.update_profile(user_id, fields)
if not ok:
return create_error_response(err or "Update failed")
self.auth_service.log_activity(
user_id=user_id,
activity_type="profile_update",
description="Profile info updated",
)
return create_success_response(None, "Profile updated")
# ββ Activity Logs βββββββββββββββββββββββββββββββββββββββββββββββββββ
def log_activity(self, user_id: str, data: Dict[str, Any]) -> Dict[str, Any]:
entry = ActivityLogEntry(
activity_type=data.get("activity_type", ""),
description=data.get("description"),
metadata=data.get("metadata"),
device_info=data.get("device_info"),
)
errors = entry.validate()
if errors:
return create_error_response("Validation failed", {"errors": errors})
self.auth_service.log_activity(
user_id=user_id,
activity_type=entry.activity_type,
description=entry.description,
metadata=entry.metadata,
device_info=entry.device_info,
)
return create_success_response(None, "Activity logged")
def get_activity_logs(self, user_id: str, limit: int = 50) -> Dict[str, Any]:
logs = self.auth_service.get_activity_logs(user_id, limit)
return create_success_response({"logs": logs, "count": len(logs)})
|