feat(googleworkspace): pass app checks when the service is off for everyone (#13117)

This commit is contained in:
Pepe Fagoaga authored and GitHub committed 2026-10-22 01:07:19 +02:00
1 parent a59eae7b24
commit eae17a5e17
124 files changed
+3447 -618

No files matched your search

@@ -7,6 +7,7 @@ from prowler.providers.googleworkspace.lib.service.service import (
OVERRIDE_SCOPE,
UNKNOWN_SCOPE,
GoogleWorkspaceService,
ServicePolicies,
)
ROOT_OU_ID = "03ph8a2z1234"
@@ -125,3 +126,236 @@ class TestPolicyScope:
svc._policy_scope({"policyQuery": {"group": "groups/xyz"}})
== OVERRIDE_SCOPE
)
def _policy(
setting_type,
value,
sort_order=None,
org_unit=f"orgUnits/{ROOT_OU_ID}",
group=None,
):
"""Build a policy as the Cloud Identity Policy API returns it."""
policy = {"setting": {"type": f"settings/{setting_type}", "value": value}}
query = {}
if org_unit:
query["orgUnit"] = org_unit
if group:
query["group"] = group
if sort_order is not None:
query["sortOrder"] = sort_order
if query:
policy["policyQuery"] = query
return policy
class TestEffectivePolicies:
def test_the_greatest_sort_order_wins_whatever_the_api_order(self):
"""The ADMIN policy saved in the console outranks Google's SYSTEM defaults, even when the API returns it first"""
admin = _policy("security.password", {"minimumLength": 12}, 201.00131)
default_a = _policy("security.password", {"minimumLength": 8}, 100.00001)
default_b = _policy("security.password", {"minimumLength": 8}, 100.00003)
svc = _make_service()
assert svc._effective_policies([admin, default_a, default_b]) == [admin]
assert svc._effective_policies([default_a, default_b, admin]) == [admin]
def test_each_setting_type_is_reduced_on_its_own(self):
password_admin = _policy("security.password", {"minimumLength": 12}, 201.1)
password_default = _policy("security.password", {"minimumLength": 8}, 100.1)
session_default = _policy(
"security.session_controls", {"webSessionDuration": "1209600s"}, 100.3
)
assert _make_service()._effective_policies(
[password_admin, password_default, session_default]
) == [password_admin, session_default]
def test_a_single_policy_is_kept_as_is(self):
policy = _policy("sites.service_status", {"serviceState": "ENABLED"})
assert _make_service()._effective_policies([policy]) == [policy]
def test_without_a_sort_order_the_last_policy_wins(self):
"""No sort order means no documented precedence, so the API order is kept"""
first = _policy("sites.service_status", {"serviceState": "ENABLED"})
last = _policy("sites.service_status", {"serviceState": "DISABLED"})
assert _make_service()._effective_policies([first, last]) == [last]
def test_policies_outside_the_customer_scope_are_dropped(self):
root = _policy("security.password", {"minimumLength": 8}, 100.1)
sub_ou = _policy(
"security.password", {"minimumLength": 14}, 300.1, org_unit="orgUnits/sub"
)
group = _policy(
"security.password", {"minimumLength": 16}, 400.1, group="groups/g1"
)
assert _make_service()._effective_policies([sub_ou, root, group]) == [root]
def test_rules_are_items_rather_than_values_so_every_one_is_kept(self):
"""Each rule.* policy is a distinct rule, not a competing value for one setting"""
dlp_a = _policy("rule.dlp", {"displayName": "cards", "state": "ACTIVE"}, 1)
dlp_b = _policy("rule.dlp", {"displayName": "ids", "state": "INACTIVE"}, 2)
alert = _policy("rule.system_defined_alerts", {"displayName": "Leaked"}, 1)
assert _make_service()._effective_policies([dlp_a, dlp_b, alert]) == [
dlp_a,
dlp_b,
alert,
]
def test_no_policies(self):
assert _make_service()._effective_policies([]) == []
class TestServiceStatus:
def test_off_at_the_customer_level_with_no_override(self):
status = _policy("chat.service_status", {"serviceState": "DISABLED"}, 201.1)
other = _policy("chat.chat_apps_access", {"enableApps": True}, 100.1)
assert _make_service()._service_status(
[other, status], "chat.service_status"
) == (
"DISABLED",
False,
)
def test_the_greatest_sort_order_gives_the_state(self):
default = _policy("chat.service_status", {"serviceState": "ENABLED"}, 100.1)
admin = _policy("chat.service_status", {"serviceState": "DISABLED"}, 201.1)
assert _make_service()._service_status(
[admin, default], "chat.service_status"
) == (
"DISABLED",
False,
)
def test_an_org_unit_or_group_with_its_own_status_is_an_override(self):
root = _policy("chat.service_status", {"serviceState": "DISABLED"}, 201.1)
sub_ou = _policy(
"chat.service_status",
{"serviceState": "ENABLED"},
301.1,
org_unit="orgUnits/sub",
)
group = _policy(
"chat.service_status", {"serviceState": "ENABLED"}, 401.1, group="groups/g1"
)
svc = _make_service()
assert svc._service_status([root, sub_ou], "chat.service_status") == (
"DISABLED",
True,
)
assert svc._service_status([root, group], "chat.service_status") == (
"DISABLED",
True,
)
def test_a_sub_org_unit_that_is_also_off_is_not_an_override(self):
"""An org unit that turns the service off as well changes nothing for anyone"""
root = _policy("chat.service_status", {"serviceState": "DISABLED"}, 201.1)
sub_ou = _policy(
"chat.service_status",
{"serviceState": "DISABLED"},
301.1,
org_unit="orgUnits/sub",
)
assert _make_service()._service_status(
[root, sub_ou], "chat.service_status"
) == (
"DISABLED",
False,
)
def test_an_unresolved_scope_counts_as_an_override(self):
"""Without the root OU id a scoped policy may be the root or a sub-OU; neither may be assumed"""
status = _policy("chat.service_status", {"serviceState": "DISABLED"}, 201.1)
assert _make_service(root_org_unit_id=None)._service_status(
[status], "chat.service_status"
) == (None, True)
def test_no_status_policy(self):
other = _policy("chat.chat_apps_access", {"enableApps": True}, 100.1)
assert _make_service()._service_status([other], "chat.service_status") == (
None,
False,
)
class TestServicePolicies:
@pytest.mark.parametrize(
"state, overridden, expected",
[
("DISABLED", False, True),
("DISABLED", True, False),
("ENABLED", False, False),
(None, False, False),
],
)
def test_off_for_everyone(self, state, overridden, expected):
policies = ServicePolicies(
service_state=state, service_state_overridden=overridden
)
assert policies.off_for_everyone is expected
class TestListPolicies:
def test_collects_every_page(self):
svc = _make_service()
page_1 = {"policies": [_policy("gmail.pop_access", {"enablePopAccess": True})]}
page_2 = {
"policies": [_policy("gmail.imap_access", {"enableImapAccess": True})]
}
request_1, request_2 = MagicMock(), MagicMock()
request_1.execute.return_value = page_1
request_2.execute.return_value = page_2
service = MagicMock()
service.policies().list.return_value = request_1
service.policies().list_next.side_effect = [request_2, None]
policies, succeeded = svc._list_policies(
service, 'setting.type.matches("gmail.*")', "fetching Gmail policies"
)
assert succeeded is True
assert policies == page_1["policies"] + page_2["policies"]
service.policies().list.assert_called_once_with(
pageSize=100, filter='setting.type.matches("gmail.*")'
)
def test_a_failing_page_keeps_what_was_read_and_reports_the_failure(self):
svc = _make_service()
page_1 = {"policies": [_policy("gmail.pop_access", {"enablePopAccess": True})]}
request_1, request_2 = MagicMock(), MagicMock()
request_1.execute.return_value = page_1
request_2.execute.side_effect = Exception("boom")
service = MagicMock()
service.policies().list.return_value = request_1
service.policies().list_next.side_effect = [request_2, None]
policies, succeeded = svc._list_policies(
service, 'setting.type.matches("gmail.*")', "fetching Gmail policies"
)
assert succeeded is False
assert policies == page_1["policies"]
def test_a_failing_list_call_reports_the_failure(self):
svc = _make_service()
service = MagicMock()
service.policies().list.side_effect = Exception("boom")
policies, succeeded = svc._list_policies(
service, 'setting.type.matches("gmail.*")', "fetching Gmail policies"
)
assert succeeded is False
assert policies == []
@@ -97,6 +97,59 @@ class TestAdditionalServicesService:
assert additional_services.policies_fetched is True
assert additional_services.policies.groups_service_state == "ENABLED"
def test_the_admin_policy_outranks_a_system_default_returned_after_it(self):
"""The greatest sortOrder is the value in force, whatever order the API lists them in"""
mock_provider = set_mocked_googleworkspace_provider()
mock_provider.audit_config = {}
mock_provider.fixer_config = {}
mock_session = MagicMock()
mock_session.credentials = MagicMock()
mock_provider.session = mock_session
mock_service = MagicMock()
mock_policies_list = MagicMock()
mock_policies_list.execute.return_value = {
"policies": [
{
"type": "ADMIN",
"policyQuery": {"sortOrder": 201.00131},
"setting": {
"type": "settings/groups.service_status",
"value": {"serviceState": "DISABLED"},
},
},
{
"type": "SYSTEM",
"policyQuery": {"sortOrder": 100.00002},
"setting": {
"type": "settings/groups.service_status",
"value": {"serviceState": "ENABLED"},
},
},
]
}
mock_service.policies().list.return_value = mock_policies_list
mock_service.policies().list_next.return_value = None
with (
patch(
"prowler.providers.common.provider.Provider.get_global_provider",
return_value=mock_provider,
),
patch(
"prowler.providers.googleworkspace.services.additionalservices.additionalservices_service.GoogleWorkspaceService._build_service",
return_value=mock_service,
),
):
from prowler.providers.googleworkspace.services.additionalservices.additionalservices_service import (
AdditionalServices,
)
additional_services = AdditionalServices(mock_provider)
assert additional_services.policies_fetched is True
assert additional_services.policies.groups_service_state == "DISABLED"
def test_fetch_policies_empty_response(self):
"""Test handling empty policies response"""
mock_provider = set_mocked_googleworkspace_provider()
@@ -5,6 +5,7 @@ from prowler.providers.googleworkspace.services.calendar.calendar_service import
)
from tests.providers.googleworkspace.googleworkspace_fixtures import (
CUSTOMER_ID,
DOMAIN,
set_mocked_googleworkspace_provider,
)
@@ -102,6 +103,38 @@ class TestCalendarExternalInvitationsWarning:
assert findings[0].status == "PASS"
assert "secure default" in findings[0].status_extended
def test_pass_when_the_service_is_off_for_everyone(self):
"""A setting that only acts while the service is on has no effect once the service is off"""
mock_provider = set_mocked_googleworkspace_provider()
with (
patch(
"prowler.providers.common.provider.Provider.get_global_provider",
return_value=mock_provider,
),
patch(
"prowler.providers.googleworkspace.services.calendar.calendar_external_invitations_warning.calendar_external_invitations_warning.calendar_client"
) as mock_client,
):
from prowler.providers.googleworkspace.services.calendar.calendar_external_invitations_warning.calendar_external_invitations_warning import (
calendar_external_invitations_warning,
)
mock_client.provider = mock_provider
mock_client.policies_fetched = True
mock_client.policies = CalendarPolicies(
service_state="DISABLED", external_invitations_warning=False
)
findings = calendar_external_invitations_warning().execute()
assert len(findings) == 1
assert findings[0].status == "PASS"
assert findings[0].status_extended == (
f"Google Calendar is turned off for everyone in domain {DOMAIN}, "
f"so no invitation can be sent."
)
def test_no_findings_when_fetch_failed(self):
"""Test no findings returned when the API fetch failed"""
mock_provider = set_mocked_googleworkspace_provider()
@@ -5,6 +5,7 @@ from prowler.providers.googleworkspace.services.calendar.calendar_service import
)
from tests.providers.googleworkspace.googleworkspace_fixtures import (
CUSTOMER_ID,
DOMAIN,
set_mocked_googleworkspace_provider,
)
@@ -140,6 +141,39 @@ class TestCalendarExternalSharingPrimaryCalendar:
assert findings[0].status == "PASS"
assert "secure default" in findings[0].status_extended
def test_pass_when_the_service_is_off_for_everyone(self):
"""A setting that only acts while the service is on has no effect once the service is off"""
mock_provider = set_mocked_googleworkspace_provider()
with (
patch(
"prowler.providers.common.provider.Provider.get_global_provider",
return_value=mock_provider,
),
patch(
"prowler.providers.googleworkspace.services.calendar.calendar_external_sharing_primary_calendar.calendar_external_sharing_primary_calendar.calendar_client"
) as mock_client,
):
from prowler.providers.googleworkspace.services.calendar.calendar_external_sharing_primary_calendar.calendar_external_sharing_primary_calendar import (
calendar_external_sharing_primary_calendar,
)
mock_client.provider = mock_provider
mock_client.policies_fetched = True
mock_client.policies = CalendarPolicies(
service_state="DISABLED",
primary_calendar_external_sharing="EXTERNAL_ALL_INFO_READ_WRITE",
)
findings = calendar_external_sharing_primary_calendar().execute()
assert len(findings) == 1
assert findings[0].status == "PASS"
assert findings[0].status_extended == (
f"Google Calendar is turned off for everyone in domain {DOMAIN}, "
f"so no calendar can be shared outside the organization."
)
def test_no_findings_when_fetch_failed(self):
"""Test no findings returned when the API fetch failed"""
mock_provider = set_mocked_googleworkspace_provider()
@@ -5,6 +5,7 @@ from prowler.providers.googleworkspace.services.calendar.calendar_service import
)
from tests.providers.googleworkspace.googleworkspace_fixtures import (
CUSTOMER_ID,
DOMAIN,
set_mocked_googleworkspace_provider,
)
@@ -133,6 +134,39 @@ class TestCalendarExternalSharingSecondaryCalendar:
assert findings[0].status == "FAIL"
assert "not explicitly configured" in findings[0].status_extended
def test_pass_when_the_service_is_off_for_everyone(self):
"""A setting that only acts while the service is on has no effect once the service is off"""
mock_provider = set_mocked_googleworkspace_provider()
with (
patch(
"prowler.providers.common.provider.Provider.get_global_provider",
return_value=mock_provider,
),
patch(
"prowler.providers.googleworkspace.services.calendar.calendar_external_sharing_secondary_calendar.calendar_external_sharing_secondary_calendar.calendar_client"
) as mock_client,
):
from prowler.providers.googleworkspace.services.calendar.calendar_external_sharing_secondary_calendar.calendar_external_sharing_secondary_calendar import (
calendar_external_sharing_secondary_calendar,
)
mock_client.provider = mock_provider
mock_client.policies_fetched = True
mock_client.policies = CalendarPolicies(
service_state="DISABLED",
secondary_calendar_external_sharing="EXTERNAL_ALL_INFO_READ_WRITE",
)
findings = calendar_external_sharing_secondary_calendar().execute()
assert len(findings) == 1
assert findings[0].status == "PASS"
assert findings[0].status_extended == (
f"Google Calendar is turned off for everyone in domain {DOMAIN}, "
f"so no calendar can be shared outside the organization."
)
def test_no_findings_when_fetch_failed(self):
"""Test no findings returned when the API fetch failed"""
mock_provider = set_mocked_googleworkspace_provider()
@@ -1,6 +1,7 @@
from unittest.mock import MagicMock, patch
from tests.providers.googleworkspace.googleworkspace_fixtures import (
ROOT_ORG_UNIT_ID,
set_mocked_googleworkspace_provider,
)
@@ -77,6 +78,171 @@ class TestCalendarService:
)
assert calendar.policies.external_invitations_warning is True
def test_the_admin_policy_outranks_a_system_default_returned_after_it(self):
"""The greatest sortOrder is the value in force, whatever order the API lists them in"""
mock_provider = set_mocked_googleworkspace_provider()
mock_provider.audit_config = {}
mock_provider.fixer_config = {}
mock_session = MagicMock()
mock_session.credentials = MagicMock()
mock_provider.session = mock_session
mock_service = MagicMock()
mock_policies_list = MagicMock()
mock_policies_list.execute.return_value = {
"policies": [
{
"type": "ADMIN",
"policyQuery": {"sortOrder": 201.00131},
"setting": {
"type": "settings/calendar.secondary_calendar_max_allowed_external_sharing",
"value": {
"maxAllowedExternalSharing": "EXTERNAL_FREE_BUSY_ONLY"
},
},
},
{
"type": "SYSTEM",
"policyQuery": {"sortOrder": 100.00004},
"setting": {
"type": "settings/calendar.secondary_calendar_max_allowed_external_sharing",
"value": {
"maxAllowedExternalSharing": "EXTERNAL_ALL_INFO_READ_ONLY"
},
},
},
]
}
mock_service.policies().list.return_value = mock_policies_list
mock_service.policies().list_next.return_value = None
with (
patch(
"prowler.providers.common.provider.Provider.get_global_provider",
return_value=mock_provider,
),
patch(
"prowler.providers.googleworkspace.services.calendar.calendar_service.GoogleWorkspaceService._build_service",
return_value=mock_service,
),
):
from prowler.providers.googleworkspace.services.calendar.calendar_service import (
Calendar,
)
calendar = Calendar(mock_provider)
assert calendar.policies_fetched is True
assert (
calendar.policies.secondary_calendar_external_sharing
== "EXTERNAL_FREE_BUSY_ONLY"
)
def test_off_for_everyone_when_off_at_the_root_with_no_override(self):
"""A root-level DISABLED status with no org unit or group override is off for everyone"""
mock_provider = set_mocked_googleworkspace_provider()
mock_provider.audit_config = {}
mock_provider.fixer_config = {}
mock_session = MagicMock()
mock_session.credentials = MagicMock()
mock_provider.session = mock_session
mock_service = MagicMock()
mock_policies_list = MagicMock()
mock_policies_list.execute.return_value = {
"policies": [
{
"type": "ADMIN",
"policyQuery": {
"orgUnit": f"orgUnits/{ROOT_ORG_UNIT_ID}",
"sortOrder": 201.00122,
},
"setting": {
"type": "settings/calendar.service_status",
"value": {"serviceState": "DISABLED"},
},
},
]
}
mock_service.policies().list.return_value = mock_policies_list
mock_service.policies().list_next.return_value = None
with (
patch(
"prowler.providers.common.provider.Provider.get_global_provider",
return_value=mock_provider,
),
patch(
"prowler.providers.googleworkspace.services.calendar.calendar_service.GoogleWorkspaceService._build_service",
return_value=mock_service,
),
):
from prowler.providers.googleworkspace.services.calendar.calendar_service import (
Calendar,
)
fetched = Calendar(mock_provider)
assert fetched.policies_fetched is True
assert fetched.policies.service_state == "DISABLED"
assert fetched.policies.service_state_overridden is False
assert fetched.policies.off_for_everyone is True
def test_reads_the_service_status_and_its_overrides(self):
"""Off at the customer level only counts when no org unit or group turns the service back on"""
mock_provider = set_mocked_googleworkspace_provider()
mock_provider.audit_config = {}
mock_provider.fixer_config = {}
mock_session = MagicMock()
mock_session.credentials = MagicMock()
mock_provider.session = mock_session
mock_service = MagicMock()
mock_policies_list = MagicMock()
mock_policies_list.execute.return_value = {
"policies": [
{
"type": "ADMIN",
"policyQuery": {"sortOrder": 201.00122},
"setting": {
"type": "settings/calendar.service_status",
"value": {"serviceState": "DISABLED"},
},
},
{
"type": "ADMIN",
"policyQuery": {"orgUnit": "orgUnits/sub", "sortOrder": 301.00122},
"setting": {
"type": "settings/calendar.service_status",
"value": {"serviceState": "ENABLED"},
},
},
]
}
mock_service.policies().list.return_value = mock_policies_list
mock_service.policies().list_next.return_value = None
with (
patch(
"prowler.providers.common.provider.Provider.get_global_provider",
return_value=mock_provider,
),
patch(
"prowler.providers.googleworkspace.services.calendar.calendar_service.GoogleWorkspaceService._build_service",
return_value=mock_service,
),
):
from prowler.providers.googleworkspace.services.calendar.calendar_service import (
Calendar,
)
fetched = Calendar(mock_provider)
assert fetched.policies_fetched is True
assert fetched.policies.service_state == "DISABLED"
assert fetched.policies.service_state_overridden is True
assert fetched.policies.off_for_everyone is False
def test_calendar_fetch_policies_empty_response(self):
"""Test handling empty policies response"""
mock_provider = set_mocked_googleworkspace_provider()
@@ -3,6 +3,7 @@ from unittest.mock import patch
from prowler.providers.googleworkspace.services.chat.chat_service import ChatPolicies
from tests.providers.googleworkspace.googleworkspace_fixtures import (
CUSTOMER_ID,
DOMAIN,
set_mocked_googleworkspace_provider,
)
@@ -93,6 +94,69 @@ class TestChatAppsInstallationDisabled:
assert findings[0].status == "PASS"
assert "secure default" in findings[0].status_extended
def test_pass_when_the_service_is_off_for_everyone(self):
"""A setting that only acts while the service is on has no effect once the service is off"""
mock_provider = set_mocked_googleworkspace_provider()
with (
patch(
"prowler.providers.common.provider.Provider.get_global_provider",
return_value=mock_provider,
),
patch(
"prowler.providers.googleworkspace.services.chat.chat_apps_installation_disabled.chat_apps_installation_disabled.chat_client"
) as mock_client,
):
from prowler.providers.googleworkspace.services.chat.chat_apps_installation_disabled.chat_apps_installation_disabled import (
chat_apps_installation_disabled,
)
mock_client.provider = mock_provider
mock_client.policies_fetched = True
mock_client.policies = ChatPolicies(
service_state="DISABLED", enable_apps=True
)
findings = chat_apps_installation_disabled().execute()
assert len(findings) == 1
assert findings[0].status == "PASS"
assert findings[0].status_extended == (
f"Google Chat is turned off for everyone in domain {DOMAIN}, "
f"so Chat apps cannot be installed."
)
def test_evaluates_the_setting_when_an_override_turns_the_service_on(self):
"""Off at the customer level with an org unit turned back on is not off for everyone"""
mock_provider = set_mocked_googleworkspace_provider()
with (
patch(
"prowler.providers.common.provider.Provider.get_global_provider",
return_value=mock_provider,
),
patch(
"prowler.providers.googleworkspace.services.chat.chat_apps_installation_disabled.chat_apps_installation_disabled.chat_client"
) as mock_client,
):
from prowler.providers.googleworkspace.services.chat.chat_apps_installation_disabled.chat_apps_installation_disabled import (
chat_apps_installation_disabled,
)
mock_client.provider = mock_provider
mock_client.policies_fetched = True
mock_client.policies = ChatPolicies(
service_state="DISABLED",
service_state_overridden=True,
enable_apps=True,
)
findings = chat_apps_installation_disabled().execute()
assert len(findings) == 1
assert findings[0].status == "FAIL"
assert "turned off" not in findings[0].status_extended
def test_no_findings_when_fetch_failed(self):
mock_provider = set_mocked_googleworkspace_provider()
@@ -3,6 +3,7 @@ from unittest.mock import patch
from prowler.providers.googleworkspace.services.chat.chat_service import ChatPolicies
from tests.providers.googleworkspace.googleworkspace_fixtures import (
CUSTOMER_ID,
DOMAIN,
set_mocked_googleworkspace_provider,
)
@@ -123,6 +124,38 @@ class TestChatExternalFileSharingDisabled:
assert findings[0].status == "FAIL"
assert "not explicitly configured" in findings[0].status_extended
def test_pass_when_the_service_is_off_for_everyone(self):
"""A setting that only acts while the service is on has no effect once the service is off"""
mock_provider = set_mocked_googleworkspace_provider()
with (
patch(
"prowler.providers.common.provider.Provider.get_global_provider",
return_value=mock_provider,
),
patch(
"prowler.providers.googleworkspace.services.chat.chat_external_file_sharing_disabled.chat_external_file_sharing_disabled.chat_client"
) as mock_client,
):
from prowler.providers.googleworkspace.services.chat.chat_external_file_sharing_disabled.chat_external_file_sharing_disabled import (
chat_external_file_sharing_disabled,
)
mock_client.provider = mock_provider
mock_client.policies_fetched = True
mock_client.policies = ChatPolicies(
service_state="DISABLED", external_file_sharing="ALL_FILES"
)
findings = chat_external_file_sharing_disabled().execute()
assert len(findings) == 1
assert findings[0].status == "PASS"
assert findings[0].status_extended == (
f"Google Chat is turned off for everyone in domain {DOMAIN}, "
f"so no files can be shared externally through Chat."
)
def test_no_findings_when_fetch_failed(self):
mock_provider = set_mocked_googleworkspace_provider()
@@ -3,6 +3,7 @@ from unittest.mock import patch
from prowler.providers.googleworkspace.services.chat.chat_service import ChatPolicies
from tests.providers.googleworkspace.googleworkspace_fixtures import (
CUSTOMER_ID,
DOMAIN,
set_mocked_googleworkspace_provider,
)
@@ -128,6 +129,40 @@ class TestChatExternalMessagingRestricted:
assert findings[0].status == "PASS"
assert "secure default" in findings[0].status_extended
def test_pass_when_the_service_is_off_for_everyone(self):
"""A setting that only acts while the service is on has no effect once the service is off"""
mock_provider = set_mocked_googleworkspace_provider()
with (
patch(
"prowler.providers.common.provider.Provider.get_global_provider",
return_value=mock_provider,
),
patch(
"prowler.providers.googleworkspace.services.chat.chat_external_messaging_restricted.chat_external_messaging_restricted.chat_client"
) as mock_client,
):
from prowler.providers.googleworkspace.services.chat.chat_external_messaging_restricted.chat_external_messaging_restricted import (
chat_external_messaging_restricted,
)
mock_client.provider = mock_provider
mock_client.policies_fetched = True
mock_client.policies = ChatPolicies(
service_state="DISABLED",
allow_external_chat=True,
external_chat_restriction="NO_RESTRICTION",
)
findings = chat_external_messaging_restricted().execute()
assert len(findings) == 1
assert findings[0].status == "PASS"
assert findings[0].status_extended == (
f"Google Chat is turned off for everyone in domain {DOMAIN}, "
f"so no external messaging can take place."
)
def test_no_findings_when_fetch_failed(self):
mock_provider = set_mocked_googleworkspace_provider()
@@ -3,6 +3,7 @@ from unittest.mock import patch
from prowler.providers.googleworkspace.services.chat.chat_service import ChatPolicies
from tests.providers.googleworkspace.googleworkspace_fixtures import (
CUSTOMER_ID,
DOMAIN,
set_mocked_googleworkspace_provider,
)
@@ -129,6 +130,40 @@ class TestChatExternalSpacesRestricted:
assert findings[0].status == "FAIL"
assert "not explicitly configured" in findings[0].status_extended
def test_pass_when_the_service_is_off_for_everyone(self):
"""A setting that only acts while the service is on has no effect once the service is off"""
mock_provider = set_mocked_googleworkspace_provider()
with (
patch(
"prowler.providers.common.provider.Provider.get_global_provider",
return_value=mock_provider,
),
patch(
"prowler.providers.googleworkspace.services.chat.chat_external_spaces_restricted.chat_external_spaces_restricted.chat_client"
) as mock_client,
):
from prowler.providers.googleworkspace.services.chat.chat_external_spaces_restricted.chat_external_spaces_restricted import (
chat_external_spaces_restricted,
)
mock_client.provider = mock_provider
mock_client.policies_fetched = True
mock_client.policies = ChatPolicies(
service_state="DISABLED",
external_spaces_enabled=True,
external_spaces_domain_allowlist_mode="ALL_DOMAINS",
)
findings = chat_external_spaces_restricted().execute()
assert len(findings) == 1
assert findings[0].status == "PASS"
assert findings[0].status_extended == (
f"Google Chat is turned off for everyone in domain {DOMAIN}, "
f"so no external spaces can be created or joined."
)
def test_no_findings_when_fetch_failed(self):
mock_provider = set_mocked_googleworkspace_provider()
@@ -3,6 +3,7 @@ from unittest.mock import patch
from prowler.providers.googleworkspace.services.chat.chat_service import ChatPolicies
from tests.providers.googleworkspace.googleworkspace_fixtures import (
CUSTOMER_ID,
DOMAIN,
set_mocked_googleworkspace_provider,
)
@@ -93,6 +94,38 @@ class TestChatIncomingWebhooksDisabled:
assert findings[0].status == "PASS"
assert "secure default" in findings[0].status_extended
def test_pass_when_the_service_is_off_for_everyone(self):
"""A setting that only acts while the service is on has no effect once the service is off"""
mock_provider = set_mocked_googleworkspace_provider()
with (
patch(
"prowler.providers.common.provider.Provider.get_global_provider",
return_value=mock_provider,
),
patch(
"prowler.providers.googleworkspace.services.chat.chat_incoming_webhooks_disabled.chat_incoming_webhooks_disabled.chat_client"
) as mock_client,
):
from prowler.providers.googleworkspace.services.chat.chat_incoming_webhooks_disabled.chat_incoming_webhooks_disabled import (
chat_incoming_webhooks_disabled,
)
mock_client.provider = mock_provider
mock_client.policies_fetched = True
mock_client.policies = ChatPolicies(
service_state="DISABLED", enable_webhooks=True
)
findings = chat_incoming_webhooks_disabled().execute()
assert len(findings) == 1
assert findings[0].status == "PASS"
assert findings[0].status_extended == (
f"Google Chat is turned off for everyone in domain {DOMAIN}, "
f"so incoming webhooks cannot be used."
)
def test_no_findings_when_fetch_failed(self):
mock_provider = set_mocked_googleworkspace_provider()
@@ -3,6 +3,7 @@ from unittest.mock import patch
from prowler.providers.googleworkspace.services.chat.chat_service import ChatPolicies
from tests.providers.googleworkspace.googleworkspace_fixtures import (
CUSTOMER_ID,
DOMAIN,
set_mocked_googleworkspace_provider,
)
@@ -96,6 +97,38 @@ class TestChatInternalFileSharingDisabled:
assert findings[0].status == "FAIL"
assert "not explicitly configured" in findings[0].status_extended
def test_pass_when_the_service_is_off_for_everyone(self):
"""A setting that only acts while the service is on has no effect once the service is off"""
mock_provider = set_mocked_googleworkspace_provider()
with (
patch(
"prowler.providers.common.provider.Provider.get_global_provider",
return_value=mock_provider,
),
patch(
"prowler.providers.googleworkspace.services.chat.chat_internal_file_sharing_disabled.chat_internal_file_sharing_disabled.chat_client"
) as mock_client,
):
from prowler.providers.googleworkspace.services.chat.chat_internal_file_sharing_disabled.chat_internal_file_sharing_disabled import (
chat_internal_file_sharing_disabled,
)
mock_client.provider = mock_provider
mock_client.policies_fetched = True
mock_client.policies = ChatPolicies(
service_state="DISABLED", internal_file_sharing="ALL_FILES"
)
findings = chat_internal_file_sharing_disabled().execute()
assert len(findings) == 1
assert findings[0].status == "PASS"
assert findings[0].status_extended == (
f"Google Chat is turned off for everyone in domain {DOMAIN}, "
f"so no files can be shared through Chat."
)
def test_no_findings_when_fetch_failed(self):
mock_provider = set_mocked_googleworkspace_provider()
@@ -93,6 +93,165 @@ class TestChatService:
assert chat.policies.enable_apps is False
assert chat.policies.enable_webhooks is False
def test_the_admin_policy_outranks_a_system_default_returned_after_it(self):
"""The greatest sortOrder is the value in force, whatever order the API lists them in"""
mock_provider = set_mocked_googleworkspace_provider()
mock_provider.audit_config = {}
mock_provider.fixer_config = {}
mock_session = MagicMock()
mock_session.credentials = MagicMock()
mock_provider.session = mock_session
mock_service = MagicMock()
mock_policies_list = MagicMock()
mock_policies_list.execute.return_value = {
"policies": [
{
"type": "ADMIN",
"policyQuery": {"sortOrder": 201.00131},
"setting": {
"type": "settings/chat.chat_apps_access",
"value": {"enableApps": False, "enableWebhooks": False},
},
},
{
"type": "SYSTEM",
"policyQuery": {"sortOrder": 100.00005},
"setting": {
"type": "settings/chat.chat_apps_access",
"value": {"enableApps": True, "enableWebhooks": True},
},
},
]
}
mock_service.policies().list.return_value = mock_policies_list
mock_service.policies().list_next.return_value = None
with (
patch(
"prowler.providers.common.provider.Provider.get_global_provider",
return_value=mock_provider,
),
patch(
"prowler.providers.googleworkspace.services.chat.chat_service.GoogleWorkspaceService._build_service",
return_value=mock_service,
),
):
from prowler.providers.googleworkspace.services.chat.chat_service import (
Chat,
)
chat = Chat(mock_provider)
assert chat.policies_fetched is True
assert chat.policies.enable_apps is False
assert chat.policies.enable_webhooks is False
def test_off_for_everyone_when_off_at_the_root_with_no_override(self):
"""A root-level DISABLED status with no org unit or group override is off for everyone"""
mock_provider = set_mocked_googleworkspace_provider()
mock_provider.audit_config = {}
mock_provider.fixer_config = {}
mock_session = MagicMock()
mock_session.credentials = MagicMock()
mock_provider.session = mock_session
mock_service = MagicMock()
mock_policies_list = MagicMock()
mock_policies_list.execute.return_value = {
"policies": [
{
"type": "ADMIN",
"policyQuery": {
"orgUnit": f"orgUnits/{ROOT_ORG_UNIT_ID}",
"sortOrder": 201.00122,
},
"setting": {
"type": "settings/chat.service_status",
"value": {"serviceState": "DISABLED"},
},
},
]
}
mock_service.policies().list.return_value = mock_policies_list
mock_service.policies().list_next.return_value = None
with (
patch(
"prowler.providers.common.provider.Provider.get_global_provider",
return_value=mock_provider,
),
patch(
"prowler.providers.googleworkspace.services.chat.chat_service.GoogleWorkspaceService._build_service",
return_value=mock_service,
),
):
from prowler.providers.googleworkspace.services.chat.chat_service import (
Chat,
)
fetched = Chat(mock_provider)
assert fetched.policies_fetched is True
assert fetched.policies.service_state == "DISABLED"
assert fetched.policies.service_state_overridden is False
assert fetched.policies.off_for_everyone is True
def test_reads_the_service_status_and_its_overrides(self):
"""Off at the customer level only counts when no org unit or group turns the service back on"""
mock_provider = set_mocked_googleworkspace_provider()
mock_provider.audit_config = {}
mock_provider.fixer_config = {}
mock_session = MagicMock()
mock_session.credentials = MagicMock()
mock_provider.session = mock_session
mock_service = MagicMock()
mock_policies_list = MagicMock()
mock_policies_list.execute.return_value = {
"policies": [
{
"type": "ADMIN",
"policyQuery": {"sortOrder": 201.00122},
"setting": {
"type": "settings/chat.service_status",
"value": {"serviceState": "DISABLED"},
},
},
{
"type": "ADMIN",
"policyQuery": {"orgUnit": "orgUnits/sub", "sortOrder": 301.00122},
"setting": {
"type": "settings/chat.service_status",
"value": {"serviceState": "ENABLED"},
},
},
]
}
mock_service.policies().list.return_value = mock_policies_list
mock_service.policies().list_next.return_value = None
with (
patch(
"prowler.providers.common.provider.Provider.get_global_provider",
return_value=mock_provider,
),
patch(
"prowler.providers.googleworkspace.services.chat.chat_service.GoogleWorkspaceService._build_service",
return_value=mock_service,
),
):
from prowler.providers.googleworkspace.services.chat.chat_service import (
Chat,
)
fetched = Chat(mock_provider)
assert fetched.policies_fetched is True
assert fetched.policies.service_state == "DISABLED"
assert fetched.policies.service_state_overridden is True
assert fetched.policies.off_for_everyone is False
def test_chat_fetch_policies_empty_response(self):
"""Test handling empty policies response"""
mock_provider = set_mocked_googleworkspace_provider()
@@ -3,6 +3,7 @@ from unittest.mock import patch
from prowler.providers.googleworkspace.services.drive.drive_service import DrivePolicies
from tests.providers.googleworkspace.googleworkspace_fixtures import (
CUSTOMER_ID,
DOMAIN,
set_mocked_googleworkspace_provider,
)
@@ -128,6 +129,39 @@ class TestDriveAccessCheckerRecipientsOnly:
assert findings[0].status == "FAIL"
assert "not explicitly configured" in findings[0].status_extended
def test_pass_when_the_service_is_off_for_everyone(self):
"""A setting that only acts while the service is on has no effect once the service is off"""
mock_provider = set_mocked_googleworkspace_provider()
with (
patch(
"prowler.providers.common.provider.Provider.get_global_provider",
return_value=mock_provider,
),
patch(
"prowler.providers.googleworkspace.services.drive.drive_access_checker_recipients_only.drive_access_checker_recipients_only.drive_client"
) as mock_client,
):
from prowler.providers.googleworkspace.services.drive.drive_access_checker_recipients_only.drive_access_checker_recipients_only import (
drive_access_checker_recipients_only,
)
mock_client.provider = mock_provider
mock_client.policies_fetched = True
mock_client.policies = DrivePolicies(
service_state="DISABLED",
access_checker_suggestions="RECIPIENTS_OR_AUDIENCE_OR_PUBLIC",
)
findings = drive_access_checker_recipients_only().execute()
assert len(findings) == 1
assert findings[0].status == "PASS"
assert findings[0].status_extended == (
f"Google Drive is turned off for everyone in domain {DOMAIN}, "
f"so Access Checker cannot widen any share."
)
def test_no_findings_when_fetch_failed(self):
"""Test no findings returned when the API fetch failed"""
mock_provider = set_mocked_googleworkspace_provider()
@@ -3,6 +3,7 @@ from unittest.mock import patch
from prowler.providers.googleworkspace.services.drive.drive_service import DrivePolicies
from tests.providers.googleworkspace.googleworkspace_fixtures import (
CUSTOMER_ID,
DOMAIN,
set_mocked_googleworkspace_provider,
)
@@ -94,6 +95,38 @@ class TestDriveDesktopAccessDisabled:
assert findings[0].status == "FAIL"
assert "not explicitly configured" in findings[0].status_extended
def test_pass_when_the_service_is_off_for_everyone(self):
"""A setting that only acts while the service is on has no effect once the service is off"""
mock_provider = set_mocked_googleworkspace_provider()
with (
patch(
"prowler.providers.common.provider.Provider.get_global_provider",
return_value=mock_provider,
),
patch(
"prowler.providers.googleworkspace.services.drive.drive_desktop_access_disabled.drive_desktop_access_disabled.drive_client"
) as mock_client,
):
from prowler.providers.googleworkspace.services.drive.drive_desktop_access_disabled.drive_desktop_access_disabled import (
drive_desktop_access_disabled,
)
mock_client.provider = mock_provider
mock_client.policies_fetched = True
mock_client.policies = DrivePolicies(
service_state="DISABLED", allow_drive_for_desktop=True
)
findings = drive_desktop_access_disabled().execute()
assert len(findings) == 1
assert findings[0].status == "PASS"
assert findings[0].status_extended == (
f"Google Drive is turned off for everyone in domain {DOMAIN}, "
f"so Drive for desktop cannot sync any content."
)
def test_no_findings_when_fetch_failed(self):
"""Test no findings returned when the API fetch failed"""
mock_provider = set_mocked_googleworkspace_provider()
@@ -99,6 +99,35 @@ class TestDriveExternalSharingWarnUsers:
assert findings[0].status == "PASS"
assert "secure default" in findings[0].status_extended
def test_evaluates_the_setting_when_the_service_is_off_for_everyone(self):
"""Existing shares stay reachable when Drive is off, so the stored setting still counts"""
mock_provider = set_mocked_googleworkspace_provider()
with (
patch(
"prowler.providers.common.provider.Provider.get_global_provider",
return_value=mock_provider,
),
patch(
"prowler.providers.googleworkspace.services.drive.drive_external_sharing_warn_users.drive_external_sharing_warn_users.drive_client"
) as mock_client,
):
from prowler.providers.googleworkspace.services.drive.drive_external_sharing_warn_users.drive_external_sharing_warn_users import (
drive_external_sharing_warn_users,
)
mock_client.provider = mock_provider
mock_client.policies_fetched = True
mock_client.policies = DrivePolicies(
service_state="DISABLED", warn_for_external_sharing=False
)
findings = drive_external_sharing_warn_users().execute()
assert len(findings) == 1
assert findings[0].status == "FAIL"
assert "turned off" not in findings[0].status_extended
def test_no_findings_when_fetch_failed(self):
"""Test no findings returned when the API fetch failed"""
mock_provider = set_mocked_googleworkspace_provider()
@@ -130,6 +130,36 @@ class TestDriveInternalUsersDistributeContent:
assert findings[0].status == "FAIL"
assert "not explicitly configured" in findings[0].status_extended
def test_evaluates_the_setting_when_the_service_is_off_for_everyone(self):
"""Existing shares stay reachable when Drive is off, so the stored setting still counts"""
mock_provider = set_mocked_googleworkspace_provider()
with (
patch(
"prowler.providers.common.provider.Provider.get_global_provider",
return_value=mock_provider,
),
patch(
"prowler.providers.googleworkspace.services.drive.drive_internal_users_distribute_content.drive_internal_users_distribute_content.drive_client"
) as mock_client,
):
from prowler.providers.googleworkspace.services.drive.drive_internal_users_distribute_content.drive_internal_users_distribute_content import (
drive_internal_users_distribute_content,
)
mock_client.provider = mock_provider
mock_client.policies_fetched = True
mock_client.policies = DrivePolicies(
service_state="DISABLED",
allowed_parties_for_distributing_content="ALL_ELIGIBLE_USERS",
)
findings = drive_internal_users_distribute_content().execute()
assert len(findings) == 1
assert findings[0].status == "FAIL"
assert "turned off" not in findings[0].status_extended
def test_no_findings_when_fetch_failed(self):
"""Test no findings returned when the API fetch failed"""
mock_provider = set_mocked_googleworkspace_provider()
@@ -94,6 +94,35 @@ class TestDrivePublishingFilesDisabled:
assert findings[0].status == "FAIL"
assert "not explicitly configured" in findings[0].status_extended
def test_evaluates_the_setting_when_the_service_is_off_for_everyone(self):
"""Existing shares stay reachable when Drive is off, so the stored setting still counts"""
mock_provider = set_mocked_googleworkspace_provider()
with (
patch(
"prowler.providers.common.provider.Provider.get_global_provider",
return_value=mock_provider,
),
patch(
"prowler.providers.googleworkspace.services.drive.drive_publishing_files_disabled.drive_publishing_files_disabled.drive_client"
) as mock_client,
):
from prowler.providers.googleworkspace.services.drive.drive_publishing_files_disabled.drive_publishing_files_disabled import (
drive_publishing_files_disabled,
)
mock_client.provider = mock_provider
mock_client.policies_fetched = True
mock_client.policies = DrivePolicies(
service_state="DISABLED", allow_publishing_files=True
)
findings = drive_publishing_files_disabled().execute()
assert len(findings) == 1
assert findings[0].status == "FAIL"
assert "turned off" not in findings[0].status_extended
def test_no_findings_when_fetch_failed(self):
"""Test no findings returned when the API fetch failed"""
mock_provider = set_mocked_googleworkspace_provider()
@@ -1,6 +1,7 @@
from unittest.mock import MagicMock, patch
from tests.providers.googleworkspace.googleworkspace_fixtures import (
ROOT_ORG_UNIT_ID,
set_mocked_googleworkspace_provider,
)
@@ -92,6 +93,164 @@ class TestDriveService:
)
assert drive.policies.allow_drive_for_desktop is False
def test_the_admin_policy_outranks_a_system_default_returned_after_it(self):
"""The greatest sortOrder is the value in force, whatever order the API lists them in"""
mock_provider = set_mocked_googleworkspace_provider()
mock_provider.audit_config = {}
mock_provider.fixer_config = {}
mock_session = MagicMock()
mock_session.credentials = MagicMock()
mock_provider.session = mock_session
mock_service = MagicMock()
mock_policies_list = MagicMock()
mock_policies_list.execute.return_value = {
"policies": [
{
"type": "ADMIN",
"policyQuery": {"sortOrder": 201.00131},
"setting": {
"type": "settings/drive_and_docs.external_sharing",
"value": {"externalSharingMode": "ALLOWLISTED_DOMAINS"},
},
},
{
"type": "SYSTEM",
"policyQuery": {"sortOrder": 100.0001},
"setting": {
"type": "settings/drive_and_docs.external_sharing",
"value": {"externalSharingMode": "ALLOWED"},
},
},
]
}
mock_service.policies().list.return_value = mock_policies_list
mock_service.policies().list_next.return_value = None
with (
patch(
"prowler.providers.common.provider.Provider.get_global_provider",
return_value=mock_provider,
),
patch(
"prowler.providers.googleworkspace.services.drive.drive_service.GoogleWorkspaceService._build_service",
return_value=mock_service,
),
):
from prowler.providers.googleworkspace.services.drive.drive_service import (
Drive,
)
drive = Drive(mock_provider)
assert drive.policies_fetched is True
assert drive.policies.external_sharing_mode == "ALLOWLISTED_DOMAINS"
def test_off_for_everyone_when_off_at_the_root_with_no_override(self):
"""A root-level DISABLED status with no org unit or group override is off for everyone"""
mock_provider = set_mocked_googleworkspace_provider()
mock_provider.audit_config = {}
mock_provider.fixer_config = {}
mock_session = MagicMock()
mock_session.credentials = MagicMock()
mock_provider.session = mock_session
mock_service = MagicMock()
mock_policies_list = MagicMock()
mock_policies_list.execute.return_value = {
"policies": [
{
"type": "ADMIN",
"policyQuery": {
"orgUnit": f"orgUnits/{ROOT_ORG_UNIT_ID}",
"sortOrder": 201.00122,
},
"setting": {
"type": "settings/drive_and_docs.service_status",
"value": {"serviceState": "DISABLED"},
},
},
]
}
mock_service.policies().list.return_value = mock_policies_list
mock_service.policies().list_next.return_value = None
with (
patch(
"prowler.providers.common.provider.Provider.get_global_provider",
return_value=mock_provider,
),
patch(
"prowler.providers.googleworkspace.services.drive.drive_service.GoogleWorkspaceService._build_service",
return_value=mock_service,
),
):
from prowler.providers.googleworkspace.services.drive.drive_service import (
Drive,
)
fetched = Drive(mock_provider)
assert fetched.policies_fetched is True
assert fetched.policies.service_state == "DISABLED"
assert fetched.policies.service_state_overridden is False
assert fetched.policies.off_for_everyone is True
def test_reads_the_service_status_and_its_overrides(self):
"""Off at the customer level only counts when no org unit or group turns the service back on"""
mock_provider = set_mocked_googleworkspace_provider()
mock_provider.audit_config = {}
mock_provider.fixer_config = {}
mock_session = MagicMock()
mock_session.credentials = MagicMock()
mock_provider.session = mock_session
mock_service = MagicMock()
mock_policies_list = MagicMock()
mock_policies_list.execute.return_value = {
"policies": [
{
"type": "ADMIN",
"policyQuery": {"sortOrder": 201.00122},
"setting": {
"type": "settings/drive_and_docs.service_status",
"value": {"serviceState": "DISABLED"},
},
},
{
"type": "ADMIN",
"policyQuery": {"orgUnit": "orgUnits/sub", "sortOrder": 301.00122},
"setting": {
"type": "settings/drive_and_docs.service_status",
"value": {"serviceState": "ENABLED"},
},
},
]
}
mock_service.policies().list.return_value = mock_policies_list
mock_service.policies().list_next.return_value = None
with (
patch(
"prowler.providers.common.provider.Provider.get_global_provider",
return_value=mock_provider,
),
patch(
"prowler.providers.googleworkspace.services.drive.drive_service.GoogleWorkspaceService._build_service",
return_value=mock_service,
),
):
from prowler.providers.googleworkspace.services.drive.drive_service import (
Drive,
)
fetched = Drive(mock_provider)
assert fetched.policies_fetched is True
assert fetched.policies.service_state == "DISABLED"
assert fetched.policies.service_state_overridden is True
assert fetched.policies.off_for_everyone is False
def test_drive_fetch_policies_empty_response(self):
"""Test handling empty policies response"""
mock_provider = set_mocked_googleworkspace_provider()
@@ -3,6 +3,7 @@ from unittest.mock import patch
from prowler.providers.googleworkspace.services.drive.drive_service import DrivePolicies
from tests.providers.googleworkspace.googleworkspace_fixtures import (
CUSTOMER_ID,
DOMAIN,
set_mocked_googleworkspace_provider,
)
@@ -96,6 +97,38 @@ class TestDriveSharedDriveCreationAllowed:
assert findings[0].status == "PASS"
assert "secure default" in findings[0].status_extended
def test_pass_when_the_service_is_off_for_everyone(self):
"""A setting that only acts while the service is on has no effect once the service is off"""
mock_provider = set_mocked_googleworkspace_provider()
with (
patch(
"prowler.providers.common.provider.Provider.get_global_provider",
return_value=mock_provider,
),
patch(
"prowler.providers.googleworkspace.services.drive.drive_shared_drive_creation_allowed.drive_shared_drive_creation_allowed.drive_client"
) as mock_client,
):
from prowler.providers.googleworkspace.services.drive.drive_shared_drive_creation_allowed.drive_shared_drive_creation_allowed import (
drive_shared_drive_creation_allowed,
)
mock_client.provider = mock_provider
mock_client.policies_fetched = True
mock_client.policies = DrivePolicies(
service_state="DISABLED", allow_shared_drive_creation=False
)
findings = drive_shared_drive_creation_allowed().execute()
assert len(findings) == 1
assert findings[0].status == "PASS"
assert findings[0].status_extended == (
f"Google Drive is turned off for everyone in domain {DOMAIN}, "
f"so no shared drive can be created."
)
def test_no_findings_when_fetch_failed(self):
"""Test no findings returned when the API fetch failed"""
mock_provider = set_mocked_googleworkspace_provider()
@@ -130,6 +130,35 @@ class TestDriveSharedDriveDisableDownloadPrintCopy:
assert findings[0].status == "PASS"
assert "secure default" in findings[0].status_extended
def test_evaluates_the_setting_when_the_service_is_off_for_everyone(self):
"""Existing shares stay reachable when Drive is off, so the stored setting still counts"""
mock_provider = set_mocked_googleworkspace_provider()
with (
patch(
"prowler.providers.common.provider.Provider.get_global_provider",
return_value=mock_provider,
),
patch(
"prowler.providers.googleworkspace.services.drive.drive_shared_drive_disable_download_print_copy.drive_shared_drive_disable_download_print_copy.drive_client"
) as mock_client,
):
from prowler.providers.googleworkspace.services.drive.drive_shared_drive_disable_download_print_copy.drive_shared_drive_disable_download_print_copy import (
drive_shared_drive_disable_download_print_copy,
)
mock_client.provider = mock_provider
mock_client.policies_fetched = True
mock_client.policies = DrivePolicies(
service_state="DISABLED", allowed_parties_for_download_print_copy="ALL"
)
findings = drive_shared_drive_disable_download_print_copy().execute()
assert len(findings) == 1
assert findings[0].status == "FAIL"
assert "turned off" not in findings[0].status_extended
def test_no_findings_when_fetch_failed(self):
"""Test no findings returned when the API fetch failed"""
mock_provider = set_mocked_googleworkspace_provider()
@@ -100,6 +100,35 @@ class TestDriveSharedDriveManagersCannotOverride:
assert findings[0].status == "FAIL"
assert "not explicitly configured" in findings[0].status_extended
def test_evaluates_the_setting_when_the_service_is_off_for_everyone(self):
"""Existing shares stay reachable when Drive is off, so the stored setting still counts"""
mock_provider = set_mocked_googleworkspace_provider()
with (
patch(
"prowler.providers.common.provider.Provider.get_global_provider",
return_value=mock_provider,
),
patch(
"prowler.providers.googleworkspace.services.drive.drive_shared_drive_managers_cannot_override.drive_shared_drive_managers_cannot_override.drive_client"
) as mock_client,
):
from prowler.providers.googleworkspace.services.drive.drive_shared_drive_managers_cannot_override.drive_shared_drive_managers_cannot_override import (
drive_shared_drive_managers_cannot_override,
)
mock_client.provider = mock_provider
mock_client.policies_fetched = True
mock_client.policies = DrivePolicies(
service_state="DISABLED", allow_managers_to_override_settings=True
)
findings = drive_shared_drive_managers_cannot_override().execute()
assert len(findings) == 1
assert findings[0].status == "FAIL"
assert "turned off" not in findings[0].status_extended
def test_no_findings_when_fetch_failed(self):
"""Test no findings returned when the API fetch failed"""
mock_provider = set_mocked_googleworkspace_provider()
@@ -94,6 +94,35 @@ class TestDriveSharedDriveMembersOnlyAccess:
assert findings[0].status == "FAIL"
assert "not explicitly configured" in findings[0].status_extended
def test_evaluates_the_setting_when_the_service_is_off_for_everyone(self):
"""Existing shares stay reachable when Drive is off, so the stored setting still counts"""
mock_provider = set_mocked_googleworkspace_provider()
with (
patch(
"prowler.providers.common.provider.Provider.get_global_provider",
return_value=mock_provider,
),
patch(
"prowler.providers.googleworkspace.services.drive.drive_shared_drive_members_only_access.drive_shared_drive_members_only_access.drive_client"
) as mock_client,
):
from prowler.providers.googleworkspace.services.drive.drive_shared_drive_members_only_access.drive_shared_drive_members_only_access import (
drive_shared_drive_members_only_access,
)
mock_client.provider = mock_provider
mock_client.policies_fetched = True
mock_client.policies = DrivePolicies(
service_state="DISABLED", allow_non_member_access=True
)
findings = drive_shared_drive_members_only_access().execute()
assert len(findings) == 1
assert findings[0].status == "FAIL"
assert "turned off" not in findings[0].status_extended
def test_no_findings_when_fetch_failed(self):
"""Test no findings returned when the API fetch failed"""
mock_provider = set_mocked_googleworkspace_provider()
@@ -126,6 +126,35 @@ class TestDriveSharingAllowlistedDomains:
assert findings[0].status == "FAIL"
assert "not explicitly configured" in findings[0].status_extended
def test_evaluates_the_setting_when_the_service_is_off_for_everyone(self):
"""Existing shares stay reachable when Drive is off, so the stored setting still counts"""
mock_provider = set_mocked_googleworkspace_provider()
with (
patch(
"prowler.providers.common.provider.Provider.get_global_provider",
return_value=mock_provider,
),
patch(
"prowler.providers.googleworkspace.services.drive.drive_sharing_allowlisted_domains.drive_sharing_allowlisted_domains.drive_client"
) as mock_client,
):
from prowler.providers.googleworkspace.services.drive.drive_sharing_allowlisted_domains.drive_sharing_allowlisted_domains import (
drive_sharing_allowlisted_domains,
)
mock_client.provider = mock_provider
mock_client.policies_fetched = True
mock_client.policies = DrivePolicies(
service_state="DISABLED", external_sharing_mode="ALLOWED"
)
findings = drive_sharing_allowlisted_domains().execute()
assert len(findings) == 1
assert findings[0].status == "FAIL"
assert "turned off" not in findings[0].status_extended
def test_no_findings_when_fetch_failed(self):
"""Test no findings returned when the API fetch failed"""
mock_provider = set_mocked_googleworkspace_provider()
@@ -100,6 +100,36 @@ class TestDriveWarnSharingWithAllowlistedDomains:
assert findings[0].status == "PASS"
assert "secure default" in findings[0].status_extended
def test_evaluates_the_setting_when_the_service_is_off_for_everyone(self):
"""Existing shares stay reachable when Drive is off, so the stored setting still counts"""
mock_provider = set_mocked_googleworkspace_provider()
with (
patch(
"prowler.providers.common.provider.Provider.get_global_provider",
return_value=mock_provider,
),
patch(
"prowler.providers.googleworkspace.services.drive.drive_warn_sharing_with_allowlisted_domains.drive_warn_sharing_with_allowlisted_domains.drive_client"
) as mock_client,
):
from prowler.providers.googleworkspace.services.drive.drive_warn_sharing_with_allowlisted_domains.drive_warn_sharing_with_allowlisted_domains import (
drive_warn_sharing_with_allowlisted_domains,
)
mock_client.provider = mock_provider
mock_client.policies_fetched = True
mock_client.policies = DrivePolicies(
service_state="DISABLED",
warn_for_sharing_outside_allowlisted_domains=False,
)
findings = drive_warn_sharing_with_allowlisted_domains().execute()
assert len(findings) == 1
assert findings[0].status == "FAIL"
assert "turned off" not in findings[0].status_extended
def test_no_findings_when_fetch_failed(self):
"""Test no findings returned when the API fetch failed"""
mock_provider = set_mocked_googleworkspace_provider()
@@ -3,6 +3,7 @@ from unittest.mock import patch
from prowler.providers.googleworkspace.services.gmail.gmail_service import GmailPolicies
from tests.providers.googleworkspace.googleworkspace_fixtures import (
CUSTOMER_ID,
DOMAIN,
set_mocked_googleworkspace_provider,
)
@@ -127,6 +128,38 @@ class TestGmailAnomalousAttachmentProtectionEnabled:
assert findings[0].status == "FAIL"
assert "insecure default" in findings[0].status_extended
def test_pass_when_the_service_is_off_for_everyone(self):
"""A setting that only acts while the service is on has no effect once the service is off"""
mock_provider = set_mocked_googleworkspace_provider()
with (
patch(
"prowler.providers.common.provider.Provider.get_global_provider",
return_value=mock_provider,
),
patch(
"prowler.providers.googleworkspace.services.gmail.gmail_anomalous_attachment_protection_enabled.gmail_anomalous_attachment_protection_enabled.gmail_client"
) as mock_client,
):
from prowler.providers.googleworkspace.services.gmail.gmail_anomalous_attachment_protection_enabled.gmail_anomalous_attachment_protection_enabled import (
gmail_anomalous_attachment_protection_enabled,
)
mock_client.provider = mock_provider
mock_client.policies_fetched = True
mock_client.policies = GmailPolicies(
service_state="DISABLED", enable_anomalous_attachment_protection=False
)
findings = gmail_anomalous_attachment_protection_enabled().execute()
assert len(findings) == 1
assert findings[0].status == "PASS"
assert findings[0].status_extended == (
f"Gmail is turned off for everyone in domain {DOMAIN}, "
f"so no user mailbox receives mail through Gmail."
)
def test_no_findings_when_fetch_failed(self):
mock_provider = set_mocked_googleworkspace_provider()
@@ -3,6 +3,7 @@ from unittest.mock import patch
from prowler.providers.googleworkspace.services.gmail.gmail_service import GmailPolicies
from tests.providers.googleworkspace.googleworkspace_fixtures import (
CUSTOMER_ID,
DOMAIN,
set_mocked_googleworkspace_provider,
)
@@ -96,6 +97,38 @@ class TestGmailAutoForwardingDisabled:
assert findings[0].status == "FAIL"
assert "not explicitly configured" in findings[0].status_extended
def test_pass_when_the_service_is_off_for_everyone(self):
"""A setting that only acts while the service is on has no effect once the service is off"""
mock_provider = set_mocked_googleworkspace_provider()
with (
patch(
"prowler.providers.common.provider.Provider.get_global_provider",
return_value=mock_provider,
),
patch(
"prowler.providers.googleworkspace.services.gmail.gmail_auto_forwarding_disabled.gmail_auto_forwarding_disabled.gmail_client"
) as mock_client,
):
from prowler.providers.googleworkspace.services.gmail.gmail_auto_forwarding_disabled.gmail_auto_forwarding_disabled import (
gmail_auto_forwarding_disabled,
)
mock_client.provider = mock_provider
mock_client.policies_fetched = True
mock_client.policies = GmailPolicies(
service_state="DISABLED", enable_auto_forwarding=True
)
findings = gmail_auto_forwarding_disabled().execute()
assert len(findings) == 1
assert findings[0].status == "PASS"
assert findings[0].status_extended == (
f"Gmail is turned off for everyone in domain {DOMAIN}, "
f"so no email can be forwarded."
)
def test_no_findings_when_fetch_failed(self):
mock_provider = set_mocked_googleworkspace_provider()
@@ -3,6 +3,7 @@ from unittest.mock import patch
from prowler.providers.googleworkspace.services.gmail.gmail_service import GmailPolicies
from tests.providers.googleworkspace.googleworkspace_fixtures import (
CUSTOMER_ID,
DOMAIN,
set_mocked_googleworkspace_provider,
)
@@ -97,6 +98,38 @@ class TestGmailComprehensiveMailStorageEnabled:
assert findings[0].status == "FAIL"
assert "not explicitly configured" in findings[0].status_extended
def test_pass_when_the_service_is_off_for_everyone(self):
"""A setting that only acts while the service is on has no effect once the service is off"""
mock_provider = set_mocked_googleworkspace_provider()
with (
patch(
"prowler.providers.common.provider.Provider.get_global_provider",
return_value=mock_provider,
),
patch(
"prowler.providers.googleworkspace.services.gmail.gmail_comprehensive_mail_storage_enabled.gmail_comprehensive_mail_storage_enabled.gmail_client"
) as mock_client,
):
from prowler.providers.googleworkspace.services.gmail.gmail_comprehensive_mail_storage_enabled.gmail_comprehensive_mail_storage_enabled import (
gmail_comprehensive_mail_storage_enabled,
)
mock_client.provider = mock_provider
mock_client.policies_fetched = True
mock_client.policies = GmailPolicies(
service_state="DISABLED", comprehensive_mail_storage_enabled=False
)
findings = gmail_comprehensive_mail_storage_enabled().execute()
assert len(findings) == 1
assert findings[0].status == "PASS"
assert findings[0].status_extended == (
f"Gmail is turned off for everyone in domain {DOMAIN}, "
f"so there is no Gmail mail to store."
)
def test_no_findings_when_fetch_failed(self):
mock_provider = set_mocked_googleworkspace_provider()
@@ -3,6 +3,7 @@ from unittest.mock import patch
from prowler.providers.googleworkspace.services.gmail.gmail_service import GmailPolicies
from tests.providers.googleworkspace.googleworkspace_fixtures import (
CUSTOMER_ID,
DOMAIN,
set_mocked_googleworkspace_provider,
)
@@ -189,6 +190,38 @@ class TestGmailDomainSpoofingProtectionEnabled:
assert findings[0].status == "FAIL"
assert "default action" in findings[0].status_extended
def test_pass_when_the_service_is_off_for_everyone(self):
"""A setting that only acts while the service is on has no effect once the service is off"""
mock_provider = set_mocked_googleworkspace_provider()
with (
patch(
"prowler.providers.common.provider.Provider.get_global_provider",
return_value=mock_provider,
),
patch(
"prowler.providers.googleworkspace.services.gmail.gmail_domain_spoofing_protection_enabled.gmail_domain_spoofing_protection_enabled.gmail_client"
) as mock_client,
):
from prowler.providers.googleworkspace.services.gmail.gmail_domain_spoofing_protection_enabled.gmail_domain_spoofing_protection_enabled import (
gmail_domain_spoofing_protection_enabled,
)
mock_client.provider = mock_provider
mock_client.policies_fetched = True
mock_client.policies = GmailPolicies(
service_state="DISABLED", detect_domain_name_spoofing=False
)
findings = gmail_domain_spoofing_protection_enabled().execute()
assert len(findings) == 1
assert findings[0].status == "PASS"
assert findings[0].status_extended == (
f"Gmail is turned off for everyone in domain {DOMAIN}, "
f"so no user mailbox receives mail through Gmail."
)
def test_no_findings_when_fetch_failed(self):
mock_provider = set_mocked_googleworkspace_provider()
@@ -3,6 +3,7 @@ from unittest.mock import patch
from prowler.providers.googleworkspace.services.gmail.gmail_service import GmailPolicies
from tests.providers.googleworkspace.googleworkspace_fixtures import (
CUSTOMER_ID,
DOMAIN,
set_mocked_googleworkspace_provider,
)
@@ -157,6 +158,38 @@ class TestGmailEmployeeNameSpoofingProtectionEnabled:
assert findings[0].status == "FAIL"
assert "default action" in findings[0].status_extended
def test_pass_when_the_service_is_off_for_everyone(self):
"""A setting that only acts while the service is on has no effect once the service is off"""
mock_provider = set_mocked_googleworkspace_provider()
with (
patch(
"prowler.providers.common.provider.Provider.get_global_provider",
return_value=mock_provider,
),
patch(
"prowler.providers.googleworkspace.services.gmail.gmail_employee_name_spoofing_protection_enabled.gmail_employee_name_spoofing_protection_enabled.gmail_client"
) as mock_client,
):
from prowler.providers.googleworkspace.services.gmail.gmail_employee_name_spoofing_protection_enabled.gmail_employee_name_spoofing_protection_enabled import (
gmail_employee_name_spoofing_protection_enabled,
)
mock_client.provider = mock_provider
mock_client.policies_fetched = True
mock_client.policies = GmailPolicies(
service_state="DISABLED", detect_employee_name_spoofing=False
)
findings = gmail_employee_name_spoofing_protection_enabled().execute()
assert len(findings) == 1
assert findings[0].status == "PASS"
assert findings[0].status_extended == (
f"Gmail is turned off for everyone in domain {DOMAIN}, "
f"so no user mailbox receives mail through Gmail."
)
def test_no_findings_when_fetch_failed(self):
mock_provider = set_mocked_googleworkspace_provider()
@@ -3,6 +3,7 @@ from unittest.mock import patch
from prowler.providers.googleworkspace.services.gmail.gmail_service import GmailPolicies
from tests.providers.googleworkspace.googleworkspace_fixtures import (
CUSTOMER_ID,
DOMAIN,
set_mocked_googleworkspace_provider,
)
@@ -127,6 +128,38 @@ class TestGmailEncryptedAttachmentProtectionEnabled:
assert findings[0].status == "PASS"
assert "secure default" in findings[0].status_extended
def test_pass_when_the_service_is_off_for_everyone(self):
"""A setting that only acts while the service is on has no effect once the service is off"""
mock_provider = set_mocked_googleworkspace_provider()
with (
patch(
"prowler.providers.common.provider.Provider.get_global_provider",
return_value=mock_provider,
),
patch(
"prowler.providers.googleworkspace.services.gmail.gmail_encrypted_attachment_protection_enabled.gmail_encrypted_attachment_protection_enabled.gmail_client"
) as mock_client,
):
from prowler.providers.googleworkspace.services.gmail.gmail_encrypted_attachment_protection_enabled.gmail_encrypted_attachment_protection_enabled import (
gmail_encrypted_attachment_protection_enabled,
)
mock_client.provider = mock_provider
mock_client.policies_fetched = True
mock_client.policies = GmailPolicies(
service_state="DISABLED", enable_encrypted_attachment_protection=False
)
findings = gmail_encrypted_attachment_protection_enabled().execute()
assert len(findings) == 1
assert findings[0].status == "PASS"
assert findings[0].status_extended == (
f"Gmail is turned off for everyone in domain {DOMAIN}, "
f"so no user mailbox receives mail through Gmail."
)
def test_no_findings_when_fetch_failed(self):
mock_provider = set_mocked_googleworkspace_provider()
@@ -3,6 +3,7 @@ from unittest.mock import patch
from prowler.providers.googleworkspace.services.gmail.gmail_service import GmailPolicies
from tests.providers.googleworkspace.googleworkspace_fixtures import (
CUSTOMER_ID,
DOMAIN,
set_mocked_googleworkspace_provider,
)
@@ -97,6 +98,38 @@ class TestGmailEnhancedPreDeliveryScanningEnabled:
assert findings[0].status == "PASS"
assert "secure default" in findings[0].status_extended
def test_pass_when_the_service_is_off_for_everyone(self):
"""A setting that only acts while the service is on has no effect once the service is off"""
mock_provider = set_mocked_googleworkspace_provider()
with (
patch(
"prowler.providers.common.provider.Provider.get_global_provider",
return_value=mock_provider,
),
patch(
"prowler.providers.googleworkspace.services.gmail.gmail_enhanced_pre_delivery_scanning_enabled.gmail_enhanced_pre_delivery_scanning_enabled.gmail_client"
) as mock_client,
):
from prowler.providers.googleworkspace.services.gmail.gmail_enhanced_pre_delivery_scanning_enabled.gmail_enhanced_pre_delivery_scanning_enabled import (
gmail_enhanced_pre_delivery_scanning_enabled,
)
mock_client.provider = mock_provider
mock_client.policies_fetched = True
mock_client.policies = GmailPolicies(
service_state="DISABLED", enable_enhanced_pre_delivery_scanning=False
)
findings = gmail_enhanced_pre_delivery_scanning_enabled().execute()
assert len(findings) == 1
assert findings[0].status == "PASS"
assert findings[0].status_extended == (
f"Gmail is turned off for everyone in domain {DOMAIN}, "
f"so no user mailbox receives mail through Gmail."
)
def test_no_findings_when_fetch_failed(self):
mock_provider = set_mocked_googleworkspace_provider()
@@ -3,6 +3,7 @@ from unittest.mock import patch
from prowler.providers.googleworkspace.services.gmail.gmail_service import GmailPolicies
from tests.providers.googleworkspace.googleworkspace_fixtures import (
CUSTOMER_ID,
DOMAIN,
set_mocked_googleworkspace_provider,
)
@@ -91,6 +92,38 @@ class TestGmailExternalImageScanningEnabled:
assert findings[0].status == "PASS"
assert "secure default" in findings[0].status_extended
def test_pass_when_the_service_is_off_for_everyone(self):
"""A setting that only acts while the service is on has no effect once the service is off"""
mock_provider = set_mocked_googleworkspace_provider()
with (
patch(
"prowler.providers.common.provider.Provider.get_global_provider",
return_value=mock_provider,
),
patch(
"prowler.providers.googleworkspace.services.gmail.gmail_external_image_scanning_enabled.gmail_external_image_scanning_enabled.gmail_client"
) as mock_client,
):
from prowler.providers.googleworkspace.services.gmail.gmail_external_image_scanning_enabled.gmail_external_image_scanning_enabled import (
gmail_external_image_scanning_enabled,
)
mock_client.provider = mock_provider
mock_client.policies_fetched = True
mock_client.policies = GmailPolicies(
service_state="DISABLED", enable_external_image_scanning=False
)
findings = gmail_external_image_scanning_enabled().execute()
assert len(findings) == 1
assert findings[0].status == "PASS"
assert findings[0].status_extended == (
f"Gmail is turned off for everyone in domain {DOMAIN}, "
f"so no user mailbox receives mail through Gmail."
)
def test_no_findings_when_fetch_failed(self):
mock_provider = set_mocked_googleworkspace_provider()
@@ -3,6 +3,7 @@ from unittest.mock import patch
from prowler.providers.googleworkspace.services.gmail.gmail_service import GmailPolicies
from tests.providers.googleworkspace.googleworkspace_fixtures import (
CUSTOMER_ID,
DOMAIN,
set_mocked_googleworkspace_provider,
)
@@ -190,6 +191,38 @@ class TestGmailGroupsSpoofingProtectionEnabled:
assert findings[0].status == "FAIL"
assert "insecure default" in findings[0].status_extended
def test_pass_when_the_service_is_off_for_everyone(self):
"""A setting that only acts while the service is on has no effect once the service is off"""
mock_provider = set_mocked_googleworkspace_provider()
with (
patch(
"prowler.providers.common.provider.Provider.get_global_provider",
return_value=mock_provider,
),
patch(
"prowler.providers.googleworkspace.services.gmail.gmail_groups_spoofing_protection_enabled.gmail_groups_spoofing_protection_enabled.gmail_client"
) as mock_client,
):
from prowler.providers.googleworkspace.services.gmail.gmail_groups_spoofing_protection_enabled.gmail_groups_spoofing_protection_enabled import (
gmail_groups_spoofing_protection_enabled,
)
mock_client.provider = mock_provider
mock_client.policies_fetched = True
mock_client.policies = GmailPolicies(
service_state="DISABLED", detect_groups_spoofing=False
)
findings = gmail_groups_spoofing_protection_enabled().execute()
assert len(findings) == 1
assert findings[0].status == "PASS"
assert findings[0].status_extended == (
f"Gmail is turned off for everyone in domain {DOMAIN}, "
f"so no user mailbox receives mail through Gmail."
)
def test_no_findings_when_fetch_failed(self):
mock_provider = set_mocked_googleworkspace_provider()
@@ -3,6 +3,7 @@ from unittest.mock import patch
from prowler.providers.googleworkspace.services.gmail.gmail_service import GmailPolicies
from tests.providers.googleworkspace.googleworkspace_fixtures import (
CUSTOMER_ID,
DOMAIN,
set_mocked_googleworkspace_provider,
)
@@ -157,6 +158,38 @@ class TestGmailInboundDomainSpoofingProtectionEnabled:
assert findings[0].status == "FAIL"
assert "default action" in findings[0].status_extended
def test_pass_when_the_service_is_off_for_everyone(self):
"""A setting that only acts while the service is on has no effect once the service is off"""
mock_provider = set_mocked_googleworkspace_provider()
with (
patch(
"prowler.providers.common.provider.Provider.get_global_provider",
return_value=mock_provider,
),
patch(
"prowler.providers.googleworkspace.services.gmail.gmail_inbound_domain_spoofing_protection_enabled.gmail_inbound_domain_spoofing_protection_enabled.gmail_client"
) as mock_client,
):
from prowler.providers.googleworkspace.services.gmail.gmail_inbound_domain_spoofing_protection_enabled.gmail_inbound_domain_spoofing_protection_enabled import (
gmail_inbound_domain_spoofing_protection_enabled,
)
mock_client.provider = mock_provider
mock_client.policies_fetched = True
mock_client.policies = GmailPolicies(
service_state="DISABLED", detect_inbound_domain_spoofing=False
)
findings = gmail_inbound_domain_spoofing_protection_enabled().execute()
assert len(findings) == 1
assert findings[0].status == "PASS"
assert findings[0].status_extended == (
f"Gmail is turned off for everyone in domain {DOMAIN}, "
f"so no user mailbox receives mail through Gmail."
)
def test_no_findings_when_fetch_failed(self):
mock_provider = set_mocked_googleworkspace_provider()
@@ -3,6 +3,7 @@ from unittest.mock import patch
from prowler.providers.googleworkspace.services.gmail.gmail_service import GmailPolicies
from tests.providers.googleworkspace.googleworkspace_fixtures import (
CUSTOMER_ID,
DOMAIN,
set_mocked_googleworkspace_provider,
)
@@ -91,6 +92,38 @@ class TestGmailMailDelegationDisabled:
assert findings[0].status == "PASS"
assert "secure default" in findings[0].status_extended
def test_pass_when_the_service_is_off_for_everyone(self):
"""A setting that only acts while the service is on has no effect once the service is off"""
mock_provider = set_mocked_googleworkspace_provider()
with (
patch(
"prowler.providers.common.provider.Provider.get_global_provider",
return_value=mock_provider,
),
patch(
"prowler.providers.googleworkspace.services.gmail.gmail_mail_delegation_disabled.gmail_mail_delegation_disabled.gmail_client"
) as mock_client,
):
from prowler.providers.googleworkspace.services.gmail.gmail_mail_delegation_disabled.gmail_mail_delegation_disabled import (
gmail_mail_delegation_disabled,
)
mock_client.provider = mock_provider
mock_client.policies_fetched = True
mock_client.policies = GmailPolicies(
service_state="DISABLED", enable_mail_delegation=True
)
findings = gmail_mail_delegation_disabled().execute()
assert len(findings) == 1
assert findings[0].status == "PASS"
assert findings[0].status_extended == (
f"Gmail is turned off for everyone in domain {DOMAIN}, "
f"so no mailbox can be delegated."
)
def test_no_findings_when_fetch_failed(self):
mock_provider = set_mocked_googleworkspace_provider()
@@ -3,6 +3,7 @@ from unittest.mock import patch
from prowler.providers.googleworkspace.services.gmail.gmail_service import GmailPolicies
from tests.providers.googleworkspace.googleworkspace_fixtures import (
CUSTOMER_ID,
DOMAIN,
set_mocked_googleworkspace_provider,
)
@@ -91,6 +92,38 @@ class TestGmailPerUserOutboundGatewayDisabled:
assert findings[0].status == "PASS"
assert "secure default" in findings[0].status_extended
def test_pass_when_the_service_is_off_for_everyone(self):
"""A setting that only acts while the service is on has no effect once the service is off"""
mock_provider = set_mocked_googleworkspace_provider()
with (
patch(
"prowler.providers.common.provider.Provider.get_global_provider",
return_value=mock_provider,
),
patch(
"prowler.providers.googleworkspace.services.gmail.gmail_per_user_outbound_gateway_disabled.gmail_per_user_outbound_gateway_disabled.gmail_client"
) as mock_client,
):
from prowler.providers.googleworkspace.services.gmail.gmail_per_user_outbound_gateway_disabled.gmail_per_user_outbound_gateway_disabled import (
gmail_per_user_outbound_gateway_disabled,
)
mock_client.provider = mock_provider
mock_client.policies_fetched = True
mock_client.policies = GmailPolicies(
service_state="DISABLED", allow_per_user_outbound_gateway=True
)
findings = gmail_per_user_outbound_gateway_disabled().execute()
assert len(findings) == 1
assert findings[0].status == "PASS"
assert findings[0].status_extended == (
f"Gmail is turned off for everyone in domain {DOMAIN}, "
f"so no outbound gateway can be used."
)
def test_no_findings_when_fetch_failed(self):
mock_provider = set_mocked_googleworkspace_provider()
@@ -3,6 +3,7 @@ from unittest.mock import patch
from prowler.providers.googleworkspace.services.gmail.gmail_service import GmailPolicies
from tests.providers.googleworkspace.googleworkspace_fixtures import (
CUSTOMER_ID,
DOMAIN,
set_mocked_googleworkspace_provider,
)
@@ -156,6 +157,40 @@ class TestGmailPopImapAccessDisabled:
assert findings[0].status == "FAIL"
assert "not explicitly configured" in findings[0].status_extended
def test_pass_when_the_service_is_off_for_everyone(self):
"""A setting that only acts while the service is on has no effect once the service is off"""
mock_provider = set_mocked_googleworkspace_provider()
with (
patch(
"prowler.providers.common.provider.Provider.get_global_provider",
return_value=mock_provider,
),
patch(
"prowler.providers.googleworkspace.services.gmail.gmail_pop_imap_access_disabled.gmail_pop_imap_access_disabled.gmail_client"
) as mock_client,
):
from prowler.providers.googleworkspace.services.gmail.gmail_pop_imap_access_disabled.gmail_pop_imap_access_disabled import (
gmail_pop_imap_access_disabled,
)
mock_client.provider = mock_provider
mock_client.policies_fetched = True
mock_client.policies = GmailPolicies(
service_state="DISABLED",
enable_pop_access=True,
enable_imap_access=True,
)
findings = gmail_pop_imap_access_disabled().execute()
assert len(findings) == 1
assert findings[0].status == "PASS"
assert findings[0].status_extended == (
f"Gmail is turned off for everyone in domain {DOMAIN}, "
f"so no mailbox can be reached over POP or IMAP."
)
def test_no_findings_when_fetch_failed(self):
mock_provider = set_mocked_googleworkspace_provider()
@@ -3,6 +3,7 @@ from unittest.mock import patch
from prowler.providers.googleworkspace.services.gmail.gmail_service import GmailPolicies
from tests.providers.googleworkspace.googleworkspace_fixtures import (
CUSTOMER_ID,
DOMAIN,
set_mocked_googleworkspace_provider,
)
@@ -127,6 +128,38 @@ class TestGmailScriptAttachmentProtectionEnabled:
assert findings[0].status == "PASS"
assert "secure default" in findings[0].status_extended
def test_pass_when_the_service_is_off_for_everyone(self):
"""A setting that only acts while the service is on has no effect once the service is off"""
mock_provider = set_mocked_googleworkspace_provider()
with (
patch(
"prowler.providers.common.provider.Provider.get_global_provider",
return_value=mock_provider,
),
patch(
"prowler.providers.googleworkspace.services.gmail.gmail_script_attachment_protection_enabled.gmail_script_attachment_protection_enabled.gmail_client"
) as mock_client,
):
from prowler.providers.googleworkspace.services.gmail.gmail_script_attachment_protection_enabled.gmail_script_attachment_protection_enabled import (
gmail_script_attachment_protection_enabled,
)
mock_client.provider = mock_provider
mock_client.policies_fetched = True
mock_client.policies = GmailPolicies(
service_state="DISABLED", enable_script_attachment_protection=False
)
findings = gmail_script_attachment_protection_enabled().execute()
assert len(findings) == 1
assert findings[0].status == "PASS"
assert findings[0].status_extended == (
f"Gmail is turned off for everyone in domain {DOMAIN}, "
f"so no user mailbox receives mail through Gmail."
)
def test_no_findings_when_fetch_failed(self):
mock_provider = set_mocked_googleworkspace_provider()
@@ -162,6 +162,164 @@ class TestGmailService:
assert gmail.policies.enable_enhanced_pre_delivery_scanning is True
assert gmail.policies.comprehensive_mail_storage_enabled is True
def test_the_admin_policy_outranks_a_system_default_returned_after_it(self):
"""The greatest sortOrder is the value in force, whatever order the API lists them in"""
mock_provider = set_mocked_googleworkspace_provider()
mock_provider.audit_config = {}
mock_provider.fixer_config = {}
mock_session = MagicMock()
mock_session.credentials = MagicMock()
mock_provider.session = mock_session
mock_service = MagicMock()
mock_policies_list = MagicMock()
mock_policies_list.execute.return_value = {
"policies": [
{
"type": "ADMIN",
"policyQuery": {"sortOrder": 201.00131},
"setting": {
"type": "settings/gmail.auto_forwarding",
"value": {"enableAutoForwarding": False},
},
},
{
"type": "SYSTEM",
"policyQuery": {"sortOrder": 100.00008},
"setting": {
"type": "settings/gmail.auto_forwarding",
"value": {"enableAutoForwarding": True},
},
},
]
}
mock_service.policies().list.return_value = mock_policies_list
mock_service.policies().list_next.return_value = None
with (
patch(
"prowler.providers.common.provider.Provider.get_global_provider",
return_value=mock_provider,
),
patch(
"prowler.providers.googleworkspace.services.gmail.gmail_service.GoogleWorkspaceService._build_service",
return_value=mock_service,
),
):
from prowler.providers.googleworkspace.services.gmail.gmail_service import (
Gmail,
)
gmail = Gmail(mock_provider)
assert gmail.policies_fetched is True
assert gmail.policies.enable_auto_forwarding is False
def test_off_for_everyone_when_off_at_the_root_with_no_override(self):
"""A root-level DISABLED status with no org unit or group override is off for everyone"""
mock_provider = set_mocked_googleworkspace_provider()
mock_provider.audit_config = {}
mock_provider.fixer_config = {}
mock_session = MagicMock()
mock_session.credentials = MagicMock()
mock_provider.session = mock_session
mock_service = MagicMock()
mock_policies_list = MagicMock()
mock_policies_list.execute.return_value = {
"policies": [
{
"type": "ADMIN",
"policyQuery": {
"orgUnit": f"orgUnits/{ROOT_ORG_UNIT_ID}",
"sortOrder": 201.00122,
},
"setting": {
"type": "settings/gmail.service_status",
"value": {"serviceState": "DISABLED"},
},
},
]
}
mock_service.policies().list.return_value = mock_policies_list
mock_service.policies().list_next.return_value = None
with (
patch(
"prowler.providers.common.provider.Provider.get_global_provider",
return_value=mock_provider,
),
patch(
"prowler.providers.googleworkspace.services.gmail.gmail_service.GoogleWorkspaceService._build_service",
return_value=mock_service,
),
):
from prowler.providers.googleworkspace.services.gmail.gmail_service import (
Gmail,
)
fetched = Gmail(mock_provider)
assert fetched.policies_fetched is True
assert fetched.policies.service_state == "DISABLED"
assert fetched.policies.service_state_overridden is False
assert fetched.policies.off_for_everyone is True
def test_reads_the_service_status_and_its_overrides(self):
"""Off at the customer level only counts when no org unit or group turns the service back on"""
mock_provider = set_mocked_googleworkspace_provider()
mock_provider.audit_config = {}
mock_provider.fixer_config = {}
mock_session = MagicMock()
mock_session.credentials = MagicMock()
mock_provider.session = mock_session
mock_service = MagicMock()
mock_policies_list = MagicMock()
mock_policies_list.execute.return_value = {
"policies": [
{
"type": "ADMIN",
"policyQuery": {"sortOrder": 201.00122},
"setting": {
"type": "settings/gmail.service_status",
"value": {"serviceState": "DISABLED"},
},
},
{
"type": "ADMIN",
"policyQuery": {"orgUnit": "orgUnits/sub", "sortOrder": 301.00122},
"setting": {
"type": "settings/gmail.service_status",
"value": {"serviceState": "ENABLED"},
},
},
]
}
mock_service.policies().list.return_value = mock_policies_list
mock_service.policies().list_next.return_value = None
with (
patch(
"prowler.providers.common.provider.Provider.get_global_provider",
return_value=mock_provider,
),
patch(
"prowler.providers.googleworkspace.services.gmail.gmail_service.GoogleWorkspaceService._build_service",
return_value=mock_service,
),
):
from prowler.providers.googleworkspace.services.gmail.gmail_service import (
Gmail,
)
fetched = Gmail(mock_provider)
assert fetched.policies_fetched is True
assert fetched.policies.service_state == "DISABLED"
assert fetched.policies.service_state_overridden is True
assert fetched.policies.off_for_everyone is False
def test_gmail_fetch_policies_empty_response(self):
"""Test handling empty policies response"""
mock_provider = set_mocked_googleworkspace_provider()
@@ -3,6 +3,7 @@ from unittest.mock import patch
from prowler.providers.googleworkspace.services.gmail.gmail_service import GmailPolicies
from tests.providers.googleworkspace.googleworkspace_fixtures import (
CUSTOMER_ID,
DOMAIN,
set_mocked_googleworkspace_provider,
)
@@ -91,6 +92,38 @@ class TestGmailShortenerScanningEnabled:
assert findings[0].status == "PASS"
assert "secure default" in findings[0].status_extended
def test_pass_when_the_service_is_off_for_everyone(self):
"""A setting that only acts while the service is on has no effect once the service is off"""
mock_provider = set_mocked_googleworkspace_provider()
with (
patch(
"prowler.providers.common.provider.Provider.get_global_provider",
return_value=mock_provider,
),
patch(
"prowler.providers.googleworkspace.services.gmail.gmail_shortener_scanning_enabled.gmail_shortener_scanning_enabled.gmail_client"
) as mock_client,
):
from prowler.providers.googleworkspace.services.gmail.gmail_shortener_scanning_enabled.gmail_shortener_scanning_enabled import (
gmail_shortener_scanning_enabled,
)
mock_client.provider = mock_provider
mock_client.policies_fetched = True
mock_client.policies = GmailPolicies(
service_state="DISABLED", enable_shortener_scanning=False
)
findings = gmail_shortener_scanning_enabled().execute()
assert len(findings) == 1
assert findings[0].status == "PASS"
assert findings[0].status_extended == (
f"Gmail is turned off for everyone in domain {DOMAIN}, "
f"so no user mailbox receives mail through Gmail."
)
def test_no_findings_when_fetch_failed(self):
mock_provider = set_mocked_googleworkspace_provider()
@@ -3,6 +3,7 @@ from unittest.mock import patch
from prowler.providers.googleworkspace.services.gmail.gmail_service import GmailPolicies
from tests.providers.googleworkspace.googleworkspace_fixtures import (
CUSTOMER_ID,
DOMAIN,
set_mocked_googleworkspace_provider,
)
@@ -127,6 +128,38 @@ class TestGmailUnauthenticatedEmailProtectionEnabled:
assert findings[0].status == "FAIL"
assert "insecure default" in findings[0].status_extended
def test_pass_when_the_service_is_off_for_everyone(self):
"""A setting that only acts while the service is on has no effect once the service is off"""
mock_provider = set_mocked_googleworkspace_provider()
with (
patch(
"prowler.providers.common.provider.Provider.get_global_provider",
return_value=mock_provider,
),
patch(
"prowler.providers.googleworkspace.services.gmail.gmail_unauthenticated_email_protection_enabled.gmail_unauthenticated_email_protection_enabled.gmail_client"
) as mock_client,
):
from prowler.providers.googleworkspace.services.gmail.gmail_unauthenticated_email_protection_enabled.gmail_unauthenticated_email_protection_enabled import (
gmail_unauthenticated_email_protection_enabled,
)
mock_client.provider = mock_provider
mock_client.policies_fetched = True
mock_client.policies = GmailPolicies(
service_state="DISABLED", detect_unauthenticated_emails=False
)
findings = gmail_unauthenticated_email_protection_enabled().execute()
assert len(findings) == 1
assert findings[0].status == "PASS"
assert findings[0].status_extended == (
f"Gmail is turned off for everyone in domain {DOMAIN}, "
f"so no user mailbox receives mail through Gmail."
)
def test_no_findings_when_fetch_failed(self):
mock_provider = set_mocked_googleworkspace_provider()
@@ -3,6 +3,7 @@ from unittest.mock import patch
from prowler.providers.googleworkspace.services.gmail.gmail_service import GmailPolicies
from tests.providers.googleworkspace.googleworkspace_fixtures import (
CUSTOMER_ID,
DOMAIN,
set_mocked_googleworkspace_provider,
)
@@ -97,6 +98,39 @@ class TestGmailUntrustedLinkWarningsEnabled:
assert findings[0].status == "FAIL"
assert "insecure default" in findings[0].status_extended
def test_pass_when_the_service_is_off_for_everyone(self):
"""A setting that only acts while the service is on has no effect once the service is off"""
mock_provider = set_mocked_googleworkspace_provider()
with (
patch(
"prowler.providers.common.provider.Provider.get_global_provider",
return_value=mock_provider,
),
patch(
"prowler.providers.googleworkspace.services.gmail.gmail_untrusted_link_warnings_enabled.gmail_untrusted_link_warnings_enabled.gmail_client"
) as mock_client,
):
from prowler.providers.googleworkspace.services.gmail.gmail_untrusted_link_warnings_enabled.gmail_untrusted_link_warnings_enabled import (
gmail_untrusted_link_warnings_enabled,
)
mock_client.provider = mock_provider
mock_client.policies_fetched = True
mock_client.policies = GmailPolicies(
service_state="DISABLED",
enable_aggressive_warnings_on_untrusted_links=False,
)
findings = gmail_untrusted_link_warnings_enabled().execute()
assert len(findings) == 1
assert findings[0].status == "PASS"
assert findings[0].status_extended == (
f"Gmail is turned off for everyone in domain {DOMAIN}, "
f"so no user mailbox receives mail through Gmail."
)
def test_no_findings_when_fetch_failed(self):
mock_provider = set_mocked_googleworkspace_provider()
@@ -5,6 +5,7 @@ from prowler.providers.googleworkspace.services.groups.groups_service import (
)
from tests.providers.googleworkspace.googleworkspace_fixtures import (
CUSTOMER_ID,
DOMAIN,
set_mocked_googleworkspace_provider,
)
@@ -244,6 +245,80 @@ class TestGroupsCreationRestricted:
assert "external members" in findings[0].status_extended
assert "incoming email" in findings[0].status_extended
def test_pass_when_the_service_is_off_and_existing_groups_are_restricted(self):
"""Off for everyone makes creation moot; existing groups still have to keep outsiders out"""
mock_provider = set_mocked_googleworkspace_provider()
with (
patch(
"prowler.providers.common.provider.Provider.get_global_provider",
return_value=mock_provider,
),
patch(
"prowler.providers.googleworkspace.services.groups.groups_creation_restricted.groups_creation_restricted.groups_client"
) as mock_client,
):
from prowler.providers.googleworkspace.services.groups.groups_creation_restricted.groups_creation_restricted import (
groups_creation_restricted,
)
mock_client.provider = mock_provider
mock_client.policies_fetched = True
mock_client.policies = GroupsPolicies(
service_state="DISABLED",
create_groups_access_level="USERS_IN_DOMAIN",
owners_can_allow_external_members=False,
owners_can_allow_incoming_mail_from_public=False,
)
findings = groups_creation_restricted().execute()
assert len(findings) == 1
assert findings[0].status == "PASS"
assert findings[0].status_extended == (
f"Groups for Business is turned off for everyone in domain {DOMAIN}, "
f"so no group can be created, and existing groups allow no external "
f"members and no incoming email from outside."
)
def test_fail_when_the_service_is_off_but_existing_groups_accept_outsiders(self):
"""Existing groups stay active when the service is off, so their email boundary still counts"""
mock_provider = set_mocked_googleworkspace_provider()
with (
patch(
"prowler.providers.common.provider.Provider.get_global_provider",
return_value=mock_provider,
),
patch(
"prowler.providers.googleworkspace.services.groups.groups_creation_restricted.groups_creation_restricted.groups_client"
) as mock_client,
):
from prowler.providers.googleworkspace.services.groups.groups_creation_restricted.groups_creation_restricted import (
groups_creation_restricted,
)
mock_client.provider = mock_provider
mock_client.policies_fetched = True
mock_client.policies = GroupsPolicies(
service_state="DISABLED",
create_groups_access_level="USERS_IN_DOMAIN",
owners_can_allow_external_members=True,
owners_can_allow_incoming_mail_from_public=True,
)
findings = groups_creation_restricted().execute()
assert len(findings) == 1
assert findings[0].status == "FAIL"
assert "group creation" not in findings[0].status_extended
assert findings[0].status_extended == (
f"Groups for Business is turned off for everyone in domain {DOMAIN}, "
f"so no group can be created, but existing groups remain active and "
f"are not fully restricted: group owners can allow external members; "
f"group owners can allow incoming email from outside the organization."
)
def test_no_findings_when_fetch_failed(self):
"""Test no findings returned when the API fetch failed"""
mock_provider = set_mocked_googleworkspace_provider()
@@ -105,6 +105,35 @@ class TestGroupsExternalAccessRestricted:
assert findings[0].status == "PASS"
assert "secure default" in findings[0].status_extended
def test_evaluates_the_setting_when_the_service_is_off_for_everyone(self):
"""Existing groups stay active when Groups for Business is off, so the stored setting still counts"""
mock_provider = set_mocked_googleworkspace_provider()
with (
patch(
"prowler.providers.common.provider.Provider.get_global_provider",
return_value=mock_provider,
),
patch(
"prowler.providers.googleworkspace.services.groups.groups_external_access_restricted.groups_external_access_restricted.groups_client"
) as mock_client,
):
from prowler.providers.googleworkspace.services.groups.groups_external_access_restricted.groups_external_access_restricted import (
groups_external_access_restricted,
)
mock_client.provider = mock_provider
mock_client.policies_fetched = True
mock_client.policies = GroupsPolicies(
service_state="DISABLED", collaboration_capability="ANYONE_CAN_POST"
)
findings = groups_external_access_restricted().execute()
assert len(findings) == 1
assert findings[0].status == "FAIL"
assert "turned off" not in findings[0].status_extended
def test_no_findings_when_fetch_failed(self):
"""Test no findings returned when the API fetch failed"""
mock_provider = set_mocked_googleworkspace_provider()
@@ -1,6 +1,7 @@
from unittest.mock import MagicMock, patch
from tests.providers.googleworkspace.googleworkspace_fixtures import (
ROOT_ORG_UNIT_ID,
set_mocked_googleworkspace_provider,
)
@@ -64,6 +65,164 @@ class TestGroupsService:
assert groups.policies.owners_can_hide_groups is False
assert groups.policies.new_groups_are_hidden is False
def test_the_admin_policy_outranks_a_system_default_returned_after_it(self):
"""The greatest sortOrder is the value in force, whatever order the API lists them in"""
mock_provider = set_mocked_googleworkspace_provider()
mock_provider.audit_config = {}
mock_provider.fixer_config = {}
mock_session = MagicMock()
mock_session.credentials = MagicMock()
mock_provider.session = mock_session
mock_service = MagicMock()
mock_policies_list = MagicMock()
mock_policies_list.execute.return_value = {
"policies": [
{
"type": "ADMIN",
"policyQuery": {"sortOrder": 201.00131},
"setting": {
"type": "settings/groups_for_business.groups_sharing",
"value": {"createGroupsAccessLevel": "ADMIN_ONLY"},
},
},
{
"type": "SYSTEM",
"policyQuery": {"sortOrder": 100.00002},
"setting": {
"type": "settings/groups_for_business.groups_sharing",
"value": {"createGroupsAccessLevel": "USERS_IN_DOMAIN"},
},
},
]
}
mock_service.policies().list.return_value = mock_policies_list
mock_service.policies().list_next.return_value = None
with (
patch(
"prowler.providers.common.provider.Provider.get_global_provider",
return_value=mock_provider,
),
patch(
"prowler.providers.googleworkspace.services.groups.groups_service.GoogleWorkspaceService._build_service",
return_value=mock_service,
),
):
from prowler.providers.googleworkspace.services.groups.groups_service import (
Groups,
)
groups = Groups(mock_provider)
assert groups.policies_fetched is True
assert groups.policies.create_groups_access_level == "ADMIN_ONLY"
def test_off_for_everyone_when_off_at_the_root_with_no_override(self):
"""A root-level DISABLED status with no org unit or group override is off for everyone"""
mock_provider = set_mocked_googleworkspace_provider()
mock_provider.audit_config = {}
mock_provider.fixer_config = {}
mock_session = MagicMock()
mock_session.credentials = MagicMock()
mock_provider.session = mock_session
mock_service = MagicMock()
mock_policies_list = MagicMock()
mock_policies_list.execute.return_value = {
"policies": [
{
"type": "ADMIN",
"policyQuery": {
"orgUnit": f"orgUnits/{ROOT_ORG_UNIT_ID}",
"sortOrder": 201.00122,
},
"setting": {
"type": "settings/groups_for_business.service_status",
"value": {"serviceState": "DISABLED"},
},
},
]
}
mock_service.policies().list.return_value = mock_policies_list
mock_service.policies().list_next.return_value = None
with (
patch(
"prowler.providers.common.provider.Provider.get_global_provider",
return_value=mock_provider,
),
patch(
"prowler.providers.googleworkspace.services.groups.groups_service.GoogleWorkspaceService._build_service",
return_value=mock_service,
),
):
from prowler.providers.googleworkspace.services.groups.groups_service import (
Groups,
)
fetched = Groups(mock_provider)
assert fetched.policies_fetched is True
assert fetched.policies.service_state == "DISABLED"
assert fetched.policies.service_state_overridden is False
assert fetched.policies.off_for_everyone is True
def test_reads_the_service_status_and_its_overrides(self):
"""Off at the customer level only counts when no org unit or group turns the service back on"""
mock_provider = set_mocked_googleworkspace_provider()
mock_provider.audit_config = {}
mock_provider.fixer_config = {}
mock_session = MagicMock()
mock_session.credentials = MagicMock()
mock_provider.session = mock_session
mock_service = MagicMock()
mock_policies_list = MagicMock()
mock_policies_list.execute.return_value = {
"policies": [
{
"type": "ADMIN",
"policyQuery": {"sortOrder": 201.00122},
"setting": {
"type": "settings/groups_for_business.service_status",
"value": {"serviceState": "DISABLED"},
},
},
{
"type": "ADMIN",
"policyQuery": {"orgUnit": "orgUnits/sub", "sortOrder": 301.00122},
"setting": {
"type": "settings/groups_for_business.service_status",
"value": {"serviceState": "ENABLED"},
},
},
]
}
mock_service.policies().list.return_value = mock_policies_list
mock_service.policies().list_next.return_value = None
with (
patch(
"prowler.providers.common.provider.Provider.get_global_provider",
return_value=mock_provider,
),
patch(
"prowler.providers.googleworkspace.services.groups.groups_service.GoogleWorkspaceService._build_service",
return_value=mock_service,
),
):
from prowler.providers.googleworkspace.services.groups.groups_service import (
Groups,
)
fetched = Groups(mock_provider)
assert fetched.policies_fetched is True
assert fetched.policies.service_state == "DISABLED"
assert fetched.policies.service_state_overridden is True
assert fetched.policies.off_for_everyone is False
def test_fetch_policies_empty_response(self):
"""Test handling empty policies response"""
mock_provider = set_mocked_googleworkspace_provider()
@@ -5,6 +5,7 @@ from prowler.providers.googleworkspace.services.groups.groups_service import (
)
from tests.providers.googleworkspace.googleworkspace_fixtures import (
CUSTOMER_ID,
DOMAIN,
set_mocked_googleworkspace_provider,
)
@@ -138,6 +139,39 @@ class TestGroupsViewConversationsRestricted:
assert "default" in findings[0].status_extended
assert "all organization users" in findings[0].status_extended
def test_pass_when_the_service_is_off_for_everyone(self):
"""A setting that only acts while the service is on has no effect once the service is off"""
mock_provider = set_mocked_googleworkspace_provider()
with (
patch(
"prowler.providers.common.provider.Provider.get_global_provider",
return_value=mock_provider,
),
patch(
"prowler.providers.googleworkspace.services.groups.groups_view_conversations_restricted.groups_view_conversations_restricted.groups_client"
) as mock_client,
):
from prowler.providers.googleworkspace.services.groups.groups_view_conversations_restricted.groups_view_conversations_restricted import (
groups_view_conversations_restricted,
)
mock_client.provider = mock_provider
mock_client.policies_fetched = True
mock_client.policies = GroupsPolicies(
service_state="DISABLED",
view_topics_default_access_level="DOMAIN_USERS",
)
findings = groups_view_conversations_restricted().execute()
assert len(findings) == 1
assert findings[0].status == "PASS"
assert findings[0].status_extended == (
f"Groups for Business is turned off for everyone in domain {DOMAIN}, "
f"so no group conversation can be viewed in the Google Groups app."
)
def test_no_findings_when_fetch_failed(self):
"""Test no findings returned when the API fetch failed"""
mock_provider = set_mocked_googleworkspace_provider()
@@ -142,6 +142,59 @@ class TestMarketplaceService:
assert marketplace.policies_fetched is True
assert marketplace.policies.access_level == "ALLOW_NONE"
def test_the_admin_policy_outranks_a_system_default_returned_after_it(self):
"""The greatest sortOrder is the value in force, whatever order the API lists them in"""
mock_provider = set_mocked_googleworkspace_provider()
mock_provider.audit_config = {}
mock_provider.fixer_config = {}
mock_session = MagicMock()
mock_session.credentials = MagicMock()
mock_provider.session = mock_session
mock_service = MagicMock()
mock_policies_list = MagicMock()
mock_policies_list.execute.return_value = {
"policies": [
{
"type": "ADMIN",
"policyQuery": {"sortOrder": 201.00131},
"setting": {
"type": "settings/workspace_marketplace.apps_access_options",
"value": {"accessLevel": "ALLOW_LISTED_APPS"},
},
},
{
"type": "SYSTEM",
"policyQuery": {"sortOrder": 100.00002},
"setting": {
"type": "settings/workspace_marketplace.apps_access_options",
"value": {"accessLevel": "ALLOW_ALL"},
},
},
]
}
mock_service.policies().list.return_value = mock_policies_list
mock_service.policies().list_next.return_value = None
with (
patch(
"prowler.providers.common.provider.Provider.get_global_provider",
return_value=mock_provider,
),
patch(
"prowler.providers.googleworkspace.services.marketplace.marketplace_service.GoogleWorkspaceService._build_service",
return_value=mock_service,
),
):
from prowler.providers.googleworkspace.services.marketplace.marketplace_service import (
Marketplace,
)
marketplace = Marketplace(mock_provider)
assert marketplace.policies_fetched is True
assert marketplace.policies.access_level == "ALLOW_LISTED_APPS"
def test_fetch_policies_empty_response(self):
"""Test handling empty policies response"""
mock_provider = set_mocked_googleworkspace_provider()
@@ -239,6 +239,115 @@ class TestSecurityService:
assert security.policies.google_services_restricted is True
assert security.policies.dlp_drive_rules_exist is True
def test_the_admin_policy_outranks_the_system_defaults_returned_after_it(self):
"""The API returns Google's SYSTEM defaults next to the ADMIN policy saved in the console.
The greatest sortOrder is the value in force, whatever the order the
API lists them in. This is the shape of a real tenant, where the last
policy returned used to overwrite the admin's password policy.
"""
mock_provider = set_mocked_googleworkspace_provider()
mock_provider.audit_config = {}
mock_provider.fixer_config = {}
mock_session = MagicMock()
mock_session.credentials = MagicMock()
mock_provider.session = mock_session
root_ou = f"orgUnits/{ROOT_ORG_UNIT_ID}"
mock_security_list = MagicMock()
mock_security_list.execute.return_value = {
"policies": [
{
"type": "ADMIN",
"policyQuery": {"orgUnit": root_ou, "sortOrder": 201.00131},
"setting": {
"type": "settings/security.password",
"value": {
"allowedStrength": "STRONG",
"minimumLength": 12,
"maximumLength": 100,
"enforceRequirementsAtLogin": True,
"allowReuse": False,
"expirationDuration": "15552000s",
},
},
},
{
"type": "SYSTEM",
"policyQuery": {"orgUnit": root_ou, "sortOrder": 100.00001},
"setting": {
"type": "settings/security.password",
"value": {
"allowedStrength": "STRONG",
"minimumLength": 8,
"maximumLength": 100,
"enforceRequirementsAtLogin": False,
"allowReuse": False,
"expirationDuration": "0s",
},
},
},
{
"type": "SYSTEM",
"policyQuery": {"orgUnit": root_ou, "sortOrder": 100.00003},
"setting": {
"type": "settings/security.password",
"value": {
"allowedStrength": "STRONG",
"minimumLength": 8,
"maximumLength": 100,
"enforceRequirementsAtLogin": False,
"allowReuse": False,
"expirationDuration": "0s",
},
},
},
{
"type": "SYSTEM",
"policyQuery": {"orgUnit": root_ou, "sortOrder": 100.00003},
"setting": {
"type": "settings/security.session_controls",
"value": {"webSessionDuration": "1209600s"},
},
},
]
}
mock_api_controls_list = MagicMock()
mock_api_controls_list.execute.return_value = {"policies": []}
mock_dlp_list = MagicMock()
mock_dlp_list.execute.return_value = {"policies": []}
mock_service = MagicMock()
mock_service.policies().list.side_effect = [
mock_security_list,
mock_api_controls_list,
mock_dlp_list,
]
mock_service.policies().list_next.return_value = None
with (
patch(
"prowler.providers.common.provider.Provider.get_global_provider",
return_value=mock_provider,
),
patch(
"prowler.providers.googleworkspace.services.security.security_service.GoogleWorkspaceService._build_service",
return_value=mock_service,
),
):
from prowler.providers.googleworkspace.services.security.security_service import (
Security,
)
security = Security(mock_provider)
assert security.policies_fetched is True
assert security.policies.password_minimum_length == 12
assert security.policies.password_enforce_at_login is True
assert security.policies.password_allow_reuse is False
assert security.policies.password_expiration_duration == "15552000s"
assert security.policies.web_session_duration == "1209600s"
assert security.policies.overridden_settings == []
def test_fetch_policies_empty_response(self):
"""Test handling empty policies response across all namespaces"""
mock_provider = set_mocked_googleworkspace_provider()
@@ -97,6 +97,59 @@ class TestSitesService:
assert sites.policies_fetched is True
assert sites.policies.service_state == "ENABLED"
def test_the_admin_policy_outranks_a_system_default_returned_after_it(self):
"""The greatest sortOrder is the value in force, whatever order the API lists them in"""
mock_provider = set_mocked_googleworkspace_provider()
mock_provider.audit_config = {}
mock_provider.fixer_config = {}
mock_session = MagicMock()
mock_session.credentials = MagicMock()
mock_provider.session = mock_session
mock_service = MagicMock()
mock_policies_list = MagicMock()
mock_policies_list.execute.return_value = {
"policies": [
{
"type": "ADMIN",
"policyQuery": {"sortOrder": 201.00131},
"setting": {
"type": "settings/sites.service_status",
"value": {"serviceState": "DISABLED"},
},
},
{
"type": "SYSTEM",
"policyQuery": {"sortOrder": 100.00005},
"setting": {
"type": "settings/sites.service_status",
"value": {"serviceState": "ENABLED"},
},
},
]
}
mock_service.policies().list.return_value = mock_policies_list
mock_service.policies().list_next.return_value = None
with (
patch(
"prowler.providers.common.provider.Provider.get_global_provider",
return_value=mock_provider,
),
patch(
"prowler.providers.googleworkspace.services.sites.sites_service.GoogleWorkspaceService._build_service",
return_value=mock_service,
),
):
from prowler.providers.googleworkspace.services.sites.sites_service import (
Sites,
)
sites = Sites(mock_provider)
assert sites.policies_fetched is True
assert sites.policies.service_state == "DISABLED"
def test_fetch_policies_empty_response(self):
"""Test handling empty policies response"""
mock_provider = set_mocked_googleworkspace_provider()