115 """Adopts base.rights as rights if base is set. |
116 """Adopts base.rights as rights if base is set. |
116 """ |
117 """ |
117 |
118 |
118 base = params.get('rights') if params else None |
119 base = params.get('rights') if params else None |
119 self.rights = base.rights if base else {} |
120 self.rights = base.rights if base else {} |
|
121 self.id = None |
|
122 self.user = None |
|
123 self.cached_rights = {} |
120 |
124 |
121 def __setitem__(self, key, value): |
125 def __setitem__(self, key, value): |
122 """Sets a value only if no old value exists. |
126 """Sets a value only if no old value exists. |
123 """ |
127 """ |
124 |
128 |
138 |
142 |
139 for i in self.rights.get(key, []): |
143 for i in self.rights.get(key, []): |
140 # Be nice an repack so that it is always a list with tuples |
144 # Be nice an repack so that it is always a list with tuples |
141 if isinstance(i, tuple): |
145 if isinstance(i, tuple): |
142 name, arg = i |
146 name, arg = i |
143 tmp = (getattr(self, name), (arg if isinstance(arg, list) else [arg])) |
147 tmp = (name, (arg if isinstance(arg, list) else [arg])) |
144 result.append(tmp) |
148 result.append(tmp) |
145 else: |
149 else: |
146 tmp = (getattr(self, i), []) |
150 tmp = (i, []) |
147 result.append(tmp) |
151 result.append(tmp) |
148 |
152 |
149 return result |
153 return result |
|
154 |
|
155 def key(self, checker_name): |
|
156 """Returns the key for the specified checker for the current user. |
|
157 """ |
|
158 |
|
159 return "%s.%s" % (self.id, checker_name) |
|
160 |
|
161 def put(self, checker_name, value): |
|
162 """Puts the result for the specified checker in the cache. |
|
163 """ |
|
164 |
|
165 retention = 30 |
|
166 |
|
167 memcache_key = self.key(checker_name) |
|
168 memcache.add(memcache_key, value, retention) |
|
169 |
|
170 def get(self, checker_name): |
|
171 """Retrieves the result for the specified checker from cache. |
|
172 """ |
|
173 |
|
174 memcache_key = self.key(checker_name) |
|
175 return memcache.get(memcache_key) |
|
176 |
|
177 def doCheck(self, checker_name, django_args, args): |
|
178 """Runs the specified checker with the specified arguments. |
|
179 """ |
|
180 |
|
181 checker = getattr(self, checker_name) |
|
182 checker(django_args, *args) |
|
183 |
|
184 def doCachedCheck(self, checker_name, django_args, args): |
|
185 """Retrieves from cache or runs the specified checker. |
|
186 """ |
|
187 |
|
188 cached = self.get(checker_name) |
|
189 |
|
190 if cached is None: |
|
191 try: |
|
192 self.doCheck(checker_name, django_args, args) |
|
193 self.put(checker_name, True) |
|
194 return |
|
195 except out_of_band.Error, e: |
|
196 self.put(checker_name, e) |
|
197 raise |
|
198 |
|
199 if cached is True: |
|
200 return |
|
201 |
|
202 # re-raise the cached exception |
|
203 raise cached |
|
204 |
|
205 def check(self, use_cache, checker_name, django_args, args): |
|
206 """Runs the checker, optionally using the cache. |
|
207 """ |
|
208 |
|
209 if use_cache: |
|
210 self.doCachedCheck(checker_name, django_args, args) |
|
211 else: |
|
212 self.doCheck(checker_name, django_args, args) |
|
213 |
|
214 def setCurrentUser(self, id, user): |
|
215 """Sets up everything for the current user. |
|
216 """ |
|
217 |
|
218 self.id = id |
|
219 self.user = user |
|
220 self.cached_rights = {} |
150 |
221 |
151 def checkAccess(self, access_type, django_args): |
222 def checkAccess(self, access_type, django_args): |
152 """Runs all the defined checks for the specified type. |
223 """Runs all the defined checks for the specified type. |
153 |
224 |
154 Args: |
225 Args: |
165 the functions in the 'unspecified' value are called. When the specified |
236 the functions in the 'unspecified' value are called. When the specified |
166 type _is_ in the rights dictionary, all the functions in that access_type's |
237 type _is_ in the rights dictionary, all the functions in that access_type's |
167 value are called. |
238 value are called. |
168 """ |
239 """ |
169 |
240 |
170 self.id = users.get_current_user() |
241 use_cache = django_args.get('SIDEBAR_CALLING') |
171 |
242 |
172 # Call each access checker |
243 # Call each access checker |
173 for check, args in self['any_access']: |
244 for checker_name, args in self['any_access']: |
174 check(django_args, *args) |
245 self.check(use_cache, checker_name, django_args, args) |
175 |
246 |
176 if access_type not in self.rights: |
247 if access_type not in self.rights: |
177 for check, args in self['unspecified']: |
248 # No checks defined, so do the 'generic' checks and bail out |
178 # No checks defined, so do the 'generic' checks and bail out |
249 for checker_name, args in self['unspecified']: |
179 check(django_args, *args) |
250 self.check(use_cache, checker_name, django_args, args) |
180 return |
251 return |
181 |
252 |
182 for check, args in self[access_type]: |
253 for checker_name, args in self[access_type]: |
183 check(django_args, *args) |
254 self.check(use_cache, checker_name, django_args, args) |
184 |
255 |
185 def allow(self, django_args): |
256 def allow(self, django_args): |
186 """Never raises an alternate HTTP response. (an access no-op, basically). |
257 """Never raises an alternate HTTP response. (an access no-op, basically). |
187 |
258 |
188 Args: |
259 Args: |
251 * if User has not agreed to the site-wide ToS, if one exists |
322 * if User has not agreed to the site-wide ToS, if one exists |
252 """ |
323 """ |
253 |
324 |
254 self.checkIsLoggedIn(django_args) |
325 self.checkIsLoggedIn(django_args) |
255 |
326 |
256 user = user_logic.getForCurrentAccount() |
327 if not self.user: |
257 |
|
258 if not user: |
|
259 raise out_of_band.LoginRequest(message_fmt=DEF_NO_USER_LOGIN_MSG_FMT) |
328 raise out_of_band.LoginRequest(message_fmt=DEF_NO_USER_LOGIN_MSG_FMT) |
260 |
329 |
261 if user_logic.agreesToSiteToS(user): |
330 if user_logic.agreesToSiteToS(self.user): |
262 return |
331 return |
263 |
332 |
264 # Would not reach this point of site-wide ToS did not exist, since |
333 # Would not reach this point of site-wide ToS did not exist, since |
265 # agreesToSiteToS() call above always returns True if no ToS is in effect. |
334 # agreesToSiteToS() call above always returns True if no ToS is in effect. |
266 login_msg_fmt = DEF_AGREE_TO_TOS_MSG_FMT % { |
335 login_msg_fmt = DEF_AGREE_TO_TOS_MSG_FMT % { |