From cab1fc4a1f45a68e81ccc7f9fc1a263638a415a7 Mon Sep 17 00:00:00 2001 From: Jitka Obselkova Date: Fri, 20 Oct 2023 14:10:58 +0200 Subject: [PATCH] Bypass row-level security in CVSS scores migrations --- osidb/migrations/0099_fix_flawcvss.py | 98 +++++++++++++++++++++++++ osidb/migrations/0100_fix_affectcvss.py | 85 +++++++++++++++++++++ 2 files changed, 183 insertions(+) create mode 100644 osidb/migrations/0099_fix_flawcvss.py create mode 100644 osidb/migrations/0100_fix_affectcvss.py diff --git a/osidb/migrations/0099_fix_flawcvss.py b/osidb/migrations/0099_fix_flawcvss.py new file mode 100644 index 000000000..243341325 --- /dev/null +++ b/osidb/migrations/0099_fix_flawcvss.py @@ -0,0 +1,98 @@ +""" +Written manually on 2023-10-20. +This fixes migration 0092, which was missing the correct ACLs. +""" + +from osidb.core import set_user_acls + +from django.conf import settings +from django.db import migrations +from itertools import islice + +BATCH_SIZE = 1000 + + +def generate_flawcvss(apps): + Flaw = apps.get_model("osidb", "Flaw") + FlawCVSS = apps.get_model("osidb", "FlawCVSS") + + for flaw in Flaw.objects.iterator(): + # Default values + nist_cvss2_score, nist_cvss2_vector = 0.0, "" + nist_cvss3_score, nist_cvss3_vector = 0.0, "" + rh_cvss2_score, rh_cvss2_vector = 0.0, "" + rh_cvss3_score, rh_cvss3_vector, rh_cvss3_comment = 0.0, "", "" + + other_fields = { + "acl_read": flaw.acl_read, + "acl_write": flaw.acl_write, + "created_dt": flaw.created_dt, + "updated_dt": flaw.updated_dt, + } + + if flaw.nvd_cvss2: + nist_cvss2_score, nist_cvss2_vector = flaw.nvd_cvss2.split("/", 1) + + if flaw.nvd_cvss3: + nist_cvss3_score, nist_cvss3_vector = flaw.nvd_cvss3.split("/", 1) + + if flaw.cvss2: + rh_cvss2_score, rh_cvss2_vector = flaw.cvss2.split("/", 1) + + if flaw.cvss3: + rh_cvss3_score, rh_cvss3_vector = flaw.cvss3.split("/", 1) + + if flaw.meta_attr.get("cvss3_comment"): + rh_cvss3_comment = flaw.meta_attr.get("cvss3_comment") + + for issuer, version, vector, score, comment in [ + ("RH", "V3", rh_cvss3_vector, float(rh_cvss3_score), rh_cvss3_comment), + ("RH", "V2", rh_cvss2_vector, float(rh_cvss2_score), ""), + ("NIST", "V3", nist_cvss3_vector, float(nist_cvss3_score), ""), + ("NIST", "V2", nist_cvss2_vector, float(nist_cvss2_score), ""), + ]: + if vector: + yield FlawCVSS( + flaw=flaw, + issuer=issuer, + version=version, + vector=vector, + score=score, + comment=comment, + **other_fields, + ) + + +def forwards_func(apps, schema_editor): + set_user_acls( + settings.PUBLIC_READ_GROUPS + + [ + settings.PUBLIC_WRITE_GROUP, + settings.EMBARGO_READ_GROUP, + settings.EMBARGO_WRITE_GROUP, + ] + ) + + FlawCVSS = apps.get_model("osidb", "FlawCVSS") + # to ensure that everything will be migrated again with correct ACLs + FlawCVSS.objects.all().delete() + + generator = generate_flawcvss(apps) + while True: + # Limiting memory usage by using a generator and slicing recommended in + # https://docs.djangoproject.com/en/3.2/ref/models/querysets/#bulk-create + batch = list(islice(generator, BATCH_SIZE)) + if not batch: + break + + FlawCVSS.objects.bulk_create(batch, BATCH_SIZE, ignore_conflicts=False) + + +class Migration(migrations.Migration): + dependencies = [ + ("osidb", "0098_ps_contact_blank"), + ] + + operations = [ + migrations.RunPython(forwards_func, migrations.RunPython.noop, atomic=True), + ] diff --git a/osidb/migrations/0100_fix_affectcvss.py b/osidb/migrations/0100_fix_affectcvss.py new file mode 100644 index 000000000..9b08b120d --- /dev/null +++ b/osidb/migrations/0100_fix_affectcvss.py @@ -0,0 +1,85 @@ +""" +Written manually on 2023-10-20. +This fixes migration 0093, which was missing the correct ACLs. +""" + +from osidb.core import set_user_acls + +from django.conf import settings +from django.db import migrations +from itertools import islice + +BATCH_SIZE = 1000 + + +def generate_affectcvss(apps): + Affect = apps.get_model("osidb", "Affect") + AffectCVSS = apps.get_model("osidb", "AffectCVSS") + + for affect in Affect.objects.iterator(): + # Default values + cvss2_score, cvss2_vector = 0.0, "" + cvss3_score, cvss3_vector = 0.0, "" + + other_fields = { + "acl_read": affect.acl_read, + "acl_write": affect.acl_write, + "created_dt": affect.created_dt, + "updated_dt": affect.updated_dt, + } + + if affect.cvss2: + cvss2_score, cvss2_vector = affect.cvss2.split("/", 1) + + if affect.cvss3: + cvss3_score, cvss3_vector = affect.cvss3.split("/", 1) + + for version, vector, score in [ + ("V3", cvss3_vector, float(cvss3_score)), + ("V2", cvss2_vector, float(cvss2_score)), + ]: + if vector: + yield AffectCVSS( + affect=affect, + issuer="RH", + version=version, + vector=vector, + score=score, + comment="", + **other_fields, + ) + + +def forwards_func(apps, schema_editor): + set_user_acls( + settings.PUBLIC_READ_GROUPS + + [ + settings.PUBLIC_WRITE_GROUP, + settings.EMBARGO_READ_GROUP, + settings.EMBARGO_WRITE_GROUP, + ] + ) + + AffectCVSS = apps.get_model("osidb", "AffectCVSS") + # to ensure that everything will be migrated again with correct ACLs + AffectCVSS.objects.all().delete() + + generator = generate_affectcvss(apps) + while True: + # Limiting memory usage by using a generator and slicing recommended in + # https://docs.djangoproject.com/en/3.2/ref/models/querysets/#bulk-create + batch = list(islice(generator, BATCH_SIZE)) + if not batch: + break + + AffectCVSS.objects.bulk_create(batch, BATCH_SIZE, ignore_conflicts=False) + + +class Migration(migrations.Migration): + dependencies = [ + ("osidb", "0099_fix_flawcvss"), + ] + + operations = [ + migrations.RunPython(forwards_func, migrations.RunPython.noop, atomic=True), + ]