Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable updating nin #716

Merged
merged 13 commits into from
Nov 28, 2024
15 changes: 14 additions & 1 deletion src/eduid/webapp/common/api/decorators.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,11 @@
FluxResponseStatus,
FluxSuccessResponse,
)
from eduid.webapp.common.api.utils import get_user
from eduid.webapp.common.api.utils import get_reference_nin_from_navet_data, get_user
from eduid.webapp.common.session import session
from eduid.webapp.letter_proofing.app import LetterProofingApp
from eduid.webapp.lookup_mobile_proofing.app import MobileProofingApp
from eduid.webapp.oidc_proofing.app import OIDCProofingApp

__author__ = "lundberg"

Expand Down Expand Up @@ -116,6 +119,16 @@ def verify_identity_decorator(*args: Any, **kwargs: Any) -> EduidViewReturnType:
if isinstance(locked_nin, NinIdentity) and locked_nin.number != kwargs["nin"]:
logger.info("User has a different locked NIN")
logger.debug(f"Locked NIN: {locked_nin.number}. New NIN: {kwargs['nin']}")
if isinstance(session.app, MobileProofingApp | LetterProofingApp | OIDCProofingApp):
helylle marked this conversation as resolved.
Show resolved Hide resolved
ref = get_reference_nin_from_navet_data(kwargs["nin"])
logger.debug(f"New NIN has reference NIN: {ref}")
# If the reference NIN is the same as the locked NIN, we can continue with the verification
if locked_nin.number == ref:
logger.info(
"User has a different locked NIN but it is the same as the reference NIN for the new NIN"
)
return f(*args, **kwargs)

return error_response(message=CommonMsg.user_has_other_locked_nin)

return f(*args, **kwargs)
Expand Down
17 changes: 15 additions & 2 deletions src/eduid/webapp/common/api/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
from eduid.userdb.user import TUserSubclass, User
from eduid.userdb.userdb import UserDB
from eduid.webapp.common.api.app import EduIDBaseApp
from eduid.webapp.common.api.utils import get_from_current_app, save_and_sync_user
from eduid.webapp.common.api.utils import get_from_current_app, get_reference_nin_from_navet_data, save_and_sync_user

__author__ = "lundberg"

Expand Down Expand Up @@ -235,6 +235,10 @@ def verify_nin_for_user(
current_app.logger.debug(f"NIN: {proofing_user.identities.nin.number}")
return True

reference_nin = get_reference_nin_from_navet_data(proofing_state.nin.number)
if reference_nin is not None:
current_app.logger.debug(f"verified nin has reference_nin: {reference_nin}")

# check if the users current nin is the same as the one just verified
# if there is no locked nin identity or the locked nin identity matches we can replace the current nin identity
# with the one just verified
Expand All @@ -244,8 +248,9 @@ def verify_nin_for_user(
if (
proofing_user.locked_identity.nin is not None
and proofing_user.locked_identity.nin.number != proofing_state.nin.number
and proofing_user.locked_identity.nin.number != reference_nin
):
raise LockedIdentityViolation("users locked nin does not match verified nin")
raise LockedIdentityViolation("users locked nin does not match verified nin or reference nin")

# user has no locked nin identity or the user has previously verified the nin
# replace the never verified nin with the one just verified
Expand All @@ -268,6 +273,14 @@ def verify_nin_for_user(
proofing_user.identities.nin.proofing_method = proofing_method
proofing_user.identities.nin.proofing_version = proofing_log_entry.proofing_version

# Replace locked nin with verified nin if it has changed in the population registry
if (
reference_nin is not None
and proofing_user.locked_identity.nin is not None
and proofing_user.locked_identity.nin.number == reference_nin
):
proofing_user.locked_identity.replace(element=nin_identity)

# Update users name
proofing_user = set_user_names_from_nin_proofing(user=proofing_user, proofing_log_entry=proofing_log_entry)

Expand Down
14 changes: 14 additions & 0 deletions src/eduid/webapp/common/api/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

from eduid.common.config.base import EduIDBaseAppConfig, Pysaml2SPConfigMixin
from eduid.common.misc.timeutil import utc_now
from eduid.common.rpc.msg_relay import MsgRelay
from eduid.userdb import User, UserDB
from eduid.userdb.exceptions import MultipleUsersReturned, UserDBValueError, UserDoesNotExist
from eduid.webapp.common.api.exceptions import ApiException
Expand Down Expand Up @@ -294,3 +295,16 @@ def is_throttled(ts: datetime, min_wait: timedelta) -> bool:

def is_expired(ts: datetime, max_age: timedelta) -> bool:
return utc_now() - ts > max_age


def get_reference_nin_from_navet_data(nin: str) -> str | None:
"""
Check if the NIN has changed in Navet data.
"""
msg_relay = get_from_current_app("msg_relay", MsgRelay)

navet_data = msg_relay.get_all_navet_data(nin=nin)
if navet_data.person.reference_national_identity_number:
return navet_data.person.reference_national_identity_number
else:
return None
12 changes: 0 additions & 12 deletions src/eduid/workers/msg/tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -153,10 +153,6 @@ def get_postal_address(self, identity_number: str) -> OrderedDict[str, Any] | No
:param identity_number: Swedish national identity number
:return: dict containing name and postal address
"""
# Only log the message if devel_mode is enabled
if MsgCelerySingleton.worker_config.devel_mode is True:
return self.get_devel_postal_address()

data = self._get_navet_data(identity_number)
# Filter name and address from the Navet lookup results
return navet_get_name_and_official_address(data)
Expand Down Expand Up @@ -187,10 +183,6 @@ def get_relations(self, identity_number: str) -> OrderedDict[str, Any] | None:
:param identity_number: Swedish national identity number
:return: dict containing name and postal address
"""
# Only log the message if devel_mode is enabled
if MsgCelerySingleton.worker_config.devel_mode is True:
return self.get_devel_relations()

data = self._get_navet_data(identity_number)
# Filter relations from the Navet lookup results
return navet_get_relations(data)
Expand Down Expand Up @@ -229,10 +221,6 @@ def get_devel_relations() -> OrderedDict[str, Any]:
return result

def get_all_navet_data(self, identity_number: str) -> OrderedDict[str, Any] | None:
# Only log the message if devel_mode is enabled
if MsgCelerySingleton.worker_config.devel_mode is True:
return self.get_devel_all_navet_data(identity_number)

data = self._get_navet_data(identity_number)
return navet_get_all_data(data)

Expand Down