From e37ee54d257e588f78bcdd7577a7027bd764f138 Mon Sep 17 00:00:00 2001 From: Magnus Hagander Date: Sun, 10 Dec 2017 17:23:03 +0100 Subject: [PATCH] Add ability for cauth sites to download ssh public keys This removes the last need to directly access the upstream database (from the git server), so remove that view as well. --- pgweb/account/urls.py | 1 + pgweb/account/views.py | 39 +++++++++++++++++++++++++++++---------- sql/community_login.sql | 22 ---------------------- sql/compat_tables.sql | 20 -------------------- 4 files changed, 30 insertions(+), 52 deletions(-) delete mode 100644 sql/community_login.sql delete mode 100644 sql/compat_tables.sql diff --git a/pgweb/account/urls.py b/pgweb/account/urls.py index 505a5a8f..b3bbfa2f 100644 --- a/pgweb/account/urls.py +++ b/pgweb/account/urls.py @@ -8,6 +8,7 @@ urlpatterns = patterns('', (r'^auth/(\d+)/$', 'pgweb.account.views.communityauth'), (r'^auth/(\d+)/logout/$', 'pgweb.account.views.communityauth_logout'), (r'^auth/(\d+)/search/$', 'pgweb.account.views.communityauth_search'), + (r'^auth/(\d+)/getkeys/(\d+/)?$', 'pgweb.account.views.communityauth_getkeys'), # Profile (r'^profile/$', 'pgweb.account.views.profile'), diff --git a/pgweb/account/views.py b/pgweb/account/views.py index 60f555fc..20af2302 100644 --- a/pgweb/account/views.py +++ b/pgweb/account/views.py @@ -509,6 +509,19 @@ def communityauth_logout(request, siteid): # Redirect user back to the specified suburl return HttpResponseRedirect("%s?s=logout" % site.redirecturl) +def _encrypt_site_response(site, s): + # Encrypt it with the shared key (and IV!) + r = Random.new() + iv = r.read(16) # Always 16 bytes for AES + encryptor = AES.new(base64.b64decode(site.cryptkey), AES.MODE_CBC, iv) + cipher = encryptor.encrypt(s + ' ' * (16-(len(s) % 16))) #Pad to even 16 bytes + + # Base64-encode the response, just to be consistent + return "%s&%s" % ( + base64.b64encode(iv, '-_'), + base64.b64encode(cipher, '-_'), + ) + def communityauth_search(request, siteid): # Perform a search for users. The response will be encrypted with the site # key to prevent abuse, therefor we need the site. @@ -531,14 +544,20 @@ def communityauth_search(request, siteid): j = json.dumps([{'u': u.username, 'e': u.email, 'f': u.first_name, 'l': u.last_name} for u in users]) - # Encrypt it with the shared key (and IV!) - r = Random.new() - iv = r.read(16) # Always 16 bytes for AES - encryptor = AES.new(base64.b64decode(site.cryptkey), AES.MODE_CBC, iv) - cipher = encryptor.encrypt(j + ' ' * (16-(len(j) % 16))) #Pad to even 16 bytes + return HttpResponse(_encrypt_site_response(site, j)) + +def communityauth_getkeys(request, siteid, since=None): + # Get any updated ssh keys for community accounts. + # The response will be encrypted with the site key to prevent abuse, + # therefor we need the site. + site = get_object_or_404(CommunityAuthSite, pk=siteid) + + if since: + keys = UserProfile.objects.select_related('user').filter(lastmodified__gte=datetime.fromtimestamp(int(since.replace('/', '')))).exclude(sshkey='') + else: + keys = UserProfile.objects.select_related('user').all().exclude(sshkey='') + + j = json.dumps([{'u': k.user.username, 's': k.sshkey} for k in keys]) + + return HttpResponse(_encrypt_site_response(site, j)) - # Base64-encode the response, just to be consistent - return HttpResponse("%s&%s" % ( - base64.b64encode(iv, '-_'), - base64.b64encode(cipher, '-_'), - )) diff --git a/sql/community_login.sql b/sql/community_login.sql deleted file mode 100644 index 7f688db9..00000000 --- a/sql/community_login.sql +++ /dev/null @@ -1,22 +0,0 @@ --- --- View that shows the ssh keys, used by services that need them --- (currently just git) --- We know we can't have the same user in both the old and the new --- table, so not doing any magic around that works fine. --- -CREATE OR REPLACE VIEW users_keys AS - SELECT auth_user.username AS userid, - core_userprofile.sshkey, - core_userprofile.lastmodified AS sshkey_last_update - FROM auth_user - JOIN core_userprofile ON auth_user.id = core_userprofile.user_id - WHERE core_userprofile.sshkey <> ''::text - UNION - SELECT users_old.userid, - users_old.sshkey, - users_old.sshkey_last_update - FROM users_old - WHERE users_old.sshkey IS NOT NULL - AND users_old.sshkey <> ''::text - AND NOT EXISTS (SELECT * FROM auth_user a WHERE a.username=users_old.userid) -; diff --git a/sql/compat_tables.sql b/sql/compat_tables.sql deleted file mode 100644 index bb121a46..00000000 --- a/sql/compat_tables.sql +++ /dev/null @@ -1,20 +0,0 @@ --- --- tables created for compatibility with migration from old system. --- Once we drop migration support they can be removed, but for now --- dummies are required for functions to work. --- -CREATE TABLE users_old ( - userid character varying(16), - fullname character varying(128), - authorblurb text, - email character varying(128), - communitydoc_superuser integer, - created timestamp with time zone, - lastlogin timestamp with time zone, - matrixeditor integer, - pwdhash text, - resethash text, - resethashtime timestamp with time zone, - sshkey text, - sshkey_last_update timestamp with time zone -); -- 2.11.4.GIT