Child: [4d7545] (diff)

Download this file

011-fix-subroles.py    94 lines (83 with data), 4.1 kB

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
"""
For projects:
* Admin role.roles should contain Developer, and Developer only
* Developer role.roles should contain Member, and Member only
For project.users:
* user.project_role().roles, if it contains Admin, should not contain
Developer or Member
* user.project_role().roles, if it contains Developer, should not contain
Member
"""
import sys
import logging
from pylons import c
from ming.orm import session
from ming.orm.ormsession import ThreadLocalORMSession
from allura import model as M
log = logging.getLogger('fix-subroles')
log.addHandler(logging.StreamHandler(sys.stdout))
def main():
test = sys.argv[-1] == 'test'
num_projects_examined = 0
log.info('Examining subroles in all non-user projects.')
n_users = M.Neighborhood.query.get(name='Users')
project_filter = dict(neighborhood_id={'$ne':n_users._id})
for some_projects in chunked_project_iterator(project_filter):
for project in some_projects:
project_name = '%s.%s' % (project.neighborhood.name, project.shortname)
project_roles = {}
for parent, child in [('Admin', 'Developer'), ('Developer', 'Member')]:
parent_role = M.ProjectRole.by_name(parent, project=project)
child_role = M.ProjectRole.by_name(child, project=project)
project_roles[parent] = parent_role
project_roles[child] = child_role
if not (parent_role and child_role):
break
if len(parent_role.roles) != 1 or parent_role.roles[0] != child_role._id:
if test:
log.info('Would reset %s subroles for project "%s".' % (parent, project_name))
log.info('- Existing %s subrole(s): %s' % (parent, parent_role.roles))
else:
log.info('Resetting %s subroles for project "%s".' % (parent, project_name))
parent_role.roles = [child_role._id]
ThreadLocalORMSession.flush_all()
if not (project_roles['Admin'] and project_roles['Developer'] \
and project_roles['Member']):
log.info('Skipping "%s": missing Admin, Developer, or Member roles' % project_name)
continue
for user in project.users():
pr = user.project_role(project=project)
if not pr.roles: continue
for parent, children in [('Admin', ('Developer', 'Member')),
('Developer', ('Member',))]:
if project_roles[parent]._id not in pr.roles: continue
for role_name in children:
extra_role = project_roles[role_name]
if extra_role._id in pr.roles:
if test:
log.info('Would remove %s role from user "%s" in project "%s" (already has %s role).' \
% (role_name, user.username, project_name, parent))
pr.roles.remove(extra_role._id)
else:
log.info('Removing %s role from user "%s" in project "%s" (already has %s role).' \
% (role_name, user.username, project_name, parent))
pr.roles.remove(extra_role._id)
ThreadLocalORMSession.flush_all()
num_projects_examined += 1
session(project).clear()
log.info('%s projects examined.' % num_projects_examined)
PAGESIZE=1024
def chunked_project_iterator(q_project):
'''shamelessly copied from refresh-all-repos.py'''
page = 0
while True:
results = (M.Project.query
.find(q_project)
.skip(PAGESIZE*page)
.limit(PAGESIZE)
.all())
if not results: break
yield results
page += 1
if __name__ == '__main__':
main()