1 from __future__ import print_function
3 from argparse import ArgumentParser
5 from sfa.util.config import Config
6 from sfa.storage.alchemy import alchemy
7 from sfa.storage.model import RegRecord
8 from sfa.trust.hierarchy import Hierarchy
11 WARNING : This script is not exactly thoroughly tested
15 * backup the /var/lib/sfa/authorities tree
16 * make sure to keep all this for a while
17 in case for example the old uuids turn out to be needed
21 Regenerates gids; mostly useful when your root gid is old or obsolete
22 for any other reason (like, it's still md5 signed)
26 all : regenerate everything no matter what, including toplevel gid
27 safe : regenerate everything *except* toplevel
28 incremental : was useful during development mostly;
32 authorities : a new gid is issued
33 users : a new gid is created with email, pubkey, and uuid restored from the previous ones
37 . do the backups - see above
38 . shutdown your sfa service
39 . rm -rf /var/lib/sfa/authorities
40 . run the script (run directly with python, no entry point is installed in PATH)
43 . on the client side, trash any old sscert or gids or similar
49 def __init__(self, session, tophrn):
50 self.session = session
53 def load_local_records(self):
55 read the database for records that start with tophrn.*
58 # just making sure we don't mess with anything else
59 # than our own local business
60 self.records = self.session.query(RegRecord)\
61 .filter(RegRecord.hrn.op('~')("{}.*".format(self.tophrn)))\
62 .order_by(RegRecord.hrn)
64 def regenerate(self, policy='safe'):
66 For all local records, gid gets regenerated
67 policy parameter works as follows
69 all gids get renewed, including toplevel hrn, no matter what
71 gid for toplevel hrn gets regenerated only if not yet existing
72 in SFA_DATA_DIR (i.e. /var/lib/sfa/authorities/<hrn>/hrn.{gid,key})
75 recreate only for entities not present in SFA_DATA_DIR
78 count_auths, count_users = 0, 0
79 hierarchy = Hierarchy()
80 for record in self.records:
81 ########## not an autority nor a user : ignored
82 if 'authority' not in record.type and 'user' not in record.type:
85 message = '[GID cleared]'
87 print("SKP (non-auth) {} {} : {}"
88 .format(message, record.type, record.hrn))
90 ########## toplevel : be careful
91 if record.hrn == self.tophrn:
93 print("SKP (toplevel) - type={} - policy={}"
94 .format(record.type, policy))
96 ########## user : rebuild a gid from pubkey and email
97 if record.type == 'user':
99 gid = record.get_gid_object()
100 uuid = gid.get_uuid()
101 pub = gid.get_pubkey()
102 email = gid.get_email()
103 print("pub {} uuid {}... email {}".format(pub, str(uuid)[:6], email))
104 new_gid = hierarchy.create_gid(hrn, uuid, pub, email=email)
105 new_gid_str = new_gid.save_to_string()
106 record.gid = new_gid_str
107 print("NEW {} {} [{}]".format(record.type, record.hrn, email))
110 ########## authorities
111 if policy in ('all', 'safe'):
114 redo = not hierarchy.auth_exists(record.hrn)
116 print("IGN (existing) {}".format(record.hrn))
118 print("NEW {} {}".format(record.type, record.hrn))
119 # because we have it sorted we should not need create_parents
120 gid = hierarchy.create_auth(str(record.hrn))
124 print("Committing to the DB {} new auth gids and {} new user gids"
125 .format(count_auths, count_users))
126 self.session.commit()
130 parser = ArgumentParser()
131 parser.add_argument("--policy", choices=('all', 'safe', 'incremental'),
133 args = parser.parse_args()
135 self.load_local_records()
136 return 0 if self.regenerate(args.policy) else 1
139 if __name__ == '__main__':
140 session = alchemy.session()
141 tophrn = Config().SFA_REGISTRY_ROOT_AUTH
142 SfaResetGids(session, tophrn).main()