def test_hash_password_weak(self): hasher = PasswordHasher() with pytest.raises(ValidationError): hasher.hash_password("weak")
def register_user(self, email: str, password: str) -> User: """ Register a new user Args: email: User's email address password: User's password Returns: Created User object Raises: ValidationError: If email is invalid or user already exists """ # Validate email if not re.match(r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]2,$', email): raise ValidationError("Invalid email format") # Check if user already exists if email in self.users: raise ValidationError("User already exists") # Hash password password_hash = self.password_hasher.hash_password(password) # Create user user = User( user_id=str(uuid4()), email=email, password_hash=password_hash, created_at=datetime.utcnow() ) self.users[email] = user return user andrei neagoie python
def generate_token(self, user_id: str, email: str) -> str: """ Generate JWT token for authenticated user Args: user_id: User's unique identifier email: User's email address Returns: JWT token string """ payload = 'user_id': user_id, 'email': email, 'exp': datetime.utcnow() + timedelta(minutes=self.token_expiry_minutes), 'iat': datetime.utcnow(), 'jti': str(uuid4()) # Unique token ID return jwt.encode(payload, self.secret_key, algorithm='HS256') password: str) ->
def login(self, email: str, password: str, ip_address: str) -> Tuple[str, User]: """ Authenticate user and return JWT token Args: email: User's email password: User's password ip_address: Client IP for rate limiting Returns: Tuple of (jwt_token, user_object) Raises: UserNotFoundError: If user doesn't exist InvalidPasswordError: If password is incorrect RateLimitExceededError: If too many attempts """ # Check rate limit by IP self.rate_limiter.check_rate_limit(ip_address) self.rate_limiter.record_attempt(ip_address) # Find user user = self.users.get(email) if not user: raise UserNotFoundError("User not found") # Check if account is locked if user.is_locked(): remaining = (user.locked_until - datetime.utcnow()).seconds raise AuthenticationError(f"Account locked. Try again in remaining seconds") # Verify password if not self.password_hasher.verify_password(password, user.password_hash): user.failed_attempts += 1 # Lock account if max attempts exceeded if user.failed_attempts >= self.max_failed_attempts: user.locked_until = datetime.utcnow() + timedelta(minutes=self.lockout_minutes) raise AuthenticationError( f"Too many failed attempts. Account locked for self.lockout_minutes minutes" ) raise InvalidPasswordError("Invalid password") # Successful login - reset failed attempts and update last login user.failed_attempts = 0 user.last_login = datetime.utcnow() # Generate token token = self.token_manager.generate_token(user.user_id, user.email) return token, user email: str) ->
class RateLimitExceededError(AuthenticationError): """Raised when too many attempts""" pass
def is_locked(self) -> bool: """Check if user account is currently locked""" if self.locked_until and datetime.utcnow() < self.locked_until: return True return False class PasswordHasher: """Handles secure password hashing and verification"""
class InvalidPasswordError(AuthenticationError): """Raised when password is incorrect""" pass