feat: Add audit logging for login/logout events

- Log successful logins (password and 2FA) to audit_logs
- Log failed login attempts to audit_logs
- Log logout events to audit_logs
- Enables tracking of login activity in admin status dashboard

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Maciej Pienczyn 2026-01-31 20:42:42 +01:00
parent c505a35f8f
commit 1d62934b57

View File

@ -19,6 +19,7 @@ from . import bp
from database import SessionLocal, User, Company, UserBlock
from utils.helpers import sanitize_input, validate_email, validate_password
from extensions import limiter
from security_service import log_audit
# Logger
logger = logging.getLogger(__name__)
@ -246,6 +247,11 @@ def login():
logger.warning(f"Failed login attempt for: {email}")
security_logger.warning(f"FAILED_LOGIN ip={client_ip} email={email}")
# Log failed login to audit
log_audit(db, 'login_failed', 'user', entity_name=email,
details={'reason': 'invalid_credentials', 'ip': client_ip})
db.commit()
# Increment failed attempts if user exists
if user:
user.failed_login_attempts = (user.failed_login_attempts or 0) + 1
@ -289,6 +295,10 @@ def login():
# No 2FA - login directly
login_user(user, remember=remember)
user.last_login = datetime.now()
# Log successful login to audit
log_audit(db, 'login', 'user', entity_id=user.id, entity_name=user.email,
details={'method': 'password', 'ip': client_ip})
db.commit()
logger.info(f"User logged in: {email}")
@ -318,6 +328,15 @@ def login():
@login_required
def logout():
"""User logout"""
# Log logout to audit
db = SessionLocal()
try:
log_audit(db, 'logout', 'user', entity_id=current_user.id,
entity_name=current_user.email)
db.commit()
finally:
db.close()
# Clear 2FA session flag
session.pop('2fa_verified', None)
logout_user()
@ -373,6 +392,13 @@ def verify_2fa():
login_user(user, remember=remember)
session['2fa_verified'] = True
user.last_login = datetime.now()
# Log successful 2FA login to audit
client_ip = request.headers.get('X-Forwarded-For', request.remote_addr)
if client_ip and ',' in client_ip:
client_ip = client_ip.split(',')[0].strip()
log_audit(db, 'login', 'user', entity_id=user.id, entity_name=user.email,
details={'method': '2fa', 'ip': client_ip})
db.commit()
logger.info(f"User logged in with 2FA: {user.email}")