refactor: introduce pydantic SecretStr to protect sensitive information like user password

This commit is contained in:
Jakub Miazek 2024-03-29 14:12:32 +01:00
parent 37c5bb316f
commit 68e73d60ec
2 changed files with 13 additions and 11 deletions

View File

@ -3,6 +3,7 @@ from typing import Any
import bcrypt
from passlib.context import CryptContext
from pydantic import SecretStr
from sqlalchemy import String, LargeBinary, select
from sqlalchemy.dialects.postgresql import UUID
from sqlalchemy.ext.asyncio import AsyncSession
@ -25,11 +26,12 @@ class User(Base):
return self._password.decode("utf-8")
@password.setter
def password(self, password: str):
self._password = bcrypt.hashpw(password.encode("utf-8"), bcrypt.gensalt())
def password(self, password: SecretStr):
_password_string = password.get_secret_value()
self._password = bcrypt.hashpw(_password_string.encode("utf-8"), bcrypt.gensalt())
def check_password(self, password: str):
return pwd_context.verify(password, self.password)
def check_password(self, password: SecretStr):
return pwd_context.verify(password.get_secret_value(), self.password)
@classmethod
async def find(cls, database_session: AsyncSession, where_conditions: list[Any]):

View File

@ -1,6 +1,6 @@
from uuid import UUID
from pydantic import BaseModel, Field, EmailStr, ConfigDict
from pydantic import BaseModel, Field, EmailStr, ConfigDict, SecretStr
config = ConfigDict(from_attributes=True)
@ -8,10 +8,10 @@ config = ConfigDict(from_attributes=True)
# TODO: add pydantic field validator for strong password
class UserSchema(BaseModel):
model_config = config
email: EmailStr = Field(title="Users email", description="Users email")
first_name: str = Field(title="Users first name", description="Users first name")
last_name: str = Field(title="Users last name", description="Users last name")
password: str = Field(title="Users password", description="Users password")
email: EmailStr = Field(title="Users email", description="Users email", examples=["john@domain.com"])
first_name: str = Field(title="Users first name", description="Users first name", examples=["John"])
last_name: str = Field(title="Users last name", description="Users last name", examples=["Doe"])
password: SecretStr = Field(title="Users password", description="Users password", examples=["@SuperSecret123"])
class UserResponse(BaseModel):
@ -29,5 +29,5 @@ class TokenResponse(BaseModel):
class UserLogin(BaseModel):
model_config = config
email: EmailStr = Field(title="Users email", description="Users email")
password: str = Field(title="Users password", description="Users password")
email: EmailStr = Field(title="Users email", description="Users email", examples=["john@domain.com"])
password: SecretStr = Field(title="Users password", description="Users password", examples=["@SuperSecret123"])