Coverage for src/lexigram/auth/authn/schemas/requests.py: 92%

49 statements  

« prev     ^ index     » next       coverage.py v7.15.4, created at 2026-08-25 12:26 +0800

1from __future__ import annotations 

2 

3from dataclasses import dataclass 

4 

5from lexigram.domain import DomainModel 

6from lexigram.validation import Field 

7 

8 

9@dataclass(init=False) 

10class LoginRequest(DomainModel): 

11 email: str = Field(..., description="Email address") 

12 password: str = Field(..., description="User password") 

13 remember_me: bool = Field(False, description="Remember login session") 

14 

15 

16@dataclass(init=False) 

17class RegisterRequest(DomainModel): 

18 name: str = Field(..., min_length=3, max_length=50, description="User name") 

19 email: str = Field(..., description="Valid email address") 

20 password: str = Field(..., min_length=8, description="Secure password") 

21 confirm_password: str = Field(..., description="Password confirmation") 

22 profile: dict = Field( 

23 default_factory=dict, 

24 description="Additional user profile data", 

25 ) 

26 

27 def validate_passwords_match(self) -> None: 

28 if self.password != self.confirm_password: 

29 raise ValueError("Passwords do not match") 

30 

31 

32@dataclass(init=False) 

33class RefreshTokenRequest(DomainModel): 

34 refresh_token: str = Field(..., description="Valid refresh token") 

35 

36 

37@dataclass(init=False) 

38class PasswordResetRequest(DomainModel): 

39 email: str = Field(..., description="User email address") 

40 

41 

42@dataclass(init=False) 

43class PasswordResetConfirm(DomainModel): 

44 token: str = Field(..., description="Reset token") 

45 new_password: str = Field(..., min_length=8, description="New password") 

46 confirm_password: str = Field(..., description="Password confirmation") 

47 

48 def validate_passwords_match(self) -> None: 

49 if self.new_password != self.confirm_password: 

50 raise ValueError("Passwords do not match") 

51 

52 

53@dataclass(init=False) 

54class OAuth2AuthorizeRequest(DomainModel): 

55 response_type: str = Field(..., description="Response type (code, token)") 

56 client_id: str = Field(..., description="OAuth2 client ID") 

57 redirect_uri: str | None = Field(None, description="Redirect URI") 

58 scope: str = Field("openid profile", description="Requested scopes") 

59 state: str | None = Field(None, description="State parameter") 

60 

61 

62@dataclass(init=False) 

63class OAuth2TokenRequest(DomainModel): 

64 grant_type: str = Field(..., description="Grant type") 

65 code: str | None = Field(None, description="Authorization code") 

66 redirect_uri: str | None = Field(None, description="Redirect URI") 

67 client_id: str | None = Field(None, description="Client ID") 

68 client_secret: str | None = Field(None, description="Client secret") 

69 refresh_token: str | None = Field(None, description="Refresh token") 

70 

71 

72__all__ = [ 

73 "LoginRequest", 

74 "OAuth2AuthorizeRequest", 

75 "OAuth2TokenRequest", 

76 "PasswordResetConfirm", 

77 "PasswordResetRequest", 

78 "RefreshTokenRequest", 

79 "RegisterRequest", 

80]