# ABOUTME: Tests for PAM authentication via ctypes wrapper. # ABOUTME: Verifies authenticate() calls libpam correctly and handles success/failure. from unittest.mock import patch, MagicMock, ANY import ctypes from moonlock.auth import authenticate, PAM_SUCCESS, PAM_AUTH_ERR class TestAuthenticate: """Tests for PAM authentication.""" @patch("moonlock.auth._get_libpam") def test_returns_true_on_successful_auth(self, mock_get_libpam): libpam = MagicMock() mock_get_libpam.return_value = libpam libpam.pam_start.return_value = PAM_SUCCESS libpam.pam_authenticate.return_value = PAM_SUCCESS libpam.pam_acct_mgmt.return_value = PAM_SUCCESS libpam.pam_end.return_value = PAM_SUCCESS assert authenticate("testuser", "correctpassword") is True @patch("moonlock.auth._get_libpam") def test_returns_false_on_wrong_password(self, mock_get_libpam): libpam = MagicMock() mock_get_libpam.return_value = libpam libpam.pam_start.return_value = PAM_SUCCESS libpam.pam_authenticate.return_value = PAM_AUTH_ERR libpam.pam_end.return_value = PAM_SUCCESS assert authenticate("testuser", "wrongpassword") is False @patch("moonlock.auth._get_libpam") def test_pam_end_always_called(self, mock_get_libpam): libpam = MagicMock() mock_get_libpam.return_value = libpam libpam.pam_start.return_value = PAM_SUCCESS libpam.pam_authenticate.return_value = PAM_AUTH_ERR libpam.pam_end.return_value = PAM_SUCCESS authenticate("testuser", "wrongpassword") libpam.pam_end.assert_called_once() @patch("moonlock.auth._get_libpam") def test_returns_false_when_pam_start_fails(self, mock_get_libpam): libpam = MagicMock() mock_get_libpam.return_value = libpam libpam.pam_start.return_value = PAM_AUTH_ERR assert authenticate("testuser", "password") is False @patch("moonlock.auth._get_libpam") def test_uses_moonlock_as_service_name(self, mock_get_libpam): libpam = MagicMock() mock_get_libpam.return_value = libpam libpam.pam_start.return_value = PAM_SUCCESS libpam.pam_authenticate.return_value = PAM_SUCCESS libpam.pam_acct_mgmt.return_value = PAM_SUCCESS libpam.pam_end.return_value = PAM_SUCCESS authenticate("testuser", "password") args = libpam.pam_start.call_args # First positional arg should be the service name assert args[0][0] == b"moonlock"