/shabti/templates/shenu/+package+/lib/conditions.py_tmpl
Unknown | 215 lines | 171 code | 44 blank | 0 comment | 0 complexity | 5c5a64fc3c68088b4f4d119c7404e04f MD5 | raw file
1# -*- coding: utf-8 -*-
2from pylons import tmpl_context as c
3
4# Copied in verbatim from Turbogears 1's identity package
5class Predicate(object):
6 '''
7 Generic base class for testing true or false for a condition.
8 '''
9 def eval_with_object( self, obj, errors=None ):
10 '''
11 Determine whether the predicate is True or False for the given object.
12 '''
13 raise NotImplementedError
14
15 def append_error_message( self, errors=None ):
16 if errors is None:
17 return
18 errors.append( self.error_message % self.__dict__ )
19
20
21class CompoundPredicate(Predicate):
22 '''
23 A predicate composed of other predicates.
24 '''
25 def __init__(self, *predicates):
26 self.predicates= predicates
27
28
29class All(CompoundPredicate):
30 '''
31 A compound predicate that evaluates to true only if all sub-predicates
32 evaluate to true for the given input.
33 '''
34 def eval_with_object( self, obj, errors=None ):
35 '''
36 Return true if all sub-predicates evaluate to true.
37 '''
38 for p in self.predicates:
39 if not p.eval_with_object( obj, errors ):
40 return False
41 return True
42
43
44class Any(CompoundPredicate):
45 '''
46 A compound predicate that evaluates to true if any one of its sub-predicates
47 evaluates to true.
48 '''
49 error_message= "No predicates were able to grant access"
50
51 def eval_with_object( self, obj, errors=None ):
52 '''
53 Return true if any sub-predicate evaluates to true.
54 '''
55 for p in self.predicates:
56 if p.eval_with_object( obj, None ):
57 return True
58 self.append_error_message( errors )
59 return False
60
61
62class IdentityPredicateHelper(object):
63 '''
64 A mix-in helper class for Identity Predicates.
65 '''
66 def __nonzero__(self):
67 return self.eval_with_object( c.user )
68
69
70class in_group(Predicate, IdentityPredicateHelper):
71 '''
72 Predicate for requiring a group.
73 '''
74 error_message= "Not member of group: %(group_name)s"
75
76 def __init__(self, group_name):
77 self.group_name= group_name
78
79 def eval_with_object( self, identity, errors=None ):
80 if self.group_name in identity.groups:
81 return True
82 self.append_error_message( errors )
83 return False
84
85
86class in_all_groups(All, IdentityPredicateHelper):
87 '''
88 Predicate for requiring membership in a number of groups.
89 '''
90 def __init__(self, *groups):
91 group_predicates= [in_group(g) for g in groups]
92 super(in_all_groups,self).__init__( *group_predicates )
93
94
95class in_any_group(Any, IdentityPredicateHelper):
96 '''
97 Predicate for requiring membership in at least one group
98 '''
99 error_message= "Not member of any group: %(group_list)s"
100
101 def __init__(self, *groups):
102 self.group_list= ", ".join(groups)
103 group_predicates= [in_group(g) for g in groups]
104 super(in_any_group,self).__init__( *group_predicates )
105
106
107class not_anonymous(Predicate, IdentityPredicateHelper):
108 '''
109 Predicate for checking whether current visitor is anonymous.
110 '''
111 error_message= "Anonymous access denied"
112
113 def eval_with_object( self, identity, errors=None ):
114 if c.user.anonymous:
115 self.append_error_message( errors )
116 return False
117 return True
118
119
120class has_permission(Predicate, IdentityPredicateHelper):
121 '''
122 Predicate for checking whether the visitor has a particular permission.
123 '''
124 error_message= "Permission denied: %(permission_name)s"
125
126 def __init__(self, permission_name):
127 self.permission_name= permission_name
128
129 def eval_with_object(self, identity, errors=None):
130 '''
131 Determine whether the visitor has the specified permission.
132 '''
133 if self.permission_name in c.user.permissions:
134 return True
135
136 self.append_error_message( errors )
137 return False
138
139
140class has_all_permissions(All, IdentityPredicateHelper):
141 '''
142 Predicate for checking whether the visitor has all permissions.
143 '''
144 def __init__(self, *permissions):
145 permission_predicates= [has_permission(p) for p in permissions]
146 super(has_all_permissions,self).__init__( *permission_predicates )
147
148
149class has_any_permission(Any, IdentityPredicateHelper):
150 '''
151 Predicate for checking whether the visitor has at least one permission.
152 '''
153 error_message= "No matching permissions: %(permission_list)s"
154
155 def __init__(self, *permissions):
156 self.permission_list= ", ".join( permissions )
157 permission_predicates= [has_permission(p) for p in permissions]
158 super(has_any_permission,self).__init__( *permission_predicates )
159
160
161def _remoteHost():
162 try:
163 ips= cherrypy.request.headers.get( "X-Forwarded-For",
164 cherrypy.request.remote_host )
165 return ips.split(",")[-1].strip()
166 except:
167 return ""
168
169
170def _match_ip(cidr, ip):
171 if not '/' in cidr:
172 return cidr == ip
173 else:
174 try:
175 b,m = cidr.split('/')
176 shift = 32 - int(m)
177 a1 = struct.unpack('!L', socket.inet_aton(b))[0] >> shift
178 a2 = struct.unpack('!L', socket.inet_aton(ip))[0] >> shift
179 return a1 == a2
180 except:
181 return False
182
183
184class from_host(Predicate, IdentityPredicateHelper):
185 '''
186 Predicate for checking whether the visitor's host is an allowed host.
187 Note: We never want to announce what the list of allowed hosts is, because
188 it is way too easy to spoof an IP address in a TCP/IP packet.
189 '''
190 error_message= "Access from this host is not permitted."
191
192 def __init__(self, host):
193 self.host= host
194
195 def eval_with_object( self, obj, errors=None ):
196 '''
197 Match the visitor's host against the criteria.
198 '''
199 ip = _remoteHost()
200 if _match_ip( self.host, ip ):
201 return True
202 self.append_error_message( errors )
203 return False
204
205
206class from_any_host(Any, IdentityPredicateHelper):
207 '''
208 Predicate for checking whether the visitor's host is one of a number of
209 permitted hosts.
210 '''
211 error_message= "Access from this host is not permitted."
212
213 def __init__(self, hosts):
214 host_predicates= [from_host(h) for h in hosts]
215 super(from_any_host,self).__init__( *host_predicates )