Skip to content

Commit

Permalink
feat(auth): implement user service with Protocol pattern
Browse files Browse the repository at this point in the history
- Add UserServiceProtocol for type safety
- Add user model with SQLAlchemy types
- Add service methods with proper typing
- Add password reset functionality
- Add email verification logic
- Add role-based access control

BREAKING CHANGE: User service now follows Protocol pattern
  • Loading branch information
gsinghjay committed Jan 3, 2025
1 parent dd7d95c commit b6b4b30
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 11 deletions.
34 changes: 25 additions & 9 deletions app/models/user.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
"""User model definition."""

from sqlalchemy import Column, Integer, String, DateTime, Boolean, Enum
from sqlalchemy.sql import func
from datetime import datetime
import enum
from sqlalchemy import Column, Integer, String, DateTime, Boolean
from app.models.base import Base


Expand All @@ -14,19 +14,35 @@ class UserRole(str, enum.Enum):


class User(Base):
"""User model for storing user related details."""
"""
User model for storing user information.
Attributes:
id (int): Primary key
email (str): User's email address, unique
full_name (str): User's full name
password (str): Hashed password
is_verified (bool): Email verification status
role (str): User role (e.g., user, admin)
verification_token (str): Token for email verification
password_reset_token (str): Token for password reset
password_reset_expires (datetime): Expiration time for password reset token
last_login (datetime): Last login timestamp
created_at (datetime): Account creation timestamp
updated_at (datetime): Last update timestamp
"""

__tablename__ = "users"

id = Column(Integer, primary_key=True, index=True)
email = Column(String, unique=True, index=True, nullable=False)
full_name = Column(String, nullable=False)
hashed_password = Column(String, nullable=False)
password = Column(String, nullable=False)
is_verified = Column(Boolean, default=False)
role = Column(Enum(UserRole), default=UserRole.USER)
role = Column(String, default=UserRole.USER)
verification_token = Column(String, nullable=True)
password_reset_token = Column(String, nullable=True)
password_reset_expires = Column(DateTime(timezone=True), nullable=True)
last_login = Column(DateTime(timezone=True), nullable=True)
created_at = Column(DateTime(timezone=True), server_default=func.now())
updated_at = Column(DateTime(timezone=True), onupdate=func.now())
password_reset_expires = Column(DateTime, nullable=True)
last_login = Column(DateTime, nullable=True)
created_at = Column(DateTime, default=datetime.utcnow)
updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
4 changes: 2 additions & 2 deletions app/services/user_service.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
"""User service module."""

from datetime import datetime, timedelta
from typing import Optional, Protocol
from typing import Optional, Protocol, cast

from sqlalchemy import select
from sqlalchemy.orm import Session
Expand Down Expand Up @@ -165,7 +165,7 @@ def authenticate(self, email: str, password: str) -> Optional[User]:
user = self.get_by_email(email)
if not user:
return None
if not verify_password(password, user.password):
if not verify_password(password, cast(str, user.password)):
return None
return user

Expand Down

0 comments on commit b6b4b30

Please sign in to comment.