Skip to content
Snippets Groups Projects
Verified Commit 226bec2f authored by Andreas Ellewsen's avatar Andreas Ellewsen
Browse files

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.
parent d7aa8a5f
No related branches found
No related tags found
1 merge request!322Prepare for guest migration
Pipeline #131365 passed
...@@ -4,13 +4,12 @@ Import guestsdata from json. ...@@ -4,13 +4,12 @@ Import guestsdata from json.
import datetime import datetime
import json import json
from typing import Optional from typing import Optional
import structlog import structlog
# from django.conf import settings
from django.core.management.base import BaseCommand, CommandParser from django.core.management.base import BaseCommand, CommandParser
from django.db import IntegrityError
from django.utils.timezone import make_aware from django.utils.timezone import make_aware
from greg.models import ( from greg.models import (
...@@ -38,6 +37,7 @@ class Command(BaseCommand): ...@@ -38,6 +37,7 @@ class Command(BaseCommand):
Identity.IdentityType.FEIDE_ID, Identity.IdentityType.FEIDE_ID,
Identity.IdentityType.NORWEGIAN_NATIONAL_ID_NUMBER, Identity.IdentityType.NORWEGIAN_NATIONAL_ID_NUMBER,
Identity.IdentityType.PASSPORT_NUMBER, Identity.IdentityType.PASSPORT_NUMBER,
Identity.IdentityType.MIGRATION_ID,
] ]
REQUIRED_IDS = [ REQUIRED_IDS = [
...@@ -49,6 +49,7 @@ class Command(BaseCommand): ...@@ -49,6 +49,7 @@ class Command(BaseCommand):
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
self._orgunit_id_type = "legacy_stedkode" self._orgunit_id_type = "legacy_stedkode"
self._end_date = datetime.datetime.today() + datetime.timedelta(days=100) self._end_date = datetime.datetime.today() + datetime.timedelta(days=100)
self._ignore_id_req = False
def add_arguments(self, parser: CommandParser) -> None: def add_arguments(self, parser: CommandParser) -> None:
parser.add_argument( parser.add_argument(
...@@ -66,6 +67,12 @@ class Command(BaseCommand): ...@@ -66,6 +67,12 @@ class Command(BaseCommand):
type=datetime.date.fromisoformat, type=datetime.date.fromisoformat,
help="End date of roles. Default: today + 100 days", 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]: def _find_person_from_ids(self, ids: dict) -> Optional[Person]:
""" """
...@@ -231,10 +238,31 @@ class Command(BaseCommand): ...@@ -231,10 +238,31 @@ class Command(BaseCommand):
matching_ids = [x for x in id_data if x["id_type"] in self.REQUIRED_IDS] matching_ids = [x for x in id_data if x["id_type"] in self.REQUIRED_IDS]
return len(matching_ids) > 0 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]: def upsert_person(self, external_id: str, data: dict) -> Optional[Person]:
"""Add or update 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) logger.error("missing_required_id", external_id=external_id)
return None return None
...@@ -263,6 +291,7 @@ class Command(BaseCommand): ...@@ -263,6 +291,7 @@ class Command(BaseCommand):
self.upsert_identity(person, identity) self.upsert_identity(person, identity)
for role in data["role"]: for role in data["role"]:
self.upsert_role(person, role) self.upsert_role(person, role)
self.create_migration_entry(person, external_id)
return person return person
def handle(self, *args, **options): def handle(self, *args, **options):
...@@ -272,6 +301,7 @@ class Command(BaseCommand): ...@@ -272,6 +301,7 @@ class Command(BaseCommand):
self._orgunit_id_type = options["orgunit_type"] self._orgunit_id_type = options["orgunit_type"]
self._end_date = options["end_date"] self._end_date = options["end_date"]
self._ignore_id_req = options["ignore_id_req"]
with open(options["file"], "r", encoding="UTF-8") as fp: with open(options["file"], "r", encoding="UTF-8") as fp:
persons = json.load(fp) persons = json.load(fp)
......
# 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,
),
),
]
...@@ -272,6 +272,8 @@ class Identity(BaseModel): ...@@ -272,6 +272,8 @@ class Identity(BaseModel):
NORWEGIAN_NATIONAL_ID_NUMBER = "norwegian_national_id_number" NORWEGIAN_NATIONAL_ID_NUMBER = "norwegian_national_id_number"
PRIVATE_EMAIL = "private_email" PRIVATE_EMAIL = "private_email"
PRIVATE_MOBILE_NUMBER = "private_mobile" 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): class Verified(models.TextChoices):
AUTOMATIC = "automatic" AUTOMATIC = "automatic"
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment