diff --git a/README.md b/README.md index 33286bf71ca9de5ebcb9092525d5afad2044dc84..4f5c4692850ecd80fef958bfeea05de9384b9af7 100644 --- a/README.md +++ b/README.md @@ -25,3 +25,52 @@ from postgrestutils.client import pgrest_client res = pgrest_client.get("kerbals?select=id,forename") ``` + +#### Django helpers + +##### custom `user_account_fetched` signal + +`postgrestutils` provides a custom signal called `user_account_fetched` which provides the current request and the account of the current user on login. +To use this feature (and you really should 99.9% of the time) configure your settings accordingly by specifying the columns you need from the `account` endpoint: + +```python +# settings.py +POSTGREST_UTILS_AUTOFETCH = 'person_id,email' # comma-separated string +``` + +When connecting to the signal you will have to provide a callback function. +That function is a great place for your custom logic to fetch and store additional information your app frequently needs into the session. +You can connect to it like so: + +```python +# apps.py +from django.apps import AppConfig +from postgrestutils.signals import user_account_fetched +from your_app.utils import your_callback_func + + +class YourAppConfig(AppConfig): + def ready(self, *args, **kwargs): + super().ready(*args, **kwargs) + user_account_fetched.connect(your_callback_func) +``` + +Your callback function could look something like this: + +```python +# utils.py +from postgrestutils.client import pgrest_client + + +def your_callback_func(sender, **kwargs): + request = kwargs['request'] + account = kwargs['account'] + # fetching some addtional data your project needs frequently using the pgrest_client (person, memberships etc.) + + # 'caching' that data in the session + request.session['account'] = account + request.session['person'] = person + request.session['memberships'] = memberships +``` + +For more information on signals refer to the django docs. They are great. Really. diff --git a/postgrestutils/app_settings.py b/postgrestutils/app_settings.py index e6cafc42c11eb1d933af8a1b0e6bb107a3d48363..df922e39fd3cc164135bec103e221f65df55fe9f 100644 --- a/postgrestutils/app_settings.py +++ b/postgrestutils/app_settings.py @@ -2,6 +2,8 @@ BASE_URI = "http://127.0.0.1:3000" JWT = str() +AUTOFETCH = str() + # merge these settings with django.conf.settings try: from django.conf import settings as django_settings diff --git a/postgrestutils/apps.py b/postgrestutils/apps.py index b7d33ec920d76e30394a26bc3d623cbaf9d92c4d..e0c67da97ffac44bbe7429660d332af1ebbf4d10 100644 --- a/postgrestutils/apps.py +++ b/postgrestutils/apps.py @@ -1,4 +1,7 @@ from django.apps import AppConfig +from django.contrib.auth.signals import user_logged_in +from postgrestutils.helpers import autofetch +from . import app_settings class PostgrestUtilsConfig(AppConfig): @@ -6,3 +9,5 @@ class PostgrestUtilsConfig(AppConfig): def ready(self, *args, **kwargs): super().ready(*args, **kwargs) + if app_settings.AUTOFETCH: + user_logged_in.connect(autofetch) diff --git a/postgrestutils/helpers.py b/postgrestutils/helpers.py new file mode 100644 index 0000000000000000000000000000000000000000..b502ab735da014fdf8f194748d284528c574f6c1 --- /dev/null +++ b/postgrestutils/helpers.py @@ -0,0 +1,22 @@ +from . import app_settings +from django.conf import settings +from .signals import user_account_fetched + +from postgrestutils.client import pgrest_client + + +def autofetch(sender, **kwargs): + """Fetch user account on login based on the AUTOFETCH configuration""" + + payload = { + 'select': app_settings.AUTOFETCH + } + + if settings.DEBUG: + # prod uuids != dev uuids, thus fall back on matching accounts by username + payload['username'] = 'eq.{}'.format(kwargs['user'].get_username()) + else: + payload['auth_provider_uid'] = 'eq.{}'.format(kwargs['user'].sso_mapping.uuid) + + account = pgrest_client.get('account', params=payload, singular=True) + user_account_fetched.send(sender=None, request=kwargs['request'], account=account) diff --git a/postgrestutils/signals.py b/postgrestutils/signals.py new file mode 100644 index 0000000000000000000000000000000000000000..0221d10e2b9ae3d54128f54328f3eedcd3a2b363 --- /dev/null +++ b/postgrestutils/signals.py @@ -0,0 +1,3 @@ +import django.dispatch + +user_account_fetched = django.dispatch.Signal(providing_args=['request', 'account'])