mirror of
https://github.com/prowler-cloud/prowler.git
synced 2026-07-24 13:01:56 +00:00
fix(github): solve Github APP auth method (#8529)
This commit is contained in:
@@ -17,7 +17,14 @@ All notable changes to the **Prowler SDK** are documented in this file.
|
||||
|
||||
---
|
||||
|
||||
## [v5.10.2] (Prowler UNRELEASED)
|
||||
## [v5.10.3] (Prowler UNRELEASED)
|
||||
|
||||
### Fixed
|
||||
- GitHub App authentication for GitHub provider [(#8529)](https://github.com/prowler-cloud/prowler/pull/8529)
|
||||
|
||||
---
|
||||
|
||||
## [v5.10.2] (Prowler v5.10.2)
|
||||
|
||||
### Fixed
|
||||
- Order requirements by ID in Prowler ThreatScore AWS compliance framework [(#8495)](https://github.com/prowler-cloud/prowler/pull/8495)
|
||||
|
||||
@@ -365,8 +365,16 @@ class GithubProvider(Provider):
|
||||
elif session.id != 0 and session.key:
|
||||
auth = Auth.AppAuth(session.id, session.key)
|
||||
gi = GithubIntegration(auth=auth, retry=retry_config)
|
||||
installations = []
|
||||
for installation in gi.get_installations():
|
||||
installations.append(
|
||||
installation.raw_data.get("account", {}).get("login")
|
||||
)
|
||||
try:
|
||||
identity = GithubAppIdentityInfo(app_id=gi.get_app().id)
|
||||
identity = GithubAppIdentityInfo(
|
||||
app_id=gi.get_app().id,
|
||||
installations=installations,
|
||||
)
|
||||
return identity
|
||||
|
||||
except Exception as error:
|
||||
|
||||
@@ -18,6 +18,7 @@ class GithubIdentityInfo(BaseModel):
|
||||
|
||||
class GithubAppIdentityInfo(BaseModel):
|
||||
app_id: str
|
||||
installations: list[str]
|
||||
|
||||
|
||||
class GithubOutputOptions(ProviderOutputOptions):
|
||||
|
||||
@@ -7,6 +7,7 @@ from pydantic.v1 import BaseModel
|
||||
|
||||
from prowler.lib.logger import logger
|
||||
from prowler.providers.github.lib.service.service import GithubService
|
||||
from prowler.providers.github.models import GithubAppIdentityInfo
|
||||
|
||||
|
||||
class Repository(GithubService):
|
||||
@@ -102,12 +103,23 @@ class Repository(GithubService):
|
||||
def _list_repositories(self):
|
||||
"""
|
||||
List repositories based on provider scoping configuration.
|
||||
If the provider is a GitHub App, it will list repositories in the organizations that the GitHub App is installed in.
|
||||
If the provider is a user, it will list repositories where the user is a member or owner.
|
||||
If input repositories are provided, it will list repositories that match the input repositories.
|
||||
If input organizations are provided, it will list repositories in the organizations that match the input organizations.
|
||||
"""
|
||||
logger.info("Repository - Listing Repositories...")
|
||||
repos = {}
|
||||
try:
|
||||
for client in self.clients:
|
||||
if self.provider.repositories or self.provider.organizations:
|
||||
if (
|
||||
self.provider.repositories
|
||||
or self.provider.organizations
|
||||
or (
|
||||
isinstance(self.provider.identity, GithubAppIdentityInfo)
|
||||
and self.provider.identity.installations
|
||||
)
|
||||
):
|
||||
if self.provider.repositories:
|
||||
logger.info(
|
||||
f"Filtering for specific repositories: {self.provider.repositories}"
|
||||
@@ -141,6 +153,24 @@ class Repository(GithubService):
|
||||
self._handle_github_api_error(
|
||||
error, "processing organization", org_name
|
||||
)
|
||||
if (
|
||||
isinstance(self.provider.identity, GithubAppIdentityInfo)
|
||||
and self.provider.identity.installations
|
||||
):
|
||||
logger.info(
|
||||
f"Filtering for repositories in the organizations or accounts that the GitHub App is installed in: {', '.join(self.provider.identity.installations)}"
|
||||
)
|
||||
for org_name in self.provider.identity.installations:
|
||||
try:
|
||||
repos_list, _ = self._get_repositories_from_owner(
|
||||
client, org_name
|
||||
)
|
||||
for repo in repos_list:
|
||||
self._process_repository(repo, repos)
|
||||
except Exception as error:
|
||||
self._handle_github_api_error(
|
||||
error, "processing organization", org_name
|
||||
)
|
||||
else:
|
||||
logger.info(
|
||||
"No repository or organization specified, discovering accessible repositories via GraphQL API..."
|
||||
|
||||
@@ -585,7 +585,9 @@ class TestFinding:
|
||||
provider = MagicMock()
|
||||
provider.type = "github"
|
||||
# GitHub App identity only has app_id, not account_name/account_id
|
||||
provider.identity = GithubAppIdentityInfo(app_id=APP_ID)
|
||||
provider.identity = GithubAppIdentityInfo(
|
||||
app_id=APP_ID, installations=["test-org"]
|
||||
)
|
||||
provider.auth_method = "GitHub App Token"
|
||||
|
||||
# Mock check result
|
||||
|
||||
@@ -673,7 +673,7 @@ class TestHTML:
|
||||
|
||||
provider = set_mocked_github_provider(
|
||||
auth_method="GitHub App Token",
|
||||
identity=GithubAppIdentityInfo(app_id=APP_ID),
|
||||
identity=GithubAppIdentityInfo(app_id=APP_ID, installations=["test-org"]),
|
||||
)
|
||||
|
||||
summary = output.get_assessment_summary(provider)
|
||||
|
||||
@@ -135,6 +135,7 @@ class TestGitHubProvider:
|
||||
"prowler.providers.github.github_provider.GithubProvider.setup_identity",
|
||||
return_value=GithubAppIdentityInfo(
|
||||
app_id=APP_ID,
|
||||
installations=["test-org"],
|
||||
),
|
||||
),
|
||||
):
|
||||
@@ -147,7 +148,9 @@ class TestGitHubProvider:
|
||||
|
||||
assert provider._type == "github"
|
||||
assert provider.session == GithubSession(token="", id=APP_ID, key=APP_KEY)
|
||||
assert provider.identity == GithubAppIdentityInfo(app_id=APP_ID)
|
||||
assert provider.identity == GithubAppIdentityInfo(
|
||||
app_id=APP_ID, installations=["test-org"]
|
||||
)
|
||||
assert provider._audit_config == {
|
||||
"inactive_not_archived_days_threshold": 180,
|
||||
}
|
||||
@@ -206,7 +209,9 @@ class TestGitHubProvider:
|
||||
),
|
||||
patch(
|
||||
"prowler.providers.github.github_provider.GithubProvider.setup_identity",
|
||||
return_value=GithubAppIdentityInfo(app_id=APP_ID),
|
||||
return_value=GithubAppIdentityInfo(
|
||||
app_id=APP_ID, installations=["test-org"]
|
||||
),
|
||||
),
|
||||
):
|
||||
connection = GithubProvider.test_connection(
|
||||
|
||||
Reference in New Issue
Block a user