mirror of
https://github.com/prowler-cloud/prowler.git
synced 2026-10-09 21:14:22 +00:00
feat(sdk): check Supabase organization member MFA
This commit is contained in:
11 files changed
+301
No files matched your search
+101
@@ -0,0 +1,101 @@
|
||||
from unittest import mock
|
||||
|
||||
from prowler.providers.supabase.services.organizations.organizations_service import (
|
||||
SupabaseOrganizationMember,
|
||||
)
|
||||
from tests.providers.supabase.supabase_fixtures import (
|
||||
ORGANIZATION_NAME,
|
||||
ORGANIZATION_SLUG,
|
||||
USER_ID,
|
||||
set_mocked_supabase_provider,
|
||||
)
|
||||
|
||||
|
||||
class Test_organizations_member_mfa_enabled:
|
||||
def _execute(self, members):
|
||||
organizations_client = mock.MagicMock()
|
||||
organizations_client.members = members
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||
return_value=set_mocked_supabase_provider(),
|
||||
),
|
||||
mock.patch(
|
||||
"prowler.providers.supabase.services.organizations.organizations_member_mfa_enabled.organizations_member_mfa_enabled.organizations_client",
|
||||
new=organizations_client,
|
||||
),
|
||||
):
|
||||
from prowler.providers.supabase.services.organizations.organizations_member_mfa_enabled.organizations_member_mfa_enabled import (
|
||||
organizations_member_mfa_enabled,
|
||||
)
|
||||
|
||||
return organizations_member_mfa_enabled().execute()
|
||||
|
||||
def test_no_members(self):
|
||||
assert self._execute({}) == []
|
||||
|
||||
def test_member_with_mfa_passes_without_email(self):
|
||||
member = SupabaseOrganizationMember(
|
||||
id=USER_ID,
|
||||
name=f"member {USER_ID}",
|
||||
organization_slug=ORGANIZATION_SLUG,
|
||||
organization_name=ORGANIZATION_NAME,
|
||||
mfa_enabled=True,
|
||||
)
|
||||
|
||||
result = self._execute({f"{ORGANIZATION_SLUG}:{USER_ID}": member})
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "PASS"
|
||||
assert result[0].resource_id == USER_ID
|
||||
assert result[0].organization_slug == ORGANIZATION_SLUG
|
||||
assert result[0].status_extended == (
|
||||
f"Supabase organization {ORGANIZATION_SLUG} member {USER_ID} has MFA enabled."
|
||||
)
|
||||
|
||||
def test_member_without_mfa_fails(self):
|
||||
member = SupabaseOrganizationMember(
|
||||
id=USER_ID,
|
||||
name=f"member {USER_ID}",
|
||||
organization_slug=ORGANIZATION_SLUG,
|
||||
organization_name=ORGANIZATION_NAME,
|
||||
mfa_enabled=False,
|
||||
)
|
||||
|
||||
result = self._execute({f"{ORGANIZATION_SLUG}:{USER_ID}": member})
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert result[0].resource_id == USER_ID
|
||||
assert result[0].status_extended == (
|
||||
f"Supabase organization {ORGANIZATION_SLUG} member {USER_ID} does not have MFA enabled."
|
||||
)
|
||||
|
||||
def test_multiple_members_return_independent_pass_and_fail_findings(self):
|
||||
enabled_member = SupabaseOrganizationMember(
|
||||
id="enabled-user",
|
||||
name="member enabled-user",
|
||||
organization_slug=ORGANIZATION_SLUG,
|
||||
organization_name=ORGANIZATION_NAME,
|
||||
mfa_enabled=True,
|
||||
)
|
||||
disabled_member = SupabaseOrganizationMember(
|
||||
id="disabled-user",
|
||||
name="member disabled-user",
|
||||
organization_slug=ORGANIZATION_SLUG,
|
||||
organization_name=ORGANIZATION_NAME,
|
||||
mfa_enabled=False,
|
||||
)
|
||||
|
||||
result = self._execute(
|
||||
{
|
||||
f"{ORGANIZATION_SLUG}:enabled-user": enabled_member,
|
||||
f"{ORGANIZATION_SLUG}:disabled-user": disabled_member,
|
||||
}
|
||||
)
|
||||
|
||||
assert [(finding.resource_id, finding.status) for finding in result] == [
|
||||
("enabled-user", "PASS"),
|
||||
("disabled-user", "FAIL"),
|
||||
]
|
||||
@@ -1,11 +1,14 @@
|
||||
import os
|
||||
from argparse import Namespace
|
||||
from pathlib import Path
|
||||
from unittest import mock
|
||||
|
||||
import pytest
|
||||
|
||||
from prowler.config.config import Provider as ProviderName
|
||||
from prowler.lib.check.models import CheckReportSupabase
|
||||
from prowler.lib.cli.parser import ProwlerArgumentParser
|
||||
from prowler.lib.outputs.finding import Finding
|
||||
from prowler.lib.outputs.html.html import HTML
|
||||
from prowler.providers.common.provider import Provider
|
||||
from prowler.providers.supabase.exceptions.exceptions import (
|
||||
@@ -15,12 +18,16 @@ from prowler.providers.supabase.exceptions.exceptions import (
|
||||
SupabaseRateLimitError,
|
||||
)
|
||||
from prowler.providers.supabase.models import SupabaseOrganization, SupabaseSession
|
||||
from prowler.providers.supabase.services.organizations.organizations_service import (
|
||||
SupabaseOrganizationMember,
|
||||
)
|
||||
from prowler.providers.supabase.supabase_provider import SupabaseProvider
|
||||
from tests.providers.supabase.supabase_fixtures import (
|
||||
ACCESS_TOKEN,
|
||||
ORGANIZATION_ID,
|
||||
ORGANIZATION_NAME,
|
||||
ORGANIZATION_SLUG,
|
||||
USER_ID,
|
||||
)
|
||||
|
||||
|
||||
@@ -149,6 +156,37 @@ class TestSupabaseProviderOutputHooks:
|
||||
"region": "global",
|
||||
}
|
||||
|
||||
def test_finding_output_pipeline_uses_supabase_fields(self):
|
||||
provider = SupabaseProvider.__new__(SupabaseProvider)
|
||||
provider._identity = mock.MagicMock(organizations=[])
|
||||
member = SupabaseOrganizationMember(
|
||||
id=USER_ID,
|
||||
name=f"member {USER_ID}",
|
||||
organization_slug=ORGANIZATION_SLUG,
|
||||
organization_name=ORGANIZATION_NAME,
|
||||
mfa_enabled=False,
|
||||
)
|
||||
metadata = Path(
|
||||
"prowler/providers/supabase/services/organizations/"
|
||||
"organizations_member_mfa_enabled/"
|
||||
"organizations_member_mfa_enabled.metadata.json"
|
||||
).read_text()
|
||||
check_output = CheckReportSupabase(metadata=metadata, resource=member)
|
||||
check_output.status = "FAIL"
|
||||
check_output.status_extended = "Member does not have MFA enabled."
|
||||
|
||||
finding = Finding.generate_output(
|
||||
provider, check_output, Namespace(unix_timestamp=False)
|
||||
)
|
||||
|
||||
assert finding.provider == "supabase"
|
||||
assert finding.account_uid == ORGANIZATION_SLUG
|
||||
assert finding.account_name == ORGANIZATION_NAME
|
||||
assert finding.resource_name == f"member {USER_ID}"
|
||||
assert finding.resource_uid == USER_ID
|
||||
assert finding.region == "global"
|
||||
assert finding.auth_method == "personal_access_token"
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("output_filename", "expected"),
|
||||
[
|
||||
|
||||
Reference in new issue
Block a user