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

Re-calculate historical risk score #789

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

leec94
Copy link
Contributor

@leec94 leec94 commented Jul 19, 2024

Description

Related to DependencyTrack/dependency-track#2824 , this issue is to allow the custom weights of risk scores to be re-calculated.

Addressed Issue

Related to DependencyTrack/dependency-track#2824

Front end issue to go along with this is DependencyTrack/hyades-frontend#94

Additional Details

Adds a new endpoint to tell the database to recalculate with /riskscore/refresh. If there's a better approach for this, I'm all ears!

This PR is draft, I have a few questions / open ended items:

  • I'm not super experienced with SQL so I'm confused about how to write the new SQL. i'm not sure how to define the columns to make sure the risk scores are recalculated throughout the DEPENDENCYMETRICS table. I have pgadmin set up and connected to the hyades database, but i'm unable to run a query of the sql as it is, or even just the "update" part.
  • I need to only run this recalculation if weight.history.enabled is True, don't run this when false. Where would this logic be done?
  • Tests haven't been added yet

Checklist

  • I have read and understand the contributing guidelines
  • This PR fixes a defect, and I have provided tests to verify that the fix is effective
  • This PR implements an enhancement, and I have provided tests to verify that it works as intended
  • This PR introduces changes to the database model, and I have updated the migration changelog accordingly
  • This PR introduces new or alters existing behavior, and I have updated the documentation accordingly

leec94 added 3 commits July 17, 2024 17:37
Signed-off-by: leec94 <[email protected]>
Signed-off-by: leec94 <[email protected]>
@nscuro
Copy link
Member

nscuro commented Jul 22, 2024

I have pgadmin set up and connected to the hyades database, but i'm unable to run a query of the sql as it is, or even just the "update" part.

Can you share some more details on the issues you're encountering? What are you trying, and is pgadmin showing any errors?

i'm not sure how to define the columns to make sure the risk scores are recalculated throughout the DEPENDENCYMETRICS table.

I'll try to provide some guidance below.


In general I think the whole thing becomes easier if you don't use a stored procedure for this. The SQL you already have:

UPDATE "DEPENDENCYMETRICS" SET "v_risk_score" = "CALC_RISK_SCORE"("v_critical", "v_high", "v_medium", "v_low", "v_unassigned");

can be rewritten to the following:

UPDATE "DEPENDENCYMETRICS"
   SET "RISK_SCORE" = "CALC_RISK_SCORE"("CRITICAL", "HIGH", "MEDIUM", "LOW", "UNASSIGNED_SEVERITY")

There is no need to declare any input or output variables, the RDBMS will execute the above as-is, and update the risk score of all records in the DEPENDENCYMETRICS table accordingly.

As for how to execute the query, the main way we interact with the database now is via JDBI. It should also "just work" in pgadmin, provided you have data in your DEPENDENCYMETRICS table.

There are multiple ways to use JDBI, but the fluent API is probably the easiest. You can find an example here:

useJdbiHandle(handle -> handle.createUpdate("""
WITH "VULN_POLICY" AS (
SELECT "ID"
FROM "VULNERABILITY_POLICY"
WHERE "NAME" = :policyName
)
UPDATE "ANALYSIS"
SET "VULNERABILITY_POLICY_ID" = (SELECT "ID" FROM "VULN_POLICY")
WHERE "ID" = :analysisId
""")
.bind("policyName", vulnPolicy.getName())
.bind("analysisId", analysis.getId())
.execute());

(Ignore the query in the example above, just want to showcase how to use createUpdate with JDBI)


I personally find that working on something like this is easiest in a test-driven way:

  1. Create a test that sets up your input data. In your case, you need a project, a component in that project, and an existing DependencyMetrics record for the component.
  2. Execute your new code on the dataset above.
  3. Assert that the dataset has changed according to your expectation. In your case, you will want to ensure that the riskScore values were updated correctly.

You can take inspiration from the existing metrics update tests.


I need to only run this recalculation if weight.history.enabled is True, don't run this when false. Where would this logic be done?

Add this as a check to the new HistoricalRiskScoreUpdateTask. Consider logging a warning when the task is executed, but the feature itself is disabled.


Tests haven't been added yet

See above. Getting tests set up will help you in developing the feature. Let me know if you need more help with that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants