From cf51d1a280a505bbf4e5f9d95ada87d002892630 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sybren=20A=2E=20St=C3=BCvel?= Date: Wed, 23 Aug 2017 12:16:11 +0200 Subject: [PATCH] Added utility function current_user() that acts like flask_login.current_user This actually returns an AnonymousUser object, instead of None, when the user is not logged in. For compatibility with existing code, this function doesn't set g.current_user to that AnonymousUser instance. We may decide to do this later. --- pillar/api/utils/authentication.py | 19 ++++++++++++++++-- tests/test_api/test_auth.py | 32 ++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 2 deletions(-) diff --git a/pillar/api/utils/authentication.py b/pillar/api/utils/authentication.py index 02fc1176..32d7337b 100644 --- a/pillar/api/utils/authentication.py +++ b/pillar/api/utils/authentication.py @@ -246,8 +246,23 @@ def _delete_expired_tokens(): def current_user_id() -> typing.Optional[bson.ObjectId]: """None-safe fetching of user ID. Can return None itself, though.""" - current_user = g.get('current_user') or {} - return current_user.get('user_id') + user = current_user() + return user.user_id + + +def current_user(): + """Returns the current user, or an AnonymousUser if not logged in. + + :rtype: pillar.auth.UserClass + """ + + import pillar.auth + + user: pillar.auth.UserClass = g.get('current_user') + if user is None: + return pillar.auth.AnonymousUser() + + return user def setup_app(app): diff --git a/tests/test_api/test_auth.py b/tests/test_api/test_auth.py index e2c06b30..f864a1a4 100644 --- a/tests/test_api/test_auth.py +++ b/tests/test_api/test_auth.py @@ -700,3 +700,35 @@ class UserCreationTest(AbstractPillarTest): auth_token='admin-token', expected_status=422) self.put(f'/api/users/{user_id}', json=without_email, etag=etag, auth_token='admin-token', expected_status=422) + + +class CurrentUserTest(AbstractPillarTest): + + def test_current_user_logged_in(self): + self.enter_app_context() + + from flask import g + from pillar.auth import UserClass + from pillar.api.utils.authentication import current_user + + with self.app.test_request_context(): + g.current_user = UserClass.construct('the token', ctd.EXAMPLE_USER) + + user = current_user() + self.assertIs(g.current_user, user) + + def test_current_user_anonymous(self): + self.enter_app_context() + + from flask import g + from pillar.auth import AnonymousUser + from pillar.api.utils.authentication import current_user + + with self.app.test_request_context(): + g.current_user = None + + user = current_user() + self.assertIsInstance(user, AnonymousUser) + self.assertIsNone(user.user_id) + self.assertTrue(user.is_anonymous) + self.assertFalse(user.is_authenticated)