feat(intune): add device compliance policy marks noncompliant check (#10599)

This commit is contained in:
Hugo Pereira Brito
2026-04-14 12:01:47 +01:00
committed by GitHub
parent 4941ed5797
commit bc3fd79457
8 changed files with 319 additions and 4 deletions
@@ -0,0 +1,163 @@
from unittest import mock
from prowler.providers.m365.services.intune.intune_service import IntuneSettings
from tests.providers.m365.m365_fixtures import DOMAIN, set_mocked_m365_provider
CHECK_MODULE_PATH = "prowler.providers.m365.services.intune.intune_device_compliance_policy_unassigned_devices_not_compliant_by_default.intune_device_compliance_policy_unassigned_devices_not_compliant_by_default"
class Test_intune_device_compliance_policy_unassigned_devices_not_compliant_by_default:
def test_secure_by_default_true(self):
intune_client = mock.MagicMock()
intune_client.audited_tenant = "audited_tenant"
intune_client.audited_domain = DOMAIN
with (
mock.patch(
"prowler.providers.common.provider.Provider.get_global_provider",
return_value=set_mocked_m365_provider(),
),
mock.patch(f"{CHECK_MODULE_PATH}.intune_client", new=intune_client),
):
from prowler.providers.m365.services.intune.intune_device_compliance_policy_unassigned_devices_not_compliant_by_default.intune_device_compliance_policy_unassigned_devices_not_compliant_by_default import (
intune_device_compliance_policy_unassigned_devices_not_compliant_by_default,
)
intune_client.settings = IntuneSettings(secure_by_default=True)
intune_client.verification_error = None
result = (
intune_device_compliance_policy_unassigned_devices_not_compliant_by_default().execute()
)
assert len(result) == 1
assert result[0].status == "PASS"
assert result[0].status_extended == (
"Intune built-in Device Compliance Policy marks devices "
"with no compliance policy assigned as Not compliant."
)
def test_secure_by_default_false(self):
intune_client = mock.MagicMock()
intune_client.audited_tenant = "audited_tenant"
intune_client.audited_domain = DOMAIN
with (
mock.patch(
"prowler.providers.common.provider.Provider.get_global_provider",
return_value=set_mocked_m365_provider(),
),
mock.patch(f"{CHECK_MODULE_PATH}.intune_client", new=intune_client),
):
from prowler.providers.m365.services.intune.intune_device_compliance_policy_unassigned_devices_not_compliant_by_default.intune_device_compliance_policy_unassigned_devices_not_compliant_by_default import (
intune_device_compliance_policy_unassigned_devices_not_compliant_by_default,
)
intune_client.settings = IntuneSettings(secure_by_default=False)
intune_client.verification_error = None
result = (
intune_device_compliance_policy_unassigned_devices_not_compliant_by_default().execute()
)
assert len(result) == 1
assert result[0].status == "FAIL"
assert result[0].status_extended == (
"Intune built-in Device Compliance Policy marks devices "
"with no compliance policy assigned as Compliant. "
"Change the default to Not compliant in Intune settings."
)
def test_secure_by_default_none(self):
intune_client = mock.MagicMock()
intune_client.audited_tenant = "audited_tenant"
intune_client.audited_domain = DOMAIN
with (
mock.patch(
"prowler.providers.common.provider.Provider.get_global_provider",
return_value=set_mocked_m365_provider(),
),
mock.patch(f"{CHECK_MODULE_PATH}.intune_client", new=intune_client),
):
from prowler.providers.m365.services.intune.intune_device_compliance_policy_unassigned_devices_not_compliant_by_default.intune_device_compliance_policy_unassigned_devices_not_compliant_by_default import (
intune_device_compliance_policy_unassigned_devices_not_compliant_by_default,
)
intune_client.settings = IntuneSettings(secure_by_default=None)
intune_client.verification_error = None
result = (
intune_device_compliance_policy_unassigned_devices_not_compliant_by_default().execute()
)
assert len(result) == 1
assert result[0].status == "MANUAL"
assert result[0].status_extended == (
"Intune built-in Device Compliance Policy could not be verified "
"because Microsoft Graph did not return the secure-by-default "
"compliance setting."
)
def test_settings_is_none(self):
intune_client = mock.MagicMock()
intune_client.audited_tenant = "audited_tenant"
intune_client.audited_domain = DOMAIN
with (
mock.patch(
"prowler.providers.common.provider.Provider.get_global_provider",
return_value=set_mocked_m365_provider(),
),
mock.patch(f"{CHECK_MODULE_PATH}.intune_client", new=intune_client),
):
from prowler.providers.m365.services.intune.intune_device_compliance_policy_unassigned_devices_not_compliant_by_default.intune_device_compliance_policy_unassigned_devices_not_compliant_by_default import (
intune_device_compliance_policy_unassigned_devices_not_compliant_by_default,
)
intune_client.settings = None
intune_client.verification_error = None
result = (
intune_device_compliance_policy_unassigned_devices_not_compliant_by_default().execute()
)
assert len(result) == 1
assert result[0].status == "MANUAL"
assert result[0].status_extended == (
"Intune built-in Device Compliance Policy could not be verified "
"because Microsoft Graph did not return the secure-by-default "
"compliance setting."
)
def test_verification_error_returns_manual(self):
intune_client = mock.MagicMock()
intune_client.audited_tenant = "audited_tenant"
intune_client.audited_domain = DOMAIN
with (
mock.patch(
"prowler.providers.common.provider.Provider.get_global_provider",
return_value=set_mocked_m365_provider(),
),
mock.patch(f"{CHECK_MODULE_PATH}.intune_client", new=intune_client),
):
from prowler.providers.m365.services.intune.intune_device_compliance_policy_unassigned_devices_not_compliant_by_default.intune_device_compliance_policy_unassigned_devices_not_compliant_by_default import (
intune_device_compliance_policy_unassigned_devices_not_compliant_by_default,
)
intune_client.settings = None
intune_client.verification_error = (
"Could not read Microsoft Intune device management settings."
)
result = (
intune_device_compliance_policy_unassigned_devices_not_compliant_by_default().execute()
)
assert len(result) == 1
assert result[0].status == "MANUAL"
assert result[0].status_extended == (
"Intune built-in Device Compliance Policy could not be verified. "
"Could not read Microsoft Intune device management settings."
)
@@ -349,6 +349,60 @@ def test_intune_get_settings_null_settings():
assert settings.secure_by_default is None
def test_intune_get_settings_retries_without_select_when_settings_missing():
"""Test _get_settings retries without $select when settings are omitted."""
intune = Intune.__new__(Intune)
selected_response = SimpleNamespace(settings=None)
full_response = SimpleNamespace(settings=SimpleNamespace(secure_by_default=True))
mock_client = mock.MagicMock()
mock_client.device_management.get = AsyncMock(
side_effect=[selected_response, full_response]
)
intune.client = mock_client
loop = asyncio.new_event_loop()
try:
settings, error = loop.run_until_complete(intune._get_settings())
finally:
loop.close()
assert error is None
assert settings is not None
assert settings.secure_by_default is True
assert mock_client.device_management.get.await_count == 2
def test_intune_get_settings_retries_without_select_when_value_missing():
"""Test _get_settings retries without $select when secure_by_default is omitted."""
intune = Intune.__new__(Intune)
selected_response = SimpleNamespace(
settings=SimpleNamespace(secure_by_default=None)
)
full_response = SimpleNamespace(settings=SimpleNamespace(secure_by_default=False))
mock_client = mock.MagicMock()
mock_client.device_management.get = AsyncMock(
side_effect=[selected_response, full_response]
)
intune.client = mock_client
loop = asyncio.new_event_loop()
try:
settings, error = loop.run_until_complete(intune._get_settings())
finally:
loop.close()
assert error is None
assert settings is not None
assert settings.secure_by_default is False
assert mock_client.device_management.get.await_count == 2
def test_intune_get_settings_exception():
"""Test _get_settings handles exceptions gracefully."""
intune = Intune.__new__(Intune)