1
0

auth.py 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. """Authentication service."""
  2. import hashlib
  3. import secrets
  4. from datetime import datetime
  5. from typing import Optional, Tuple
  6. from models import User
  7. from database import db
  8. from validation import validate_email, validate_password
  9. def hash_password(password: str) -> str:
  10. """Hash a password for storage."""
  11. salt = secrets.token_hex(16)
  12. hash_obj = hashlib.sha256((password + salt).encode())
  13. return f"{salt}:{hash_obj.hexdigest()}"
  14. def verify_password(password: str, password_hash: str) -> bool:
  15. """Verify a password against its hash."""
  16. salt, stored_hash = password_hash.split(":")
  17. hash_obj = hashlib.sha256((password + salt).encode())
  18. return hash_obj.hexdigest() == stored_hash
  19. def generate_token() -> str:
  20. """Generate a secure random token."""
  21. return secrets.token_urlsafe(32)
  22. class AuthService:
  23. def __init__(self):
  24. self.tokens: dict = {}
  25. def register(self, email: str, password: str, name: str) -> Tuple[bool, str]:
  26. """Register a new user."""
  27. if not validate_email(email):
  28. return False, "Invalid email format"
  29. if not validate_password(password):
  30. return False, "Password too weak"
  31. if db.get_user_by_email(email):
  32. return False, "Email already registered"
  33. user = User(
  34. id=generate_token(),
  35. email=email,
  36. name=name,
  37. password_hash=hash_password(password),
  38. created_at=datetime.now(),
  39. )
  40. db.create_user(user)
  41. return True, user.id
  42. def login(self, email: str, password: str) -> Optional[str]:
  43. """Authenticate user and return token."""
  44. user = db.get_user_by_email(email)
  45. if not user:
  46. return None
  47. if not verify_password(password, user.password_hash):
  48. return None
  49. token = generate_token()
  50. self.tokens[token] = user.id
  51. return token
  52. def logout(self, token: str) -> None:
  53. """Invalidate a token."""
  54. self.tokens.pop(token, None)
  55. def get_user_id(self, token: str) -> Optional[str]:
  56. """Get user ID from token."""
  57. return self.tokens.get(token)
  58. auth_service = AuthService()