@@ -1555,6 +1555,13 @@ def create(self, validated_data):
15551555 instance = super ().create (validated_data )
15561556 user = getattr (self .context .get ("request" , None ), "user" , None )
15571557 ra_helper .add_findings_to_risk_acceptance (user , instance , instance .accepted_findings .all ())
1558+
1559+ # Add risk acceptance to engagement
1560+ # This is fine as Pro has its own model + relationshop to track links with engagements.
1561+ if instance .accepted_findings .exists ():
1562+ engagement = instance .accepted_findings .first ().test .engagement
1563+ engagement .risk_acceptance .add (instance )
1564+
15581565 return instance
15591566
15601567 def update (self , instance , validated_data ):
@@ -1574,6 +1581,13 @@ def update(self, instance, validated_data):
15741581 # Remove the ones that were not present in the payload
15751582 for finding in findings_to_remove :
15761583 ra_helper .remove_finding_from_risk_acceptance (user , instance , finding )
1584+
1585+ # Handle orphaned risk acceptances: link to engagement if it now has findings
1586+ # This is fine as Pro has its own model + relationshop to track links with engagements.
1587+ if instance .accepted_findings .exists () and not instance .engagement :
1588+ engagement = instance .accepted_findings .first ().test .engagement
1589+ engagement .risk_acceptance .add (instance )
1590+
15771591 return instance
15781592
15791593 @extend_schema_field (serializers .CharField ())
@@ -1610,16 +1624,32 @@ def validate_findings_have_same_engagement(finding_objects: list[Finding]):
16101624 findings = data .get ("accepted_findings" , [])
16111625 findings_ids = [x .id for x in findings ]
16121626 finding_objects = Finding .objects .filter (id__in = findings_ids )
1613- authed_findings = get_authorized_findings (Permissions .Finding_Edit ).filter (id__in = findings_ids )
1627+ authed_findings = get_authorized_findings (Permissions .Risk_Acceptance ).filter (id__in = findings_ids )
16141628 if len (findings ) != len (authed_findings ):
16151629 msg = "You are not permitted to add one or more selected findings to this risk acceptance"
16161630 raise PermissionDenied (msg )
16171631 if self .context ["request" ].method == "POST" :
16181632 validate_findings_have_same_engagement (finding_objects )
1633+
1634+ # Validate product allows full risk acceptance BEFORE creating instance
1635+ if finding_objects .exists ():
1636+ engagement = finding_objects .first ().test .engagement
1637+ if not engagement .product .enable_full_risk_acceptance :
1638+ msg = "Full risk acceptance is not enabled for this product"
1639+ raise PermissionDenied (msg )
16191640 elif self .context ["request" ].method in {"PATCH" , "PUT" }:
1620- existing_findings = Finding .objects .filter (risk_acceptance = self .instance .id )
1641+ # Use the reverse relation instead of filtering
1642+ existing_findings = self .instance .accepted_findings .all ()
16211643 existing_and_new_findings = existing_findings | finding_objects
16221644 validate_findings_have_same_engagement (existing_and_new_findings )
1645+
1646+ # Explicit check to prevent engagement switching
1647+ risk_acceptance_engagement = self .instance .engagement
1648+ if risk_acceptance_engagement and finding_objects .exists ():
1649+ new_findings_engagement = finding_objects .first ().test .engagement
1650+ if risk_acceptance_engagement .id != new_findings_engagement .id :
1651+ msg = f"Risk Acceptance belongs to engagement { risk_acceptance_engagement .id } . Cannot add findings from engagement { new_findings_engagement .id } "
1652+ raise ValidationError (msg )
16231653 return data
16241654
16251655 class Meta :
0 commit comments