Skip to content

Commit

Permalink
Add function checking for login availability
Browse files Browse the repository at this point in the history
  • Loading branch information
lukasjuhrich committed Sep 4, 2024
1 parent f6a6bc9 commit 700cfc7
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 4 deletions.
29 changes: 25 additions & 4 deletions pycroft/lib/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
from pycroft.helpers.i18n import deferred_gettext
from pycroft.helpers.interval import closed, Interval, starting_from
from pycroft.helpers.printing import generate_user_sheet as generate_pdf
from pycroft.helpers.user import generate_random_str
from pycroft.helpers.user import generate_random_str, login_hash
from pycroft.helpers.utc import DateTimeTz
from pycroft.lib.address import get_or_create_address
from pycroft.lib.exc import PycroftLibException
Expand Down Expand Up @@ -62,7 +62,7 @@
PropertyGroup,
Membership,
)
from pycroft.model.unix_account import UnixAccount
from pycroft.model.unix_account import UnixAccount, UnixTombstone
from pycroft.model.webstorage import WebStorage
from pycroft.task import send_mails_async

Expand Down Expand Up @@ -274,9 +274,15 @@ def create_user(
:param passwd_hash: Use password hash instead of generating a new password
:param send_confirm_mail: If a confirmation mail should be send to the user
:return:
:raises LoginTakenException: if the login is used or has been used in the past
"""

now = session.utcnow()

if not login_available(login, session.session):
raise LoginTakenException(login)

plain_password: str | None = user_helper.generate_password(12)
# create a new user
new_user = User(
Expand Down Expand Up @@ -321,6 +327,20 @@ def create_user(
return new_user, plain_password


def login_available(login: str, session: Session) -> bool:
"""Check whether there is a tombstone with the hash of the given login"""
hash = login_hash(login)
stmt = select(
~func.exists(
select()
.select_from(UnixTombstone)
.filter(UnixTombstone.login_hash == hash)
.add_columns(1)
)
)
return session.scalar(stmt)

Check failure on line 341 in pycroft/lib/user.py

View workflow job for this annotation

GitHub Actions / python-lint

Error

Returning Any from function declared to return "bool" [no-any-return]


@with_transaction
def move_in(
user: User,
Expand Down Expand Up @@ -1139,8 +1159,9 @@ def send_confirmation_email(user: BaseUser) -> None:


class LoginTakenException(PycroftLibException):
def __init__(self) -> None:
super().__init__("Login already taken")
def __init__(self, login: str | None = None) -> None:
msg = "Login already taken" if not login else f"Login {login!r} already taken"
super().__init__(msg)


class EmailTakenException(PycroftLibException):
Expand Down
25 changes: 25 additions & 0 deletions tests/lib/user/test_login_availability.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import pytest

from pycroft.helpers.user import login_hash
from pycroft.lib.user import login_available
from pycroft.model.unix_account import UnixTombstone


def test_login_reuse_present(session, processor):
assert not login_available(processor.login, session)


LOGIN = "taken"


def test_login_reuse_past(session, tombstone):
assert not login_available(LOGIN, session)
assert login_available(f"not-{LOGIN}", session)


@pytest.fixture(scope="module")
def tombstone(module_session) -> UnixTombstone:
ts = UnixTombstone(login_hash=login_hash(LOGIN))
with module_session.begin_nested():
module_session.add(ts)
return ts

0 comments on commit 700cfc7

Please sign in to comment.