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

feat: Provide a User.is_active() function #1309

Merged
merged 3 commits into from
Oct 31, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 24 additions & 4 deletions src/viur/core/modules/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -438,11 +438,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"
)
)
Expand Down Expand Up @@ -486,6 +487,7 @@ def transact(key):
skel = self._user_module.editSkel()
if not key or not skel.read(key):
return None

skel["status"] = Status.WAITING_FOR_ADMIN_VERIFICATION \
if self.registrationAdminVerificationRequired else Status.ACTIVE

Expand Down Expand Up @@ -1367,6 +1369,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.
Expand All @@ -1381,7 +1401,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
Expand Down Expand Up @@ -1547,7 +1567,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):
Expand Down
Loading