feat: complete github app login

This commit is contained in:
HugoPBrito committed 2024-11-26 14:10:02 +01:00
1 parent 7001789997
commit 6f961139a1
6 files changed
+81 -61

No files matched your search

+7 -2
View File
@@ -11,6 +11,7 @@ from prowler.config.config import (
orange_color,
)
from prowler.lib.logger import logger
from prowler.providers.github.models import GithubAppIdentityInfo, GithubIdentityInfo
def display_summary_table(
@@ -41,8 +42,12 @@ def display_summary_table(
entity_type = "Context"
audited_entities = provider.identity.context
elif provider.type == "github":
entity_type = "User Name"
audited_entities = provider.identity.account_name
if isinstance(provider.identity, GithubIdentityInfo):
entity_type = "User Name"
audited_entities = provider.identity.account_name
elif isinstance(provider.identity, GithubAppIdentityInfo):
entity_type = "App ID"
audited_entities = provider.identity.app_id
# Check if there are findings and that they are not all MANUAL
if findings and not all(finding.status == "MANUAL" for finding in findings):
@@ -27,7 +27,7 @@ class GithubBaseException(ProwlerException):
"remediation": "Check credentials and ensure they are properly set up for Github and the identity provider.",
},
(5005, "GithubInvalidCredentialsError"): {
"message": "Github invalid user or password for basic login",
"message": "Github invalid App Key or App ID for GitHub APP login",
"remediation": "Check user and password and ensure they are properly set up as in your Github account.",
},
}
+19 -18
View File
@@ -1,7 +1,7 @@
import os
from os import getenv
from github import Auth, Github, GithubIntegration
from github import Auth, Github
from prowler.config.config import (
default_config_file_path,
@@ -20,7 +20,11 @@ from prowler.providers.github.exceptions.exceptions import (
GithubSetUpSessionError,
)
from prowler.providers.github.lib.mutelist.mutelist import GithubMutelist
from prowler.providers.github.models import GithubIdentityInfo, GithubSession
from prowler.providers.github.models import (
GithubAppIdentityInfo,
GithubIdentityInfo,
GithubSession,
)
class GithubProvider(Provider):
@@ -216,6 +220,7 @@ class GithubProvider(Provider):
file=os.path.basename(__file__),
message="Missing Github environment variable GITHUB_OAUTH_APP_TOKEN required to authenticate.",
)
session_token = getenv("GITHUB_OAUTH_APP_TOKEN")
self._auth_method = "Enviroment Variable for OAuth App Token"
elif github_app_key and github_app_id:
@@ -224,16 +229,17 @@ class GithubProvider(Provider):
self._auth_method = "GitHub App Token"
elif github_app:
if not getenv("github_app_key"):
if not getenv("GITHUB_APP_KEY") or not getenv("GITHUB_APP_ID"):
logger.critical(
"GitHub provider: Missing enviroment variable github_app_key needed to authenticate against GitHub."
"GitHub provider: Missing enviroment variables GITHUB_APP_KEY or GITHUB_APP_ID needed to authenticate against GitHub."
)
raise GithubEnvironmentVariableError(
file=os.path.basename(__file__),
message="Missing Github environment variable github_app_key required to authenticate.",
message="Missing enviroment variables GITHUB_APP_KEY or GITHUB_APP_ID required to authenticate.",
)
session_token = getenv("github_app_key")
self._auth_method = "Enviroment Variable for GitHub App Token"
app_key = getenv("GITHUB_APP_KEY")
app_id = getenv("GITHUB_APP_ID")
self._auth_method = "Enviroment Variables for GitHub App Key and ID"
else:
logger.critical(
@@ -266,7 +272,7 @@ class GithubProvider(Provider):
oauth_app_token,
github_app_key,
github_app_id: int = 0,
) -> GithubIdentityInfo:
) -> GithubIdentityInfo | GithubAppIdentityInfo:
"""
Returns the GitHub identity information
@@ -276,7 +282,7 @@ class GithubProvider(Provider):
oauth_app (bool): Flag indicating whether to use OAuth App as authentication method.
Returns:
GithubIdentityInfo: An instance of GithubIdentityInfo containing the identity information.
GithubIdentityInfo | GithubAppIdentityInfo: An instance of GithubIdentityInfo or GithubAppIdentityInfo containing the identity information.
"""
credentials = self.session
@@ -296,8 +302,8 @@ class GithubProvider(Provider):
try:
identity = GithubIdentityInfo(
account_name=g.get_user().login,
account_id=g.get_user().id,
account_name=g.get_user().login,
account_url=g.get_user().url,
)
return identity
@@ -308,16 +314,11 @@ class GithubProvider(Provider):
original_exception=error,
)
elif github_app_key and github_app_id:
auth = Auth.AppAuth(credentials.key, credentials.id)
gi = GithubIntegration(auth=auth)
elif (github_app_key and github_app_id) or github_app:
auth = Auth.AppAuth(credentials.id, credentials.key)
try:
identity = GithubIdentityInfo(
account_name=gi.get_user().login,
account_id=gi.get_user().id,
account_url=gi.get_user().url,
)
identity = GithubAppIdentityInfo(app_id=auth.app_id)
return identity
except Exception as error:
@@ -10,28 +10,32 @@ class GithubService:
service: str,
provider: GithubProvider,
):
self.client = self.__set_client__(
self.clients = self.__set_clients__(
provider.session,
)
self.audit_config = provider.audit_config
self.fixer_config = provider.fixer_config
def __set_client__(self, session):
def __set_clients__(self, session):
clients = []
try:
if session.token:
auth = Auth.Token(session.token)
client = Github(auth=auth)
clients = [Github(auth=auth)]
elif session.key and session.id:
auth = Auth.GithubApp(
session.github_app_id,
session.github_app_key,
auth = Auth.AppAuth(
session.id,
session.key,
)
client = GithubIntegration(auth=auth)
gi = GithubIntegration(auth=auth)
for installation in gi.get_installations():
clients.append(installation.get_github_for_installation())
except Exception as error:
logger.error(
f"{error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}"
)
return client
return clients
+18 -9
View File
@@ -4,18 +4,22 @@ from prowler.config.config import output_file_timestamp
from prowler.providers.common.models import ProviderOutputOptions
class GithubIdentityInfo(BaseModel):
account_name: str
account_id: str
account_url: str
class GithubSession(BaseModel):
token: str
key: str
id: str
class GithubIdentityInfo(BaseModel):
account_id: str
account_name: str
account_url: str
class GithubAppIdentityInfo(BaseModel):
app_id: str
class GithubOutputOptions(ProviderOutputOptions):
def __init__(self, arguments, bulk_checks_metadata, identity):
# First call ProviderOutputOptions init
@@ -26,8 +30,13 @@ class GithubOutputOptions(ProviderOutputOptions):
not hasattr(arguments, "output_filename")
or arguments.output_filename is None
):
self.output_filename = (
f"prowler-output-{identity.account_name}-{output_file_timestamp}"
)
if isinstance(identity, GithubIdentityInfo):
self.output_filename = (
f"prowler-output-{identity.account_name}-{output_file_timestamp}"
)
elif isinstance(identity, GithubAppIdentityInfo):
self.output_filename = (
f"prowler-output-{identity.app_id}-{output_file_timestamp}"
)
else:
self.output_filename = arguments.output_filename
@@ -15,29 +15,30 @@ class Repository(GithubService):
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
"""
securitymd_exists = False
contents = repo.get_contents("")
while contents:
file_content = contents.pop(0)
if file_content.type == "dir":
contents.extend(repo.get_contents(file_content.path))
elif file_content.path.endswith("SECURITY.md"):
securitymd_exists = True
break
"""
except Exception:
securitymd_exists = False
repos[repo.id] = Repo(
id=repo.id,
name=repo.name,
full_name=repo.full_name,
private=repo.private,
securitymd=securitymd_exists,
)
for client in self.clients:
for repo in client.get_user().get_repos():
try:
securitymd_exists = repo.get_contents("SECURITY.md") is not None
"""
securitymd_exists = False
contents = repo.get_contents("")
while contents:
file_content = contents.pop(0)
if file_content.type == "dir":
contents.extend(repo.get_contents(file_content.path))
elif file_content.path.endswith("SECURITY.md"):
securitymd_exists = True
break
"""
except Exception:
securitymd_exists = False
repos[repo.id] = Repo(
id=repo.id,
name=repo.name,
full_name=repo.full_name,
private=repo.private,
securitymd=securitymd_exists,
)
except Exception as error:
logger.error(
f"{error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}"