admin / Bid-Sentinel
publicBid Scrape and Tracking Application with AI Capability
Bid-Sentinel / bid-sentinel-v2 / backend / app / security.py
1265 B · main
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | """Password hashing and JWT helpers.""" from datetime import datetime, timedelta, timezone import bcrypt from jose import JWTError, jwt from app.config import settings # bcrypt has a hard 72-byte limit on the password input; longer inputs are # truncated by the algorithm, so we truncate explicitly for predictable behaviour. _BCRYPT_MAX_BYTES = 72 def hash_password(password: str) -> str: pw = password.encode("utf-8")[:_BCRYPT_MAX_BYTES] return bcrypt.hashpw(pw, bcrypt.gensalt()).decode("utf-8") def verify_password(plain: str, hashed: str) -> bool: try: return bcrypt.checkpw( plain.encode("utf-8")[:_BCRYPT_MAX_BYTES], hashed.encode("utf-8") ) except (ValueError, TypeError): return False def create_access_token(subject: str, role: str) -> str: expire = datetime.now(timezone.utc) + timedelta( minutes=settings.access_token_expire_minutes ) payload = {"sub": subject, "role": role, "exp": expire} return jwt.encode(payload, settings.jwt_secret, algorithm=settings.jwt_algorithm) def decode_access_token(token: str) -> dict | None: try: return jwt.decode(token, settings.jwt_secret, algorithms=[settings.jwt_algorithm]) except JWTError: return None |