From d1305fbc1a40a28f4210fabb19c4708ec1fce0b2 Mon Sep 17 00:00:00 2001 From: Jan Max Meyer Date: Wed, 30 Oct 2024 13:09:18 +0100 Subject: [PATCH] feat: Provide a `User.is_active()` function --- src/viur/core/modules/user.py | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/src/viur/core/modules/user.py b/src/viur/core/modules/user.py index f86097e92..63526fe23 100644 --- a/src/viur/core/modules/user.py +++ b/src/viur/core/modules/user.py @@ -450,11 +450,12 @@ def pwrecover(self, recovery_key: str | None = None, skey: str | None = None, *a ) ) - if user_skel["status"] != Status.ACTIVE: # The account is locked or not yet validated. Abort the process. + # If the account is locked or not yet validated, abort the process. + if not self._user_module.is_active(user_skel): raise errors.NotFound( i18n.translate( key="viur.modules.user.passwordrecovery.accountlocked", - defaultText="This account is currently locked. You cannot change it's password.", + defaultText="This account is currently locked. You cannot change its password.", hint="Attempted password recovery on a locked account" ) ) @@ -498,6 +499,7 @@ def transact(key): skel = self._user_module.editSkel() if not key or not skel.fromDB(key): return None + skel["status"] = Status.WAITING_FOR_ADMIN_VERIFICATION \ if self.registrationAdminVerificationRequired else Status.ACTIVE @@ -1374,6 +1376,24 @@ def secondFactorSucceeded(self, provider: UserSecondFactorAuthentication, user_k return self.authenticateUser(user_key) + def is_active(self, skel: skeleton.SkeletonInstance) -> bool: + """ + Hookable check if a user is defined as "active" and can login. + + :param skel: The UserSkel of the user who wants to login. + """ + if "status" in skel: + status = skel["status"] + if not isinstance(status, (Status, int)): + try: + status = int(status) + except ValueError: + status = Status.UNSET + + return status >= Status.ACTIVE.value + + return False + def authenticateUser(self, key: db.Key, **kwargs): """ Performs Log-In for the current session and the given user key. @@ -1388,7 +1408,7 @@ def authenticateUser(self, key: db.Key, **kwargs): raise ValueError(f"Unable to authenticate unknown user {key}") # Verify that this user account is active - if skel["status"] < Status.ACTIVE.value: + if not self.is_active(skel): raise errors.Forbidden("The user is disabled and cannot be authenticated.") # Update session for user @@ -1552,7 +1572,7 @@ def trigger(self, action: str, key: str): def onEdited(self, skel): super().onEdited(skel) # In case the user is set to inactive, kill all sessions - if "status" in skel and skel["status"] < Status.ACTIVE.value: + if not self.is_active(skel): session.killSessionByUser(skel["key"]) def onDeleted(self, skel):