--- a/Allura/allura/lib/security.py +++ b/Allura/allura/lib/security.py @@ -21,6 +21,12 @@ def __init__(self): self.clear() + @property + def project_role(self): + from allura import model as M + db = M.session.main_doc_session.db + return db[M.ProjectRole.__mongometa__.name] + @classmethod def get(cls): 'get the global Credentials instance' @@ -33,43 +39,47 @@ self.projects = {} def clear_user(self, user_id, project_id=None): - self.users.pop((user_id, project_id), None) + if project_id == '*': + to_remove = [(uid, pid) for uid, pid in self.users if uid == user_id] + else: + to_remove = [(user_id, project_id)] + for uid, pid in to_remove: + self.projects.pop(pid, None) + self.users.pop((uid, pid), None) def load_user_roles(self, user_id, *project_ids): '''Load the credentials with all user roles for a set of projects''' - from allura import model as M # Don't reload roles project_ids = [ pid for pid in project_ids if self.users.get((user_id, pid)) is None ] - if not project_ids: return + if not project_ids: return if user_id is None: - q = M.ProjectRole.query.find( - dict( - project_id={'$in': project_ids}, - name='*anonymous')) + q = self.project_role.find({ + 'project_id': {'$in': project_ids}, + 'name': '*anonymous'}) else: - q0 = M.ProjectRole.query.find( - dict(project_id={'$in': list(project_ids)}, - name={'$in':['*anonymous', '*authenticated']})) - q1 = M.ProjectRole.query.find( - dict(project_id={'$in': list(project_ids)},user_id=user_id)) + q0 = self.project_role.find({ + 'project_id': {'$in': project_ids}, + 'name': {'$in': ['*anonymous', '*authenticated']}}) + q1 = self.project_role.find({ + 'project_id': {'$in': project_ids}, + 'user_id': user_id}) q = chain(q0, q1) roles_by_project = dict((pid, []) for pid in project_ids) for role in q: - roles_by_project[role.project_id].append(role) + roles_by_project[role['project_id']].append(role) for pid, roles in roles_by_project.iteritems(): self.users[user_id, pid] = RoleCache(self, roles) def load_project_roles(self, *project_ids): '''Load the credentials with all user roles for a set of projects''' - from allura import model as M # Don't reload roles project_ids = [ pid for pid in project_ids if self.projects.get(pid) is None ] - if not project_ids: return - q = M.ProjectRole.query.find(dict( - project_id={'$in': project_ids})) + if not project_ids: return + q = self.project_role.find({ + 'project_id': {'$in': project_ids}}) roles_by_project = dict((pid, []) for pid in project_ids) for role in q: - roles_by_project[role.project_id].append(role) + roles_by_project[role['project_id']].append(role) for pid, roles in roles_by_project.iteritems(): self.projects[pid] = RoleCache(self, roles) @@ -87,14 +97,13 @@ ''' :returns: a RoleCache of ProjectRoles for given user_id and project_id, *anonymous and *authenticated checked as appropriate ''' - from allura import model as M roles = self.users.get((user_id, project_id)) if roles is None: if project_id is None: if user_id is None: q = [] else: - q = M.ProjectRole.query.find(dict(user_id=user_id)) + q = self.project_role.find({'user_id': user_id}) roles = RoleCache(self, q) else: self.load_user_roles(user_id, project_id) @@ -126,7 +135,7 @@ def _iter(): for r in self: for k,v in tests: - val = getattr(r, k) + val = r.get(k) if callable(v): if not v(val): break elif v != val: break @@ -146,19 +155,19 @@ @LazyProperty def index(self): - return dict((r._id, r) for r in self.q) + return dict((r['_id'], r) for r in self.q) @LazyProperty def named(self): return RoleCache(self.cred, ( r for r in self - if r.name and not r.name.startswith('*'))) + if r.get('name') and not r.get('name').startswith('*'))) @LazyProperty def reverse_index(self): rev_index = defaultdict(list) for r in self: - for rr_id in r.roles: + for rr_id in r['roles']: rev_index[rr_id].append(r) return rev_index @@ -169,22 +178,22 @@ to_visit = list(self) while to_visit: r = to_visit.pop(0) - if r in visited: continue - visited.add(r) + if r['_id'] in visited: continue + visited.add(r['_id']) yield r - pr_rindex = self.cred.project_roles(r.project_id).reverse_index - to_visit += pr_rindex[r._id] + pr_rindex = self.cred.project_roles(r['project_id']).reverse_index + to_visit += pr_rindex[r['_id']] return RoleCache(self.cred, _iter()) @LazyProperty def users_that_reach(self): - return [ - r.user for r in self.roles_that_reach if r.user ] + from allura import model as M + uids = [uid for uid in self.userids_that_reach if uid] + return M.User.query.find({'_id': {'$in': uids}}) @LazyProperty def userids_that_reach(self): - return [ - r.user_id for r in self.roles_that_reach ] + return [ r['user_id'] for r in self.roles_that_reach ] @LazyProperty def reaching_roles(self): @@ -195,16 +204,16 @@ (rid, role) = to_visit.pop() if rid in visited: continue yield role - pr_index = self.cred.project_roles(role.project_id).index + pr_index = self.cred.project_roles(role['project_id']).index if rid in pr_index: - for i in pr_index[rid].roles: + for i in pr_index[rid]['roles']: if i in pr_index: to_visit.append((i, pr_index[i])) return RoleCache(self.cred, _iter()) @LazyProperty def reaching_ids(self): - return [ r._id for r in self.reaching_roles ] + return [ r['_id'] for r in self.reaching_roles ] @LazyProperty def reaching_ids_set(self):