Add user authentication system
- Implement secure user registration and login - Add password hashing with PBKDF2 and random salts - Create session-based authentication with secure tokens - Support user deactivation and session management - Include comprehensive unit tests for authentication - Integrate authentication demo into main application 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
141
tests/unit/test_auth.py
Normal file
141
tests/unit/test_auth.py
Normal file
@@ -0,0 +1,141 @@
|
||||
import pytest
|
||||
import sys
|
||||
import os
|
||||
import time
|
||||
|
||||
# Add src directory to path for imports
|
||||
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', '..', 'src'))
|
||||
|
||||
from auth import UserManager, AuthenticationError, User
|
||||
|
||||
class TestUserManager:
|
||||
|
||||
def setup_method(self):
|
||||
"""Setup test fixtures"""
|
||||
self.user_manager = UserManager()
|
||||
|
||||
def test_register_user_success(self):
|
||||
"""Test successful user registration"""
|
||||
result = self.user_manager.register_user("testuser", "test@example.com", "password123")
|
||||
assert result is True
|
||||
assert "testuser" in self.user_manager.users
|
||||
|
||||
user = self.user_manager.users["testuser"]
|
||||
assert user.username == "testuser"
|
||||
assert user.email == "test@example.com"
|
||||
assert user.is_active is True
|
||||
assert user.created_at is not None
|
||||
|
||||
def test_register_duplicate_username(self):
|
||||
"""Test registration with duplicate username"""
|
||||
self.user_manager.register_user("testuser", "test1@example.com", "password123")
|
||||
|
||||
with pytest.raises(ValueError, match="Username already exists"):
|
||||
self.user_manager.register_user("testuser", "test2@example.com", "password456")
|
||||
|
||||
def test_register_weak_password(self):
|
||||
"""Test registration with weak password"""
|
||||
with pytest.raises(ValueError, match="Password must be at least 8 characters long"):
|
||||
self.user_manager.register_user("testuser", "test@example.com", "123")
|
||||
|
||||
def test_authenticate_success(self):
|
||||
"""Test successful authentication"""
|
||||
self.user_manager.register_user("testuser", "test@example.com", "password123")
|
||||
|
||||
session_token = self.user_manager.authenticate("testuser", "password123")
|
||||
|
||||
assert session_token is not None
|
||||
assert len(session_token) > 0
|
||||
assert session_token in self.user_manager.sessions
|
||||
assert self.user_manager.sessions[session_token] == "testuser"
|
||||
|
||||
def test_authenticate_invalid_username(self):
|
||||
"""Test authentication with invalid username"""
|
||||
with pytest.raises(AuthenticationError, match="Invalid username or password"):
|
||||
self.user_manager.authenticate("nonexistent", "password123")
|
||||
|
||||
def test_authenticate_invalid_password(self):
|
||||
"""Test authentication with invalid password"""
|
||||
self.user_manager.register_user("testuser", "test@example.com", "password123")
|
||||
|
||||
with pytest.raises(AuthenticationError, match="Invalid username or password"):
|
||||
self.user_manager.authenticate("testuser", "wrongpassword")
|
||||
|
||||
def test_authenticate_deactivated_user(self):
|
||||
"""Test authentication with deactivated user"""
|
||||
self.user_manager.register_user("testuser", "test@example.com", "password123")
|
||||
self.user_manager.deactivate_user("testuser")
|
||||
|
||||
with pytest.raises(AuthenticationError, match="Account is deactivated"):
|
||||
self.user_manager.authenticate("testuser", "password123")
|
||||
|
||||
def test_validate_session_success(self):
|
||||
"""Test successful session validation"""
|
||||
self.user_manager.register_user("testuser", "test@example.com", "password123")
|
||||
session_token = self.user_manager.authenticate("testuser", "password123")
|
||||
|
||||
username = self.user_manager.validate_session(session_token)
|
||||
assert username == "testuser"
|
||||
|
||||
def test_validate_session_invalid_token(self):
|
||||
"""Test session validation with invalid token"""
|
||||
username = self.user_manager.validate_session("invalid_token")
|
||||
assert username is None
|
||||
|
||||
def test_logout_success(self):
|
||||
"""Test successful logout"""
|
||||
self.user_manager.register_user("testuser", "test@example.com", "password123")
|
||||
session_token = self.user_manager.authenticate("testuser", "password123")
|
||||
|
||||
result = self.user_manager.logout(session_token)
|
||||
assert result is True
|
||||
assert session_token not in self.user_manager.sessions
|
||||
|
||||
def test_logout_invalid_token(self):
|
||||
"""Test logout with invalid token"""
|
||||
result = self.user_manager.logout("invalid_token")
|
||||
assert result is False
|
||||
|
||||
def test_get_user_success(self):
|
||||
"""Test getting user information"""
|
||||
self.user_manager.register_user("testuser", "test@example.com", "password123")
|
||||
|
||||
user = self.user_manager.get_user("testuser")
|
||||
assert user is not None
|
||||
assert user.username == "testuser"
|
||||
assert user.email == "test@example.com"
|
||||
|
||||
def test_get_user_nonexistent(self):
|
||||
"""Test getting nonexistent user"""
|
||||
user = self.user_manager.get_user("nonexistent")
|
||||
assert user is None
|
||||
|
||||
def test_deactivate_user_success(self):
|
||||
"""Test successful user deactivation"""
|
||||
self.user_manager.register_user("testuser", "test@example.com", "password123")
|
||||
session_token = self.user_manager.authenticate("testuser", "password123")
|
||||
|
||||
result = self.user_manager.deactivate_user("testuser")
|
||||
assert result is True
|
||||
assert self.user_manager.users["testuser"].is_active is False
|
||||
assert session_token not in self.user_manager.sessions
|
||||
|
||||
def test_deactivate_user_nonexistent(self):
|
||||
"""Test deactivating nonexistent user"""
|
||||
result = self.user_manager.deactivate_user("nonexistent")
|
||||
assert result is False
|
||||
|
||||
def test_password_hashing_security(self):
|
||||
"""Test that passwords are properly hashed and salted"""
|
||||
self.user_manager.register_user("user1", "user1@example.com", "password123")
|
||||
self.user_manager.register_user("user2", "user2@example.com", "password123")
|
||||
|
||||
user1 = self.user_manager.users["user1"]
|
||||
user2 = self.user_manager.users["user2"]
|
||||
|
||||
# Same password should have different hashes due to different salts
|
||||
assert user1.password_hash != user2.password_hash
|
||||
|
||||
# Password hash should contain salt and hash separated by colon
|
||||
assert ":" in user1.password_hash
|
||||
assert ":" in user2.password_hash
|
||||
Reference in New Issue
Block a user