chore(m365_powershell): remove unnecessary test_credentials (#9204)

This commit is contained in:
Hugo Pereira Brito
2025-11-11 10:16:57 +01:00
committed by GitHub
parent 822d201159
commit 73a277f27b
5 changed files with 13 additions and 363 deletions

View File

@@ -4,10 +4,7 @@ from unittest.mock import MagicMock, call, patch
import pytest
from prowler.lib.powershell.powershell import PowerShellSession
from prowler.providers.m365.exceptions.exceptions import (
M365CertificateCreationError,
M365GraphConnectionError,
)
from prowler.providers.m365.exceptions.exceptions import M365CertificateCreationError
from prowler.providers.m365.lib.powershell.m365_powershell import M365PowerShell
from prowler.providers.m365.models import M365Credentials, M365IdentityInfo
@@ -115,31 +112,6 @@ class Testm365PowerShell:
)
session.close()
@patch("subprocess.Popen")
def test_test_credentials_application_auth(self, mock_popen):
mock_process = MagicMock()
mock_popen.return_value = mock_process
credentials = M365Credentials(
client_id="test_client_id",
client_secret="test_client_secret",
tenant_id="test_tenant_id",
)
identity = M365IdentityInfo(
identity_id="test_id",
identity_type="Service Principal",
tenant_id="test_tenant",
tenant_domain="contoso.onmicrosoft.com",
tenant_domains=["contoso.onmicrosoft.com"],
location="test_location",
)
session = M365PowerShell(credentials, identity)
session.execute = MagicMock(return_value="sometoken")
result = session.test_credentials(credentials)
assert result is True
session.execute.assert_any_call("Write-Output $graphToken")
session.close()
@patch("subprocess.Popen")
def test_remove_ansi(self, mock_popen):
credentials = M365Credentials(
@@ -339,13 +311,14 @@ class Testm365PowerShell:
# Verify successful initialization
assert result is True
# Verify that execute was called for each module
assert mock_execute_obj.call_count == 9 # 3 modules * 3 commands each
assert (
mock_execute_obj.call_count == 2 * 3
) # number of modules * 3 commands each
# Verify success messages were logged
mock_info.assert_any_call(
"Successfully installed module ExchangeOnlineManagement"
)
mock_info.assert_any_call("Successfully installed module MicrosoftTeams")
mock_info.assert_any_call("Successfully installed module MSAL.PS")
@patch("subprocess.Popen")
def test_initialize_m365_powershell_modules_failure(self, mock_popen):
@@ -408,12 +381,11 @@ class Testm365PowerShell:
main()
# Verify all info messages were logged in the correct order
assert mock_info.call_count == 4
assert mock_info.call_count == 3
mock_info.assert_has_calls(
[
call("Successfully installed module ExchangeOnlineManagement"),
call("Successfully installed module MicrosoftTeams"),
call("Successfully installed module MSAL.PS"),
call("M365 PowerShell modules initialized successfully"),
]
)
@@ -456,96 +428,6 @@ class Testm365PowerShell:
# Verify no info messages were logged
mock_info.assert_not_called()
@patch("subprocess.Popen")
def test_test_graph_connection_success(self, mock_popen):
"""Test test_graph_connection when token is valid"""
mock_process = MagicMock()
mock_popen.return_value = mock_process
credentials = M365Credentials(
client_id="test_client_id",
client_secret="test_client_secret",
tenant_id="test_tenant_id",
)
identity = M365IdentityInfo(
identity_id="test_id",
identity_type="Application",
tenant_id="test_tenant",
tenant_domain="example.com",
tenant_domains=["example.com"],
location="test_location",
)
session = M365PowerShell(credentials, identity)
# Mock execute to return a valid token
session.execute = MagicMock(return_value="valid_token")
result = session.test_graph_connection()
assert result is True
session.execute.assert_called_once_with("Write-Output $graphToken")
session.close()
@patch("subprocess.Popen")
def test_test_graph_connection_empty_token(self, mock_popen):
"""Test test_graph_connection when token is empty"""
mock_process = MagicMock()
mock_popen.return_value = mock_process
credentials = M365Credentials(
client_id="test_client_id",
client_secret="test_client_secret",
tenant_id="test_tenant_id",
)
identity = M365IdentityInfo(
identity_id="test_id",
identity_type="Application",
tenant_id="test_tenant",
tenant_domain="example.com",
tenant_domains=["example.com"],
location="test_location",
)
session = M365PowerShell(credentials, identity)
# Mock execute to return empty token
session.execute = MagicMock(return_value="")
with pytest.raises(M365GraphConnectionError) as exc_info:
session.test_graph_connection()
assert "Microsoft Graph token is empty or invalid" in str(exc_info.value)
session.execute.assert_called_once_with("Write-Output $graphToken")
session.close()
@patch("subprocess.Popen")
def test_test_graph_connection_exception(self, mock_popen):
"""Test test_graph_connection when an exception occurs"""
mock_process = MagicMock()
mock_popen.return_value = mock_process
credentials = M365Credentials(
client_id="test_client_id",
client_secret="test_client_secret",
tenant_id="test_tenant_id",
)
identity = M365IdentityInfo(
identity_id="test_id",
identity_type="Application",
tenant_id="test_tenant",
tenant_domain="example.com",
tenant_domains=["example.com"],
location="test_location",
)
session = M365PowerShell(credentials, identity)
# Mock execute to raise an exception
session.execute = MagicMock(side_effect=Exception("PowerShell error"))
with pytest.raises(M365GraphConnectionError) as exc_info:
session.test_graph_connection()
assert "Failed to connect to Microsoft Graph API: PowerShell error" in str(
exc_info.value
)
session.close()
@patch("subprocess.Popen")
def test_test_teams_connection_success(self, mock_popen):
"""Test test_teams_connection when token is valid"""
@@ -1007,36 +889,6 @@ class Testm365PowerShell:
session.close()
@patch("subprocess.Popen")
def test_test_credentials_certificate_auth_success(self, mock_popen):
"""Test test_credentials method with certificate authentication - successful"""
mock_process = MagicMock()
mock_popen.return_value = mock_process
certificate_content = base64.b64encode(b"fake_certificate").decode("utf-8")
credentials = M365Credentials(
client_id="test_client_id", certificate_content=certificate_content
)
identity = M365IdentityInfo()
# Create session without calling init_credential
with patch.object(M365PowerShell, "init_credential"):
session = M365PowerShell(credentials, identity)
# Mock successful certificate connections
# Note: The actual implementation uses "or" so if teams succeeds, exchange won't be called
session.test_teams_certificate_connection = MagicMock(return_value=True)
session.test_exchange_certificate_connection = MagicMock(return_value=True)
result = session.test_credentials(credentials)
assert result is True
session.test_teams_certificate_connection.assert_called_once()
# Exchange connection should NOT be called if teams connection succeeds (due to "or" logic)
session.test_exchange_certificate_connection.assert_not_called()
session.close()
@patch("subprocess.Popen")
def test_test_credentials_certificate_auth_failure(self, mock_popen):
"""Test test_credentials method with certificate authentication - failure"""
@@ -1057,9 +909,6 @@ class Testm365PowerShell:
session.test_teams_certificate_connection = MagicMock(return_value=False)
session.test_exchange_certificate_connection = MagicMock(return_value=False)
result = session.test_credentials(credentials)
assert result is True # Method always returns True after the try block
session.close()
@patch("subprocess.Popen")
@@ -1287,94 +1136,3 @@ class Testm365PowerShell:
assert any('$tenantDomain = "contoso.com"' in cmd for cmd in executed_commands)
session.close()
@patch("subprocess.Popen")
def test_test_credentials_certificate_auth_with_or_logic(self, mock_popen):
"""Test test_credentials method with certificate auth using OR logic between Teams and Exchange"""
certificate_content = base64.b64encode(b"fake_certificate").decode("utf-8")
mock_process = MagicMock()
mock_popen.return_value = mock_process
mock_process.returncode = 0
# Create session with non-certificate credentials first
session = M365PowerShell(
M365Credentials(
client_id="test_client_id",
client_secret="test_secret",
tenant_id="test_tenant_id",
tenant_domains=["contoso.com"],
),
M365IdentityInfo(
tenant_id="test_tenant_id",
tenant_domain="contoso.com",
tenant_domains=["contoso.com"],
identity_id="test_identity_id",
identity_type="Service Principal with Certificate",
),
)
# Mock that Teams connection fails but Exchange succeeds
session.test_teams_certificate_connection = MagicMock(return_value=False)
session.test_exchange_certificate_connection = MagicMock(return_value=True)
result = session.test_credentials(
M365Credentials(
client_id="test_client_id",
tenant_id="test_tenant_id",
certificate_content=certificate_content,
tenant_domains=["contoso.com"],
)
)
assert result is True
session.test_teams_certificate_connection.assert_called_once()
session.test_exchange_certificate_connection.assert_called_once()
session.close()
@patch("subprocess.Popen")
def test_test_credentials_certificate_auth_both_fail(self, mock_popen):
"""Test test_credentials method with certificate auth when both Teams and Exchange fail"""
certificate_content = base64.b64encode(b"fake_certificate").decode("utf-8")
mock_process = MagicMock()
mock_popen.return_value = mock_process
mock_process.returncode = 0
# Create session with non-certificate credentials first
session = M365PowerShell(
M365Credentials(
client_id="test_client_id",
client_secret="test_secret",
tenant_id="test_tenant_id",
tenant_domains=["contoso.com"],
),
M365IdentityInfo(
tenant_id="test_tenant_id",
tenant_domain="contoso.com",
tenant_domains=["contoso.com"],
identity_id="test_identity_id",
identity_type="Service Principal with Certificate",
),
)
# Mock that both connections fail
session.test_teams_certificate_connection = MagicMock(return_value=False)
session.test_exchange_certificate_connection = MagicMock(return_value=False)
# Even when both fail, the method should return True (this is the intended logic)
result = session.test_credentials(
M365Credentials(
client_id="test_client_id",
tenant_id="test_tenant_id",
certificate_content=certificate_content,
tenant_domains=["contoso.com"],
)
)
assert result is True
session.test_teams_certificate_connection.assert_called_once()
session.test_exchange_certificate_connection.assert_called_once()
session.close()

View File

@@ -932,37 +932,6 @@ class TestM365Provider:
assert result.certificate_content == certificate_content
assert identity.identity_type == "Service Principal with Certificate"
def test_setup_powershell_invalid_credentials(self):
"""Test setup_powershell with invalid credentials"""
credentials_dict = {
"client_id": "test_client_id",
"tenant_id": "test_tenant_id",
"client_secret": "test_client_secret",
}
with (
patch("prowler.providers.m365.m365_provider.M365PowerShell") as mock_ps,
pytest.raises(M365ConfigCredentialsError) as exception,
):
mock_session = MagicMock()
mock_session.test_credentials.return_value = False
mock_session.close = MagicMock()
mock_ps.return_value = mock_session
M365Provider.setup_powershell(
m365_credentials=credentials_dict,
identity=M365IdentityInfo(
identity_id=IDENTITY_ID,
identity_type="User",
tenant_id=TENANT_ID,
tenant_domain=DOMAIN,
tenant_domains=["test.onmicrosoft.com"],
location=LOCATION,
),
)
assert exception.type == M365ConfigCredentialsError
assert "The provided credentials are not valid." in str(exception.value)
def test_validate_arguments_browser_auth_without_tenant_id(self):
"""Test validate_arguments with browser_auth but missing tenant_id"""
with pytest.raises(M365BrowserAuthNoTenantIDError) as exception: