Parent: [e795ce] (diff)

Child: [b42895] (diff)

Download this file

security.py    96 lines (88 with data), 3.6 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
94
"""
This module provides the security predicates used in decorating various models.
"""
from pylons import c, request
from webob import exc
def has_neighborhood_access(access_type, neighborhood, user=None):
from allura import model as M
def result(user=user):
if user is None: user = c.user
acl = neighborhood.acl[access_type]
anon = M.User.anonymous()
if not acl: return user != anon
for u in acl:
if u == anon._id or u == user._id: return True
return False
return result
def has_project_access(access_type, project=None, user=None,
user_roles=None):
def result(project=project, user=user, user_roles=user_roles):
if project is None: project = c.project
if user is None: user = c.user
if not project.database_configured: return False
assert user, 'c.user should always be at least M.User.anonymous()'
if user_roles is None:
user_roles = set(r._id for r in user.role_iter())
for proj in project.parent_iter():
acl = set(proj.acl.get(access_type, []))
if acl & user_roles: return True
if has_neighborhood_access('admin', project.neighborhood, user)():
return True
return False
return result
def has_artifact_access(access_type, obj=None, user=None, app=None,
user_roles=None):
def result(user=user, app=app, user_roles=user_roles):
if user is None: user = c.user
if app is None: app = c.app
assert user, 'c.user should always be at least M.User.anonymous()'
if user_roles is None:
user_roles = set(r._id for r in user.role_iter())
acl = set(app.config.acl.get(access_type, []))
if obj is not None:
acl |= set(obj.acl.get(access_type, []))
if acl & user_roles: return True
if has_neighborhood_access('admin', app.project.neighborhood, user)():
return True
return False
return result
def require(predicate, message=None):
from allura import model as M
if predicate(): return
if not message:
message = """You don't have permission to do that.
You must ask a project administrator for rights to perform this task.
Please click the back button to return to the previous page."""
if c.user != M.User.anonymous():
request.environ['error_message'] = message
raise exc.HTTPForbidden(detail=message)
else:
raise exc.HTTPUnauthorized()
def require_authenticated():
from allura import model as M
if c.user == M.User.anonymous():
raise exc.HTTPUnauthorized()
def roles_with_project_access(access_type, project=None):
'''Return all ProjectRoles' _ids who directly or transitively have the given access
'''
from allura import model as M
if project is None: project = c.project
# Direct roles
result = set(project.acl.get(access_type, []))
roles = M.ProjectRole.query.find(project_id=project._id).all()
# Compute roles who can reach the direct roles
found = True
while found:
found = False
new_roles = []
for r in roles:
if r in result: continue
for rr_id in r.roles:
if rr_id in result:
result.add(r._id)
found = True
break
else:
new_roles.append(r)
roles =new_roles
return M.ProjectRole.query.find(dict(_id={'$in':list(result)})).all()