Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix Code Scanning Bugs #87

Merged
merged 7 commits into from
Dec 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .release.yml
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
name: "ghas-reviewer-app"
version: "0.5.2"
repository: "advanced-security/ghas-reviewer-app"
version: "0.6.0"
10 changes: 7 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,12 @@ The application is designed to be run in a container, this allows for easy deplo
**Pull / Download image:**

```bash
# Pull latest (or a release)
docker pull ghcr.io/advanced-security/ghas-reviewer-app:main
# Pull latest or a release
docker pull ghcr.io/advanced-security/ghas-reviewer-app:latest

or

docker pull ghcr.io/advanced-security/ghas-reviewer-app:v0.6.0
theztefan marked this conversation as resolved.
Show resolved Hide resolved
```

**Or Build From Source:**
Expand All @@ -116,7 +120,7 @@ docker run \
--env-file=.env \
-v ./config:/ghasreview/config \
-p 9000:9000 \
ghcr.io/advanced-security/ghas-reviewer-app:main
ghcr.io/advanced-security/ghas-reviewer-app:latest # or use release tag, example v0.6.0
```
theztefan marked this conversation as resolved.
Show resolved Hide resolved

or run it locally
Expand Down
2 changes: 1 addition & 1 deletion ghasreview/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
__version__ = "0.5.0"
__version__ = "0.6.0"

__url__ = "https://github.com/advanced-security/ghas-reviewer-app"
2 changes: 1 addition & 1 deletion ghasreview/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@

if __name__ == "__main__":
app = create_app(config)
app.run("0.0.0.0", port=9000, debug=True)
app.run("0.0.0.0", port=9000, debug=config.get("GHAS_DEBUG", False))
48 changes: 28 additions & 20 deletions ghasreview/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,48 +132,56 @@ def onCodeScanningAlertClose():
f"Processing Alert :: {alert.owner}/{alert.repository} => {alert.id} ({alert.ref})"
)

# Check if comment in alert
if current_app.config.get("GHAS_COMMENT_REQUIRED") and not alert.hasDismissedComment():
logger.debug(f"Comment required, reopeneing alert: {alert.id}")

open_alert = alert.client.reOpenCodeScanningAlert(
alert.owner, alert.repository, alert.id,
)
if open_alert.status_code != 200:
logger.error(f"Unable to re-open alert :: {alert.id}")
logger.error("This might be a permissions issue, please check the documentation for more details")
return {"message": "Unable to re-open alert"}
return {
"message": "Comment required, re-opening alert"
}

# Check tool and severity
tool = current_app.config.get("GHAS_TOOL")
if tool and alert.tool != tool:
logger.debug(f"Tool is not in the list of approved tools: {alert.tool}")
return {"message": "Tool is not in the list of approved tools"}

# Severity check, if not high enough, do not involve security team
severities = current_app.config.get("GHAS_SEVERITIES")
if severities and alert.severity not in severities:
logger.debug(
f"Severity is not high enough to get security involved: {alert.severity}"
)
return {"message": "Severity is not high enough to get security involved"}
return {"message": "Severity is not high enough to get security involved, doing nothing."}

# Check if an org account
# try:
# # TODO: Is this needed this org check?
# alert.client.organization(alert.owner)
# except Exception:
# logger.debug(f"Non-organization account is using the App, lets do nothing...")
# return {"message": "Non-organization account is using the App. Do nothing."}

# Check team
# Check team exists
if not alert.client.checkIfTeamExists(alert.owner, config.get("GHAS_TEAM")):
alert.createTeam(alert.owner, config.get("GHAS_TEAM"))

# TODO: Check and Create Project Board
# process.createProjectBoard()
logger.info(f"GHAS Reviewer Team `{config.get('GHAS_TEAM')}` does not exist, creating team.")
Dismissed Show dismissed Hide dismissed
alert.client.createTeam(alert.owner, config.get("GHAS_TEAM"))

# check if the user is part of the security team
if alert.client.isUserPartOfTeam(alert.owner, alert.getUser()):
if alert.client.isUserPartOfTeam(alert.owner, config.get("GHAS_TEAM"), alert.getUser()):
logger.debug(f"User is part of security team, no action taken.")
return {"message": "User is part of the security team"}

logger.debug(f"User is not allowed to close alerts: {alert.getUser()}")
logger.info(f"User is not allowed to close alerts: {alert.getUser()} ({alert.owner}/{alert.repository} => {alert.id})")

# Open Alert back up
open_alert = alert.client.reOpenCodeScanningAlert(
alert.owner, alert.repository, alert.id
alert.owner, alert.repository, alert.id,
)

if open_alert.status_code != 200:
logger.warning(f"Unable to re-open alert")
return
logger.error(f"Unable to re-open alert :: {alert.id}")
logger.error("This might be a permissions issue, please check the documentation for more details")
return {"message": "Unable to re-open alert"}

if alert.isPR():
logger.debug(f"In PR request")
Expand All @@ -183,7 +191,7 @@ def onCodeScanningAlertClose():

@app.errorhandler(500)
def page_not_found(error):
data = {"error": 500}
data = {"error": 500, "msg": "Internal Server Error"}
if app.debug:
data["msg"] = str(error)
resp = jsonify(**data)
Expand Down
4 changes: 2 additions & 2 deletions ghasreview/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ def isUserPartOfTeam(self, owner_name: str, team_name: str, user: str) -> bool:
f"{self.installation_client.session.base_url}/orgs/{owner_name}/teams/{team_name}",
)
if team.status_code != 200:
logger.debug(f"Team does not exist :: {team_name} - {team.json()}")
logger.error(f"Team does not exist :: {team_name} - {team.json()}")
Dismissed Show dismissed Hide dismissed
return False

membership_res = self.callApi(
Expand Down Expand Up @@ -75,7 +75,7 @@ def createTeam(self, owner: str, team_name: str) -> bool:
"description": "GitHub Advanced Security Reviewers",
}
team_creation = self.installation_client.session.post(
f"{self.base_url}/orgs/{owner}/teams", json=team_request
f"{self.installation_client.session.base_url}/orgs/{owner}/teams", json=team_request
)
if team_creation.status_code != 200:
logger.warning(f"Failed to create team :: {team_name} in {owner}")
Expand Down
4 changes: 4 additions & 0 deletions ghasreview/models/codescanning.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ def ref(self) -> str:
"ref"
) or self.payload.get("ref", "")


def hasDismissedComment(self) -> bool:
return self.payload.get("dismissed_comment") is not None

@property
def tool(self) -> str:
return self.payload.get("alert", {}).get("tool", {}).get("name", "")
Expand Down
6 changes: 6 additions & 0 deletions ghasreview/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ def parse_arguments():
parser_github.add_argument(
"--ghas-tool-name", default=os.environ.get("GITHUB_TOOL_NAME") or "CodeQL"
)
parser_github.add_argument(
"--ghas-comment-required", default=bool(os.environ.get("GITHUB_GHAS_COMMENT_REQUIRED", 0))
)

parser_github = parser.add_argument_group("GitHub")
parser_github.add_argument(
Expand Down Expand Up @@ -59,6 +62,7 @@ def setup_logging(arguments):
logging.info(f"GitHub Key Path :: {arguments.github_app_key_path}")
logging.debug(f"GitHub App Secret :: {arguments.github_app_secret}")
logging.debug(f"GHAS Tool Name :: {arguments.ghas_tool_name}")
logging.debug(f"GHAS Comment Required :: {arguments.ghas_comment_required}")


def validate_arguments(arguments):
Expand Down Expand Up @@ -89,11 +93,13 @@ def setup_app():
setup_logging(arguments)
app_key = validate_arguments(arguments)
config = {
"GHAS_DEBUG": arguments.debug,
# Set the route
"GITHUBAPP_ROUTE": arguments.github_app_endpoint,
# Team name
"GHAS_TEAM": arguments.ghas_team_name,
"GHAS_BOARD_NAME": "GHAS Reviewers Audit Board",
"GHAS_COMMENT_REQUIRED": arguments.ghas_comment_required,
# Tool and severities to check
"GHAS_TOOL": arguments.ghas_tool_name,
"GHAS_SEVERITIES": ["critical", "high", "error", "errors"],
Expand Down
Loading