* Fix pylint warnings across all 24 Python files in web_server - Add module, class, and function docstrings (C0114, C0115, C0116) - Fix import ordering: stdlib before third-party before local (C0411) - Replace wildcard imports with explicit named imports (W0401) - Remove trailing whitespace and add missing final newlines (C0303, C0304) - Replace dict() with dict literals (R1735) - Remove unused imports and variables (W0611, W0612) - Narrow broad Exception catches to specific exceptions (W0718) - Replace f-string logging with lazy % formatting (W1203) - Fix variable naming: UPPER_CASE for constants, snake_case for locals (C0103) - Add pylint disable comments for necessary global statements (W0603) - Fix no-else-return, simplifiable-if-expression, singleton-comparison - Fix bad indentation in stripe.py (W0311) - Add encoding="utf-8" to open() calls (W1514) - Add check=True to subprocess.run() calls (W1510) - Register Celery task modules via conf.include * Update `package-lock.json` add peer dependencies
48 lines
1.4 KiB
Python
48 lines
1.4 KiB
Python
"""Token generation and verification for password resets."""
|
|
|
|
from typing import Optional
|
|
from os import getenv
|
|
|
|
from database.database import Database
|
|
from itsdangerous import URLSafeTimedSerializer, BadSignature, SignatureExpired
|
|
from dotenv import load_dotenv
|
|
from werkzeug.security import generate_password_hash
|
|
|
|
load_dotenv()
|
|
|
|
serializer = URLSafeTimedSerializer(getenv("AUTH_SECRET_KEY"))
|
|
|
|
def generate_token(email, salt_value) -> str:
|
|
"""
|
|
Creates a token for password reset
|
|
"""
|
|
token = serializer.dumps(email, salt=salt_value)
|
|
return token
|
|
|
|
def verify_token(token: str, salt_value) -> Optional[str]:
|
|
"""
|
|
Given a token, verifies and decodes it into an email
|
|
"""
|
|
try:
|
|
email = serializer.loads(token, salt=salt_value, max_age=3600)
|
|
return email
|
|
except SignatureExpired:
|
|
# Token expired
|
|
print("Token has expired", flush=True)
|
|
return None
|
|
except BadSignature:
|
|
# Invalid token
|
|
print("Token is invalid", flush=True)
|
|
return None
|
|
|
|
def reset_password(new_password: str, email: str):
|
|
"""
|
|
Given email and new password reset the password for a given user
|
|
"""
|
|
with Database() as db:
|
|
db.execute("""
|
|
UPDATE users
|
|
SET password = ?
|
|
WHERE email = ?
|
|
""", (generate_password_hash(new_password), email))
|