fix(github): separate --github-app-key and --github-app-key-path CLI parameters

This commit is contained in:
Andoni A.
2025-07-31 20:06:27 +02:00
parent 02b416b4f8
commit 31d0db2d2c
4 changed files with 48 additions and 25 deletions
+1
View File
@@ -238,6 +238,7 @@ class Provider(ABC):
provider_class(
personal_access_token=arguments.personal_access_token,
oauth_app_token=arguments.oauth_app_token,
github_app_key_path=arguments.github_app_key_path,
github_app_key=arguments.github_app_key,
github_app_id=arguments.github_app_id,
mutelist_path=arguments.mutelist_file,
+35 -19
View File
@@ -102,8 +102,8 @@ class GithubProvider(Provider):
# Authentication credentials
personal_access_token: str = "",
oauth_app_token: str = "",
github_app_key_path: str = "",
github_app_key: str = "",
github_app_key_content: str = "",
github_app_id: int = 0,
# Provider configuration
config_path: str = None,
@@ -120,8 +120,8 @@ class GithubProvider(Provider):
Args:
personal_access_token (str): GitHub personal access token.
oauth_app_token (str): GitHub OAuth App token.
github_app_key (str): GitHub App key.
github_app_key_content (str): GitHub App key content.
github_app_key_path (str): Path to GitHub App private key file.
github_app_key (str): GitHub App private key content.
github_app_id (int): GitHub App ID.
config_path (str): Path to the audit configuration file.
config_content (dict): Audit configuration content.
@@ -141,8 +141,8 @@ class GithubProvider(Provider):
personal_access_token,
oauth_app_token,
github_app_id,
github_app_key_path,
github_app_key,
github_app_key_content,
)
# Set the authentication method
@@ -150,7 +150,7 @@ class GithubProvider(Provider):
self._auth_method = "Personal Access Token"
elif oauth_app_token:
self._auth_method = "OAuth App Token"
elif github_app_id and github_app_key:
elif github_app_id and (github_app_key_path or github_app_key):
self._auth_method = "GitHub App Token"
elif environ.get("GITHUB_PERSONAL_ACCESS_TOKEN", ""):
self._auth_method = "Environment Variable for Personal Access Token"
@@ -244,8 +244,8 @@ class GithubProvider(Provider):
personal_access_token: str = None,
oauth_app_token: str = None,
github_app_id: int = 0,
github_app_key_path: str = None,
github_app_key: str = None,
github_app_key_content: str = None,
) -> GithubSession:
"""
Returns the GitHub headers responsible authenticating API calls.
@@ -254,8 +254,8 @@ class GithubProvider(Provider):
personal_access_token (str): GitHub personal access token.
oauth_app_token (str): GitHub OAuth App token.
github_app_id (int): GitHub App ID.
github_app_key (str): GitHub App key.
github_app_key_content (str): GitHub App key content.
github_app_key_path (str): Path to GitHub App private key file.
github_app_key (str): GitHub App private key content.
Returns:
GithubSession: Authenticated session token for API requests.
"""
@@ -272,13 +272,16 @@ class GithubProvider(Provider):
elif oauth_app_token:
session_token = oauth_app_token
elif github_app_id and (github_app_key or github_app_key_content):
elif github_app_id and (github_app_key_path or github_app_key):
app_id = github_app_id
if github_app_key:
with open(github_app_key, "r") as rsa_key:
if github_app_key_path:
with open(github_app_key_path, "r") as rsa_key:
app_key = rsa_key.read()
elif github_app_key:
app_key = format_rsa_key(github_app_key)
else:
app_key = format_rsa_key(github_app_key_content)
# This shouldn't happen due to the condition above, but handle gracefully
app_key = ""
else:
# PAT
@@ -300,10 +303,23 @@ class GithubProvider(Provider):
"Looking for GITHUB_APP_ID and GITHUB_APP_KEY environment variables as user has not provided any token...."
)
app_id = environ.get("GITHUB_APP_ID", "")
app_key = format_rsa_key(environ.get("GITHUB_APP_KEY", ""))
env_key = environ.get("GITHUB_APP_KEY", "")
if app_id and app_key:
pass
if app_id and env_key:
# Smart detection: check if env_key is file path or key content
if env_key.startswith("-----BEGIN"):
# It's key content
app_key = format_rsa_key(env_key)
elif os.path.isfile(env_key):
# It's a file path
with open(env_key, "r") as rsa_key:
app_key = rsa_key.read()
else:
# Invalid format
raise GithubEnvironmentVariableError(
file=os.path.basename(__file__),
message="GITHUB_APP_KEY must contain either RSA key content (starting with -----BEGIN) or a valid file path.",
)
if not session_token and not (app_id and app_key):
raise GithubEnvironmentVariableError(
@@ -484,8 +500,8 @@ class GithubProvider(Provider):
def test_connection(
personal_access_token: str = "",
oauth_app_token: str = "",
github_app_key_path: str = "",
github_app_key: str = "",
github_app_key_content: str = "",
github_app_id: int = 0,
raise_on_exception: bool = True,
provider_id: str = None,
@@ -497,8 +513,8 @@ class GithubProvider(Provider):
Args:
personal_access_token (str): GitHub personal access token.
oauth_app_token (str): GitHub OAuth App token.
github_app_key (str): GitHub App key.
github_app_key_content (str): GitHub App key content.
github_app_key_path (str): Path to GitHub App private key file.
github_app_key (str): GitHub App private key content.
github_app_id (int): GitHub App ID.
raise_on_exception (bool): Flag indicating whether to raise an exception if the connection fails.
provider_id (str): The provider ID, in this case it's the GitHub organization/username.
@@ -529,8 +545,8 @@ class GithubProvider(Provider):
personal_access_token=personal_access_token,
oauth_app_token=oauth_app_token,
github_app_id=github_app_id,
github_app_key_path=github_app_key_path,
github_app_key=github_app_key,
github_app_key_content=github_app_key_content,
)
# Set up the identity to test the connection
@@ -30,12 +30,18 @@ def init_parser(self):
metavar="GITHUB_APP_ID",
)
github_auth_subparser.add_argument(
"--github-app-key",
"--github-app-key-path",
nargs="?",
help="GitHub App Key Path to log in against GitHub",
help="Path to GitHub App private key file",
default=None,
metavar="GITHUB_APP_KEY",
metavar="GITHUB_APP_KEY_PATH",
)
github_auth_subparser.add_argument(
"--github-app-key",
nargs="?",
help="GitHub App private key content",
default=None,
metavar="GITHUB_APP_KEY_CONTENT",
)
github_scoping_subparser = github_parser.add_argument_group("Scan Scoping")
@@ -61,7 +61,7 @@ class Test_GitHubArguments:
arguments.init_parser(mock_github_args)
# Verify authentication arguments were added
assert self.mock_auth_group.add_argument.call_count == 4
assert self.mock_auth_group.add_argument.call_count == 5
# Check that all authentication arguments are present
calls = self.mock_auth_group.add_argument.call_args_list
@@ -70,8 +70,8 @@ class Test_GitHubArguments:
assert "--personal-access-token" in auth_args
assert "--oauth-app-token" in auth_args
assert "--github-app-id" in auth_args
# Check for either form of the github app key argument
assert any("--github-app-key" in arg for arg in auth_args)
assert "--github-app-key-path" in auth_args
assert "--github-app-key" in auth_args
def test_init_parser_adds_scoping_arguments(self):
"""Test that init_parser adds all scoping arguments"""