mirror of
https://github.com/prowler-cloud/prowler.git
synced 2026-06-10 21:42:29 +00:00
feat: added testing
Added testing classes for provider, new service and check and corrected minor issues.
This commit is contained in:
@@ -0,0 +1,117 @@
|
||||
from prowler.exceptions.exceptions import ProwlerException
|
||||
|
||||
|
||||
# Exceptions codes from 5000 to 5999 are reserved for GitHub exceptions
|
||||
class GitHubBaseException(ProwlerException):
|
||||
"""Base class for GitHub Errors."""
|
||||
|
||||
GITHUB_ERROR_CODES = {
|
||||
(2000, "GitHubEnvironmentVariableError"): {
|
||||
"message": "GitHub environment variable error",
|
||||
"remediation": "Check the GitHub environment variables and ensure they are properly set.",
|
||||
},
|
||||
(2001, "GitHubInvalidTokenError"): {
|
||||
"message": "GitHub token provided is not valid",
|
||||
"remediation": "Check the GitHub token and ensure it is valid.",
|
||||
},
|
||||
(2002, "GitHubSetUpIdentityError"): {
|
||||
"message": "GitHub identity setup error related with credentials",
|
||||
"remediation": "Check credentials and ensure they are properly set up for GitHub and the identity provider.",
|
||||
},
|
||||
(2003, "GitHubNoAuthenticationMethodError"): {
|
||||
"message": "No GitHub authentication method found",
|
||||
"remediation": "Check that any authentication method is properly set up for GitHub.",
|
||||
},
|
||||
(2006, "GitHubArgumentTypeValidationError"): {
|
||||
"message": "GitHub argument type validation error",
|
||||
"remediation": "Check the provided argument types specific to GitHub and ensure they meet the required format.",
|
||||
},
|
||||
(2010, "GitHubHTTPResponseError"): {
|
||||
"message": "Error in HTTP response from GitHub",
|
||||
"remediation": "",
|
||||
},
|
||||
(2014, "GitHubClientAuthenticationError"): {
|
||||
"message": "Error in client authentication",
|
||||
"remediation": "Check the client authentication and ensure it is properly set up.",
|
||||
},
|
||||
(2015, "GitHubSetUpSessionError"): {
|
||||
"message": "Error setting up session",
|
||||
"remediation": "Check the session setup and ensure it is properly set up.",
|
||||
},
|
||||
}
|
||||
|
||||
def __init__(self, code, file=None, original_exception=None, message=None):
|
||||
provider = "GitHub"
|
||||
error_info = self.GITHUB_ERROR_CODES.get((code, self.__class__.__name__))
|
||||
if message:
|
||||
error_info["message"] = message
|
||||
super().__init__(
|
||||
code=code,
|
||||
source=provider,
|
||||
file=file,
|
||||
original_exception=original_exception,
|
||||
error_info=error_info,
|
||||
)
|
||||
|
||||
|
||||
class GitHubCredentialsError(GitHubBaseException):
|
||||
"""Base class for GitHub credentials errors."""
|
||||
|
||||
def __init__(self, code, file=None, original_exception=None, message=None):
|
||||
super().__init__(code, file, original_exception, message)
|
||||
|
||||
|
||||
class GitHubEnvironmentVariableError(GitHubCredentialsError):
|
||||
def __init__(self, file=None, original_exception=None, message=None):
|
||||
super().__init__(
|
||||
2000, file=file, original_exception=original_exception, message=message
|
||||
)
|
||||
|
||||
|
||||
class GitHubInvalidTokenError(GitHubCredentialsError):
|
||||
def __init__(self, file=None, original_exception=None, message=None):
|
||||
super().__init__(
|
||||
2001, file=file, original_exception=original_exception, message=message
|
||||
)
|
||||
|
||||
|
||||
class GitHubSetUpIdentityError(GitHubCredentialsError):
|
||||
def __init__(self, file=None, original_exception=None, message=None):
|
||||
super().__init__(
|
||||
2002, file=file, original_exception=original_exception, message=message
|
||||
)
|
||||
|
||||
|
||||
class GitHubNoAuthenticationMethodError(GitHubCredentialsError):
|
||||
def __init__(self, file=None, original_exception=None, message=None):
|
||||
super().__init__(
|
||||
2003, file=file, original_exception=original_exception, message=message
|
||||
)
|
||||
|
||||
|
||||
class GitHubArgumentTypeValidationError(GitHubBaseException):
|
||||
def __init__(self, file=None, original_exception=None, message=None):
|
||||
super().__init__(
|
||||
2006, file=file, original_exception=original_exception, message=message
|
||||
)
|
||||
|
||||
|
||||
class GitHubHTTPResponseError(GitHubBaseException):
|
||||
def __init__(self, file=None, original_exception=None, message=None):
|
||||
super().__init__(
|
||||
2010, file=file, original_exception=original_exception, message=message
|
||||
)
|
||||
|
||||
|
||||
class GitHubClientAuthenticationError(GitHubCredentialsError):
|
||||
def __init__(self, file=None, original_exception=None, message=None):
|
||||
super().__init__(
|
||||
2014, file=file, original_exception=original_exception, message=message
|
||||
)
|
||||
|
||||
|
||||
class GitHubSetUpSessionError(GitHubCredentialsError):
|
||||
def __init__(self, file=None, original_exception=None, message=None):
|
||||
super().__init__(
|
||||
2015, file=file, original_exception=original_exception, message=message
|
||||
)
|
||||
@@ -11,7 +11,7 @@ from prowler.lib.logger import logger
|
||||
from prowler.lib.mutelist.mutelist import Mutelist
|
||||
from prowler.providers.common.models import Audit_Metadata
|
||||
from prowler.providers.common.provider import Provider
|
||||
from prowler.providers.github.lib.mutelist.mutelist import GitHubMutelist
|
||||
from prowler.providers.github.lib.mutelist.mutelist import GithubMutelist
|
||||
from prowler.providers.github.models import GithubIdentityInfo, GithubSession
|
||||
|
||||
|
||||
@@ -70,13 +70,13 @@ class GithubProvider(Provider):
|
||||
|
||||
# Mutelist
|
||||
if mutelist_content:
|
||||
self._mutelist = GitHubMutelist(
|
||||
self._mutelist = GithubMutelist(
|
||||
mutelist_content=mutelist_content,
|
||||
)
|
||||
else:
|
||||
if not mutelist_path:
|
||||
mutelist_path = get_default_mute_file_path(self.type)
|
||||
self._mutelist = GitHubMutelist(
|
||||
self._mutelist = GithubMutelist(
|
||||
mutelist_path=mutelist_path,
|
||||
)
|
||||
Provider.set_global_provider(self)
|
||||
@@ -110,7 +110,7 @@ class GithubProvider(Provider):
|
||||
return self._fixer_config
|
||||
|
||||
@property
|
||||
def mutelist(self) -> GitHubMutelist:
|
||||
def mutelist(self) -> GithubMutelist:
|
||||
"""
|
||||
mutelist method returns the provider's mutelist.
|
||||
"""
|
||||
|
||||
@@ -3,7 +3,7 @@ from prowler.lib.mutelist.mutelist import Mutelist
|
||||
from prowler.lib.outputs.utils import unroll_dict, unroll_tags
|
||||
|
||||
|
||||
class GitHubMutelist(Mutelist):
|
||||
class GithubMutelist(Mutelist):
|
||||
def is_finding_muted(
|
||||
self,
|
||||
finding: Check_Report_Github,
|
||||
|
||||
@@ -9,18 +9,18 @@ from prowler.providers.github.lib.service.service import GithubService
|
||||
class Repository(GithubService):
|
||||
def __init__(self, provider):
|
||||
super().__init__(__class__.__name__, provider)
|
||||
self.repositories = {}
|
||||
self._list_repositories()
|
||||
self.repositories = self._list_repositories()
|
||||
|
||||
def _list_repositories(self):
|
||||
logger.info("Repository - Listing Repositories...")
|
||||
repos = {}
|
||||
try:
|
||||
for repo in self.client.get_user().get_repos():
|
||||
try:
|
||||
securitymd_exists = repo.get_contents("SECURITY.md") is not None
|
||||
except Exception:
|
||||
securitymd_exists = False
|
||||
self.repositories[repo.id] = Repo(
|
||||
repos[repo.id] = Repo(
|
||||
id=repo.id,
|
||||
name=repo.name,
|
||||
full_name=repo.full_name,
|
||||
@@ -31,6 +31,7 @@ class Repository(GithubService):
|
||||
logger.error(
|
||||
f"{error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}"
|
||||
)
|
||||
return repos
|
||||
|
||||
|
||||
class Repo(BaseModel):
|
||||
|
||||
@@ -739,7 +739,6 @@ class TestGCPProvider:
|
||||
), patch(
|
||||
"prowler.providers.gcp.gcp_provider.GcpProvider.validate_project_id"
|
||||
) as mock_validate_project_id:
|
||||
|
||||
mock_validate_project_id.side_effect = GCPInvalidProviderIdError(
|
||||
"Invalid project ID"
|
||||
)
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
from mock import MagicMock
|
||||
|
||||
from prowler.providers.github.github_provider import GithubProvider
|
||||
from prowler.providers.github.models import GithubIdentityInfo, GithubSession
|
||||
|
||||
@@ -7,16 +8,27 @@ ACCOUNT_NAME = "account-name"
|
||||
ACCOUNT_ID = "account-id"
|
||||
ACCOUNT_URL = "/user"
|
||||
|
||||
# GitHub Credentials
|
||||
TOKEN = "github-token"
|
||||
|
||||
|
||||
# Mocked GitHub Provider
|
||||
def set_mocked_github_provider(
|
||||
credentials:
|
||||
) -> GithubProvider:
|
||||
provider = MagicMock()
|
||||
provider.type = "github"
|
||||
provider.session = GithubSession()
|
||||
provider.identity = GithubIdentityInfo(
|
||||
auth_method: str = "personal_access_token",
|
||||
credentials: GithubSession = GithubSession(token=TOKEN),
|
||||
identity: GithubIdentityInfo = GithubIdentityInfo(
|
||||
account_name=ACCOUNT_NAME,
|
||||
account_id=ACCOUNT_ID,
|
||||
account_url=ACCOUNT_URL,
|
||||
)
|
||||
return provider
|
||||
),
|
||||
audit_config: dict = None,
|
||||
) -> GithubProvider:
|
||||
|
||||
provider = MagicMock()
|
||||
provider.type = "github"
|
||||
provider.auth_method = auth_method
|
||||
provider.session = credentials
|
||||
provider.identity = identity
|
||||
provider.audit_config = audit_config
|
||||
|
||||
return provider
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
from unittest.mock import patch
|
||||
|
||||
from prowler.config.config import (
|
||||
default_fixer_config_file_path,
|
||||
load_and_validate_config_file,
|
||||
)
|
||||
from prowler.providers.github.github_provider import GithubProvider
|
||||
from prowler.providers.github.models import GithubIdentityInfo, GithubSession
|
||||
from tests.providers.github.github_fixtures import (
|
||||
ACCOUNT_ID,
|
||||
ACCOUNT_NAME,
|
||||
ACCOUNT_URL,
|
||||
TOKEN,
|
||||
)
|
||||
|
||||
|
||||
class TestGitHubProvider:
|
||||
def test_github_provider(self):
|
||||
# We need to set exactly one auth method
|
||||
personal_access_token = True
|
||||
oauth_app = False
|
||||
github_app = False
|
||||
fixer_config = load_and_validate_config_file(
|
||||
"github", default_fixer_config_file_path
|
||||
)
|
||||
|
||||
with patch(
|
||||
"prowler.providers.github.github_provider.GithubProvider.setup_session",
|
||||
return_value=GithubSession(token=TOKEN),
|
||||
), patch(
|
||||
"prowler.providers.github.github_provider.GithubProvider.setup_identity",
|
||||
return_value=GithubIdentityInfo(
|
||||
account_id=ACCOUNT_ID,
|
||||
account_name=ACCOUNT_NAME,
|
||||
account_url=ACCOUNT_URL,
|
||||
),
|
||||
):
|
||||
provider = GithubProvider(
|
||||
personal_access_token,
|
||||
github_app,
|
||||
oauth_app,
|
||||
)
|
||||
|
||||
assert provider._type == "github"
|
||||
assert provider.session == GithubSession(token=TOKEN)
|
||||
assert provider.identity == GithubIdentityInfo(
|
||||
account_name=ACCOUNT_NAME,
|
||||
account_id=ACCOUNT_ID,
|
||||
account_url=ACCOUNT_URL,
|
||||
)
|
||||
assert provider._audit_config == {}
|
||||
assert provider._fixer_config == fixer_config
|
||||
|
||||
+95
@@ -0,0 +1,95 @@
|
||||
from unittest import mock
|
||||
|
||||
from prowler.providers.github.services.repository.repository_service import Repo
|
||||
from tests.providers.github.github_fixtures import set_mocked_github_provider
|
||||
|
||||
|
||||
class Test_repository_public_has_securitymd_file_test:
|
||||
def test_no_repositories(self):
|
||||
repository_client = mock.MagicMock
|
||||
repository_client.repositories = {}
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||
return_value=set_mocked_github_provider(),
|
||||
), mock.patch(
|
||||
"prowler.providers.github.services.repository.repository_public_has_securitymd_file.repository_public_has_securitymd_file.repository_client",
|
||||
new=repository_client,
|
||||
):
|
||||
from prowler.providers.github.services.repository.repository_public_has_securitymd_file.repository_public_has_securitymd_file import (
|
||||
repository_public_has_securitymd_file,
|
||||
)
|
||||
|
||||
check = repository_public_has_securitymd_file()
|
||||
result = check.execute()
|
||||
assert len(result) == 0
|
||||
|
||||
def test_one_repository_no_securitymd(self):
|
||||
repository_client = mock.MagicMock
|
||||
repo_name = "repo1"
|
||||
repository_client.repositories = {
|
||||
1: Repo(
|
||||
id=1,
|
||||
name=repo_name,
|
||||
full_name="account-name/repo1",
|
||||
private=False,
|
||||
securitymd=False,
|
||||
),
|
||||
}
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||
return_value=set_mocked_github_provider(),
|
||||
), mock.patch(
|
||||
"prowler.providers.github.services.repository.repository_public_has_securitymd_file.repository_public_has_securitymd_file.repository_client",
|
||||
new=repository_client,
|
||||
):
|
||||
from prowler.providers.github.services.repository.repository_public_has_securitymd_file.repository_public_has_securitymd_file import (
|
||||
repository_public_has_securitymd_file,
|
||||
)
|
||||
|
||||
check = repository_public_has_securitymd_file()
|
||||
result = check.execute()
|
||||
assert len(result) == 1
|
||||
assert result[0].resource_id == 1
|
||||
assert result[0].resource_name == "repo1"
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Repository {repo_name} does not have a SECURITY.md file."
|
||||
)
|
||||
|
||||
def test_one_repository_securitymd(self):
|
||||
repository_client = mock.MagicMock
|
||||
repo_name = "repo1"
|
||||
repository_client.repositories = {
|
||||
1: Repo(
|
||||
id=1,
|
||||
name=repo_name,
|
||||
full_name="account-name/repo1",
|
||||
private=False,
|
||||
securitymd=True,
|
||||
),
|
||||
}
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||
return_value=set_mocked_github_provider(),
|
||||
), mock.patch(
|
||||
"prowler.providers.github.services.repository.repository_public_has_securitymd_file.repository_public_has_securitymd_file.repository_client",
|
||||
new=repository_client,
|
||||
):
|
||||
from prowler.providers.github.services.repository.repository_public_has_securitymd_file.repository_public_has_securitymd_file import (
|
||||
repository_public_has_securitymd_file,
|
||||
)
|
||||
|
||||
check = repository_public_has_securitymd_file()
|
||||
result = check.execute()
|
||||
assert len(result) == 1
|
||||
assert result[0].resource_id == 1
|
||||
assert result[0].resource_name == "repo1"
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Repository {repo_name} does have a SECURITY.md file."
|
||||
)
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
from unittest.mock import patch
|
||||
|
||||
from prowler.providers.github.services.repository.repository_service import (
|
||||
Repo,
|
||||
Repository,
|
||||
)
|
||||
from tests.providers.github.github_fixtures import set_mocked_github_provider
|
||||
|
||||
|
||||
def mock_list_repositories(_):
|
||||
return {
|
||||
1: Repo(
|
||||
id=1,
|
||||
name="repo1",
|
||||
full_name="account-name/repo1",
|
||||
private=False,
|
||||
securitymd=False,
|
||||
),
|
||||
}
|
||||
|
||||
|
||||
@patch(
|
||||
"prowler.providers.github.services.repository.repository_service.Repository._list_repositories",
|
||||
new=mock_list_repositories,
|
||||
)
|
||||
class Test_Repository_Service:
|
||||
def test_get_client(self):
|
||||
repository_service = Repository(set_mocked_github_provider())
|
||||
assert repository_service.client.__class__.__name__ == "Github"
|
||||
|
||||
def test_get_service(self):
|
||||
repository_service = Repository(set_mocked_github_provider())
|
||||
assert repository_service.__class__.__name__ == "Repository"
|
||||
|
||||
def test_list_repositories(self):
|
||||
repository_service = Repository(set_mocked_github_provider())
|
||||
assert len(repository_service.repositories) == 1
|
||||
assert repository_service.repositories[1].name == "repo1"
|
||||
assert repository_service.repositories[1].full_name == "account-name/repo1"
|
||||
assert repository_service.repositories[1].private is False
|
||||
assert repository_service.repositories[1].securitymd is False
|
||||
|
||||
Reference in New Issue
Block a user