PageRenderTime 24ms CodeModel.GetById 14ms app.highlight 8ms RepoModel.GetById 1ms app.codeStats 0ms

/shabti/templates/shenu/+package+/lib/conditions.py_tmpl

https://bitbucket.org/gawel/shabti
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 )