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') |
|