Properly separate the auth.fcgi and unauth.fcgi scripts
[invirt/packages/invirt-web.git] / code / cache_acls.py
1 #!/usr/bin/python
2 from invirt.database import *
3 from invirt.config import structs as config
4 import sys
5 import getafsgroups
6 import subprocess
7
8 def expandLocker(name):
9     try:
10         groups = getafsgroups.getLockerAcl(name)
11     except getafsgroups.AfsProcessError, e:
12         if e.message.startswith("fs: You don't have the required access rights on"):
13             return []
14         elif e.message.endswith("doesn't exist\n"):
15             # presumably deactivated
16             return []
17         else:
18             raise
19     cell = getafsgroups.getCell(name)
20     ans = set()
21     for group in groups:
22         if ':' in group:
23             ans.update(getafsgroups.getAfsGroupMembers(group, cell))
24         else:
25             ans.add(group)
26     return ans
27
28 def isUser(name):
29     p = subprocess.Popen(['vos', 'examine', 'user.'+name],
30                          stdout=subprocess.PIPE, stderr=subprocess.PIPE)
31     if p.wait():
32         return False
33     return True
34     
35
36 def expandName(name):
37     if ':' not in name:
38         if isUser(name):
39             return [name]
40         return []
41     try:
42         return getafsgroups.getAfsGroupMembers(name, config.authz.afs.cells[0].cell)
43     except getafsgroups.AfsProcessError:
44         return []
45
46 def accessList(m):
47     people = set()
48     people.update(expandLocker(m.owner))
49     if m.administrator is not None:
50         people.update(expandName(m.administrator))
51     return people
52
53 def refreshMachine(m):
54     people = accessList(m)
55     old_people = set(a.user for a in m.acl)
56     for removed in old_people - people:
57         ma = [x for x in m.acl if x.user == removed][0]
58         session.delete(ma)
59     for p in people - old_people:
60         ma = MachineAccess(user=p)
61         m.acl.append(ma)
62         session.save_or_update(ma)
63     
64 def refreshCache():
65     session.begin()
66
67     try:
68         machines = Machine.query().all()
69         for m in machines:
70             refreshMachine(m)
71         session.flush()
72             
73         # Update the admin ACL as well
74         admin_acl = set(expandName(config.adminacl))
75         old_admin_acl = set(a.user for a in Admin.query())
76         for removed in old_admin_acl - admin_acl:
77             old = Admin.query.filter_by(user=removed).first()
78             session.delete(old)
79         for added in admin_acl - old_admin_acl:
80             a = Admin(user=added)
81             session.save_or_update(a)
82         session.flush()
83     
84         # Atomically execute our changes
85         session.commit()
86     except:
87         # Failed! Rollback all the changes.
88         session.rollback()
89         raise
90
91 if __name__ == '__main__':
92     connect()
93     refreshCache()