From b53170fd58f346d57ed8d192a7c8ad8b78f4f35a Mon Sep 17 00:00:00 2001
From: Andreas Ellewsen <ae@uio.no>
Date: Wed, 2 Mar 2022 15:13:38 +0100
Subject: [PATCH] Fix bug where nin was not saved from feide

Was removed by mistake at some time in the past. Introduced a few tests
to ensure that things work as expected.

Resolves: GREG-223
---
 gregui/authentication/auth_backends.py        |   2 +-
 .../tests/authentication/test_user_profile.py | 138 ++++++++++++++++++
 2 files changed, 139 insertions(+), 1 deletion(-)

diff --git a/gregui/authentication/auth_backends.py b/gregui/authentication/auth_backends.py
index 8efe0568..c8d5b322 100644
--- a/gregui/authentication/auth_backends.py
+++ b/gregui/authentication/auth_backends.py
@@ -243,7 +243,7 @@ class GregOIDCBackend(ValidatingOIDCBackend):
                 extended_userinfo = self.get_extended_userinfo(access_token)
                 if "norEduPersonNIN" in extended_userinfo:
                     userinfo["userid_nin"] = extended_userinfo["norEduPersonNIN"]
-
+            self._get_or_create_greg_user_profile(userinfo, user)
         return user
 
     def _get_sponsor_from_userinfo(self, userinfo: dict) -> Optional[Sponsor]:
diff --git a/gregui/tests/authentication/test_user_profile.py b/gregui/tests/authentication/test_user_profile.py
index 2b935030..ba5d5190 100644
--- a/gregui/tests/authentication/test_user_profile.py
+++ b/gregui/tests/authentication/test_user_profile.py
@@ -318,3 +318,141 @@ def test_invited_existing_user(invited_person, user_person):
 
     user_profile = GregUserProfile.objects.get(user=user)
     assert user_profile.person == old_person
+
+
+@pytest.mark.django_db
+def test_invited_feide_nin_from_extended(requests_mock, invited_person):
+    """
+    Invitation login, user with existing person and no sponsor object,
+    nin only present in extended userinfo.
+
+    A GregUserProfile should be created, and the person should get feide-id and nin set
+    """
+    person, invitation_link = invited_person
+
+    email = "foo@example.com"
+    feide_id = "bar@example.com"
+    nin = "12345678901"
+    access_token = "foo"
+    id_token = "foo"
+    payload = "foo"
+    requests_mock.get(
+        "https://auth.dataporten.no/openid/userinfo",
+        json={
+            "sub": "subsub",
+            "dataporten-userid_sec": [f"feide:{feide_id}"],
+            "name": f"{person.first_name} {person.last_name}",
+            "email": f"{email}",
+        },
+    )
+    requests_mock.get(
+        "https://api.dataporten.no/userinfo/v1/userinfo", json={"norEduPersonNIN": nin}
+    )
+    auth_request = RequestFactory().get("/foo", {"code": "foo", "state": "bar"})
+    auth_request.session = {"invite_id": invitation_link.uuid}
+
+    backend = GregOIDCBackend()
+    backend.request = auth_request
+
+    # No profile beforehand
+    assert len(GregUserProfile.objects.filter(person_id=person.id)) == 0
+    user = backend.get_or_create_user(access_token, id_token, payload)
+
+    # User profile exists and all things set correctly after
+    user_profile = GregUserProfile.objects.get(user=user)
+    assert user_profile.person == person
+    assert user_profile.person.fnr and user_profile.person.fnr.value == nin
+    assert (
+        user_profile.person.feide_id and user_profile.person.feide_id.value == feide_id
+    )
+    assert user_profile.sponsor is None
+
+
+@pytest.mark.django_db
+def test_invited_feide_nin_from_regular(requests_mock, invited_person):
+    """
+    Invitation login, user with existing person and no sponsor object,
+    nin present in regular userinfo.
+
+    A GregUserProfile should be created, and the person should get feide-id and nin set
+    """
+    person, invitation_link = invited_person
+
+    email = "foo@example.com"
+    feide_id = "bar@example.com"
+    nin = "12345678901"
+    access_token = "foo"
+    id_token = "foo"
+    payload = "foo"
+    requests_mock.get(
+        "https://auth.dataporten.no/openid/userinfo",
+        json={
+            "sub": "subsub",
+            "dataporten-userid_sec": [f"feide:{feide_id}", f"nin:{nin}"],
+            "name": f"{person.first_name} {person.last_name}",
+            "email": f"{email}",
+        },
+    )
+    requests_mock.get("https://api.dataporten.no/userinfo/v1/userinfo", json={})
+    auth_request = RequestFactory().get("/foo", {"code": "foo", "state": "bar"})
+    auth_request.session = {"invite_id": invitation_link.uuid}
+
+    backend = GregOIDCBackend()
+    backend.request = auth_request
+
+    # No profile beforehand
+    assert len(GregUserProfile.objects.filter(person_id=person.id)) == 0
+    user = backend.get_or_create_user(access_token, id_token, payload)
+
+    # User profile exists and all things set correctly after
+    user_profile = GregUserProfile.objects.get(user=user)
+    assert user_profile.person == person
+    assert user_profile.person.fnr and user_profile.person.fnr.value == nin
+    assert (
+        user_profile.person.feide_id and user_profile.person.feide_id.value == feide_id
+    )
+    assert user_profile.sponsor is None
+
+
+@pytest.mark.django_db
+def test_invited_feide_no_nin(requests_mock, invited_person):
+    """
+    Invitation login, user with existing person and no sponsor object,
+    nin not present
+
+    A GregUserProfile should be created, and the person should get feide-id set
+    """
+    person, invitation_link = invited_person
+    email = "foo@example.com"
+    feide_id = "bar@example.com"
+    access_token = "foo"
+    id_token = "foo"
+    payload = "foo"
+    requests_mock.get(
+        "https://auth.dataporten.no/openid/userinfo",
+        json={
+            "sub": "subsub",
+            "dataporten-userid_sec": [f"feide:{feide_id}"],
+            "name": f"{person.first_name} {person.last_name}",
+            "email": f"{email}",
+        },
+    )
+    requests_mock.get("https://api.dataporten.no/userinfo/v1/userinfo", json={})
+
+    auth_request = RequestFactory().get("/foo", {"code": "foo", "state": "bar"})
+    auth_request.session = {"invite_id": invitation_link.uuid}
+    backend = GregOIDCBackend()
+    backend.request = auth_request
+
+    # No profile beforehand
+    assert len(GregUserProfile.objects.filter(person_id=person.id)) == 0
+    user = backend.get_or_create_user(access_token, id_token, payload)
+
+    # User profile exists and all things set correctly after
+    user_profile = GregUserProfile.objects.get(user=user)
+    assert user_profile.person == person
+    assert user_profile.person.fnr is None
+    assert (
+        user_profile.person.feide_id and user_profile.person.feide_id.value == feide_id
+    )
+    assert user_profile.sponsor is None
-- 
GitLab