import pytest from sqlalchemy import create_engine from sqlalchemy.orm import sessionmaker from app.core.database import Base from app.modules.auth.models import User from app.modules.auth.service import authenticate_user, get_user, hash_password, verify_password @pytest.fixture def db(): engine = create_engine("sqlite:///:memory:", connect_args={"check_same_thread": False}) Base.metadata.create_all(bind=engine) Session = sessionmaker(bind=engine) session = Session() yield session session.close() Base.metadata.drop_all(bind=engine) @pytest.fixture def alice(db): user = User(username="alice", full_name="Alice Smith", pw_hash=hash_password("secret123")) db.add(user) db.commit() db.refresh(user) return user def test_hash_and_verify_password(): hashed = hash_password("mypassword") assert verify_password("mypassword", hashed) is True assert verify_password("wrong", hashed) is False def test_get_user_found(db, alice): assert get_user(db, "alice") is not None def test_get_user_not_found(db): assert get_user(db, "nobody") is None def test_authenticate_correct_password(db, alice): user = authenticate_user(db, "alice", "secret123", ldap_enabled=False) assert user is not None assert user.last_login is not None def test_authenticate_wrong_password(db, alice): assert authenticate_user(db, "alice", "wrong", ldap_enabled=False) is None def test_authenticate_unknown_user(db): assert authenticate_user(db, "ghost", "any", ldap_enabled=False) is None def test_authenticate_inactive_user(db): user = User(username="inactive", full_name="X", pw_hash=hash_password("pw"), is_active=False) db.add(user) db.commit() assert authenticate_user(db, "inactive", "pw", ldap_enabled=False) is None def test_authenticate_no_pw_hash_no_ldap(db): user = User(username="ldaponly", full_name="Y", pw_hash=None) db.add(user) db.commit() assert authenticate_user(db, "ldaponly", "any", ldap_enabled=False) is None # --- LDAP auth integration (uses mocked ldap_authenticate) --- from unittest.mock import patch as mock_patch def test_authenticate_creates_user_on_ldap_success(db): ldap_attrs = { "username": "newldap", "full_name": "New LDAP User", "department": "EFI", "role": "ST", "account_expires": None, } with mock_patch("app.modules.auth.ldap.ldap_authenticate", return_value=ldap_attrs): user = authenticate_user(db, "newldap", "password", ldap_enabled=True) assert user is not None assert user.username == "newldap" assert user.full_name == "New LDAP User" assert user.last_login is not None def test_authenticate_updates_existing_user_on_ldap_success(db): existing = User(username="existing", full_name="Old Name", pw_hash=None) db.add(existing) db.commit() ldap_attrs = { "username": "existing", "full_name": "New Name", "department": "EFI", "role": "PF", "account_expires": None, } with mock_patch("app.modules.auth.ldap.ldap_authenticate", return_value=ldap_attrs): user = authenticate_user(db, "existing", "password", ldap_enabled=True) assert user.full_name == "New Name" def test_authenticate_returns_none_on_ldap_failure(db): with mock_patch("app.modules.auth.ldap.ldap_authenticate", return_value=None): result = authenticate_user(db, "anyone", "wrong", ldap_enabled=True) assert result is None def test_authenticate_blocked_user_not_bypassed_by_ldap(db): blocked = User(username="blocked", full_name="B", pw_hash=None, is_active=False) db.add(blocked) db.commit() ldap_attrs = {"username": "blocked", "full_name": "B", "department": "", "role": "", "account_expires": None} with mock_patch("app.modules.auth.ldap.ldap_authenticate", return_value=ldap_attrs): result = authenticate_user(db, "blocked", "any", ldap_enabled=True) assert result is None