Synchronize ssh keys using http API instead of postgresql call
authorMagnus Hagander <magnus@hagander.net>
Sun, 10 Dec 2017 16:22:09 +0000 (17:22 +0100)
committerMagnus Hagander <magnus@hagander.net>
Sun, 10 Dec 2017 16:22:09 +0000 (17:22 +0100)
Finally break the ties with community auth 1.0

keysync.py
pggit.settings.sample

index 50e17b5ad59c1d6aa86a3fbdd24f00621ab4be25..0fff2f0737ff5d35ff1a55f2ff3bfb6f1155bbfd 100644 (file)
@@ -9,7 +9,13 @@ wwwmaster system.
 import sys
 import os
 import psycopg2
-import ConfigParser 
+import ConfigParser
+import requests
+import base64
+import json
+import time
+import datetime
+from Crypto.Cipher import AES
 
 class KeySynchronizer(object):
        def __init__(self, db):
@@ -17,40 +23,39 @@ class KeySynchronizer(object):
 
        def sync(self):
                """
-               Perform the synchronization. This is going to be rather inefficient - we just
-               load up the complete list of users in memory, and then write it to a local table.
-
-               There's not likely (TM) to ever be a lot of data...
+               Perform the synchronization.
                """
-               masterpg = psycopg2.connect(c.get('database','masterdb'))
                curs = self.db.cursor()
-               mcurs = masterpg.cursor()
+
+               # Record synctime at *start* of sync, in case it takes some time
+               synctime = datetime.datetime.now()
 
                # Fetch last sync date, and see if anything has changed since
-               curs.execute("SELECT lastsync FROM key_last_sync LIMIT 1")
+               curs.execute("SELECT lastsync-'5 minutes'::interval FROM key_last_sync LIMIT 1")
                lastsync = curs.fetchone()[0]
 
-               mcurs.execute("SELECT CURRENT_TIMESTAMP, CASE WHEN EXISTS (SELECT * FROM users_keys WHERE sshkey_last_update >= %s) THEN 1 ELSE 0 END", [lastsync])
-               synctime, hasupd = mcurs.fetchone()
-               if hasupd == 0:
-                       return # Nothing changed, just get out
-
-               # Fetch a list of all keys on the master server
-               mcurs.execute("SELECT userid, sshkey FROM users_keys")
-               allkeys = mcurs.fetchall()
-               mcurs.close()
-               masterpg.close()
-
-               # Load them into the local table
-               curs.execute("TRUNCATE TABLE git_users")
-               for row in allkeys:
-                       curs.execute("INSERT INTO git_users (userid, sshkey) VALUES (%s,%s)", row)
-
-               # If there ever turns out to be a bunch, better analyze
-               curs.execute("ANALYZE git_users")
-               
-               # Note the fact that we have synced (note that we use the timestamp value from the master,
-               # in case there is clock skew)
+               r = requests.get("{0}/account/auth/{1}/getkeys/{2}/".format(
+                       c.get('upstream', 'root'),
+                       c.get('upstream', 'siteid'),
+                       int(time.mktime(lastsync.timetuple())),
+               ))
+               if r.status_code != 200:
+                       print("API call failed: %s" % r.status_code)
+                       return
+
+               (ivs, datas) = str(r.text).split('&')
+               decryptor = AES.new(base64.b64decode(c.get('upstream', 'key')),
+                                                       AES.MODE_CBC,
+                                                       base64.b64decode(ivs, "-_"))
+               s = decryptor.decrypt(base64.b64decode(datas, "-_")).rstrip(' ')
+               j = json.loads(s)
+               for u in j:
+                       curs.execute("INSERT INTO git_users (userid, sshkey) VALUES (%(userid)s, %(key)s) ON CONFLICT (userid) DO UPDATE SET sshkey=excluded.sshkey", {
+                               'userid': u['u'],
+                               'key': u['s'],
+                       })
+
+               # Flag our last sync time
                curs.execute("UPDATE key_last_sync SET lastsync=%s", [synctime])
 
                self.db.commit()
index 3b748e146987cb8912b0aab4380c01edbfb32f9d..d5c484b4c4c1abaf3cb1ef65130731ca2489a625 100644 (file)
@@ -1,7 +1,10 @@
 [database]
 db=dbname=pggit host=/tmp/ user=mha
-;masterdb=hostname=wwwmaster.postgresql.org dbname=186_www user=auth_svc
-masterdb=dbname=186_www host=/tmp/ user=mha
+
+[upstream]
+root=http://localhost:8000
+siteid=1
+key=secret
 
 [user]
 user=pggit