From f2f66d7a6c997aa52ba0d0498a6585c18774295d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sybren=20A=2E=20St=C3=BCvel?= Date: Tue, 18 Oct 2016 15:34:39 +0200 Subject: [PATCH] Moved subquery.py from Attract to Pillar, as it's useful for comments too. It's an attempt to speed up common queries which would ordinarily be embedded by Eve. We want to move away from embedding due to security issues (allowing the embedding of users leaks privacy-sensitive info). --- pillar/web/__init__.py | 3 ++- pillar/web/subquery.py | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 pillar/web/subquery.py diff --git a/pillar/web/__init__.py b/pillar/web/__init__.py index 3e9aaa7a..5e959f78 100644 --- a/pillar/web/__init__.py +++ b/pillar/web/__init__.py @@ -1,8 +1,9 @@ def setup_app(app): - from . import main, users, projects, nodes, notifications, redirects + from . import main, users, projects, nodes, notifications, redirects, subquery main.setup_app(app, url_prefix=None) users.setup_app(app, url_prefix=None) redirects.setup_app(app, url_prefix='/r') projects.setup_app(app, url_prefix='/p') nodes.setup_app(app, url_prefix='/nodes') notifications.setup_app(app, url_prefix='/notifications') + subquery.setup_app(app) diff --git a/pillar/web/subquery.py b/pillar/web/subquery.py new file mode 100644 index 00000000..c5f2597e --- /dev/null +++ b/pillar/web/subquery.py @@ -0,0 +1,36 @@ +"""Sub-query stuff, for things we would otherwise let Eve embed (but don't want to). + +Uses app.cache.memoize() to cache the results. However, since this decorator needs +to run in Flask Application context, it is manually applied in setup_app(). +""" + +import pillarsdk +from pillar.web.system_util import pillar_api + + +def get_user_info(user_id): + """Returns email & full name of the user. + + Only returns those two fields, so the return value is the same + for authenticated & non-authenticated users, which is why we're + allowed to cache it globally. + + Returns an empty dict when the user cannot be found. + """ + + if user_id is None: + return {} + + user = pillarsdk.User.find(user_id, api=pillar_api()) + if not user: + return {} + + return {'email': user.email, + 'full_name': user.full_name} + + +def setup_app(app): + global get_user_info + + decorator = app.cache.memoize(timeout=300, make_name='%s.get_user_info' % __name__) + get_user_info = decorator(get_user_info)