You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: cla-backend-go/signatures/service.go
+19Lines changed: 19 additions & 0 deletions
Original file line number
Diff line number
Diff line change
@@ -833,6 +833,14 @@ func (s service) CreateOrUpdateEmployeeSignature(ctx context.Context, claGroupMo
833
833
"companyID": companyModel.CompanyID,
834
834
}
835
835
836
+
// Sanctions gate: never auto-create employee (ECLA) signatures for a sanctioned
837
+
// company. is_sanctioned is the persisted gate (SSS origin="sss" or a manual/admin
838
+
// block); both must block ECLA creation (auto-create toggle and approval-list edits).
839
+
ifcompanyModel.IsSanctioned {
840
+
log.WithFields(f).Warnf("company %s is sanctioned (origin=%q); refusing to auto-create employee (ECLA) signatures", companyModel.CompanyID, companyModel.SanctionOrigin)
841
+
returnnil, fmt.Errorf("company %s is sanctioned; employee (ECLA) signatures cannot be created", companyModel.CompanyID)
842
+
}
843
+
836
844
// Most of the following business logic is all the same - however, we need to handle the different types of approval lists entries and process them in the same way
837
845
// We build a list of users to process - this is a list of simple user models that contain the email, GitHub username, and GitLab username - typically only one of the values in the model will be set
msg:=fmt.Sprintf("can't load company signature record for company: %s for user : %s (%s), error : %v", companyID, userModel.Username, userModel.UserID, err)
log.WithFields(f).WithError(complianceErr).Warnf("company compliance check failed in corporate callback for company %s; not finalizing CCLA", companyID)
1157
+
returncomplianceErr
1158
+
} elseifsanctioned {
1159
+
log.WithFields(f).Warnf("company %s is sanctioned; refusing to finalize corporate CLA in callback", companyID)
1160
+
returnfmt.Errorf("company %s is sanctioned; corporate CLA cannot be finalized", companyID)
log.WithFields(f).Infof("SSS GetOrganizationStatus result for company %s: status=%q (domain=%s, mode=%s)", company.CompanyID, result.Status, req.Domain, sssMode)
3059
3079
3060
3080
sanctioned:=result.Status==sss.StatusFlagged
3061
3081
@@ -3073,9 +3093,16 @@ func (s *service) checkCompanyCompliance(ctx context.Context, company *v1Models.
3073
3093
}
3074
3094
} else {
3075
3095
// Clear only when previously set by SSS; manual blocks are left untouched.
3096
+
// ClearCompanySanctionStatusIfSSS treats a conditional-check failure (manual
3097
+
// block / nothing to clear) as a no-op, so a non-nil error here is a real
3098
+
// persistence failure. In required mode we fail closed rather than allow with a
3099
+
// stale persisted sanction still in place.
3076
3100
log.WithFields(f).Debugf("SSS returned clean status for company %s; attempting conditional clear", company.CompanyID)
log.WithFields(f).WithError(clearErr).Warnf("failed to conditionally clear sanction status for company %s", company.CompanyID)
3103
+
ifs.sssRequired {
3104
+
returnfalse, fmt.Errorf("checkCompanyCompliance: SSS returned clean but clearing the persisted sanction failed for company %s: %w", company.CompanyID, clearErr)
logging.Warnf("failed to conditionally clear sanction status for company %s: %v", companyID, clearErr)
8997
+
ifh.sssRequired {
8998
+
returnfalse, fmt.Errorf("checkCompanyCompliance: SSS returned clean but clearing the persisted sanction failed for company %s: %w", companyID, clearErr)
0 commit comments