auth service up running

This commit is contained in:
2025-01-10 14:17:22 +03:00
parent 03accfed1b
commit 79aa3a1bc5
41 changed files with 480 additions and 340 deletions

View File

@@ -8,8 +8,10 @@ class DateTimeLocal:
def __init__(self, timezone: str = None, is_client: bool = True):
if timezone and timezone not in Config.SUPPORTED_TIMEZONES:
raise ValueError(f"Unsupported timezone: {timezone}. Must be one of {Config.SUPPORTED_TIMEZONES}")
raise ValueError(
f"Unsupported timezone: {timezone}. Must be one of {Config.SUPPORTED_TIMEZONES}"
)
self.timezone = Config.SYSTEM_TIMEZONE
if is_client:
self.timezone = (timezone or Config.DEFAULT_TIMEZONE).replace("-", "+")
@@ -84,11 +86,11 @@ class DateTimeLocal:
components = [str(base_key)]
components.extend(str(arg) for arg in args)
components.append(f"tz_{self.timezone}")
return ':'.join(components)
return ":".join(components)
def format_for_db(self, date):
"""Format date for database storage"""
return self.get(date).format('YYYY-MM-DD HH:mm:ss.SSSZZ')
return self.get(date).format("YYYY-MM-DD HH:mm:ss.SSSZZ")
def parse_from_db(self, date_str):
"""Parse date from database format"""
@@ -99,16 +101,17 @@ class DateTimeLocal:
def get_day_boundaries(self, date=None):
"""Get start and end of day in current timezone"""
dt = self.get(date) if date else self.now()
start = dt.floor('day')
end = dt.ceil('day')
start = dt.floor("day")
end = dt.ceil("day")
return start, end
def get_month_boundaries(self, date=None):
"""Get start and end of month in current timezone"""
dt = self.get(date) if date else self.now()
start = dt.floor('month')
end = dt.ceil('month')
start = dt.floor("month")
end = dt.ceil("month")
return start, end
client_arrow = DateTimeLocal(is_client=True)
system_arrow = DateTimeLocal(is_client=False)

View File

@@ -4,18 +4,19 @@ from typing import Optional, Dict, Any
from fastapi.requests import Request
from api_library.date_time_actions.date_functions import system_arrow
class UserActivityLogger:
def __init__(self):
self.logger = logging.getLogger("user_activity")
self.logger.setLevel(logging.INFO)
# Add handlers if not already added
if not self.logger.handlers:
log_path = "/service_app/logs/user_activity.log"
os.makedirs(os.path.dirname(log_path), exist_ok=True)
handler = logging.FileHandler(log_path)
formatter = logging.Formatter(
'%(asctime)s - %(name)s - %(levelname)s - %(message)s'
"%(asctime)s - %(name)s - %(levelname)s - %(message)s"
)
handler.setFormatter(formatter)
self.logger.addHandler(handler)
@@ -24,9 +25,10 @@ class UserActivityLogger:
"""Extract common metadata from request"""
return {
"agent": request.headers.get("User-Agent"),
"ip": getattr(request, "remote_addr", None) or request.headers.get("X-Forwarded-For"),
"ip": getattr(request, "remote_addr", None)
or request.headers.get("X-Forwarded-For"),
"platform": request.headers.get("Origin"),
"timestamp": str(system_arrow.now())
"timestamp": str(system_arrow.now()),
}
def log_login_attempt(
@@ -36,7 +38,7 @@ class UserActivityLogger:
domain: str,
access_key: str,
success: bool,
error: Optional[str] = None
error: Optional[str] = None,
):
"""Log login attempts"""
metadata = self._get_request_metadata(request)
@@ -47,9 +49,9 @@ class UserActivityLogger:
"access_key": access_key,
"success": success,
"error": error,
**metadata
**metadata,
}
if success:
self.logger.info("Login successful", extra=log_data)
else:
@@ -61,7 +63,7 @@ class UserActivityLogger:
user_id: int,
change_type: str,
success: bool,
error: Optional[str] = None
error: Optional[str] = None,
):
"""Log password changes"""
metadata = self._get_request_metadata(request)
@@ -71,9 +73,9 @@ class UserActivityLogger:
"change_type": change_type,
"success": success,
"error": error,
**metadata
**metadata,
}
if success:
self.logger.info("Password change successful", extra=log_data)
else:
@@ -86,7 +88,7 @@ class UserActivityLogger:
activity_type: str,
domain: Optional[str] = None,
success: bool = True,
error: Optional[str] = None
error: Optional[str] = None,
):
"""Log session activities (logout, disconnect, etc)"""
metadata = self._get_request_metadata(request)
@@ -97,13 +99,14 @@ class UserActivityLogger:
"domain": domain,
"success": success,
"error": error,
**metadata
**metadata,
}
if success:
self.logger.info(f"{activity_type} successful", extra=log_data)
else:
self.logger.warning(f"{activity_type} failed", extra=log_data)
# Global logger instance
user_logger = UserActivityLogger()

View File

@@ -2,9 +2,12 @@ from typing import Any, Optional
from fastapi import status
from fastapi.responses import JSONResponse
class ResponseHandler:
@staticmethod
def success(message: str, data: Optional[Any] = None, status_code: int = status.HTTP_200_OK) -> JSONResponse:
def success(
message: str, data: Optional[Any] = None, status_code: int = status.HTTP_200_OK
) -> JSONResponse:
"""Create a success response"""
return JSONResponse(
content={
@@ -16,7 +19,11 @@ class ResponseHandler:
)
@staticmethod
def error(message: str, data: Optional[Any] = None, status_code: int = status.HTTP_400_BAD_REQUEST) -> JSONResponse:
def error(
message: str,
data: Optional[Any] = None,
status_code: int = status.HTTP_400_BAD_REQUEST,
) -> JSONResponse:
"""Create an error response"""
return JSONResponse(
content={