Skip to content

Commit 68e73d6

Browse files
committed
refactor: introduce pydantic SecretStr to protect sensitive information like user password
1 parent 37c5bb3 commit 68e73d6

File tree

2 files changed

+13
-11
lines changed

2 files changed

+13
-11
lines changed

app/models/user.py

+6-4
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
import bcrypt
55
from passlib.context import CryptContext
6+
from pydantic import SecretStr
67
from sqlalchemy import String, LargeBinary, select
78
from sqlalchemy.dialects.postgresql import UUID
89
from sqlalchemy.ext.asyncio import AsyncSession
@@ -25,11 +26,12 @@ def password(self):
2526
return self._password.decode("utf-8")
2627

2728
@password.setter
28-
def password(self, password: str):
29-
self._password = bcrypt.hashpw(password.encode("utf-8"), bcrypt.gensalt())
29+
def password(self, password: SecretStr):
30+
_password_string = password.get_secret_value()
31+
self._password = bcrypt.hashpw(_password_string.encode("utf-8"), bcrypt.gensalt())
3032

31-
def check_password(self, password: str):
32-
return pwd_context.verify(password, self.password)
33+
def check_password(self, password: SecretStr):
34+
return pwd_context.verify(password.get_secret_value(), self.password)
3335

3436
@classmethod
3537
async def find(cls, database_session: AsyncSession, where_conditions: list[Any]):

app/schemas/user.py

+7-7
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
11
from uuid import UUID
22

3-
from pydantic import BaseModel, Field, EmailStr, ConfigDict
3+
from pydantic import BaseModel, Field, EmailStr, ConfigDict, SecretStr
44

55
config = ConfigDict(from_attributes=True)
66

77

88
# TODO: add pydantic field validator for strong password
99
class UserSchema(BaseModel):
1010
model_config = config
11-
email: EmailStr = Field(title="User’s email", description="User’s email")
12-
first_name: str = Field(title="User’s first name", description="User’s first name")
13-
last_name: str = Field(title="User’s last name", description="User’s last name")
14-
password: str = Field(title="User’s password", description="User’s password")
11+
email: EmailStr = Field(title="User’s email", description="User’s email", examples=["john@domain.com"])
12+
first_name: str = Field(title="User’s first name", description="User’s first name", examples=["John"])
13+
last_name: str = Field(title="User’s last name", description="User’s last name", examples=["Doe"])
14+
password: SecretStr = Field(title="User’s password", description="User’s password", examples=["@SuperSecret123"])
1515

1616

1717
class UserResponse(BaseModel):
@@ -29,5 +29,5 @@ class TokenResponse(BaseModel):
2929

3030
class UserLogin(BaseModel):
3131
model_config = config
32-
email: EmailStr = Field(title="User’s email", description="User’s email")
33-
password: str = Field(title="User’s password", description="User’s password")
32+
email: EmailStr = Field(title="User’s email", description="User’s email", examples=["john@domain.com"])
33+
password: SecretStr = Field(title="User’s password", description="User’s password", examples=["@SuperSecret123"])

0 commit comments

Comments
 (0)