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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
|
from zope.interface import implements
from zope.component import queryUtility
from zope.location.location import LocationIterator
from repoze.bfg.interfaces import ISecurityPolicy
from repoze.bfg.interfaces import IViewPermission
from repoze.bfg.interfaces import IViewPermissionFactory
from repoze.bfg.interfaces import NoAuthorizationInformation
Everyone = 'system.Everyone'
Authenticated = 'system.Authenticated'
Allow = 'Allow'
Deny = 'Deny'
def has_permission(permission, context, request):
policy = queryUtility(ISecurityPolicy)
if policy is None:
return True
return policy.permits(context, request, permission)
class ACLAuthorizer(object):
def __init__(self, context, logger=None):
self.context = context
self.logger = logger
def get_acl(self, default=None):
return getattr(self.context, '__acl__', default)
def permits(self, permission, *principals):
acl = self.get_acl()
if acl is None:
raise NoAuthorizationInformation('%s item has no __acl__' % acl)
for ace in acl:
ace_action, ace_principal, ace_permissions = ace
for principal in flatten(principals):
if ace_principal == principal:
permissions = flatten(ace_permissions)
if permission in permissions:
action = ace_action
if action == Allow:
result = Allowed(ace, acl, permission, principals,
self.context)
self.logger and self.logger.debug(str(result))
return result
result = Denied(ace, acl, permission, principals,
self.context)
self.logger and self.logger.debug(str(result))
return result
result = Denied(None, acl, permission, principals, self.context)
self.logger and self.logger.debug(str(result))
return result
class RemoteUserACLSecurityPolicy(object):
implements(ISecurityPolicy)
authorizer_factory = ACLAuthorizer
def __init__(self, logger=None):
self.logger = logger
def permits(self, context, request, permission):
userid = request.environ.get('REMOTE_USER', None)
effective_principals = [Everyone]
if userid is not None:
effective_principals.append(Authenticated)
effective_principals.append(userid)
for location in LocationIterator(context):
authorizer = self.authorizer_factory(context, self.logger)
try:
return authorizer.permits(permission, *effective_principals)
except NoAuthorizationInformation:
continue
return False
class PermitsResult:
def __init__(self, ace, acl, permission, principals, context):
self.acl = acl
self.ace = ace
self.permission = permission
self.principals = principals
self.context_repr = repr(context)
def __str__(self):
msg = '%s: %r via ace %r in acl %s or principals %r in context %s'
msg = msg % (self.__class__.__name__,
self.permission, self.ace, self.acl, self.principals,
self.context_repr)
return msg
class Denied(PermitsResult):
def __nonzero__(self):
return False
def __eq__(self, other):
if bool(other) is False:
return True
class Allowed(PermitsResult):
def __nonzero__(self):
return True
def __eq__(self, other):
if bool(other) is True:
return True
def flatten(x):
"""flatten(sequence) -> list
Returns a single, flat list which contains all elements retrieved
from the sequence and all recursively contained sub-sequences
(iterables).
Examples:
>>> [1, 2, [3,4], (5,6)]
[1, 2, [3, 4], (5, 6)]
>>> flatten([[[1,2,3], (42,None)], [4,5], [6], 7, MyVector(8,9,10)])
[1, 2, 3, 42, None, 4, 5, 6, 7, 8, 9, 10]"""
if isinstance(x, basestring):
return [x]
result = []
for el in x:
if hasattr(el, "__iter__") and not isinstance(el, basestring):
result.extend(flatten(el))
else:
result.append(el)
return result
class ViewPermission(object):
implements(IViewPermission)
def __init__(self, context, request, permission_name):
self.context = context
self.request = request
self.permission_name = permission_name
def __call__(self, security_policy):
return security_policy.permits(self.context, self.request,
self.permission_name)
def __repr__(self):
return '<Permission at %s named %r for %r>' % (id(self),
self.permission_name,
self.request.view_name)
class ViewPermissionFactory(object):
implements(IViewPermissionFactory)
def __init__(self, permission_name):
self.permission_name = permission_name
def __call__(self, context, request):
return ViewPermission(context, request, self.permission_name)
|