mirror of
https://github.com/prowler-cloud/prowler.git
synced 2026-10-09 21:14:22 +00:00
feat(googleworkspace): add sites, additional_services and marketplace service checks (#11281)
This commit is contained in:
@@ -6,6 +6,7 @@ All notable changes to the **Prowler SDK** are documented in this file.
|
||||
|
||||
### 🚀 Added
|
||||
|
||||
- Sites, Additional Google services, and Marketplace checks for Google Workspace provider using the Cloud Identity Policy API [(#11281)](https://github.com/prowler-cloud/prowler/pull/11281)
|
||||
- `entra_app_registration_client_secret_unused` check for M365 provider [(#11232)](https://github.com/prowler-cloud/prowler/pull/11232)
|
||||
- `cloudsql_instance_cmek_encryption_enabled` check for GCP provider [(#11023)](https://github.com/prowler-cloud/prowler/pull/11023)
|
||||
- Google Workspace Groups service with 3 new checks [(#11186)](https://github.com/prowler-cloud/prowler/pull/11186)
|
||||
|
||||
@@ -1291,7 +1291,9 @@
|
||||
{
|
||||
"Id": "3.1.7.1",
|
||||
"Description": "Ensure service status for Google Sites is set to off",
|
||||
"Checks": [],
|
||||
"Checks": [
|
||||
"sites_service_disabled"
|
||||
],
|
||||
"Attributes": [
|
||||
{
|
||||
"Section": "3 Apps",
|
||||
@@ -1312,7 +1314,9 @@
|
||||
{
|
||||
"Id": "3.1.8.1",
|
||||
"Description": "Ensure access to external Google Groups is OFF for Everyone",
|
||||
"Checks": [],
|
||||
"Checks": [
|
||||
"additionalservices_external_groups_disabled"
|
||||
],
|
||||
"Attributes": [
|
||||
{
|
||||
"Section": "3 Apps",
|
||||
@@ -1333,7 +1337,9 @@
|
||||
{
|
||||
"Id": "3.1.9.1.1",
|
||||
"Description": "Ensure users access to Google Workspace Marketplace apps is restricted",
|
||||
"Checks": [],
|
||||
"Checks": [
|
||||
"marketplace_apps_access_restricted"
|
||||
],
|
||||
"Attributes": [
|
||||
{
|
||||
"Section": "3 Apps",
|
||||
|
||||
@@ -374,7 +374,9 @@
|
||||
{
|
||||
"Id": "GWS.COMMONCONTROLS.11.1",
|
||||
"Description": "Only approved Marketplace apps SHALL be allowed for installation",
|
||||
"Checks": [],
|
||||
"Checks": [
|
||||
"marketplace_apps_access_restricted"
|
||||
],
|
||||
"Attributes": [
|
||||
{
|
||||
"Section": "Common Controls",
|
||||
@@ -1714,7 +1716,9 @@
|
||||
{
|
||||
"Id": "GWS.SITES.1.1",
|
||||
"Description": "Sites Service SHOULD be disabled for all users",
|
||||
"Checks": [],
|
||||
"Checks": [
|
||||
"sites_service_disabled"
|
||||
],
|
||||
"Attributes": [
|
||||
{
|
||||
"Section": "Sites",
|
||||
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
from prowler.providers.common.provider import Provider
|
||||
from prowler.providers.googleworkspace.services.additionalservices.additionalservices_service import (
|
||||
AdditionalServices,
|
||||
)
|
||||
|
||||
additionalservices_client = AdditionalServices(Provider.get_global_provider())
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
{
|
||||
"Provider": "googleworkspace",
|
||||
"CheckID": "additionalservices_external_groups_disabled",
|
||||
"CheckTitle": "Access to external Google Groups is off for everyone",
|
||||
"CheckType": [],
|
||||
"ServiceName": "additionalservices",
|
||||
"SubServiceName": "",
|
||||
"ResourceIdTemplate": "",
|
||||
"Severity": "medium",
|
||||
"ResourceType": "NotDefined",
|
||||
"ResourceGroup": "collaboration",
|
||||
"Description": "The Additional Google services configuration **disables access to external Google Groups** for all users. This setting controls whether users can access groups created outside the organization from their Google Workspace account.",
|
||||
"Risk": "When external Google Groups access is enabled, users can access and participate in groups created **outside the organization**, potentially exposing them to **phishing, social engineering, or data leakage** through unmanaged external group communications.",
|
||||
"RelatedUrl": "",
|
||||
"AdditionalURLs": [
|
||||
"https://support.google.com/a/answer/181865",
|
||||
"https://cloud.google.com/identity/docs/concepts/supported-policy-api-settings"
|
||||
],
|
||||
"Remediation": {
|
||||
"Code": {
|
||||
"CLI": "",
|
||||
"NativeIaC": "",
|
||||
"Other": "1. Sign in to the Google **Admin console** at https://admin.google.com\n2. Navigate to **Apps** > **Google Workspace** > **Additional Google services**\n3. Scroll down to **Google Groups**\n4. Set it to **OFF for everyone**\n5. Click **Save**",
|
||||
"Terraform": ""
|
||||
},
|
||||
"Recommendation": {
|
||||
"Text": "Disable access to **external Google Groups** for all users. If specific users require access to external groups, enable it by exception for those users or groups only.",
|
||||
"Url": "https://hub.prowler.com/check/additionalservices_external_groups_disabled"
|
||||
}
|
||||
},
|
||||
"Categories": [
|
||||
"trust-boundaries"
|
||||
],
|
||||
"DependsOn": [],
|
||||
"RelatedTo": [],
|
||||
"Notes": "This check covers the 'Additional Google services > Google Groups' toggle, which is distinct from the 'Groups for Business' sharing settings covered by the groups service checks."
|
||||
}
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
from typing import List
|
||||
|
||||
from prowler.lib.check.models import Check, CheckReportGoogleWorkspace
|
||||
from prowler.providers.googleworkspace.services.additionalservices.additionalservices_client import (
|
||||
additionalservices_client,
|
||||
)
|
||||
|
||||
|
||||
class additionalservices_external_groups_disabled(Check):
|
||||
"""Check that access to external Google Groups is disabled for all users.
|
||||
|
||||
This check verifies that the domain-level Additional Google services policy
|
||||
disables external Google Groups access, preventing users from accessing
|
||||
groups created outside the organization.
|
||||
"""
|
||||
|
||||
def execute(self) -> List[CheckReportGoogleWorkspace]:
|
||||
findings = []
|
||||
|
||||
if additionalservices_client.policies_fetched:
|
||||
report = CheckReportGoogleWorkspace(
|
||||
metadata=self.metadata(),
|
||||
resource=additionalservices_client.policies,
|
||||
resource_id="additionalServicesPolicies",
|
||||
resource_name="Additional Services Policies",
|
||||
customer_id=additionalservices_client.provider.identity.customer_id,
|
||||
)
|
||||
|
||||
groups_state = additionalservices_client.policies.groups_service_state
|
||||
|
||||
if groups_state == "DISABLED":
|
||||
report.status = "PASS"
|
||||
report.status_extended = (
|
||||
f"Access to external Google Groups is disabled "
|
||||
f"in domain {additionalservices_client.provider.identity.domain}."
|
||||
)
|
||||
else:
|
||||
report.status = "FAIL"
|
||||
if groups_state is None:
|
||||
report.status_extended = (
|
||||
f"Access to external Google Groups is not explicitly configured "
|
||||
f"in domain {additionalservices_client.provider.identity.domain}. "
|
||||
f"The default is ON for everyone. "
|
||||
f"External Google Groups access should be disabled."
|
||||
)
|
||||
else:
|
||||
report.status_extended = (
|
||||
f"Access to external Google Groups is enabled "
|
||||
f"in domain {additionalservices_client.provider.identity.domain}. "
|
||||
f"External Google Groups access should be disabled."
|
||||
)
|
||||
|
||||
findings.append(report)
|
||||
|
||||
return findings
|
||||
+92
@@ -0,0 +1,92 @@
|
||||
from typing import Optional
|
||||
|
||||
from pydantic import BaseModel
|
||||
|
||||
from prowler.lib.logger import logger
|
||||
from prowler.providers.googleworkspace.lib.service.service import GoogleWorkspaceService
|
||||
|
||||
|
||||
class AdditionalServices(GoogleWorkspaceService):
|
||||
"""Google Workspace Additional Services for auditing domain-level service toggles.
|
||||
|
||||
Uses the Cloud Identity Policy API v1 to read the service status of
|
||||
additional Google services configured in the Admin Console, such as
|
||||
the external Google Groups access toggle.
|
||||
"""
|
||||
|
||||
def __init__(self, provider):
|
||||
super().__init__(provider)
|
||||
self.policies = AdditionalServicesPolicies()
|
||||
self.policies_fetched = False
|
||||
self._fetch_additional_services_policies()
|
||||
|
||||
def _fetch_additional_services_policies(self):
|
||||
"""Fetch Additional Services policies from the Cloud Identity Policy API v1."""
|
||||
logger.info("Additional Services - Fetching policies...")
|
||||
|
||||
try:
|
||||
service = self._build_service("cloudidentity", "v1")
|
||||
|
||||
if not service:
|
||||
logger.error("Failed to build Cloud Identity service")
|
||||
return
|
||||
|
||||
request = service.policies().list(
|
||||
pageSize=100,
|
||||
filter='setting.type.matches("groups.service_status")',
|
||||
)
|
||||
fetch_succeeded = True
|
||||
|
||||
while request is not None:
|
||||
try:
|
||||
response = request.execute()
|
||||
|
||||
for policy in response.get("policies", []):
|
||||
if not self._is_customer_level_policy(policy):
|
||||
continue
|
||||
|
||||
setting = policy.get("setting", {})
|
||||
setting_type = setting.get("type", "").removeprefix("settings/")
|
||||
value = setting.get("value", {})
|
||||
|
||||
if setting_type == "groups.service_status":
|
||||
self.policies.groups_service_state = value.get(
|
||||
"serviceState"
|
||||
)
|
||||
logger.debug(
|
||||
"Additional Services - Groups service state: "
|
||||
f"{self.policies.groups_service_state}"
|
||||
)
|
||||
|
||||
request = service.policies().list_next(request, response)
|
||||
|
||||
except Exception as error:
|
||||
self._handle_api_error(
|
||||
error,
|
||||
"fetching Additional Services policies",
|
||||
self.provider.identity.customer_id,
|
||||
)
|
||||
fetch_succeeded = False
|
||||
break
|
||||
|
||||
self.policies_fetched = fetch_succeeded
|
||||
|
||||
logger.info(
|
||||
f"Additional Services policies fetched - "
|
||||
f"Groups service state: {self.policies.groups_service_state}"
|
||||
)
|
||||
|
||||
except Exception as error:
|
||||
self._handle_api_error(
|
||||
error,
|
||||
"fetching Additional Services policies",
|
||||
self.provider.identity.customer_id,
|
||||
)
|
||||
self.policies_fetched = False
|
||||
|
||||
|
||||
class AdditionalServicesPolicies(BaseModel):
|
||||
"""Model for domain-level Additional Google Services policy settings."""
|
||||
|
||||
# groups.service_status
|
||||
groups_service_state: Optional[str] = None
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
{
|
||||
"Provider": "googleworkspace",
|
||||
"CheckID": "marketplace_apps_access_restricted",
|
||||
"CheckTitle": "Users access to Google Workspace Marketplace apps is restricted",
|
||||
"CheckType": [],
|
||||
"ServiceName": "marketplace",
|
||||
"SubServiceName": "",
|
||||
"ResourceIdTemplate": "",
|
||||
"Severity": "medium",
|
||||
"ResourceType": "NotDefined",
|
||||
"ResourceGroup": "collaboration",
|
||||
"Description": "The domain-wide Google Workspace Marketplace configuration **restricts which apps users can install**. Only admin-approved apps from the Marketplace allowlist are permitted, preventing users from installing unvetted third-party applications.",
|
||||
"Risk": "Allowing unrestricted Marketplace app installation exposes the organization to **unvetted third-party applications** that may request broad OAuth scopes, potentially gaining access to **sensitive organizational data** including emails, documents, and calendar events without proper security review.",
|
||||
"RelatedUrl": "",
|
||||
"AdditionalURLs": [
|
||||
"https://support.google.com/a/answer/6089179",
|
||||
"https://cloud.google.com/identity/docs/concepts/supported-policy-api-settings"
|
||||
],
|
||||
"Remediation": {
|
||||
"Code": {
|
||||
"CLI": "",
|
||||
"NativeIaC": "",
|
||||
"Other": "1. Sign in to the Google **Admin console** at https://admin.google.com\n2. Navigate to **Apps** > **Google Workspace Marketplace apps**\n3. Click **Settings**\n4. Under **Manage Google Workspace Marketplace allowlist access**, select **Allow users to install and run only selected apps from the Marketplace**\n5. Click **Save**",
|
||||
"Terraform": ""
|
||||
},
|
||||
"Recommendation": {
|
||||
"Text": "Restrict **Marketplace app installation** to only **admin-approved apps** to prevent users from installing unvetted third-party applications that could access sensitive organizational data.",
|
||||
"Url": "https://hub.prowler.com/check/marketplace_apps_access_restricted"
|
||||
}
|
||||
},
|
||||
"Categories": [
|
||||
"trust-boundaries"
|
||||
],
|
||||
"DependsOn": [],
|
||||
"RelatedTo": [],
|
||||
"Notes": ""
|
||||
}
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
from typing import List
|
||||
|
||||
from prowler.lib.check.models import Check, CheckReportGoogleWorkspace
|
||||
from prowler.providers.googleworkspace.services.marketplace.marketplace_client import (
|
||||
marketplace_client,
|
||||
)
|
||||
|
||||
|
||||
class marketplace_apps_access_restricted(Check):
|
||||
"""Check that Google Workspace Marketplace app installation is restricted.
|
||||
|
||||
This check verifies that the domain-level Marketplace policy restricts
|
||||
which apps users can install, preventing unvetted third-party applications
|
||||
from accessing organizational data.
|
||||
"""
|
||||
|
||||
def execute(self) -> List[CheckReportGoogleWorkspace]:
|
||||
findings = []
|
||||
|
||||
if marketplace_client.policies_fetched:
|
||||
report = CheckReportGoogleWorkspace(
|
||||
metadata=self.metadata(),
|
||||
resource=marketplace_client.policies,
|
||||
resource_id="marketplacePolicies",
|
||||
resource_name="Marketplace Policies",
|
||||
customer_id=marketplace_client.provider.identity.customer_id,
|
||||
)
|
||||
|
||||
access_level = marketplace_client.policies.access_level
|
||||
|
||||
if access_level == "ALLOW_LISTED_APPS":
|
||||
report.status = "PASS"
|
||||
report.status_extended = (
|
||||
f"Marketplace app installation is restricted to admin-approved apps "
|
||||
f"in domain {marketplace_client.provider.identity.domain}."
|
||||
)
|
||||
elif access_level == "ALLOW_NONE":
|
||||
report.status = "PASS"
|
||||
report.status_extended = (
|
||||
f"Marketplace app installation is fully blocked "
|
||||
f"in domain {marketplace_client.provider.identity.domain}."
|
||||
)
|
||||
else:
|
||||
report.status = "FAIL"
|
||||
if access_level is None:
|
||||
report.status_extended = (
|
||||
f"Marketplace app access is not explicitly configured "
|
||||
f"in domain {marketplace_client.provider.identity.domain}. "
|
||||
f"The default allows all apps. "
|
||||
f"App installation should be restricted to approved apps only."
|
||||
)
|
||||
else:
|
||||
report.status_extended = (
|
||||
f"Marketplace allows users to install any app "
|
||||
f"in domain {marketplace_client.provider.identity.domain}. "
|
||||
f"App installation should be restricted to approved apps only."
|
||||
)
|
||||
|
||||
findings.append(report)
|
||||
|
||||
return findings
|
||||
@@ -0,0 +1,6 @@
|
||||
from prowler.providers.common.provider import Provider
|
||||
from prowler.providers.googleworkspace.services.marketplace.marketplace_service import (
|
||||
Marketplace,
|
||||
)
|
||||
|
||||
marketplace_client = Marketplace(Provider.get_global_provider())
|
||||
@@ -0,0 +1,89 @@
|
||||
from typing import Optional
|
||||
|
||||
from pydantic import BaseModel
|
||||
|
||||
from prowler.lib.logger import logger
|
||||
from prowler.providers.googleworkspace.lib.service.service import GoogleWorkspaceService
|
||||
|
||||
|
||||
class Marketplace(GoogleWorkspaceService):
|
||||
"""Google Workspace Marketplace service for auditing domain-level Marketplace policies.
|
||||
|
||||
Uses the Cloud Identity Policy API v1 to read the Marketplace app access
|
||||
settings configured in the Admin Console.
|
||||
"""
|
||||
|
||||
def __init__(self, provider):
|
||||
super().__init__(provider)
|
||||
self.policies = MarketplacePolicies()
|
||||
self.policies_fetched = False
|
||||
self._fetch_marketplace_policies()
|
||||
|
||||
def _fetch_marketplace_policies(self):
|
||||
"""Fetch Marketplace policies from the Cloud Identity Policy API v1."""
|
||||
logger.info("Marketplace - Fetching marketplace policies...")
|
||||
|
||||
try:
|
||||
service = self._build_service("cloudidentity", "v1")
|
||||
|
||||
if not service:
|
||||
logger.error("Failed to build Cloud Identity service")
|
||||
return
|
||||
|
||||
request = service.policies().list(
|
||||
pageSize=100,
|
||||
filter='setting.type.matches("workspace_marketplace.*")',
|
||||
)
|
||||
fetch_succeeded = True
|
||||
|
||||
while request is not None:
|
||||
try:
|
||||
response = request.execute()
|
||||
|
||||
for policy in response.get("policies", []):
|
||||
if not self._is_customer_level_policy(policy):
|
||||
continue
|
||||
|
||||
setting = policy.get("setting", {})
|
||||
setting_type = setting.get("type", "").removeprefix("settings/")
|
||||
value = setting.get("value", {})
|
||||
|
||||
if setting_type == "workspace_marketplace.apps_access_options":
|
||||
self.policies.access_level = value.get("accessLevel")
|
||||
logger.debug(
|
||||
"Marketplace access level: "
|
||||
f"{self.policies.access_level}"
|
||||
)
|
||||
|
||||
request = service.policies().list_next(request, response)
|
||||
|
||||
except Exception as error:
|
||||
self._handle_api_error(
|
||||
error,
|
||||
"fetching Marketplace policies",
|
||||
self.provider.identity.customer_id,
|
||||
)
|
||||
fetch_succeeded = False
|
||||
break
|
||||
|
||||
self.policies_fetched = fetch_succeeded
|
||||
|
||||
logger.info(
|
||||
f"Marketplace policies fetched - "
|
||||
f"Access level: {self.policies.access_level}"
|
||||
)
|
||||
|
||||
except Exception as error:
|
||||
self._handle_api_error(
|
||||
error,
|
||||
"fetching Marketplace policies",
|
||||
self.provider.identity.customer_id,
|
||||
)
|
||||
self.policies_fetched = False
|
||||
|
||||
|
||||
class MarketplacePolicies(BaseModel):
|
||||
"""Model for domain-level Marketplace policy settings."""
|
||||
|
||||
# workspace_marketplace.apps_access_options
|
||||
access_level: Optional[str] = None
|
||||
@@ -0,0 +1,6 @@
|
||||
from prowler.providers.common.provider import Provider
|
||||
from prowler.providers.googleworkspace.services.sites.sites_service import (
|
||||
Sites,
|
||||
)
|
||||
|
||||
sites_client = Sites(Provider.get_global_provider())
|
||||
@@ -0,0 +1,88 @@
|
||||
from typing import Optional
|
||||
|
||||
from pydantic import BaseModel
|
||||
|
||||
from prowler.lib.logger import logger
|
||||
from prowler.providers.googleworkspace.lib.service.service import GoogleWorkspaceService
|
||||
|
||||
|
||||
class Sites(GoogleWorkspaceService):
|
||||
"""Google Workspace Sites service for auditing domain-level Sites policies.
|
||||
|
||||
Uses the Cloud Identity Policy API v1 to read the Sites service status
|
||||
configured in the Admin Console.
|
||||
"""
|
||||
|
||||
def __init__(self, provider):
|
||||
super().__init__(provider)
|
||||
self.policies = SitesPolicies()
|
||||
self.policies_fetched = False
|
||||
self._fetch_sites_policies()
|
||||
|
||||
def _fetch_sites_policies(self):
|
||||
"""Fetch Sites policies from the Cloud Identity Policy API v1."""
|
||||
logger.info("Sites - Fetching sites policies...")
|
||||
|
||||
try:
|
||||
service = self._build_service("cloudidentity", "v1")
|
||||
|
||||
if not service:
|
||||
logger.error("Failed to build Cloud Identity service")
|
||||
return
|
||||
|
||||
request = service.policies().list(
|
||||
pageSize=100,
|
||||
filter='setting.type.matches("sites.*")',
|
||||
)
|
||||
fetch_succeeded = True
|
||||
|
||||
while request is not None:
|
||||
try:
|
||||
response = request.execute()
|
||||
|
||||
for policy in response.get("policies", []):
|
||||
if not self._is_customer_level_policy(policy):
|
||||
continue
|
||||
|
||||
setting = policy.get("setting", {})
|
||||
setting_type = setting.get("type", "").removeprefix("settings/")
|
||||
value = setting.get("value", {})
|
||||
|
||||
if setting_type == "sites.service_status":
|
||||
self.policies.service_state = value.get("serviceState")
|
||||
logger.debug(
|
||||
"Sites service state: " f"{self.policies.service_state}"
|
||||
)
|
||||
|
||||
request = service.policies().list_next(request, response)
|
||||
|
||||
except Exception as error:
|
||||
self._handle_api_error(
|
||||
error,
|
||||
"fetching Sites policies",
|
||||
self.provider.identity.customer_id,
|
||||
)
|
||||
fetch_succeeded = False
|
||||
break
|
||||
|
||||
self.policies_fetched = fetch_succeeded
|
||||
|
||||
logger.info(
|
||||
f"Sites policies fetched - "
|
||||
f"Service state: {self.policies.service_state}"
|
||||
)
|
||||
|
||||
except Exception as error:
|
||||
self._handle_api_error(
|
||||
error,
|
||||
"fetching Sites policies",
|
||||
self.provider.identity.customer_id,
|
||||
)
|
||||
self.policies_fetched = False
|
||||
|
||||
|
||||
class SitesPolicies(BaseModel):
|
||||
"""Model for domain-level Sites policy settings."""
|
||||
|
||||
# sites.service_status
|
||||
service_state: Optional[str] = None
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
{
|
||||
"Provider": "googleworkspace",
|
||||
"CheckID": "sites_service_disabled",
|
||||
"CheckTitle": "Service status for Google Sites is set to off",
|
||||
"CheckType": [],
|
||||
"ServiceName": "sites",
|
||||
"SubServiceName": "",
|
||||
"ResourceIdTemplate": "",
|
||||
"Severity": "medium",
|
||||
"ResourceType": "NotDefined",
|
||||
"ResourceGroup": "collaboration",
|
||||
"Description": "The domain-wide Google Sites configuration has the service **disabled for all users**. Google Sites allows users to create internal and external websites, which may expose sensitive information or create unmanaged content outside the organization's control.",
|
||||
"Risk": "When Google Sites is enabled, users can create websites that may **inadvertently expose internal information** to external parties. These sites can be difficult to track and manage, creating potential **data leakage vectors** outside the organization's standard content management controls.",
|
||||
"RelatedUrl": "",
|
||||
"AdditionalURLs": [
|
||||
"https://support.google.com/a/answer/182442",
|
||||
"https://cloud.google.com/identity/docs/concepts/supported-policy-api-settings"
|
||||
],
|
||||
"Remediation": {
|
||||
"Code": {
|
||||
"CLI": "",
|
||||
"NativeIaC": "",
|
||||
"Other": "1. Sign in to the Google **Admin console** at https://admin.google.com\n2. Navigate to **Apps** > **Google Workspace** > **Sites**\n3. Click **Service status**\n4. Select **OFF for everyone**\n5. Click **Save**",
|
||||
"Terraform": ""
|
||||
},
|
||||
"Recommendation": {
|
||||
"Text": "Disable **Google Sites** for all users to reduce the organization's attack surface. If specific users require access, enable it by exception for those users or groups only.",
|
||||
"Url": "https://hub.prowler.com/check/sites_service_disabled"
|
||||
}
|
||||
},
|
||||
"Categories": [
|
||||
"trust-boundaries"
|
||||
],
|
||||
"DependsOn": [],
|
||||
"RelatedTo": [],
|
||||
"Notes": ""
|
||||
}
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
from typing import List
|
||||
|
||||
from prowler.lib.check.models import Check, CheckReportGoogleWorkspace
|
||||
from prowler.providers.googleworkspace.services.sites.sites_client import sites_client
|
||||
|
||||
|
||||
class sites_service_disabled(Check):
|
||||
"""Check that the Google Sites service is disabled for all users.
|
||||
|
||||
This check verifies that the domain-level policy disables the Google Sites
|
||||
service, reducing the organization's attack surface by preventing users
|
||||
from creating internal or external websites.
|
||||
"""
|
||||
|
||||
def execute(self) -> List[CheckReportGoogleWorkspace]:
|
||||
findings = []
|
||||
|
||||
if sites_client.policies_fetched:
|
||||
report = CheckReportGoogleWorkspace(
|
||||
metadata=self.metadata(),
|
||||
resource=sites_client.policies,
|
||||
resource_id="sitesPolicies",
|
||||
resource_name="Sites Policies",
|
||||
customer_id=sites_client.provider.identity.customer_id,
|
||||
)
|
||||
|
||||
service_state = sites_client.policies.service_state
|
||||
|
||||
if service_state == "DISABLED":
|
||||
report.status = "PASS"
|
||||
report.status_extended = (
|
||||
f"Google Sites service is disabled "
|
||||
f"in domain {sites_client.provider.identity.domain}."
|
||||
)
|
||||
else:
|
||||
report.status = "FAIL"
|
||||
if service_state is None:
|
||||
report.status_extended = (
|
||||
f"Google Sites service is not explicitly configured "
|
||||
f"in domain {sites_client.provider.identity.domain}. "
|
||||
f"The default is ON for everyone. Google Sites should be disabled."
|
||||
)
|
||||
else:
|
||||
report.status_extended = (
|
||||
f"Google Sites service is enabled "
|
||||
f"in domain {sites_client.provider.identity.domain}. "
|
||||
f"Google Sites should be disabled."
|
||||
)
|
||||
|
||||
findings.append(report)
|
||||
|
||||
return findings
|
||||
+128
@@ -0,0 +1,128 @@
|
||||
from unittest.mock import patch
|
||||
|
||||
from prowler.providers.googleworkspace.services.additionalservices.additionalservices_service import (
|
||||
AdditionalServicesPolicies,
|
||||
)
|
||||
from tests.providers.googleworkspace.googleworkspace_fixtures import (
|
||||
CUSTOMER_ID,
|
||||
set_mocked_googleworkspace_provider,
|
||||
)
|
||||
|
||||
|
||||
class TestAdditionalServicesExternalGroupsDisabled:
|
||||
def test_pass_groups_disabled(self):
|
||||
"""Test PASS when external Google Groups access is disabled"""
|
||||
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.additionalservices.additionalservices_external_groups_disabled.additionalservices_external_groups_disabled.additionalservices_client"
|
||||
) as mock_client,
|
||||
):
|
||||
from prowler.providers.googleworkspace.services.additionalservices.additionalservices_external_groups_disabled.additionalservices_external_groups_disabled import (
|
||||
additionalservices_external_groups_disabled,
|
||||
)
|
||||
|
||||
mock_client.provider = mock_provider
|
||||
mock_client.policies_fetched = True
|
||||
mock_client.policies = AdditionalServicesPolicies(
|
||||
groups_service_state="DISABLED"
|
||||
)
|
||||
|
||||
check = additionalservices_external_groups_disabled()
|
||||
findings = check.execute()
|
||||
|
||||
assert len(findings) == 1
|
||||
assert findings[0].status == "PASS"
|
||||
assert "disabled" in findings[0].status_extended
|
||||
assert findings[0].resource_name == "Additional Services Policies"
|
||||
assert findings[0].resource_id == "additionalServicesPolicies"
|
||||
assert findings[0].customer_id == CUSTOMER_ID
|
||||
|
||||
def test_fail_groups_enabled(self):
|
||||
"""Test FAIL when external Google Groups access is enabled"""
|
||||
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.additionalservices.additionalservices_external_groups_disabled.additionalservices_external_groups_disabled.additionalservices_client"
|
||||
) as mock_client,
|
||||
):
|
||||
from prowler.providers.googleworkspace.services.additionalservices.additionalservices_external_groups_disabled.additionalservices_external_groups_disabled import (
|
||||
additionalservices_external_groups_disabled,
|
||||
)
|
||||
|
||||
mock_client.provider = mock_provider
|
||||
mock_client.policies_fetched = True
|
||||
mock_client.policies = AdditionalServicesPolicies(
|
||||
groups_service_state="ENABLED"
|
||||
)
|
||||
|
||||
check = additionalservices_external_groups_disabled()
|
||||
findings = check.execute()
|
||||
|
||||
assert len(findings) == 1
|
||||
assert findings[0].status == "FAIL"
|
||||
assert "enabled" in findings[0].status_extended
|
||||
|
||||
def test_fail_no_policy_set(self):
|
||||
"""Test FAIL when no explicit policy is set (None) - Google default is ON (insecure)"""
|
||||
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.additionalservices.additionalservices_external_groups_disabled.additionalservices_external_groups_disabled.additionalservices_client"
|
||||
) as mock_client,
|
||||
):
|
||||
from prowler.providers.googleworkspace.services.additionalservices.additionalservices_external_groups_disabled.additionalservices_external_groups_disabled import (
|
||||
additionalservices_external_groups_disabled,
|
||||
)
|
||||
|
||||
mock_client.provider = mock_provider
|
||||
mock_client.policies_fetched = True
|
||||
mock_client.policies = AdditionalServicesPolicies(groups_service_state=None)
|
||||
|
||||
check = additionalservices_external_groups_disabled()
|
||||
findings = check.execute()
|
||||
|
||||
assert len(findings) == 1
|
||||
assert findings[0].status == "FAIL"
|
||||
assert "not explicitly configured" 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()
|
||||
|
||||
with (
|
||||
patch(
|
||||
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||
return_value=mock_provider,
|
||||
),
|
||||
patch(
|
||||
"prowler.providers.googleworkspace.services.additionalservices.additionalservices_external_groups_disabled.additionalservices_external_groups_disabled.additionalservices_client"
|
||||
) as mock_client,
|
||||
):
|
||||
from prowler.providers.googleworkspace.services.additionalservices.additionalservices_external_groups_disabled.additionalservices_external_groups_disabled import (
|
||||
additionalservices_external_groups_disabled,
|
||||
)
|
||||
|
||||
mock_client.provider = mock_provider
|
||||
mock_client.policies_fetched = False
|
||||
mock_client.policies = AdditionalServicesPolicies()
|
||||
|
||||
check = additionalservices_external_groups_disabled()
|
||||
findings = check.execute()
|
||||
|
||||
assert len(findings) == 0
|
||||
+234
@@ -0,0 +1,234 @@
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
||||
from tests.providers.googleworkspace.googleworkspace_fixtures import (
|
||||
set_mocked_googleworkspace_provider,
|
||||
)
|
||||
|
||||
|
||||
class TestAdditionalServicesService:
|
||||
def test_fetch_policies_groups_off(self):
|
||||
"""Test fetching Additional Services policy with Groups OFF"""
|
||||
mock_provider = set_mocked_googleworkspace_provider()
|
||||
mock_provider.audit_config = {}
|
||||
mock_provider.fixer_config = {}
|
||||
mock_credentials = MagicMock()
|
||||
mock_session = MagicMock()
|
||||
mock_session.credentials = mock_credentials
|
||||
mock_provider.session = mock_session
|
||||
|
||||
mock_service = MagicMock()
|
||||
mock_policies_list = MagicMock()
|
||||
mock_policies_list.execute.return_value = {
|
||||
"policies": [
|
||||
{
|
||||
"setting": {
|
||||
"type": "settings/groups.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.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_groups_on(self):
|
||||
"""Test fetching Additional Services policy with Groups 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": [
|
||||
{
|
||||
"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 == "ENABLED"
|
||||
|
||||
def test_fetch_policies_empty_response(self):
|
||||
"""Test handling empty policies response"""
|
||||
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": []}
|
||||
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 is None
|
||||
|
||||
def test_fetch_policies_api_error(self):
|
||||
"""Test handling of API errors during policy fetch"""
|
||||
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_service.policies().list.side_effect = Exception("API Error")
|
||||
|
||||
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 False
|
||||
assert additional_services.policies.groups_service_state is None
|
||||
|
||||
def test_fetch_policies_build_service_returns_none(self):
|
||||
"""Test early return when _build_service fails to construct the client"""
|
||||
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
|
||||
|
||||
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=None,
|
||||
),
|
||||
):
|
||||
from prowler.providers.googleworkspace.services.additionalservices.additionalservices_service import (
|
||||
AdditionalServices,
|
||||
)
|
||||
|
||||
additional_services = AdditionalServices(mock_provider)
|
||||
|
||||
assert additional_services.policies_fetched is False
|
||||
assert additional_services.policies.groups_service_state is None
|
||||
|
||||
def test_fetch_policies_execute_raises(self):
|
||||
"""Test inner except handler when request.execute() raises during pagination"""
|
||||
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_request = MagicMock()
|
||||
mock_request.execute.side_effect = Exception("Execute failed")
|
||||
mock_service.policies().list.return_value = mock_request
|
||||
|
||||
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 False
|
||||
assert additional_services.policies.groups_service_state is None
|
||||
|
||||
def test_additional_services_policies_model(self):
|
||||
"""Test AdditionalServicesPolicies Pydantic model"""
|
||||
from prowler.providers.googleworkspace.services.additionalservices.additionalservices_service import (
|
||||
AdditionalServicesPolicies,
|
||||
)
|
||||
|
||||
policies = AdditionalServicesPolicies(groups_service_state="DISABLED")
|
||||
|
||||
assert policies.groups_service_state == "DISABLED"
|
||||
+152
@@ -0,0 +1,152 @@
|
||||
from unittest.mock import patch
|
||||
|
||||
from prowler.providers.googleworkspace.services.marketplace.marketplace_service import (
|
||||
MarketplacePolicies,
|
||||
)
|
||||
from tests.providers.googleworkspace.googleworkspace_fixtures import (
|
||||
CUSTOMER_ID,
|
||||
set_mocked_googleworkspace_provider,
|
||||
)
|
||||
|
||||
|
||||
class TestMarketplaceAppsAccessRestricted:
|
||||
def test_pass_allow_listed_apps(self):
|
||||
"""Test PASS when Marketplace access is restricted to admin-approved apps"""
|
||||
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.marketplace.marketplace_apps_access_restricted.marketplace_apps_access_restricted.marketplace_client"
|
||||
) as mock_client,
|
||||
):
|
||||
from prowler.providers.googleworkspace.services.marketplace.marketplace_apps_access_restricted.marketplace_apps_access_restricted import (
|
||||
marketplace_apps_access_restricted,
|
||||
)
|
||||
|
||||
mock_client.provider = mock_provider
|
||||
mock_client.policies_fetched = True
|
||||
mock_client.policies = MarketplacePolicies(access_level="ALLOW_LISTED_APPS")
|
||||
|
||||
check = marketplace_apps_access_restricted()
|
||||
findings = check.execute()
|
||||
|
||||
assert len(findings) == 1
|
||||
assert findings[0].status == "PASS"
|
||||
assert "restricted" in findings[0].status_extended
|
||||
assert findings[0].resource_name == "Marketplace Policies"
|
||||
assert findings[0].resource_id == "marketplacePolicies"
|
||||
assert findings[0].customer_id == CUSTOMER_ID
|
||||
|
||||
def test_pass_allow_none(self):
|
||||
"""Test PASS when Marketplace app installation is fully blocked"""
|
||||
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.marketplace.marketplace_apps_access_restricted.marketplace_apps_access_restricted.marketplace_client"
|
||||
) as mock_client,
|
||||
):
|
||||
from prowler.providers.googleworkspace.services.marketplace.marketplace_apps_access_restricted.marketplace_apps_access_restricted import (
|
||||
marketplace_apps_access_restricted,
|
||||
)
|
||||
|
||||
mock_client.provider = mock_provider
|
||||
mock_client.policies_fetched = True
|
||||
mock_client.policies = MarketplacePolicies(access_level="ALLOW_NONE")
|
||||
|
||||
check = marketplace_apps_access_restricted()
|
||||
findings = check.execute()
|
||||
|
||||
assert len(findings) == 1
|
||||
assert findings[0].status == "PASS"
|
||||
assert "blocked" in findings[0].status_extended
|
||||
|
||||
def test_fail_allow_all(self):
|
||||
"""Test FAIL when Marketplace allows all apps"""
|
||||
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.marketplace.marketplace_apps_access_restricted.marketplace_apps_access_restricted.marketplace_client"
|
||||
) as mock_client,
|
||||
):
|
||||
from prowler.providers.googleworkspace.services.marketplace.marketplace_apps_access_restricted.marketplace_apps_access_restricted import (
|
||||
marketplace_apps_access_restricted,
|
||||
)
|
||||
|
||||
mock_client.provider = mock_provider
|
||||
mock_client.policies_fetched = True
|
||||
mock_client.policies = MarketplacePolicies(access_level="ALLOW_ALL")
|
||||
|
||||
check = marketplace_apps_access_restricted()
|
||||
findings = check.execute()
|
||||
|
||||
assert len(findings) == 1
|
||||
assert findings[0].status == "FAIL"
|
||||
assert "any app" in findings[0].status_extended
|
||||
|
||||
def test_fail_no_policy_set(self):
|
||||
"""Test FAIL when no explicit policy is set (None) - Google default is ALLOW_ALL (insecure)"""
|
||||
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.marketplace.marketplace_apps_access_restricted.marketplace_apps_access_restricted.marketplace_client"
|
||||
) as mock_client,
|
||||
):
|
||||
from prowler.providers.googleworkspace.services.marketplace.marketplace_apps_access_restricted.marketplace_apps_access_restricted import (
|
||||
marketplace_apps_access_restricted,
|
||||
)
|
||||
|
||||
mock_client.provider = mock_provider
|
||||
mock_client.policies_fetched = True
|
||||
mock_client.policies = MarketplacePolicies(access_level=None)
|
||||
|
||||
check = marketplace_apps_access_restricted()
|
||||
findings = check.execute()
|
||||
|
||||
assert len(findings) == 1
|
||||
assert findings[0].status == "FAIL"
|
||||
assert "not explicitly configured" 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()
|
||||
|
||||
with (
|
||||
patch(
|
||||
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||
return_value=mock_provider,
|
||||
),
|
||||
patch(
|
||||
"prowler.providers.googleworkspace.services.marketplace.marketplace_apps_access_restricted.marketplace_apps_access_restricted.marketplace_client"
|
||||
) as mock_client,
|
||||
):
|
||||
from prowler.providers.googleworkspace.services.marketplace.marketplace_apps_access_restricted.marketplace_apps_access_restricted import (
|
||||
marketplace_apps_access_restricted,
|
||||
)
|
||||
|
||||
mock_client.provider = mock_provider
|
||||
mock_client.policies_fetched = False
|
||||
mock_client.policies = MarketplacePolicies()
|
||||
|
||||
check = marketplace_apps_access_restricted()
|
||||
findings = check.execute()
|
||||
|
||||
assert len(findings) == 0
|
||||
@@ -0,0 +1,279 @@
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
||||
from tests.providers.googleworkspace.googleworkspace_fixtures import (
|
||||
set_mocked_googleworkspace_provider,
|
||||
)
|
||||
|
||||
|
||||
class TestMarketplaceService:
|
||||
def test_fetch_policies_allow_all(self):
|
||||
"""Test fetching Marketplace policy with ALLOW_ALL access level"""
|
||||
mock_provider = set_mocked_googleworkspace_provider()
|
||||
mock_provider.audit_config = {}
|
||||
mock_provider.fixer_config = {}
|
||||
mock_credentials = MagicMock()
|
||||
mock_session = MagicMock()
|
||||
mock_session.credentials = mock_credentials
|
||||
mock_provider.session = mock_session
|
||||
|
||||
mock_service = MagicMock()
|
||||
mock_policies_list = MagicMock()
|
||||
mock_policies_list.execute.return_value = {
|
||||
"policies": [
|
||||
{
|
||||
"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_ALL"
|
||||
|
||||
def test_fetch_policies_allow_listed_apps(self):
|
||||
"""Test fetching Marketplace policy with ALLOW_LISTED_APPS access level"""
|
||||
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": [
|
||||
{
|
||||
"setting": {
|
||||
"type": "settings/workspace_marketplace.apps_access_options",
|
||||
"value": {
|
||||
"accessLevel": "ALLOW_LISTED_APPS",
|
||||
},
|
||||
}
|
||||
},
|
||||
]
|
||||
}
|
||||
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_allow_none(self):
|
||||
"""Test fetching Marketplace policy with ALLOW_NONE access level"""
|
||||
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": [
|
||||
{
|
||||
"setting": {
|
||||
"type": "settings/workspace_marketplace.apps_access_options",
|
||||
"value": {
|
||||
"accessLevel": "ALLOW_NONE",
|
||||
},
|
||||
}
|
||||
},
|
||||
]
|
||||
}
|
||||
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_NONE"
|
||||
|
||||
def test_fetch_policies_empty_response(self):
|
||||
"""Test handling empty policies response"""
|
||||
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": []}
|
||||
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 is None
|
||||
|
||||
def test_fetch_policies_api_error(self):
|
||||
"""Test handling of API errors during policy fetch"""
|
||||
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_service.policies().list.side_effect = Exception("API Error")
|
||||
|
||||
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 False
|
||||
assert marketplace.policies.access_level is None
|
||||
|
||||
def test_fetch_policies_build_service_returns_none(self):
|
||||
"""Test early return when _build_service fails to construct the client"""
|
||||
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
|
||||
|
||||
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=None,
|
||||
),
|
||||
):
|
||||
from prowler.providers.googleworkspace.services.marketplace.marketplace_service import (
|
||||
Marketplace,
|
||||
)
|
||||
|
||||
marketplace = Marketplace(mock_provider)
|
||||
|
||||
assert marketplace.policies_fetched is False
|
||||
assert marketplace.policies.access_level is None
|
||||
|
||||
def test_fetch_policies_execute_raises(self):
|
||||
"""Test inner except handler when request.execute() raises during pagination"""
|
||||
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_request = MagicMock()
|
||||
mock_request.execute.side_effect = Exception("Execute failed")
|
||||
mock_service.policies().list.return_value = mock_request
|
||||
|
||||
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 False
|
||||
assert marketplace.policies.access_level is None
|
||||
|
||||
def test_marketplace_policies_model(self):
|
||||
"""Test MarketplacePolicies Pydantic model"""
|
||||
from prowler.providers.googleworkspace.services.marketplace.marketplace_service import (
|
||||
MarketplacePolicies,
|
||||
)
|
||||
|
||||
policies = MarketplacePolicies(access_level="ALLOW_LISTED_APPS")
|
||||
|
||||
assert policies.access_level == "ALLOW_LISTED_APPS"
|
||||
+124
@@ -0,0 +1,124 @@
|
||||
from unittest.mock import patch
|
||||
|
||||
from prowler.providers.googleworkspace.services.sites.sites_service import (
|
||||
SitesPolicies,
|
||||
)
|
||||
from tests.providers.googleworkspace.googleworkspace_fixtures import (
|
||||
CUSTOMER_ID,
|
||||
set_mocked_googleworkspace_provider,
|
||||
)
|
||||
|
||||
|
||||
class TestSitesServiceDisabled:
|
||||
def test_pass_service_disabled(self):
|
||||
"""Test PASS when Sites service is disabled (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.sites.sites_service_disabled.sites_service_disabled.sites_client"
|
||||
) as mock_client,
|
||||
):
|
||||
from prowler.providers.googleworkspace.services.sites.sites_service_disabled.sites_service_disabled import (
|
||||
sites_service_disabled,
|
||||
)
|
||||
|
||||
mock_client.provider = mock_provider
|
||||
mock_client.policies_fetched = True
|
||||
mock_client.policies = SitesPolicies(service_state="DISABLED")
|
||||
|
||||
check = sites_service_disabled()
|
||||
findings = check.execute()
|
||||
|
||||
assert len(findings) == 1
|
||||
assert findings[0].status == "PASS"
|
||||
assert "disabled" in findings[0].status_extended
|
||||
assert findings[0].resource_name == "Sites Policies"
|
||||
assert findings[0].resource_id == "sitesPolicies"
|
||||
assert findings[0].customer_id == CUSTOMER_ID
|
||||
|
||||
def test_fail_service_enabled(self):
|
||||
"""Test FAIL when Sites service is enabled (ON 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.sites.sites_service_disabled.sites_service_disabled.sites_client"
|
||||
) as mock_client,
|
||||
):
|
||||
from prowler.providers.googleworkspace.services.sites.sites_service_disabled.sites_service_disabled import (
|
||||
sites_service_disabled,
|
||||
)
|
||||
|
||||
mock_client.provider = mock_provider
|
||||
mock_client.policies_fetched = True
|
||||
mock_client.policies = SitesPolicies(service_state="ENABLED")
|
||||
|
||||
check = sites_service_disabled()
|
||||
findings = check.execute()
|
||||
|
||||
assert len(findings) == 1
|
||||
assert findings[0].status == "FAIL"
|
||||
assert "enabled" in findings[0].status_extended
|
||||
|
||||
def test_fail_no_policy_set(self):
|
||||
"""Test FAIL when no explicit policy is set (None) - Google default is ON (insecure)"""
|
||||
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.sites.sites_service_disabled.sites_service_disabled.sites_client"
|
||||
) as mock_client,
|
||||
):
|
||||
from prowler.providers.googleworkspace.services.sites.sites_service_disabled.sites_service_disabled import (
|
||||
sites_service_disabled,
|
||||
)
|
||||
|
||||
mock_client.provider = mock_provider
|
||||
mock_client.policies_fetched = True
|
||||
mock_client.policies = SitesPolicies(service_state=None)
|
||||
|
||||
check = sites_service_disabled()
|
||||
findings = check.execute()
|
||||
|
||||
assert len(findings) == 1
|
||||
assert findings[0].status == "FAIL"
|
||||
assert "not explicitly configured" 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()
|
||||
|
||||
with (
|
||||
patch(
|
||||
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||
return_value=mock_provider,
|
||||
),
|
||||
patch(
|
||||
"prowler.providers.googleworkspace.services.sites.sites_service_disabled.sites_service_disabled.sites_client"
|
||||
) as mock_client,
|
||||
):
|
||||
from prowler.providers.googleworkspace.services.sites.sites_service_disabled.sites_service_disabled import (
|
||||
sites_service_disabled,
|
||||
)
|
||||
|
||||
mock_client.provider = mock_provider
|
||||
mock_client.policies_fetched = False
|
||||
mock_client.policies = SitesPolicies()
|
||||
|
||||
check = sites_service_disabled()
|
||||
findings = check.execute()
|
||||
|
||||
assert len(findings) == 0
|
||||
@@ -0,0 +1,234 @@
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
||||
from tests.providers.googleworkspace.googleworkspace_fixtures import (
|
||||
set_mocked_googleworkspace_provider,
|
||||
)
|
||||
|
||||
|
||||
class TestSitesService:
|
||||
def test_fetch_policies_service_status_off(self):
|
||||
"""Test fetching Sites policy with service status OFF"""
|
||||
mock_provider = set_mocked_googleworkspace_provider()
|
||||
mock_provider.audit_config = {}
|
||||
mock_provider.fixer_config = {}
|
||||
mock_credentials = MagicMock()
|
||||
mock_session = MagicMock()
|
||||
mock_session.credentials = mock_credentials
|
||||
mock_provider.session = mock_session
|
||||
|
||||
mock_service = MagicMock()
|
||||
mock_policies_list = MagicMock()
|
||||
mock_policies_list.execute.return_value = {
|
||||
"policies": [
|
||||
{
|
||||
"setting": {
|
||||
"type": "settings/sites.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.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_service_status_on(self):
|
||||
"""Test fetching Sites policy with service status 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": [
|
||||
{
|
||||
"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 == "ENABLED"
|
||||
|
||||
def test_fetch_policies_empty_response(self):
|
||||
"""Test handling empty policies response"""
|
||||
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": []}
|
||||
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 is None
|
||||
|
||||
def test_fetch_policies_api_error(self):
|
||||
"""Test handling of API errors during policy fetch"""
|
||||
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_service.policies().list.side_effect = Exception("API Error")
|
||||
|
||||
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 False
|
||||
assert sites.policies.service_state is None
|
||||
|
||||
def test_fetch_policies_build_service_returns_none(self):
|
||||
"""Test early return when _build_service fails to construct the client"""
|
||||
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
|
||||
|
||||
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=None,
|
||||
),
|
||||
):
|
||||
from prowler.providers.googleworkspace.services.sites.sites_service import (
|
||||
Sites,
|
||||
)
|
||||
|
||||
sites = Sites(mock_provider)
|
||||
|
||||
assert sites.policies_fetched is False
|
||||
assert sites.policies.service_state is None
|
||||
|
||||
def test_fetch_policies_execute_raises(self):
|
||||
"""Test inner except handler when request.execute() raises during pagination"""
|
||||
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_request = MagicMock()
|
||||
mock_request.execute.side_effect = Exception("Execute failed")
|
||||
mock_service.policies().list.return_value = mock_request
|
||||
|
||||
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 False
|
||||
assert sites.policies.service_state is None
|
||||
|
||||
def test_sites_policies_model(self):
|
||||
"""Test SitesPolicies Pydantic model"""
|
||||
from prowler.providers.googleworkspace.services.sites.sites_service import (
|
||||
SitesPolicies,
|
||||
)
|
||||
|
||||
policies = SitesPolicies(service_state="DISABLED")
|
||||
|
||||
assert policies.service_state == "DISABLED"
|
||||
Reference in New Issue
Block a user