fix(jira): correct Data Sensitivity field ID and replicate Jira's real classification scheme
Aegis CI / lint-and-test (push) Has been cancelled
Snyk Security Scan / Python vulnerabilities (backend) (push) Has been cancelled
Snyk Security Scan / npm vulnerabilities (frontend) (push) Has been cancelled
Snyk Security Scan / Docker image vulnerabilities (backend) (push) Has been cancelled
Aegis CI / lint-and-test (push) Has been cancelled
Snyk Security Scan / Python vulnerabilities (backend) (push) Has been cancelled
Snyk Security Scan / npm vulnerabilities (frontend) (push) Has been cancelled
Snyk Security Scan / Docker image vulnerabilities (backend) (push) Has been cancelled
The auto-create-ticket call was sending customfield_11233 (a field that doesn't exist in the project) instead of the real Data Sensitivity field customfield_11814, which made Jira reject the WHOLE issue and silently block ticket creation for every new test. Also replaces Aegis's invented 4-tier data_classification scheme (public_release/general_use/confidential/restricted) with the 6 values Jira's Data Sensitivity field actually uses (public/general_use/ internal_use_only/trusted_people/customer_content/pii), since that is the classification the organization actually applies. Includes a data migration remapping existing rows and a defensive retry if Jira ever rejects an unscreened custom field again.
This commit is contained in:
@@ -34,7 +34,7 @@ def _seed_technique(db, tactic="execution") -> Technique:
|
||||
return technique
|
||||
|
||||
|
||||
def test_new_test_defaults_to_confidential_via_db_default(db, red_lead_user):
|
||||
def test_new_test_defaults_to_internal_use_only_via_db_default(db, red_lead_user):
|
||||
"""A Test() constructed without going through the create_test service
|
||||
still gets a safe classification via the column's server_default."""
|
||||
technique = _seed_technique(db)
|
||||
@@ -46,7 +46,7 @@ def test_new_test_defaults_to_confidential_via_db_default(db, red_lead_user):
|
||||
db.add(test)
|
||||
db.commit()
|
||||
db.refresh(test)
|
||||
assert test.data_classification == "confidential"
|
||||
assert test.data_classification == "internal_use_only"
|
||||
|
||||
|
||||
def test_create_test_endpoint_uses_tactic_heuristic(client, db, api, auth_headers, technique):
|
||||
@@ -57,8 +57,8 @@ def test_create_test_endpoint_uses_tactic_heuristic(client, db, api, auth_header
|
||||
)
|
||||
assert resp.status_code == 201, resp.text
|
||||
# The shared `technique` fixture (see conftest/test_tests.py) doesn't set
|
||||
# a restricted-tier tactic, so this should land on the baseline.
|
||||
assert resp.json()["data_classification"] == "confidential"
|
||||
# a pii-tier tactic, so this should land on the baseline.
|
||||
assert resp.json()["data_classification"] == "internal_use_only"
|
||||
|
||||
|
||||
def test_admin_can_update_classification(client, db, admin_user, admin_token, red_lead_user):
|
||||
@@ -74,14 +74,14 @@ def test_admin_can_update_classification(client, db, admin_user, admin_token, re
|
||||
|
||||
response = client.patch(
|
||||
f"/api/v1/tests/{test.id}/classification",
|
||||
json={"data_classification": "restricted"},
|
||||
json={"data_classification": "pii"},
|
||||
headers={"Authorization": f"Bearer {admin_token}"},
|
||||
)
|
||||
assert response.status_code == 200
|
||||
assert response.json()["data_classification"] == "restricted"
|
||||
assert response.json()["data_classification"] == "pii"
|
||||
|
||||
db.refresh(test)
|
||||
assert test.data_classification == "restricted"
|
||||
assert test.data_classification == "pii"
|
||||
|
||||
|
||||
def test_operator_can_update_classification(client, db, admin_user, red_lead_token, red_lead_user):
|
||||
@@ -130,7 +130,7 @@ def test_viewer_cannot_update_classification(client, db, admin_user, red_lead_us
|
||||
|
||||
response = client.patch(
|
||||
f"/api/v1/tests/{test.id}/classification",
|
||||
json={"data_classification": "restricted"},
|
||||
json={"data_classification": "pii"},
|
||||
headers={"Authorization": f"Bearer {viewer_token}"},
|
||||
)
|
||||
assert response.status_code == 403
|
||||
@@ -142,15 +142,15 @@ def _technique_stub(tactic):
|
||||
return t
|
||||
|
||||
|
||||
def test_determine_initial_classification_defaults_to_confidential():
|
||||
assert determine_initial_classification(_technique_stub("execution")) == "confidential"
|
||||
assert determine_initial_classification(_technique_stub(None)) == "confidential"
|
||||
assert determine_initial_classification(None) == "confidential"
|
||||
def test_determine_initial_classification_defaults_to_internal_use_only():
|
||||
assert determine_initial_classification(_technique_stub("execution")) == "internal_use_only"
|
||||
assert determine_initial_classification(_technique_stub(None)) == "internal_use_only"
|
||||
assert determine_initial_classification(None) == "internal_use_only"
|
||||
|
||||
|
||||
def test_determine_initial_classification_escalates_for_sensitive_tactics():
|
||||
assert determine_initial_classification(_technique_stub("exfiltration")) == "restricted"
|
||||
assert determine_initial_classification(_technique_stub("collection")) == "restricted"
|
||||
assert determine_initial_classification(_technique_stub("credential-access")) == "restricted"
|
||||
assert determine_initial_classification(_technique_stub("impact")) == "restricted"
|
||||
assert determine_initial_classification(_technique_stub("Exfiltration")) == "restricted"
|
||||
assert determine_initial_classification(_technique_stub("exfiltration")) == "pii"
|
||||
assert determine_initial_classification(_technique_stub("collection")) == "pii"
|
||||
assert determine_initial_classification(_technique_stub("credential-access")) == "pii"
|
||||
assert determine_initial_classification(_technique_stub("impact")) == "pii"
|
||||
assert determine_initial_classification(_technique_stub("Exfiltration")) == "pii"
|
||||
|
||||
Reference in New Issue
Block a user