Mercurial > public > mercurial-scm > hg
comparison mercurial/hgweb/hgweb_mod.py @ 9910:6f92997dbdca
hgweb: add support for extension-provided permission hooks
This allows extensions to hook into permission checking, providing both
authentication and authorization as needed. The existing authorization
function has been changed to a hook, which is added by default.
author | Sune Foldager <cryo@cyanite.org> |
---|---|
date | Mon, 23 Nov 2009 11:03:55 +0100 |
parents | 510122bb3c7f |
children | 97c75ad3b1a0 |
comparison
equal
deleted
inserted
replaced
9905:95517eb3c9a7 | 9910:6f92997dbdca |
---|---|
6 # This software may be used and distributed according to the terms of the | 6 # This software may be used and distributed according to the terms of the |
7 # GNU General Public License version 2, incorporated herein by reference. | 7 # GNU General Public License version 2, incorporated herein by reference. |
8 | 8 |
9 import os | 9 import os |
10 from mercurial import ui, hg, hook, error, encoding, templater | 10 from mercurial import ui, hg, hook, error, encoding, templater |
11 from common import get_mtime, ErrorResponse | 11 from common import get_mtime, ErrorResponse, permhooks |
12 from common import HTTP_OK, HTTP_BAD_REQUEST, HTTP_NOT_FOUND, HTTP_SERVER_ERROR | 12 from common import HTTP_OK, HTTP_BAD_REQUEST, HTTP_NOT_FOUND, HTTP_SERVER_ERROR |
13 from common import HTTP_UNAUTHORIZED, HTTP_METHOD_NOT_ALLOWED | 13 from common import HTTP_UNAUTHORIZED, HTTP_METHOD_NOT_ALLOWED |
14 from request import wsgirequest | 14 from request import wsgirequest |
15 import webcommands, protocol, webutil | 15 import webcommands, protocol, webutil |
16 | 16 |
281 'gz': ('application/x-tar', 'tgz', '.tar.gz', None), | 281 'gz': ('application/x-tar', 'tgz', '.tar.gz', None), |
282 'zip': ('application/zip', 'zip', '.zip', None), | 282 'zip': ('application/zip', 'zip', '.zip', None), |
283 } | 283 } |
284 | 284 |
285 def check_perm(self, req, op): | 285 def check_perm(self, req, op): |
286 '''Check permission for operation based on request data (including | 286 for hook in permhooks: |
287 authentication info). Return if op allowed, else raise an ErrorResponse | 287 hook(self, req, op) |
288 exception.''' | |
289 | |
290 user = req.env.get('REMOTE_USER') | |
291 | |
292 deny_read = self.configlist('web', 'deny_read') | |
293 if deny_read and (not user or deny_read == ['*'] or user in deny_read): | |
294 raise ErrorResponse(HTTP_UNAUTHORIZED, 'read not authorized') | |
295 | |
296 allow_read = self.configlist('web', 'allow_read') | |
297 result = (not allow_read) or (allow_read == ['*']) | |
298 if not (result or user in allow_read): | |
299 raise ErrorResponse(HTTP_UNAUTHORIZED, 'read not authorized') | |
300 | |
301 if op == 'pull' and not self.allowpull: | |
302 raise ErrorResponse(HTTP_UNAUTHORIZED, 'pull not authorized') | |
303 elif op == 'pull' or op is None: # op is None for interface requests | |
304 return | |
305 | |
306 # enforce that you can only push using POST requests | |
307 if req.env['REQUEST_METHOD'] != 'POST': | |
308 msg = 'push requires POST request' | |
309 raise ErrorResponse(HTTP_METHOD_NOT_ALLOWED, msg) | |
310 | |
311 # require ssl by default for pushing, auth info cannot be sniffed | |
312 # and replayed | |
313 scheme = req.env.get('wsgi.url_scheme') | |
314 if self.configbool('web', 'push_ssl', True) and scheme != 'https': | |
315 raise ErrorResponse(HTTP_OK, 'ssl required') | |
316 | |
317 deny = self.configlist('web', 'deny_push') | |
318 if deny and (not user or deny == ['*'] or user in deny): | |
319 raise ErrorResponse(HTTP_UNAUTHORIZED, 'push not authorized') | |
320 | |
321 allow = self.configlist('web', 'allow_push') | |
322 result = allow and (allow == ['*'] or user in allow) | |
323 if not result: | |
324 raise ErrorResponse(HTTP_UNAUTHORIZED, 'push not authorized') |