forked from kaw393939/event-manager-qa-onboarding
-
Notifications
You must be signed in to change notification settings - Fork 25
Expand file tree
/
Copy pathuser_model.py
More file actions
97 lines (84 loc) · 4.7 KB
/
Copy pathuser_model.py
File metadata and controls
97 lines (84 loc) · 4.7 KB
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
from builtins import bool, int, str
from datetime import datetime
from enum import Enum
import uuid
from sqlalchemy import (
Column, String, Integer, DateTime, Boolean, func, Enum as SQLAlchemyEnum
)
from sqlalchemy.dialects.postgresql import UUID, ENUM
from sqlalchemy.orm import Mapped, mapped_column
from app.database import Base
class UserRole(Enum):
"""Enumeration of user roles within the application, stored as ENUM in the database."""
ANONYMOUS = "ANONYMOUS"
AUTHENTICATED = "AUTHENTICATED"
MANAGER = "MANAGER"
ADMIN = "ADMIN"
class User(Base):
"""
Represents a user within the application, corresponding to the 'users' table in the database.
This class uses SQLAlchemy ORM for mapping attributes to database columns efficiently.
Attributes:
id (UUID): Unique identifier for the user.
nickname (str): Unique nickname for privacy, required.
email (str): Unique email address, required.
email_verified (bool): Flag indicating if the email has been verified.
hashed_password (str): Hashed password for security, required.
first_name (str): Optional first name of the user.
last_name (str): Optional first name of the user.
bio (str): Optional biographical information.
profile_picture_url (str): Optional URL to a profile picture.
linkedin_profile_url (str): Optional LinkedIn profile URL.
github_profile_url (str): Optional GitHub profile URL.
role (UserRole): Role of the user within the application.
is_professional (bool): Flag indicating professional status.
professional_status_updated_at (datetime): Timestamp of last professional status update.
last_login_at (datetime): Timestamp of the last login.
failed_login_attempts (int): Count of failed login attempts.
is_locked (bool): Flag indicating if the account is locked.
created_at (datetime): Timestamp when the user was created, set by the server.
updated_at (datetime): Timestamp of the last update, set by the server.
Methods:
lock_account(): Locks the user account.
unlock_account(): Unlocks the user account.
verify_email(): Marks the user's email as verified.
has_role(role_name): Checks if the user has a specified role.
update_professional_status(status): Updates the professional status and logs the update time.
"""
__tablename__ = "users"
__mapper_args__ = {"eager_defaults": True}
id: Mapped[uuid.UUID] = mapped_column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
nickname: Mapped[str] = Column(String(50), unique=True, nullable=False, index=True)
email: Mapped[str] = Column(String(255), unique=True, nullable=False, index=True)
first_name: Mapped[str] = Column(String(100), nullable=True)
last_name: Mapped[str] = Column(String(100), nullable=True)
bio: Mapped[str] = Column(String(500), nullable=True)
profile_picture_url: Mapped[str] = Column(String(255), nullable=True)
linkedin_profile_url: Mapped[str] = Column(String(255), nullable=True)
github_profile_url: Mapped[str] = Column(String(255), nullable=True)
role: Mapped[UserRole] = Column(SQLAlchemyEnum(UserRole, name='UserRole', create_constraint=False), default=UserRole.ANONYMOUS, nullable=False)
is_professional: Mapped[bool] = Column(Boolean, default=False)
professional_status_updated_at: Mapped[datetime] = Column(DateTime(timezone=True), nullable=True)
last_login_at: Mapped[datetime] = Column(DateTime(timezone=True), nullable=True)
failed_login_attempts: Mapped[int] = Column(Integer, default=0)
is_locked: Mapped[bool] = Column(Boolean, default=False)
created_at: Mapped[datetime] = Column(DateTime(timezone=True), server_default=func.now())
updated_at: Mapped[datetime] = Column(DateTime(timezone=True), server_default=func.now(), onupdate=func.now())
verification_token = Column(String, nullable=True)
email_verified: Mapped[bool] = Column(Boolean, default=False, nullable=False)
hashed_password: Mapped[str] = Column(String(255), nullable=False)
def __repr__(self) -> str:
"""Provides a readable representation of a user object."""
return f"<User {self.nickname}, Role: {self.role.name}>"
def lock_account(self):
self.is_locked = True
def unlock_account(self):
self.is_locked = False
def verify_email(self):
self.email_verified = True
def has_role(self, role_name: UserRole) -> bool:
return self.role == role_name
def update_professional_status(self, status: bool):
"""Updates the professional status and logs the update time."""
self.is_professional = status
self.professional_status_updated_at = func.now()