From de2bf6a81abe9af60cda0af7e5741b74f61edb88 Mon Sep 17 00:00:00 2001 From: Ethan Dalool Date: Sun, 6 Nov 2022 22:51:53 -0800 Subject: [PATCH] Move login code over to User object. --- etiquette/objects.py | 10 ++++++++++ etiquette/photodb.py | 19 ------------------- .../backend/endpoints/user_endpoints.py | 16 ++++++++++------ 3 files changed, 20 insertions(+), 25 deletions(-) diff --git a/etiquette/objects.py b/etiquette/objects.py index 4136762..8a1ed75 100644 --- a/etiquette/objects.py +++ b/etiquette/objects.py @@ -1947,6 +1947,16 @@ class User(ObjectBase): def _uncache(self): self.photodb.caches[User].remove(self.id) + @decorators.required_feature('user.login') + def check_password(self, password): + if not isinstance(password, bytes): + password = password.encode('utf-8') + + success = bcrypt.checkpw(password, self.password_hash) + if not success: + raise exceptions.WrongLogin() + return success + @decorators.required_feature('user.edit') @worms.atomic def delete(self, *, disown_authored_things) -> None: diff --git a/etiquette/photodb.py b/etiquette/photodb.py index 12bc3cd..fcd84d8 100644 --- a/etiquette/photodb.py +++ b/etiquette/photodb.py @@ -1117,25 +1117,6 @@ class PDBUserMixin: def get_users_by_sql(self, query, bindings=None) -> typing.Iterable[objects.User]: return self.get_objects_by_sql(objects.User, query, bindings) - @decorators.required_feature('user.login') - def login(self, username=None, id=None, *, password) -> objects.User: - ''' - Return the User object for the user if the credentials are correct. - ''' - try: - user = self.get_user(username=username, id=id) - except exceptions.NoSuchUser: - raise exceptions.WrongLogin() - - if not isinstance(password, bytes): - password = password.encode('utf-8') - - success = bcrypt.checkpw(password, user.password_hash) - if not success: - raise exceptions.WrongLogin() - - return user - @decorators.required_feature('user.new') @worms.atomic def new_user(self, username, password, *, display_name=None) -> objects.User: diff --git a/frontends/etiquette_flask/backend/endpoints/user_endpoints.py b/frontends/etiquette_flask/backend/endpoints/user_endpoints.py index b5fa6cc..fb3af3b 100644 --- a/frontends/etiquette_flask/backend/endpoints/user_endpoints.py +++ b/frontends/etiquette_flask/backend/endpoints/user_endpoints.py @@ -77,18 +77,22 @@ def post_login(): username = request.form['username'] password = request.form['password'] try: - # Consideration: Should the server hash the password to discourage - # information (user exists) leak via response time? - # Currently I think not, because they can check if the account - # page 404s anyway. - user = common.P.login(username=username, password=password) - except (etiquette.exceptions.NoSuchUser, etiquette.exceptions.WrongLogin): + user = common.P_user(username, 'json') + except (etiquette.exceptions.NoSuchUser): + exc = etiquette.exceptions.WrongLogin() + response = exc.jsonify() + return flasktools.json_response(response, status=404) + + try: + user.check_password(password) + except (etiquette.exceptions.WrongLogin): exc = etiquette.exceptions.WrongLogin() response = exc.jsonify() return flasktools.json_response(response, status=422) except etiquette.exceptions.FeatureDisabled as exc: response = exc.jsonify() return flasktools.json_response(response, status=400) + session = sessions.Session(request, user) session_manager.add(session) return flasktools.json_response({})