mirror of
https://github.com/wizarrrr/wizarr.git
synced 2026-06-12 15:55:05 -04:00
249 lines
8.6 KiB
Python
249 lines
8.6 KiB
Python
from unittest.mock import MagicMock, patch
|
|
|
|
import pytest
|
|
|
|
from app.models import LDAPConfiguration
|
|
from app.services.ldap.client import LDAPClient
|
|
|
|
|
|
@pytest.fixture
|
|
def ldap_config():
|
|
from app.services.ldap.encryption import encrypt_credential
|
|
|
|
config = LDAPConfiguration()
|
|
config.server_url = "ldap://ldap.example.com:389"
|
|
config.use_tls = True
|
|
config.verify_cert = True
|
|
config.service_account_dn = "cn=wizarr,ou=people,dc=example,dc=com"
|
|
# Use a properly encrypted password for testing
|
|
config.service_account_password_encrypted = encrypt_credential("test_password")
|
|
config.user_base_dn = "ou=people,dc=example,dc=com"
|
|
config.user_search_filter = "(uid={username})"
|
|
config.username_attribute = "uid"
|
|
config.email_attribute = "mail"
|
|
config.user_object_class = "inetOrgPerson"
|
|
config.group_base_dn = "ou=groups,dc=example,dc=com"
|
|
config.group_object_class = "groupOfUniqueNames"
|
|
config.group_member_attribute = "uniqueMember"
|
|
return config
|
|
|
|
|
|
@patch("app.services.ldap.client.Connection")
|
|
@patch("app.services.ldap.client.Server")
|
|
def test_test_connection_success(mock_server, mock_connection, ldap_config):
|
|
"""Test successful LDAP connection test."""
|
|
mock_conn = MagicMock()
|
|
mock_connection.return_value = mock_conn
|
|
|
|
client = LDAPClient(ldap_config)
|
|
success, message = client.test_connection()
|
|
|
|
assert success is True
|
|
assert message == "Connection successful"
|
|
mock_conn.unbind.assert_called_once()
|
|
|
|
|
|
@patch("app.services.ldap.client.Connection")
|
|
@patch("app.services.ldap.client.Server")
|
|
def test_test_connection_bind_error(mock_server, mock_connection, ldap_config):
|
|
from ldap3.core.exceptions import LDAPBindError
|
|
|
|
mock_connection.side_effect = LDAPBindError("Invalid credentials")
|
|
|
|
client = LDAPClient(ldap_config)
|
|
success, message = client.test_connection()
|
|
|
|
assert success is False
|
|
assert "Authentication failed" in message
|
|
|
|
|
|
@patch("app.services.ldap.client.Connection")
|
|
@patch("app.services.ldap.client.Server")
|
|
def test_authenticate_user_success(mock_server, mock_connection, ldap_config):
|
|
# Mock service account connection for DN lookup
|
|
mock_service_conn = MagicMock()
|
|
mock_entry = MagicMock()
|
|
mock_entry.entry_dn = "uid=testuser,ou=people,dc=example,dc=com"
|
|
mock_service_conn.entries = [mock_entry]
|
|
|
|
# Mock user connection for authentication
|
|
mock_user_conn = MagicMock()
|
|
mock_user_entry = MagicMock()
|
|
mock_user_entry.entry_dn = "uid=testuser,ou=people,dc=example,dc=com"
|
|
mock_user_entry.uid.value = "testuser"
|
|
mock_user_entry.mail.value = "test@example.com"
|
|
mock_user_conn.entries = [mock_user_entry]
|
|
|
|
# Return service conn first, then user conn
|
|
mock_connection.side_effect = [mock_service_conn, mock_user_conn]
|
|
|
|
client = LDAPClient(ldap_config)
|
|
success, attrs = client.authenticate_user("testuser", "userpassword")
|
|
|
|
assert success is True
|
|
assert "uid" in attrs
|
|
assert attrs["uid"] == "testuser"
|
|
|
|
|
|
@patch("app.services.ldap.client.Connection")
|
|
@patch("app.services.ldap.client.Server")
|
|
def test_create_user_success(mock_server, mock_connection, ldap_config):
|
|
mock_conn = MagicMock()
|
|
mock_conn.add.return_value = True
|
|
mock_conn.extend.standard.modify_password.return_value = True
|
|
mock_conn.search.return_value = False
|
|
mock_conn.entries = []
|
|
mock_connection.return_value = mock_conn
|
|
|
|
client = LDAPClient(ldap_config)
|
|
success, result = client.create_user(
|
|
username="newuser",
|
|
email="newuser@example.com",
|
|
password="password123",
|
|
)
|
|
|
|
assert success is True
|
|
assert "uid=newuser,ou=people,dc=example,dc=com" in result
|
|
mock_conn.add.assert_called_once()
|
|
mock_conn.extend.standard.modify_password.assert_called_once()
|
|
mock_conn.unbind.assert_called_once()
|
|
|
|
|
|
@patch("app.services.ldap.client.Connection")
|
|
@patch("app.services.ldap.client.Server")
|
|
def test_search_groups(mock_server, mock_connection, ldap_config):
|
|
mock_conn = MagicMock()
|
|
mock_conn.search.return_value = True
|
|
|
|
# Mock group entries
|
|
mock_entry1 = MagicMock()
|
|
mock_entry1.entry_dn = "cn=users,ou=groups,dc=example,dc=com"
|
|
mock_entry1.cn.value = "users"
|
|
|
|
mock_entry2 = MagicMock()
|
|
mock_entry2.entry_dn = "cn=admins,ou=groups,dc=example,dc=com"
|
|
mock_entry2.cn.value = "admins"
|
|
|
|
mock_conn.entries = [mock_entry1, mock_entry2]
|
|
mock_connection.return_value = mock_conn
|
|
|
|
client = LDAPClient(ldap_config)
|
|
groups = client.search_groups()
|
|
|
|
assert len(groups) == 2
|
|
assert groups[0]["cn"] == "users"
|
|
assert groups[0]["description"] is None
|
|
assert groups[1]["cn"] == "admins"
|
|
assert groups[1]["description"] is None
|
|
mock_conn.search.assert_called_once()
|
|
mock_conn.unbind.assert_called_once()
|
|
|
|
|
|
@patch("app.services.ldap.client.Connection")
|
|
@patch("app.services.ldap.client.Server")
|
|
def test_delete_user_success(mock_server, mock_connection, ldap_config):
|
|
"""Test successful LDAP user deletion."""
|
|
mock_conn = MagicMock()
|
|
mock_conn.delete.return_value = True
|
|
mock_connection.return_value = mock_conn
|
|
|
|
client = LDAPClient(ldap_config)
|
|
user_dn = "uid=testuser,ou=people,dc=example,dc=com"
|
|
success, message = client.delete_user(user_dn)
|
|
|
|
assert success is True
|
|
assert message == "User deleted successfully"
|
|
mock_conn.delete.assert_called_once_with(user_dn)
|
|
mock_conn.unbind.assert_called_once()
|
|
|
|
|
|
@patch("app.services.ldap.client.Connection")
|
|
@patch("app.services.ldap.client.Server")
|
|
def test_delete_user_failure(mock_server, mock_connection, ldap_config):
|
|
"""Test failed LDAP user deletion."""
|
|
mock_conn = MagicMock()
|
|
mock_conn.delete.return_value = False
|
|
mock_conn.result = {"description": "No such object"}
|
|
mock_connection.return_value = mock_conn
|
|
|
|
client = LDAPClient(ldap_config)
|
|
user_dn = "uid=nonexistent,ou=people,dc=example,dc=com"
|
|
success, message = client.delete_user(user_dn)
|
|
|
|
assert success is False
|
|
assert "Failed to delete LDAP user" in message
|
|
mock_conn.unbind.assert_called_once()
|
|
|
|
|
|
@patch("app.services.ldap.client.Connection")
|
|
@patch("app.services.ldap.client.Server")
|
|
def test_delete_user_missing_dn(mock_server, mock_connection, ldap_config):
|
|
"""Test LDAP user deletion with missing DN."""
|
|
client = LDAPClient(ldap_config)
|
|
success, message = client.delete_user("")
|
|
|
|
assert success is False
|
|
assert message == "User DN is required"
|
|
|
|
|
|
@patch("app.services.ldap.client.Connection")
|
|
@patch("app.services.ldap.client.Server")
|
|
def test_change_password_success(mock_server, mock_connection, ldap_config):
|
|
"""Test successful LDAP password change."""
|
|
mock_conn = MagicMock()
|
|
mock_conn.extend.standard.modify_password.return_value = True
|
|
mock_connection.return_value = mock_conn
|
|
|
|
client = LDAPClient(ldap_config)
|
|
user_dn = "uid=testuser,ou=people,dc=example,dc=com"
|
|
success, message = client.change_password(user_dn, "newpassword123")
|
|
|
|
assert success is True
|
|
assert message == "Password changed successfully"
|
|
mock_conn.extend.standard.modify_password.assert_called_once_with(
|
|
user_dn, None, "newpassword123"
|
|
)
|
|
mock_conn.unbind.assert_called_once()
|
|
|
|
|
|
@patch("app.services.ldap.client.Connection")
|
|
@patch("app.services.ldap.client.Server")
|
|
def test_change_password_failure(mock_server, mock_connection, ldap_config):
|
|
"""Test failed LDAP password change."""
|
|
mock_conn = MagicMock()
|
|
mock_conn.extend.standard.modify_password.return_value = False
|
|
mock_conn.result = {"description": "Insufficient access rights"}
|
|
mock_connection.return_value = mock_conn
|
|
|
|
client = LDAPClient(ldap_config)
|
|
user_dn = "uid=testuser,ou=people,dc=example,dc=com"
|
|
success, message = client.change_password(user_dn, "newpassword123")
|
|
|
|
assert success is False
|
|
assert "Failed to change password" in message
|
|
assert "lldap_password_manager" in message
|
|
mock_conn.unbind.assert_called_once()
|
|
|
|
|
|
@patch("app.services.ldap.client.Connection")
|
|
@patch("app.services.ldap.client.Server")
|
|
def test_change_password_missing_dn(mock_server, mock_connection, ldap_config):
|
|
"""Test LDAP password change with missing DN."""
|
|
client = LDAPClient(ldap_config)
|
|
success, message = client.change_password("", "newpassword123")
|
|
|
|
assert success is False
|
|
assert message == "User DN is required"
|
|
|
|
|
|
@patch("app.services.ldap.client.Connection")
|
|
@patch("app.services.ldap.client.Server")
|
|
def test_change_password_missing_password(mock_server, mock_connection, ldap_config):
|
|
"""Test LDAP password change with missing password."""
|
|
client = LDAPClient(ldap_config)
|
|
user_dn = "uid=testuser,ou=people,dc=example,dc=com"
|
|
success, message = client.change_password(user_dn, "")
|
|
|
|
assert success is False
|
|
assert message == "New password is required"
|