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 |