|
150 | 150 | from vulnerabilities.models import Vulnerability |
151 | 151 | from vulnerabilities.models import VulnerabilityAnalysis |
152 | 152 | from vulnerabilities.models import get_risk_level |
| 153 | +from vulnerabilities.triage.engine import evaluate_ruleset |
| 154 | +from vulnerabilities.triage.models import ProductTriageRuleset |
153 | 155 | from vulnerabilities.triage.models import TriageAction |
154 | 156 | from vulnerabilities.triage.models import TriageRecord |
| 157 | +from vulnerabilities.triage.models import TriageRuleset |
155 | 158 |
|
156 | 159 | TRIAGE_ACTION_STYLES = { |
157 | 160 | "upgrade": ("bg-danger-subtle text-danger-emphasis", "fa-arrow-circle-up"), |
@@ -2129,6 +2132,58 @@ def evaluate_policy_rules_view(request, dataspace, name, version=""): |
2129 | 2132 | return HttpResponse(headers={"HX-Refresh": "true"}) |
2130 | 2133 |
|
2131 | 2134 |
|
| 2135 | +@login_required |
| 2136 | +def manage_triage_rulesets_view(request, dataspace, name, version=""): |
| 2137 | + guarded_qs = Product.objects.get_queryset(request.user, perms="change_product") |
| 2138 | + product = get_object_or_404( |
| 2139 | + guarded_qs, |
| 2140 | + name=unquote_plus(name), |
| 2141 | + version=unquote_plus(version), |
| 2142 | + dataspace__name=dataspace, |
| 2143 | + ) |
| 2144 | + available_rulesets = list( |
| 2145 | + TriageRuleset.objects.filter(dataspace=product.dataspace, enabled=True).order_by( |
| 2146 | + "-precedence", "name" |
| 2147 | + ) |
| 2148 | + ) |
| 2149 | + |
| 2150 | + if request.method == "POST": |
| 2151 | + submitted_uuids = set(request.POST.getlist("ruleset_uuids")) |
| 2152 | + current_assignments = { |
| 2153 | + str(ptr.ruleset.uuid): ptr |
| 2154 | + for ptr in ProductTriageRuleset.objects.filter(product=product).select_related( |
| 2155 | + "ruleset" |
| 2156 | + ) |
| 2157 | + } |
| 2158 | + for ruleset in available_rulesets: |
| 2159 | + ruleset_uuid = str(ruleset.uuid) |
| 2160 | + if ruleset_uuid in submitted_uuids and ruleset_uuid not in current_assignments: |
| 2161 | + ProductTriageRuleset.objects.create( |
| 2162 | + product=product, |
| 2163 | + ruleset=ruleset, |
| 2164 | + dataspace=product.dataspace, |
| 2165 | + ) |
| 2166 | + evaluate_ruleset(ruleset=ruleset, product=product) |
| 2167 | + for ruleset_uuid, assignment in current_assignments.items(): |
| 2168 | + if ruleset_uuid not in submitted_uuids: |
| 2169 | + assignment.delete() |
| 2170 | + return JsonResponse({"success": True}) |
| 2171 | + |
| 2172 | + assigned_ruleset_ids = set(product.product_triage_rulesets.values_list("ruleset_id", flat=True)) |
| 2173 | + action_labels = dict(TriageAction.choices) |
| 2174 | + for ruleset in available_rulesets: |
| 2175 | + ruleset.action_label = action_labels.get(ruleset.action, ruleset.action) |
| 2176 | + |
| 2177 | + return render( |
| 2178 | + request, |
| 2179 | + "product_portfolio/modals/manage_triage_rulesets_form.html", |
| 2180 | + { |
| 2181 | + "available_rulesets": available_rulesets, |
| 2182 | + "assigned_ruleset_ids": assigned_ruleset_ids, |
| 2183 | + }, |
| 2184 | + ) |
| 2185 | + |
| 2186 | + |
2132 | 2187 | @login_required |
2133 | 2188 | def import_from_scan_view(request, dataspace, name, version=""): |
2134 | 2189 | """ |
|
0 commit comments