diff --git a/tailbone/api/auth.py b/tailbone/api/auth.py index 0fbe8b82..4306da78 100644 --- a/tailbone/api/auth.py +++ b/tailbone/api/auth.py @@ -35,17 +35,6 @@ from tailbone.auth import login_user, logout_user class AuthenticationView(APIView): - def user_info(self, user): - return { - 'ok': True, - 'user': { - 'uuid': user.uuid, - 'username': user.username, - 'display_name': user.display_name, - 'short_name': user.get_short_name(), - }, - } - @api def check_session(self): """ @@ -55,9 +44,7 @@ class AuthenticationView(APIView): """ data = {'ok': True} if self.request.user: - data = self.user_info(self.request.user) - data['user']['is_admin'] = self.request.is_admin - data['user']['is_root'] = self.request.is_root + data['user'] = self.get_user_info(self.request.user) data['permissions'] = list(self.request.tailbone_cached_permissions) @@ -94,7 +81,10 @@ class AuthenticationView(APIView): return {'error': error} login_user(self.request, user) - return self.user_info(user) + return { + 'ok': True, + 'user': self.get_user_info(user), + } def authenticate_user(self, username, password): return authenticate_user(Session(), username, password) @@ -130,7 +120,10 @@ class AuthenticationView(APIView): raise self.forbidden() self.request.user.record_event(self.enum.USER_EVENT_BECOME_ROOT) self.request.session['is_root'] = True - return self.user_info(self.request.user) + return { + 'ok': True, + 'user': self.get_user_info(self.request.user), + } @api def stop_root(self): @@ -141,7 +134,10 @@ class AuthenticationView(APIView): raise self.forbidden() self.request.user.record_event(self.enum.USER_EVENT_STOP_ROOT) self.request.session['is_root'] = False - return self.user_info(self.request.user) + return { + 'ok': True, + 'user': self.get_user_info(self.request.user), + } @classmethod def defaults(cls, config): diff --git a/tailbone/api/core.py b/tailbone/api/core.py index f129ec82..f263450b 100644 --- a/tailbone/api/core.py +++ b/tailbone/api/core.py @@ -2,7 +2,7 @@ ################################################################################ # # Rattail -- Retail Software Framework -# Copyright © 2010-2018 Lance Edgar +# Copyright © 2010-2020 Lance Edgar # # This file is part of Rattail. # @@ -26,6 +26,8 @@ Tailbone Web API - Core Views from __future__ import unicode_literals, absolute_import +from rattail.util import load_object + from tailbone.views import View @@ -68,3 +70,54 @@ class APIView(View): if not dt: return "" return dt.strftime('%Y-%m-%d @ %I:%M %p') + + def get_user_info(self, user): + """ + This method is present on *all* API views, and is meant to provide a + single means of obtaining "common" user info, for return to the caller. + Such info may be returned in several places, e.g. upon login but also + in the "check session" call, or e.g. as part of a broader return value + from any other call. + + :returns: Dictionary of user info data, ready for JSON serialization. + + Note that you should *not* (usually) override this method in any view, + but instead configure a "supplemental" function which can then add or + replace info entries. Config for that looks like e.g.: + + .. code-block:: ini + + [tailbone.api] + extra_user_info = poser.web.api.util:extra_user_info + + Note that the above config assumes a simple *function* defined in your + ``util`` module; such a function would look like e.g.:: + + def extra_user_info(request, user, **info): + # add favorite color + info['favorite_color'] = 'green' + # override display name + info['display_name'] = "TODO" + # remove short_name + info.pop('short_name', None) + return info + """ + # basic / default info + is_admin = user.is_admin() + info = { + 'uuid': user.uuid, + 'username': user.username, + 'display_name': user.display_name, + 'short_name': user.get_short_name(), + 'is_admin': is_admin, + 'is_root': is_admin and self.request.session.get('is_root', False), + } + + # maybe get/use "extra" info + extra = self.rattail_config.get('tailbone.api', 'extra_user_info', + usedb=False) + if extra: + extra = load_object(extra) + info = extra(self.request, user, **info) + + return info