Files
zulip/zilencer/migrations/0026_auditlog_models_extra_data_json.py
Zixuan Li e39e04c3ce migration: Add extra_data_json for audit log models.
Note that we use the DjangoJSONEncoder so that we have builtin support
for parsing Decimal and datetime.

During this intermediate state, the migration that creates
extra_data_json field has been run. We prepare for running the backfilling
migration that populates extra_data_json from extra_data.

This change implements double-write, which is important to keep the
state of extra data consistent. For most extra_data usage, this is
handled by the overriden `save` method on `AbstractRealmAuditLog`, where
we either generates extra_data_json using orjson.loads or
ast.literal_eval.

While backfilling ensures that old realm audit log entries have
extra_data_json populated, double-write ensures that any new entries
generated will also have extra_data_json set. So that we can then safely
rename extra_data_json to extra_data while ensuring the non-nullable
invariant.

For completeness, we additionally set RealmAuditLog.NEW_VALUE for
the USER_FULL_NAME_CHANGED event. This cannot be handled with the
overridden `save`.

This addresses: https://github.com/zulip/zulip/pull/23116#discussion_r1040277795

Note that extra_data_json at this point is not used yet. So the test
cases do not need to switch to testing extra_data_json. This is later
done after we rename extra_data_json to extra_data.

Double-write for the remote server audit logs is special, because we only
get the dumped bytes from an external source. Luckily, none of the
payload carries extra_data that is not generated using orjson.dumps for
audit logs of event types in SYNC_BILLING_EVENTS. This can be verified
by looking at:

`git grep -A 6 -E "event_type=.*(USER_CREATED|USER_ACTIVATED|USER_DEACTIVATED|USER_REACTIVATED|USER_ROLE_CHANGED|REALM_DEACTIVATED|REALM_REACTIVATED)"`

Therefore, we just need to populate extra_data_json doing an
orjson.loads call after a None-check.

Co-authored-by: Zixuan James Li <p359101898@gmail.com>
2023-06-07 12:14:43 -07:00

28 lines
797 B
Python

# Generated by Django 4.0.7 on 2022-09-30 20:25
import django
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("zilencer", "0025_alter_remotepushdevicetoken_user_id_drop_index"),
]
operations = [
migrations.AddField(
model_name="remoterealmauditlog",
name="extra_data_json",
field=models.JSONField(
default=dict, encoder=django.core.serializers.json.DjangoJSONEncoder
),
),
migrations.AddField(
model_name="remotezulipserverauditlog",
name="extra_data_json",
field=models.JSONField(
default=dict, encoder=django.core.serializers.json.DjangoJSONEncoder
),
),
]