comparison mercurial/hgweb/common.py @ 19032:7d31f2e42a8a

hgweb: refactor checks for granting and revoking user permissions Provides an entry point for extensions implementing more complex authorization schemes. Original patch proposed by Markus Zapke-Gr?ndemann.
author Wagner Bruna <wbruna@softwareexpress.com.br>
date Mon, 15 Apr 2013 18:57:04 -0300
parents 76ff3a715cf2
children d51c4d85ec23
comparison
equal deleted inserted replaced
19031:341083b02d1b 19032:7d31f2e42a8a
16 HTTP_NOT_FOUND = 404 16 HTTP_NOT_FOUND = 404
17 HTTP_METHOD_NOT_ALLOWED = 405 17 HTTP_METHOD_NOT_ALLOWED = 405
18 HTTP_SERVER_ERROR = 500 18 HTTP_SERVER_ERROR = 500
19 19
20 20
21 def ismember(ui, username, userlist):
22 """Check if username is a member of userlist.
23
24 If userlist has a single '*' member, all users are considered members.
25 Can be overriden by extensions to provide more complex authorization
26 schemes.
27 """
28 return userlist == ['*'] or username in userlist
29
21 def checkauthz(hgweb, req, op): 30 def checkauthz(hgweb, req, op):
22 '''Check permission for operation based on request data (including 31 '''Check permission for operation based on request data (including
23 authentication info). Return if op allowed, else raise an ErrorResponse 32 authentication info). Return if op allowed, else raise an ErrorResponse
24 exception.''' 33 exception.'''
25 34
26 user = req.env.get('REMOTE_USER') 35 user = req.env.get('REMOTE_USER')
27 36
28 deny_read = hgweb.configlist('web', 'deny_read') 37 deny_read = hgweb.configlist('web', 'deny_read')
29 if deny_read and (not user or deny_read == ['*'] or user in deny_read): 38 if deny_read and (not user or ismember(hgweb.repo.ui, user, deny_read)):
30 raise ErrorResponse(HTTP_UNAUTHORIZED, 'read not authorized') 39 raise ErrorResponse(HTTP_UNAUTHORIZED, 'read not authorized')
31 40
32 allow_read = hgweb.configlist('web', 'allow_read') 41 allow_read = hgweb.configlist('web', 'allow_read')
33 result = (not allow_read) or (allow_read == ['*']) 42 if allow_read and (not ismember(hgweb.repo.ui, user, allow_read)):
34 if not (result or user in allow_read):
35 raise ErrorResponse(HTTP_UNAUTHORIZED, 'read not authorized') 43 raise ErrorResponse(HTTP_UNAUTHORIZED, 'read not authorized')
36 44
37 if op == 'pull' and not hgweb.allowpull: 45 if op == 'pull' and not hgweb.allowpull:
38 raise ErrorResponse(HTTP_UNAUTHORIZED, 'pull not authorized') 46 raise ErrorResponse(HTTP_UNAUTHORIZED, 'pull not authorized')
39 elif op == 'pull' or op is None: # op is None for interface requests 47 elif op == 'pull' or op is None: # op is None for interface requests
49 scheme = req.env.get('wsgi.url_scheme') 57 scheme = req.env.get('wsgi.url_scheme')
50 if hgweb.configbool('web', 'push_ssl', True) and scheme != 'https': 58 if hgweb.configbool('web', 'push_ssl', True) and scheme != 'https':
51 raise ErrorResponse(HTTP_FORBIDDEN, 'ssl required') 59 raise ErrorResponse(HTTP_FORBIDDEN, 'ssl required')
52 60
53 deny = hgweb.configlist('web', 'deny_push') 61 deny = hgweb.configlist('web', 'deny_push')
54 if deny and (not user or deny == ['*'] or user in deny): 62 if deny and (not user or ismember(hgweb.repo.ui, user, deny)):
55 raise ErrorResponse(HTTP_UNAUTHORIZED, 'push not authorized') 63 raise ErrorResponse(HTTP_UNAUTHORIZED, 'push not authorized')
56 64
57 allow = hgweb.configlist('web', 'allow_push') 65 allow = hgweb.configlist('web', 'allow_push')
58 result = allow and (allow == ['*'] or user in allow) 66 if not (allow and ismember(hgweb.repo.ui, user, allow)):
59 if not result:
60 raise ErrorResponse(HTTP_UNAUTHORIZED, 'push not authorized') 67 raise ErrorResponse(HTTP_UNAUTHORIZED, 'push not authorized')
61 68
62 # Hooks for hgweb permission checks; extensions can add hooks here. 69 # Hooks for hgweb permission checks; extensions can add hooks here.
63 # Each hook is invoked like this: hook(hgweb, request, operation), 70 # Each hook is invoked like this: hook(hgweb, request, operation),
64 # where operation is either read, pull or push. Hooks should either 71 # where operation is either read, pull or push. Hooks should either