diff --git a/prowler/providers/common/provider.py b/prowler/providers/common/provider.py index 9fb0461194..26b1653f50 100644 --- a/prowler/providers/common/provider.py +++ b/prowler/providers/common/provider.py @@ -214,9 +214,10 @@ class Provider(ABC): elif "github" in provider_class_name.lower(): provider_class( personal_access_token=arguments.personal_access_token, + oauth_app_token=arguments.oauth_app_token, github_app=arguments.github_app, - oauth_app=arguments.oauth_app, - pat=arguments.pat, + user=arguments.user, + password=arguments.password, config_path=arguments.config_file, ) diff --git a/prowler/providers/github/exceptions/exceptions.py b/prowler/providers/github/exceptions/exceptions.py index afb0f4fc3a..5037fa2bf0 100644 --- a/prowler/providers/github/exceptions/exceptions.py +++ b/prowler/providers/github/exceptions/exceptions.py @@ -26,6 +26,10 @@ class GithubBaseException(ProwlerException): "message": "Github identity setup error due to bad credentials", "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", + "remediation": "Check user and password and ensure they are properly set up as in your Github account.", + }, } def __init__(self, code, file=None, original_exception=None, message=None): @@ -82,3 +86,10 @@ class GithubSetUpIdentityError(GithubCredentialsError): super().__init__( 5004, file=file, original_exception=original_exception, message=message ) + + +class GithubInvalidCredentialsError(GithubCredentialsError): + def __init__(self, file=None, original_exception=None, message=None): + super().__init__( + 5005, file=file, original_exception=original_exception, message=message + ) diff --git a/prowler/providers/github/github_provider.py b/prowler/providers/github/github_provider.py index 4657d1876f..73adc0cd44 100644 --- a/prowler/providers/github/github_provider.py +++ b/prowler/providers/github/github_provider.py @@ -14,6 +14,7 @@ from prowler.providers.common.models import Audit_Metadata from prowler.providers.common.provider import Provider from prowler.providers.github.exceptions.exceptions import ( GithubEnvironmentVariableError, + GithubInvalidCredentialsError, GithubInvalidTokenError, GithubSetUpIdentityError, GithubSetUpSessionError, @@ -34,9 +35,10 @@ class GithubProvider(Provider): def __init__( self, personal_access_token: bool = False, + oauth_app_token: str = None, github_app: bool = False, - oauth_app: bool = False, - pat: str = None, + user: str = None, + password: str = None, config_path: str = None, config_content: dict = None, fixer_config: dict = {}, @@ -57,14 +59,18 @@ class GithubProvider(Provider): self._session = self.setup_session( personal_access_token, + oauth_app_token, github_app, - oauth_app, + user, + password, ) self._identity = self.setup_identity( personal_access_token, + oauth_app_token, github_app, - oauth_app, + user, + password, ) # Audit Config @@ -134,9 +140,10 @@ class GithubProvider(Provider): def setup_session( self, personal_access_token: bool, - github_app: bool, - oauth_app: bool, - pat: str = None, + oauth_app_token: str = None, + github_app: bool = False, + user: str = None, + password: str = None, ) -> GithubSession: """ Returns the GitHub headers responsible authenticating API calls. @@ -149,18 +156,26 @@ class GithubProvider(Provider): Returns: GithubSession: Authenticated session token for API requests. """ + + session_token = "" + login_user = "" + login_password = "" + try: - if not personal_access_token and not github_app and not oauth_app: + # Ensure that at least one authentication method is selected. Default to environment variable PAT if none is provided. + if ( + not personal_access_token + and not oauth_app_token + and not github_app + and not user + and not password + ): logger.error( "GitHub provider: No authentication method selected. Prowler will try to use GITHUB_PERSONAL_ACCESS_TOKEN enviroment variable to log in by default." ) personal_access_token = True - if pat: - session_token = pat - self._auth_method = "personal_access_token" - - elif personal_access_token: + if personal_access_token: if not getenv("GITHUB_PERSONAL_ACCESS_TOKEN"): logger.critical( "GitHub provider: Missing enviroment variable GITHUB_PERSONAL_ACCESS_TOKEN needed to authenticate against GitHub." @@ -172,6 +187,20 @@ class GithubProvider(Provider): session_token = getenv("GITHUB_PERSONAL_ACCESS_TOKEN") self._auth_method = "personal_access_token" + elif oauth_app_token: + """ + if not getenv("GITHUB_OAUTH_APP_TOKEN"): + logger.critical( + "GitHub provider: Missing enviroment variable GITHUB_OAUTH_APP_TOKEN needed to authenticate against GitHub." + ) + raise GithubEnvironmentVariableError( + file=os.path.basename(__file__), + message="Missing Github environment variable GITHUB_OAUTH_APP_TOKEN required to authenticate.", + ) + """ + session_token = oauth_app_token + self._auth_method = "oauth_app" + elif github_app: if not getenv("GITHUB_APP_TOKEN"): logger.critical( @@ -184,24 +213,19 @@ class GithubProvider(Provider): session_token = getenv("GITHUB_APP_TOKEN") self._auth_method = "github_app" - elif oauth_app: - if not getenv("GITHUB_OAUTH_APP_TOKEN"): - logger.critical( - "GitHub provider: Missing enviroment variable GITHUB_OAUTH_APP_TOKEN needed to authenticate against GitHub." - ) - raise GithubEnvironmentVariableError( - 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 = "oauth_app" + elif user and password: + login_user = user + login_password = password + self._auth_method = "login_auth" else: logger.critical( "GitHub provider: A Github token is required to authenticate against Github." ) - credentials = GithubSession(token=session_token) + credentials = GithubSession( + token=session_token, user=login_user, password=login_password + ) return credentials @@ -217,9 +241,10 @@ class GithubProvider(Provider): def setup_identity( self, personal_access_token: bool, - github_app: bool, - oauth_app: bool, - pat: str = None, + oauth_app_token: str = None, + github_app: bool = False, + user: str = None, + password: str = None, ) -> GithubIdentityInfo: """ Returns the GitHub identity information @@ -235,11 +260,12 @@ class GithubProvider(Provider): credentials = self.session try: - if (pat or personal_access_token or github_app or oauth_app) or ( - not pat - and not personal_access_token + if (personal_access_token or github_app or oauth_app_token) or ( + not personal_access_token + and not oauth_app_token and not github_app - and not oauth_app + and not user + and not password ): auth = Auth.Token(credentials.token) g = Github(auth=auth) @@ -253,11 +279,29 @@ class GithubProvider(Provider): return identity except Exception as error: - logger.critical("GitHub provider: Given credentials are not valid.") + logger.critical("GitHub provider: Given token is not valid.") raise GithubInvalidTokenError( original_exception=error, ) + elif user and password: + auth = Auth.Login(user, password) + g = Github(auth=auth) + + try: + identity = GithubIdentityInfo( + account_name=g.get_user().login, + account_id=g.get_user().id, + account_url=g.get_user().url, + ) + return identity + + except Exception as error: + logger.critical("GitHub provider: Given credentials are not valid.") + raise GithubInvalidCredentialsError( + original_exception=error, + ) + except Exception as error: logger.critical("GitHub provider: Error setting up identity.") logger.critical( diff --git a/prowler/providers/github/lib/arguments/arguments.py b/prowler/providers/github/lib/arguments/arguments.py index 1b9d25afa6..dbb552f145 100644 --- a/prowler/providers/github/lib/arguments/arguments.py +++ b/prowler/providers/github/lib/arguments/arguments.py @@ -12,29 +12,17 @@ def init_parser(self): help="Use Personal Access Token to log in against GitHub", default=False, ) - github_auth_modes_group.add_argument( - "--oauth-app", - action="store_true", - help="Use Oauth app token to log in against GitHub", - default=False, - ) + github_auth_subparser.add_argument( + "--oauth-app-token", + nargs="?", + default=None, + help="Oauth app token to log in against GitHub", + ), github_auth_modes_group.add_argument( "--github-app", action="store_true", help="Use GitHub app token to log in against GitHub", default=False, - ) - github_auth_modes_group.add_argument( - "--user-password", - action="store_true", - help="Use user login and password to log in against GitHub", - default=False, - ), - github_auth_subparser.add_argument( - "--pat", - nargs="?", - default=None, - help="Personal access token to log in against GitHub", ), github_auth_subparser.add_argument( "--user", diff --git a/prowler/providers/github/models.py b/prowler/providers/github/models.py index c6dfa4bd67..656b1de2ae 100644 --- a/prowler/providers/github/models.py +++ b/prowler/providers/github/models.py @@ -12,6 +12,8 @@ class GithubIdentityInfo(BaseModel): class GithubSession(BaseModel): token: str + user: str + password: str class GithubOutputOptions(ProviderOutputOptions):