Coverage for polar/models/user_session.py: 96%

23 statements  

« prev     ^ index     » next       coverage.py v7.15.2, created at 2026-10-07 12:42 +0000

1from datetime import datetime 

2from uuid import UUID 

3 

4from sqlalchemy import CHAR, TIMESTAMP, ForeignKey, Text, Uuid 

5from sqlalchemy.dialects.postgresql import ARRAY 

6from sqlalchemy.orm import Mapped, declared_attr, mapped_column, relationship 

7 

8from polar.auth.scope import Scope 

9from polar.config import settings 

10from polar.kit.db.models.base import RecordModel 

11from polar.kit.extensions.sqlalchemy import StringEnum 

12from polar.kit.utils import utc_now 

13from polar.models.user import User 

14 

15 

16def get_expires_at() -> datetime: 

17 return utc_now() + settings.USER_SESSION_TTL 

18 

19 

20class UserSession(RecordModel): 

21 __tablename__ = "user_sessions" 

22 

23 token: Mapped[str] = mapped_column(CHAR(64), unique=True, nullable=False) 

24 expires_at: Mapped[datetime] = mapped_column( 

25 TIMESTAMP(timezone=True), nullable=False, index=True, default=get_expires_at 

26 ) 

27 user_agent: Mapped[str] = mapped_column(Text, nullable=False) 

28 scopes: Mapped[list[Scope]] = mapped_column( 

29 ARRAY(StringEnum(Scope)), nullable=False, default=list 

30 ) 

31 

32 user_id: Mapped[UUID] = mapped_column( 

33 Uuid, ForeignKey("users.id", ondelete="cascade"), nullable=False 

34 ) 

35 

36 @declared_attr 

37 def user(cls) -> Mapped[User]: 

38 return relationship(User, lazy="joined")