From 226bec2f66d3297def8a56ea0f42ed966c890baa Mon Sep 17 00:00:00 2001 From: Andreas Ellewsen <andreas@ellewsen.no> Date: Tue, 3 May 2022 10:54:49 +0200 Subject: [PATCH] Prepare for guest migration Introduces the new identity type migration id, meant to be used when migrating a person from another system. The cerebrum guest import script has been expanded to use this new migration id. The script has also gotten an option to import people without the necessary IDs (NIN/Passport) so that we can generate IDs for them in GREG. The can then be imported by cerebrum manually before we add the remaning info from a different source. In this case we use old info from UiO SAP. --- greg/management/commands/import_guests.py | 36 +++++++++++++++++++-- greg/migrations/0022_alter_identity_type.py | 29 +++++++++++++++++ greg/models.py | 2 ++ 3 files changed, 64 insertions(+), 3 deletions(-) create mode 100644 greg/migrations/0022_alter_identity_type.py diff --git a/greg/management/commands/import_guests.py b/greg/management/commands/import_guests.py index 3af001a5..5dec520e 100644 --- a/greg/management/commands/import_guests.py +++ b/greg/management/commands/import_guests.py @@ -4,13 +4,12 @@ Import guestsdata from json. import datetime import json - from typing import Optional import structlog -# from django.conf import settings from django.core.management.base import BaseCommand, CommandParser +from django.db import IntegrityError from django.utils.timezone import make_aware from greg.models import ( @@ -38,6 +37,7 @@ class Command(BaseCommand): Identity.IdentityType.FEIDE_ID, Identity.IdentityType.NORWEGIAN_NATIONAL_ID_NUMBER, Identity.IdentityType.PASSPORT_NUMBER, + Identity.IdentityType.MIGRATION_ID, ] REQUIRED_IDS = [ @@ -49,6 +49,7 @@ class Command(BaseCommand): super().__init__(*args, **kwargs) self._orgunit_id_type = "legacy_stedkode" self._end_date = datetime.datetime.today() + datetime.timedelta(days=100) + self._ignore_id_req = False def add_arguments(self, parser: CommandParser) -> None: parser.add_argument( @@ -66,6 +67,12 @@ class Command(BaseCommand): type=datetime.date.fromisoformat, help="End date of roles. Default: today + 100 days", ) + parser.add_argument( + "--ignore_id_req", + default=False, + action="store_true", + help="Imports people without required ids if set", + ) def _find_person_from_ids(self, ids: dict) -> Optional[Person]: """ @@ -231,10 +238,31 @@ class Command(BaseCommand): matching_ids = [x for x in id_data if x["id_type"] in self.REQUIRED_IDS] return len(matching_ids) > 0 + def create_migration_entry(self, person: Person, external_id: str): + """Mark the person with entity id from cerebrum""" + + existing_entry = Identity.objects.filter( + person=person, type=Identity.IdentityType.MIGRATION_ID, value=external_id + ) + if existing_entry: + return + try: + Identity.objects.create( + person=person, + type=Identity.IdentityType.MIGRATION_ID, + source="cerebrum", + value=external_id, + verified=Identity.Verified.AUTOMATIC, + verified_at=make_aware(datetime.datetime.now()), + ) + except IntegrityError as e: + logger.error("Migration ID in use by a different person") + raise e + def upsert_person(self, external_id: str, data: dict) -> Optional[Person]: """Add or update person""" - if not self._has_required_id(data["ids"]): + if not self._ignore_id_req and not self._has_required_id(data["ids"]): logger.error("missing_required_id", external_id=external_id) return None @@ -263,6 +291,7 @@ class Command(BaseCommand): self.upsert_identity(person, identity) for role in data["role"]: self.upsert_role(person, role) + self.create_migration_entry(person, external_id) return person def handle(self, *args, **options): @@ -272,6 +301,7 @@ class Command(BaseCommand): self._orgunit_id_type = options["orgunit_type"] self._end_date = options["end_date"] + self._ignore_id_req = options["ignore_id_req"] with open(options["file"], "r", encoding="UTF-8") as fp: persons = json.load(fp) diff --git a/greg/migrations/0022_alter_identity_type.py b/greg/migrations/0022_alter_identity_type.py new file mode 100644 index 00000000..8561da28 --- /dev/null +++ b/greg/migrations/0022_alter_identity_type.py @@ -0,0 +1,29 @@ +# Generated by Django 4.0.2 on 2022-04-29 14:37 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("greg", "0021_identity_identity_type_value_unique"), + ] + + operations = [ + migrations.AlterField( + model_name="identity", + name="type", + field=models.CharField( + choices=[ + ("feide_id", "Feide Id"), + ("feide_email", "Feide Email"), + ("passport_number", "Passport Number"), + ("norwegian_national_id_number", "Norwegian National Id Number"), + ("private_email", "Private Email"), + ("private_mobile", "Private Mobile Number"), + ("migration_id", "Migration Id"), + ], + max_length=64, + ), + ), + ] diff --git a/greg/models.py b/greg/models.py index 43fe9f07..20e01efc 100644 --- a/greg/models.py +++ b/greg/models.py @@ -272,6 +272,8 @@ class Identity(BaseModel): NORWEGIAN_NATIONAL_ID_NUMBER = "norwegian_national_id_number" PRIVATE_EMAIL = "private_email" PRIVATE_MOBILE_NUMBER = "private_mobile" + # Used to identify the id of this person in some other system + MIGRATION_ID = "migration_id" class Verified(models.TextChoices): AUTOMATIC = "automatic" -- GitLab