diff options
author | Magnus Hagander | 2023-06-07 20:21:48 +0000 |
---|---|---|
committer | Magnus Hagander | 2023-06-07 20:21:48 +0000 |
commit | 76f248bfeadf7fa43286a7bc15b3bda5cd433e90 (patch) | |
tree | 4dc57f1d05d68aa2653950009f1fffa29f6a53d4 /pgcommitfest/auth.py | |
parent | 325da2e32c92db363247f05d4eb00e747e250935 (diff) |
Sync up to latest version of pgweb auth plugin
Diffstat (limited to 'pgcommitfest/auth.py')
-rw-r--r-- | pgcommitfest/auth.py | 48 |
1 files changed, 43 insertions, 5 deletions
diff --git a/pgcommitfest/auth.py b/pgcommitfest/auth.py index d7bd25c..0a07571 100644 --- a/pgcommitfest/auth.py +++ b/pgcommitfest/auth.py @@ -8,6 +8,8 @@ # * Make sure the view "login" from this module is used for login # * Map an url somwehere (typically /auth_receive/) to the auth_receive # view. +# * To get notified when a user is created from upstream, connect to the signal +# auth_user_created_from_upstream. # * To receive live updates (not just during login), map an url somewhere # (typically /auth_api/) to the auth_api view. # * To receive live updates, also connect to the signal auth_user_data_received. @@ -44,6 +46,9 @@ from Cryptodome import Random import time +# This signal fires when a user is created based on data from upstream. +auth_user_created_from_upstream = Signal(providing_args=['user', ]) + # This signal fires whenever new user data has been received. Note that this # happens *after* first_name, last_name and email has been updated on the user # record, so those are not included in the userdata struct. @@ -104,10 +109,15 @@ def auth_receive(request): return HttpResponse("Missing data in url!", status=400) # Set up an AES object and decrypt the data we received - decryptor = AES.new(base64.b64decode(settings.PGAUTH_KEY), - AES.MODE_CBC, - base64.b64decode(str(request.GET['i']), "-_")) - s = decryptor.decrypt(base64.b64decode(str(request.GET['d']), "-_")).rstrip(b' ').decode('utf8') + try: + decryptor = AES.new(base64.b64decode(settings.PGAUTH_KEY), + AES.MODE_CBC, + base64.b64decode(str(request.GET['i']), "-_")) + s = decryptor.decrypt(base64.b64decode(str(request.GET['d']), "-_")).rstrip(b' ').decode('utf8') + except UnicodeDecodeError: + return HttpResponse("Badly encoded data found", 400) + except Exception: + return HttpResponse("Could not decrypt data", status=400) # Now un-urlencode it try: @@ -174,6 +184,8 @@ We apologize for the inconvenience. ) user.save() + auth_user_created_from_upstream.send(sender=auth_receive, user=user) + # Ok, we have a proper user record. Now tell django that # we're authenticated so it persists it in the session. Before # we do that, we have to annotate it with the backend information. @@ -281,7 +293,7 @@ def auth_api(request): # Unlike the authentication, searching does not involve the browser - we just make # a direct http call. def user_search(searchterm=None, userid=None): - # If upsteam isn't responding quickly, it's not going to respond at all, and + # If upstream isn't responding quickly, it's not going to respond at all, and # 10 seconds is already quite long. socket.setdefaulttimeout(10) if userid: @@ -308,6 +320,30 @@ def user_search(searchterm=None, userid=None): return j +# Subscribe to any changes about this user on the community auth upstream +def subscribe_to_user_changes(userid): + socket.setdefaulttimeout(10) + + body = json.dumps({ + 'u': userid, + }) + + h = hmac.digest( + base64.b64decode(settings.PGAUTH_KEY), + msg=bytes(body, 'utf-8'), + digest='sha512', + ) + + # Ignore the result code, just post it + requests.post( + '{0}subscribe/'.format(settings.PGAUTH_REDIRECT), + data=body, + headers={ + 'X-pgauth-sig': base64.b64encode(h), + }, + ) + + # Import a user into the local authentication system. Will initially # make a search for it, and if anything other than one entry is returned # the import will fail. @@ -335,4 +371,6 @@ def user_import(uid): ) u.save() + auth_user_created_from_upstream.send(sender=user_import, user=u) + return u |