annotate mercurial/hgweb/common.py @ 50439:4077d6222cf1

hgweb: add support to explicitly access hidden changesets This changeset adds a "global" `access-hidden` argument to hgweb. This argument lift the "hidden" filtering. This means the request has access to hidden (eg: obsolete) changesets. Secret changesets remains filtered. This feature has multiple applications. The first main use case is to allow the hgweb interface to display more obsolescence related data, such as the Anton Shestakov work to add `obslog` support to hgweb. The second foreseen usecase is support for a `--remote-hidden` argument to `hg pull` and `hg clone`. This flag will make it possible to retrieve hidden (typically obsolete) changeset under some conditions. This is useful when digging up obsolescence history or when doing full mirroring. More on this feature coming in later changesets. To avoid exposing information by mistake, access to this feature is currently controlled with the `experimental.server.allow-hidden-access` config option. The option works the same way as `web.allow-push`. The current default is to not allow any hidden access. However we might change it before the feature stop being experimental.
author Pierre-Yves David <pierre-yves.david@octobus.net>
date Sat, 13 Apr 2019 01:17:56 +0200
parents 642e31cb55f0
children 4bddc2f72879
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
2391
d351a3be3371 Fixing up comment headers for split up code.
Eric Hopper <hopper@omnifarious.org>
parents: 2356
diff changeset
1 # hgweb/common.py - Utility functions needed by hgweb_mod and hgwebdir_mod
131
c9d51742471c moving hgweb to mercurial subdir
jake@edge2.net
parents:
diff changeset
2 #
238
3b92f8fe47ae hgweb.py: kill #! line, clean up copyright notice
mpm@selenic.com
parents: 222
diff changeset
3 # Copyright 21 May 2005 - (c) 2005 Jake Edge <jake@edge2.net>
46819
d4ba4d51f85f contributor: change mentions of mpm to olivia
Raphaël Gomès <rgomes@octobus.net>
parents: 45942
diff changeset
4 # Copyright 2005, 2006 Olivia Mackall <olivia@selenic.com>
131
c9d51742471c moving hgweb to mercurial subdir
jake@edge2.net
parents:
diff changeset
5 #
8225
46293a0c7e9f updated license to be explicit about GPL version 2
Martin Geisler <mg@lazybytes.net>
parents: 7966
diff changeset
6 # This software may be used and distributed according to the terms of the
10263
25e572394f5c Update license to GPLv2+
Matt Mackall <mpm@selenic.com>
parents: 9694
diff changeset
7 # GNU General Public License version 2 or any later version.
131
c9d51742471c moving hgweb to mercurial subdir
jake@edge2.net
parents:
diff changeset
8
27046
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27044
diff changeset
9
30766
d7bf7d2bd5ab hgweb: support Content Security Policy
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30636
diff changeset
10 import base64
27046
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27044
diff changeset
11 import errno
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27044
diff changeset
12 import mimetypes
37fcfe52c68c hgweb: use absolute_import
Yuya Nishihara <yuya@tcha.org>
parents: 27044
diff changeset
13 import os
36781
ffa3026d4196 cleanup: use stat_result[stat.ST_MTIME] instead of stat_result.st_mtime
Augie Fackler <augie@google.com>
parents: 36648
diff changeset
14 import stat
5561
22713dce19f6 hgweb: return meaningful HTTP status codes instead of nonsense
Bryan O'Sullivan <bos@serpentine.com>
parents: 4462
diff changeset
15
50439
4077d6222cf1 hgweb: add support to explicitly access hidden changesets
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48946
diff changeset
16 from ..i18n import _
43089
c59eb1560c44 py3: manually import getattr where it is needed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43085
diff changeset
17 from ..pycompat import (
c59eb1560c44 py3: manually import getattr where it is needed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43085
diff changeset
18 getattr,
c59eb1560c44 py3: manually import getattr where it is needed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43085
diff changeset
19 open,
c59eb1560c44 py3: manually import getattr where it is needed
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43085
diff changeset
20 )
30615
bb77654dc7ae py3: replace os.sep with pycompat.ossep (part 3 of 4)
Pulkit Goyal <7895pulkit@gmail.com>
parents: 29566
diff changeset
21 from .. import (
30636
f1c9fafcbf46 py3: replace os.environ with encoding.environ (part 3 of 5)
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30625
diff changeset
22 encoding,
30615
bb77654dc7ae py3: replace os.sep with pycompat.ossep (part 3 of 4)
Pulkit Goyal <7895pulkit@gmail.com>
parents: 29566
diff changeset
23 pycompat,
45378
dc9fe90bdbd5 hgweb: let staticfile() look up path from default location unless provided
Martin von Zweigbergk <martinvonz@google.com>
parents: 45306
diff changeset
24 templater,
30615
bb77654dc7ae py3: replace os.sep with pycompat.ossep (part 3 of 4)
Pulkit Goyal <7895pulkit@gmail.com>
parents: 29566
diff changeset
25 util,
bb77654dc7ae py3: replace os.sep with pycompat.ossep (part 3 of 4)
Pulkit Goyal <7895pulkit@gmail.com>
parents: 29566
diff changeset
26 )
29566
075146e85bb6 py3: conditionalize BaseHTTPServer, SimpleHTTPServer and CGIHTTPServer import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 29491
diff changeset
27
075146e85bb6 py3: conditionalize BaseHTTPServer, SimpleHTTPServer and CGIHTTPServer import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 29491
diff changeset
28 httpserver = util.httpserver
075146e85bb6 py3: conditionalize BaseHTTPServer, SimpleHTTPServer and CGIHTTPServer import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 29491
diff changeset
29
5993
948a41e77902 hgweb: explicit response status
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5930
diff changeset
30 HTTP_OK = 200
37149
cc0a6ea95d98 lfs: add support for serving blob files
Matt Harbison <matt_harbison@yahoo.com>
parents: 37147
diff changeset
31 HTTP_CREATED = 201
12183
f64b416b0ac8 hgweb: support very simple caching model (issue1845)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 10264
diff changeset
32 HTTP_NOT_MODIFIED = 304
5993
948a41e77902 hgweb: explicit response status
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5930
diff changeset
33 HTTP_BAD_REQUEST = 400
6926
57b954d8d003 hgweb: raise ErrorResponses to communicate protocol errors
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6924
diff changeset
34 HTTP_UNAUTHORIZED = 401
7029
b84d27386285 hgweb: Respond with HTTP 403 for disabled archive types instead of 404
Rocco Rutte <pdmef@gmx.net>
parents: 6926
diff changeset
35 HTTP_FORBIDDEN = 403
5993
948a41e77902 hgweb: explicit response status
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5930
diff changeset
36 HTTP_NOT_FOUND = 404
6926
57b954d8d003 hgweb: raise ErrorResponses to communicate protocol errors
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6924
diff changeset
37 HTTP_METHOD_NOT_ALLOWED = 405
37693
31a0d47d69b3 lfs: update the HTTP status codes in error cases
Matt Harbison <matt_harbison@yahoo.com>
parents: 37149
diff changeset
38 HTTP_NOT_ACCEPTABLE = 406
31a0d47d69b3 lfs: update the HTTP status codes in error cases
Matt Harbison <matt_harbison@yahoo.com>
parents: 37149
diff changeset
39 HTTP_UNSUPPORTED_MEDIA_TYPE = 415
5993
948a41e77902 hgweb: explicit response status
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5930
diff changeset
40 HTTP_SERVER_ERROR = 500
948a41e77902 hgweb: explicit response status
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5930
diff changeset
41
9910
6f92997dbdca hgweb: add support for extension-provided permission hooks
Sune Foldager <cryo@cyanite.org>
parents: 9694
diff changeset
42
19032
7d31f2e42a8a hgweb: refactor checks for granting and revoking user permissions
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 18645
diff changeset
43 def ismember(ui, username, userlist):
7d31f2e42a8a hgweb: refactor checks for granting and revoking user permissions
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 18645
diff changeset
44 """Check if username is a member of userlist.
7d31f2e42a8a hgweb: refactor checks for granting and revoking user permissions
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 18645
diff changeset
45
7d31f2e42a8a hgweb: refactor checks for granting and revoking user permissions
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 18645
diff changeset
46 If userlist has a single '*' member, all users are considered members.
19951
d51c4d85ec23 spelling: random spell checker fixes
Mads Kiilerich <madski@unity3d.com>
parents: 19032
diff changeset
47 Can be overridden by extensions to provide more complex authorization
19032
7d31f2e42a8a hgweb: refactor checks for granting and revoking user permissions
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 18645
diff changeset
48 schemes.
7d31f2e42a8a hgweb: refactor checks for granting and revoking user permissions
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 18645
diff changeset
49 """
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
50 return userlist == [b'*'] or username in userlist
19032
7d31f2e42a8a hgweb: refactor checks for granting and revoking user permissions
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 18645
diff changeset
51
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42922
diff changeset
52
50439
4077d6222cf1 hgweb: add support to explicitly access hidden changesets
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48946
diff changeset
53 def hashiddenaccess(repo, req):
4077d6222cf1 hgweb: add support to explicitly access hidden changesets
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48946
diff changeset
54 if bool(req.qsparams.get(b'access-hidden')):
4077d6222cf1 hgweb: add support to explicitly access hidden changesets
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48946
diff changeset
55 # Disable this by default for now. Main risk is to get critical
4077d6222cf1 hgweb: add support to explicitly access hidden changesets
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48946
diff changeset
56 # information exposed through this. This is expecially risky if
4077d6222cf1 hgweb: add support to explicitly access hidden changesets
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48946
diff changeset
57 # someone decided to make a changeset secret for good reason, but
4077d6222cf1 hgweb: add support to explicitly access hidden changesets
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48946
diff changeset
58 # its predecessors are still draft.
4077d6222cf1 hgweb: add support to explicitly access hidden changesets
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48946
diff changeset
59 #
4077d6222cf1 hgweb: add support to explicitly access hidden changesets
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48946
diff changeset
60 # The feature is currently experimental, so we can still decide to
4077d6222cf1 hgweb: add support to explicitly access hidden changesets
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48946
diff changeset
61 # change the default.
4077d6222cf1 hgweb: add support to explicitly access hidden changesets
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48946
diff changeset
62 ui = repo.ui
4077d6222cf1 hgweb: add support to explicitly access hidden changesets
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48946
diff changeset
63 allow = ui.configlist(b'experimental', b'server.allow-hidden-access')
4077d6222cf1 hgweb: add support to explicitly access hidden changesets
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48946
diff changeset
64 user = req.remoteuser
4077d6222cf1 hgweb: add support to explicitly access hidden changesets
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48946
diff changeset
65 if allow and ismember(ui, user, allow):
4077d6222cf1 hgweb: add support to explicitly access hidden changesets
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48946
diff changeset
66 return True
4077d6222cf1 hgweb: add support to explicitly access hidden changesets
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48946
diff changeset
67 else:
4077d6222cf1 hgweb: add support to explicitly access hidden changesets
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48946
diff changeset
68 msg = (
4077d6222cf1 hgweb: add support to explicitly access hidden changesets
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48946
diff changeset
69 _(
4077d6222cf1 hgweb: add support to explicitly access hidden changesets
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48946
diff changeset
70 b'ignoring request to access hidden changeset by '
4077d6222cf1 hgweb: add support to explicitly access hidden changesets
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48946
diff changeset
71 b'unauthorized user: %r\n'
4077d6222cf1 hgweb: add support to explicitly access hidden changesets
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48946
diff changeset
72 )
4077d6222cf1 hgweb: add support to explicitly access hidden changesets
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48946
diff changeset
73 % user
4077d6222cf1 hgweb: add support to explicitly access hidden changesets
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48946
diff changeset
74 )
4077d6222cf1 hgweb: add support to explicitly access hidden changesets
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48946
diff changeset
75 ui.warn(msg)
4077d6222cf1 hgweb: add support to explicitly access hidden changesets
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48946
diff changeset
76 return False
4077d6222cf1 hgweb: add support to explicitly access hidden changesets
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48946
diff changeset
77
4077d6222cf1 hgweb: add support to explicitly access hidden changesets
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 48946
diff changeset
78
9910
6f92997dbdca hgweb: add support for extension-provided permission hooks
Sune Foldager <cryo@cyanite.org>
parents: 9694
diff changeset
79 def checkauthz(hgweb, req, op):
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45380
diff changeset
80 """Check permission for operation based on request data (including
9910
6f92997dbdca hgweb: add support for extension-provided permission hooks
Sune Foldager <cryo@cyanite.org>
parents: 9694
diff changeset
81 authentication info). Return if op allowed, else raise an ErrorResponse
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45380
diff changeset
82 exception."""
9910
6f92997dbdca hgweb: add support for extension-provided permission hooks
Sune Foldager <cryo@cyanite.org>
parents: 9694
diff changeset
83
36877
02bea04b4c54 hgweb: transition permissions hooks to modern request type (API)
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36873
diff changeset
84 user = req.remoteuser
9910
6f92997dbdca hgweb: add support for extension-provided permission hooks
Sune Foldager <cryo@cyanite.org>
parents: 9694
diff changeset
85
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
86 deny_read = hgweb.configlist(b'web', b'deny_read')
19032
7d31f2e42a8a hgweb: refactor checks for granting and revoking user permissions
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 18645
diff changeset
87 if deny_read and (not user or ismember(hgweb.repo.ui, user, deny_read)):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
88 raise ErrorResponse(HTTP_UNAUTHORIZED, b'read not authorized')
9910
6f92997dbdca hgweb: add support for extension-provided permission hooks
Sune Foldager <cryo@cyanite.org>
parents: 9694
diff changeset
89
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
90 allow_read = hgweb.configlist(b'web', b'allow_read')
19032
7d31f2e42a8a hgweb: refactor checks for granting and revoking user permissions
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 18645
diff changeset
91 if allow_read and (not ismember(hgweb.repo.ui, user, allow_read)):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
92 raise ErrorResponse(HTTP_UNAUTHORIZED, b'read not authorized')
9910
6f92997dbdca hgweb: add support for extension-provided permission hooks
Sune Foldager <cryo@cyanite.org>
parents: 9694
diff changeset
93
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
94 if op == b'pull' and not hgweb.allowpull:
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
95 raise ErrorResponse(HTTP_UNAUTHORIZED, b'pull not authorized')
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
96 elif op == b'pull' or op is None: # op is None for interface requests
9910
6f92997dbdca hgweb: add support for extension-provided permission hooks
Sune Foldager <cryo@cyanite.org>
parents: 9694
diff changeset
97 return
6f92997dbdca hgweb: add support for extension-provided permission hooks
Sune Foldager <cryo@cyanite.org>
parents: 9694
diff changeset
98
37147
a2566597acb5 lfs: add basic routing for the server side wire protocol processing
Matt Harbison <matt_harbison@yahoo.com>
parents: 36877
diff changeset
99 # Allow LFS uploading via PUT requests
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
100 if op == b'upload':
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
101 if req.method != b'PUT':
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
102 msg = b'upload requires PUT request'
37147
a2566597acb5 lfs: add basic routing for the server side wire protocol processing
Matt Harbison <matt_harbison@yahoo.com>
parents: 36877
diff changeset
103 raise ErrorResponse(HTTP_METHOD_NOT_ALLOWED, msg)
9910
6f92997dbdca hgweb: add support for extension-provided permission hooks
Sune Foldager <cryo@cyanite.org>
parents: 9694
diff changeset
104 # enforce that you can only push using POST requests
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
105 elif req.method != b'POST':
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
106 msg = b'push requires POST request'
9910
6f92997dbdca hgweb: add support for extension-provided permission hooks
Sune Foldager <cryo@cyanite.org>
parents: 9694
diff changeset
107 raise ErrorResponse(HTTP_METHOD_NOT_ALLOWED, msg)
6f92997dbdca hgweb: add support for extension-provided permission hooks
Sune Foldager <cryo@cyanite.org>
parents: 9694
diff changeset
108
6f92997dbdca hgweb: add support for extension-provided permission hooks
Sune Foldager <cryo@cyanite.org>
parents: 9694
diff changeset
109 # require ssl by default for pushing, auth info cannot be sniffed
6f92997dbdca hgweb: add support for extension-provided permission hooks
Sune Foldager <cryo@cyanite.org>
parents: 9694
diff changeset
110 # and replayed
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
111 if hgweb.configbool(b'web', b'push_ssl') and req.urlscheme != b'https':
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
112 raise ErrorResponse(HTTP_FORBIDDEN, b'ssl required')
9910
6f92997dbdca hgweb: add support for extension-provided permission hooks
Sune Foldager <cryo@cyanite.org>
parents: 9694
diff changeset
113
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
114 deny = hgweb.configlist(b'web', b'deny_push')
19032
7d31f2e42a8a hgweb: refactor checks for granting and revoking user permissions
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 18645
diff changeset
115 if deny and (not user or ismember(hgweb.repo.ui, user, deny)):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
116 raise ErrorResponse(HTTP_UNAUTHORIZED, b'push not authorized')
9910
6f92997dbdca hgweb: add support for extension-provided permission hooks
Sune Foldager <cryo@cyanite.org>
parents: 9694
diff changeset
117
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
118 allow = hgweb.configlist(b'web', b'allow-push')
19032
7d31f2e42a8a hgweb: refactor checks for granting and revoking user permissions
Wagner Bruna <wbruna@softwareexpress.com.br>
parents: 18645
diff changeset
119 if not (allow and ismember(hgweb.repo.ui, user, allow)):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
120 raise ErrorResponse(HTTP_UNAUTHORIZED, b'push not authorized')
9910
6f92997dbdca hgweb: add support for extension-provided permission hooks
Sune Foldager <cryo@cyanite.org>
parents: 9694
diff changeset
121
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42922
diff changeset
122
14058
3233b39d756f hgweb: initialize permhooks at definition time
Martin Geisler <mg@lazybytes.net>
parents: 13959
diff changeset
123 # Hooks for hgweb permission checks; extensions can add hooks here.
3233b39d756f hgweb: initialize permhooks at definition time
Martin Geisler <mg@lazybytes.net>
parents: 13959
diff changeset
124 # Each hook is invoked like this: hook(hgweb, request, operation),
37147
a2566597acb5 lfs: add basic routing for the server side wire protocol processing
Matt Harbison <matt_harbison@yahoo.com>
parents: 36877
diff changeset
125 # where operation is either read, pull, push or upload. Hooks should either
14058
3233b39d756f hgweb: initialize permhooks at definition time
Martin Geisler <mg@lazybytes.net>
parents: 13959
diff changeset
126 # raise an ErrorResponse exception, or just return.
3233b39d756f hgweb: initialize permhooks at definition time
Martin Geisler <mg@lazybytes.net>
parents: 13959
diff changeset
127 #
3233b39d756f hgweb: initialize permhooks at definition time
Martin Geisler <mg@lazybytes.net>
parents: 13959
diff changeset
128 # It is possible to do both authentication and authorization through
3233b39d756f hgweb: initialize permhooks at definition time
Martin Geisler <mg@lazybytes.net>
parents: 13959
diff changeset
129 # this.
3233b39d756f hgweb: initialize permhooks at definition time
Martin Geisler <mg@lazybytes.net>
parents: 13959
diff changeset
130 permhooks = [checkauthz]
9910
6f92997dbdca hgweb: add support for extension-provided permission hooks
Sune Foldager <cryo@cyanite.org>
parents: 9694
diff changeset
131
6f92997dbdca hgweb: add support for extension-provided permission hooks
Sune Foldager <cryo@cyanite.org>
parents: 9694
diff changeset
132
5561
22713dce19f6 hgweb: return meaningful HTTP status codes instead of nonsense
Bryan O'Sullivan <bos@serpentine.com>
parents: 4462
diff changeset
133 class ErrorResponse(Exception):
31390
7dafa8d0e006 hgweb: don't use mutable default argument value
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30766
diff changeset
134 def __init__(self, code, message=None, headers=None):
13444
75f5f312df5f hgweb: give ErrorResponse a descriptive string/Exception representation
Mads Kiilerich <mads@kiilerich.com>
parents: 13400
diff changeset
135 if message is None:
75f5f312df5f hgweb: give ErrorResponse a descriptive string/Exception representation
Mads Kiilerich <mads@kiilerich.com>
parents: 13400
diff changeset
136 message = _statusmessage(code)
36429
f8ea6988a5fb hgweb: pass exception message to builtin Exception ctor as sysstr
Augie Fackler <augie@google.com>
parents: 36397
diff changeset
137 Exception.__init__(self, pycompat.sysstr(message))
5561
22713dce19f6 hgweb: return meaningful HTTP status codes instead of nonsense
Bryan O'Sullivan <bos@serpentine.com>
parents: 4462
diff changeset
138 self.code = code
31435
2daeab02b4b1 hgweb: explicitly tests for None
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31390
diff changeset
139 if headers is None:
2daeab02b4b1 hgweb: explicitly tests for None
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31390
diff changeset
140 headers = []
2daeab02b4b1 hgweb: explicitly tests for None
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31390
diff changeset
141 self.headers = headers
42922
8d9322b6e687 hgweb: add a `message` attribute to `hgweb.common.ErrorResponse`
Connor Sheehan <sheehan@mozilla.com>
parents: 40211
diff changeset
142 self.message = message
5563
d61fea133f2d hgweb: fix breaking tests on Python < 2.5
Bryan O'Sullivan <bos@serpentine.com>
parents: 5561
diff changeset
143
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42922
diff changeset
144
48946
642e31cb55f0 py3: use class X: instead of class X(object):
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48875
diff changeset
145 class continuereader:
36853
7066617187c1 hgweb: document continuereader
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36781
diff changeset
146 """File object wrapper to handle HTTP 100-continue.
7066617187c1 hgweb: document continuereader
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36781
diff changeset
147
7066617187c1 hgweb: document continuereader
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36781
diff changeset
148 This is used by servers so they automatically handle Expect: 100-continue
7066617187c1 hgweb: document continuereader
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36781
diff changeset
149 request headers. On first read of the request body, the 100 Continue
7066617187c1 hgweb: document continuereader
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36781
diff changeset
150 response is sent. This should trigger the client into actually sending
7066617187c1 hgweb: document continuereader
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36781
diff changeset
151 the request body.
7066617187c1 hgweb: document continuereader
Gregory Szorc <gregory.szorc@gmail.com>
parents: 36781
diff changeset
152 """
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42922
diff changeset
153
13570
617a87cb7eb2 hgweb: add support for 100-continue as recommended by PEP 333.
Augie Fackler <durin42@gmail.com>
parents: 13444
diff changeset
154 def __init__(self, f, write):
617a87cb7eb2 hgweb: add support for 100-continue as recommended by PEP 333.
Augie Fackler <durin42@gmail.com>
parents: 13444
diff changeset
155 self.f = f
617a87cb7eb2 hgweb: add support for 100-continue as recommended by PEP 333.
Augie Fackler <durin42@gmail.com>
parents: 13444
diff changeset
156 self._write = write
617a87cb7eb2 hgweb: add support for 100-continue as recommended by PEP 333.
Augie Fackler <durin42@gmail.com>
parents: 13444
diff changeset
157 self.continued = False
617a87cb7eb2 hgweb: add support for 100-continue as recommended by PEP 333.
Augie Fackler <durin42@gmail.com>
parents: 13444
diff changeset
158
617a87cb7eb2 hgweb: add support for 100-continue as recommended by PEP 333.
Augie Fackler <durin42@gmail.com>
parents: 13444
diff changeset
159 def read(self, amt=-1):
617a87cb7eb2 hgweb: add support for 100-continue as recommended by PEP 333.
Augie Fackler <durin42@gmail.com>
parents: 13444
diff changeset
160 if not self.continued:
617a87cb7eb2 hgweb: add support for 100-continue as recommended by PEP 333.
Augie Fackler <durin42@gmail.com>
parents: 13444
diff changeset
161 self.continued = True
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
162 self._write(b'HTTP/1.1 100 Continue\r\n\r\n')
13570
617a87cb7eb2 hgweb: add support for 100-continue as recommended by PEP 333.
Augie Fackler <durin42@gmail.com>
parents: 13444
diff changeset
163 return self.f.read(amt)
617a87cb7eb2 hgweb: add support for 100-continue as recommended by PEP 333.
Augie Fackler <durin42@gmail.com>
parents: 13444
diff changeset
164
617a87cb7eb2 hgweb: add support for 100-continue as recommended by PEP 333.
Augie Fackler <durin42@gmail.com>
parents: 13444
diff changeset
165 def __getattr__(self, attr):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
166 if attr in (b'close', b'readline', b'readlines', b'__iter__'):
13570
617a87cb7eb2 hgweb: add support for 100-continue as recommended by PEP 333.
Augie Fackler <durin42@gmail.com>
parents: 13444
diff changeset
167 return getattr(self.f, attr)
16687
e34106fa0dc3 cleanup: "raise SomeException()" -> "raise SomeException"
Brodie Rao <brodie@sf.io>
parents: 14058
diff changeset
168 raise AttributeError
5563
d61fea133f2d hgweb: fix breaking tests on Python < 2.5
Bryan O'Sullivan <bos@serpentine.com>
parents: 5561
diff changeset
169
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42922
diff changeset
170
5563
d61fea133f2d hgweb: fix breaking tests on Python < 2.5
Bryan O'Sullivan <bos@serpentine.com>
parents: 5561
diff changeset
171 def _statusmessage(code):
29566
075146e85bb6 py3: conditionalize BaseHTTPServer, SimpleHTTPServer and CGIHTTPServer import
Pulkit Goyal <7895pulkit@gmail.com>
parents: 29491
diff changeset
172 responses = httpserver.basehttprequesthandler.responses
43506
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43089
diff changeset
173 return pycompat.bytesurl(responses.get(code, ('Error', 'Unknown error'))[0])
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42922
diff changeset
174
5760
0145f9afb0e7 Removed tabs and trailing whitespace in python files
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5563
diff changeset
175
9694
8269fe2d48f6 hgweb: send proper error messages to the client
Sune Foldager <cryo@cyanite.org>
parents: 9031
diff changeset
176 def statusmessage(code, message=None):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
177 return b'%d %s' % (code, message or _statusmessage(code))
131
c9d51742471c moving hgweb to mercurial subdir
jake@edge2.net
parents:
diff changeset
178
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42922
diff changeset
179
25717
46e2c57026bc hgweb: drop the default argument for get_stat
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25660
diff changeset
180 def get_stat(spath, fn):
46e2c57026bc hgweb: drop the default argument for get_stat
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 25660
diff changeset
181 """stat fn if it exists, spath otherwise"""
22577
a111e460318a hgweb: refresh hgweb.repo on phase change (issue4061)
Anton Shestakov <engored@ya.ru>
parents: 19951
diff changeset
182 cl_path = os.path.join(spath, fn)
3853
c0b449154a90 switch to the .hg/store layout, fix the tests
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 3276
diff changeset
183 if os.path.exists(cl_path):
13958
71f51cc71652 hgweb: detect change based on changelog size too
Martin Geisler <mg@lazybytes.net>
parents: 13444
diff changeset
184 return os.stat(cl_path)
1418
68f81ba07b2a Make hgweb work when the repository is empty (no 00changelog.i)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1416
diff changeset
185 else:
13958
71f51cc71652 hgweb: detect change based on changelog size too
Martin Geisler <mg@lazybytes.net>
parents: 13444
diff changeset
186 return os.stat(spath)
71f51cc71652 hgweb: detect change based on changelog size too
Martin Geisler <mg@lazybytes.net>
parents: 13444
diff changeset
187
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42922
diff changeset
188
13958
71f51cc71652 hgweb: detect change based on changelog size too
Martin Geisler <mg@lazybytes.net>
parents: 13444
diff changeset
189 def get_mtime(spath):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
190 return get_stat(spath, b"00changelog.i")[stat.ST_MTIME]
1418
68f81ba07b2a Make hgweb work when the repository is empty (no 00changelog.i)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1416
diff changeset
191
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42922
diff changeset
192
31790
62f9679df1f2 hgweb: extract path traversal checking into standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 31789
diff changeset
193 def ispathsafe(path):
62f9679df1f2 hgweb: extract path traversal checking into standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 31789
diff changeset
194 """Determine if a path is safe to use for filesystem access."""
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
195 parts = path.split(b'/')
31790
62f9679df1f2 hgweb: extract path traversal checking into standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 31789
diff changeset
196 for part in parts:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42922
diff changeset
197 if (
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
198 part in (b'', pycompat.oscurdir, pycompat.ospardir)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42922
diff changeset
199 or pycompat.ossep in part
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42922
diff changeset
200 or pycompat.osaltsep is not None
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42922
diff changeset
201 and pycompat.osaltsep in part
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42922
diff changeset
202 ):
31790
62f9679df1f2 hgweb: extract path traversal checking into standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 31789
diff changeset
203 return False
62f9679df1f2 hgweb: extract path traversal checking into standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 31789
diff changeset
204
62f9679df1f2 hgweb: extract path traversal checking into standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 31789
diff changeset
205 return True
62f9679df1f2 hgweb: extract path traversal checking into standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 31789
diff changeset
206
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42922
diff changeset
207
45378
dc9fe90bdbd5 hgweb: let staticfile() look up path from default location unless provided
Martin von Zweigbergk <martinvonz@google.com>
parents: 45306
diff changeset
208 def staticfile(templatepath, directory, fname, res):
5930
c301f15c965a send conservatively capitalized HTTP headers
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5779
diff changeset
209 """return a file inside directory with guessed Content-Type header
1825
a9343f9d7365 Make hgweb.staticfile() more secure and portable.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 1796
diff changeset
210
a9343f9d7365 Make hgweb.staticfile() more secure and portable.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 1796
diff changeset
211 fname always uses '/' as directory separator and isn't allowed to
a9343f9d7365 Make hgweb.staticfile() more secure and portable.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 1796
diff changeset
212 contain unusual path components.
5930
c301f15c965a send conservatively capitalized HTTP headers
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5779
diff changeset
213 Content-Type is guessed using the mimetypes module.
1825
a9343f9d7365 Make hgweb.staticfile() more secure and portable.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 1796
diff changeset
214 Return an empty string if fname is illegal or file not found.
1793
83c6d8355909 Allow serving static files from hgwebdir to fix CSS and favicon.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 1792
diff changeset
215
1825
a9343f9d7365 Make hgweb.staticfile() more secure and portable.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 1796
diff changeset
216 """
31790
62f9679df1f2 hgweb: extract path traversal checking into standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 31789
diff changeset
217 if not ispathsafe(fname):
62f9679df1f2 hgweb: extract path traversal checking into standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 31789
diff changeset
218 return
62f9679df1f2 hgweb: extract path traversal checking into standalone function
Gregory Szorc <gregory.szorc@gmail.com>
parents: 31789
diff changeset
219
45378
dc9fe90bdbd5 hgweb: let staticfile() look up path from default location unless provided
Martin von Zweigbergk <martinvonz@google.com>
parents: 45306
diff changeset
220 if not directory:
dc9fe90bdbd5 hgweb: let staticfile() look up path from default location unless provided
Martin von Zweigbergk <martinvonz@google.com>
parents: 45306
diff changeset
221 tp = templatepath or templater.templatedir()
dc9fe90bdbd5 hgweb: let staticfile() look up path from default location unless provided
Martin von Zweigbergk <martinvonz@google.com>
parents: 45306
diff changeset
222 if tp is not None:
dc9fe90bdbd5 hgweb: let staticfile() look up path from default location unless provided
Martin von Zweigbergk <martinvonz@google.com>
parents: 45306
diff changeset
223 directory = os.path.join(tp, b'static')
dc9fe90bdbd5 hgweb: let staticfile() look up path from default location unless provided
Martin von Zweigbergk <martinvonz@google.com>
parents: 45306
diff changeset
224
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
225 fpath = os.path.join(*fname.split(b'/'))
45380
f0735f2ce542 hgweb: minimize scope of a try-block in staticfile()
Martin von Zweigbergk <martinvonz@google.com>
parents: 45379
diff changeset
226 ct = pycompat.sysbytes(
f0735f2ce542 hgweb: minimize scope of a try-block in staticfile()
Martin von Zweigbergk <martinvonz@google.com>
parents: 45379
diff changeset
227 mimetypes.guess_type(pycompat.fsdecode(fpath))[0] or r"text/plain"
f0735f2ce542 hgweb: minimize scope of a try-block in staticfile()
Martin von Zweigbergk <martinvonz@google.com>
parents: 45379
diff changeset
228 )
45306
9a5c4875a88c hgweb: simplify staticfile() now that we always pass it a single directory
Martin von Zweigbergk <martinvonz@google.com>
parents: 43793
diff changeset
229 path = os.path.join(directory, fpath)
1793
83c6d8355909 Allow serving static files from hgwebdir to fix CSS and favicon.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 1792
diff changeset
230 try:
1825
a9343f9d7365 Make hgweb.staticfile() more secure and portable.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 1796
diff changeset
231 os.stat(path)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
232 with open(path, b'rb') as fh:
31789
161a87ed456e hgweb: use context manager for file I/O
Gregory Szorc <gregory.szorc@gmail.com>
parents: 31435
diff changeset
233 data = fh.read()
5561
22713dce19f6 hgweb: return meaningful HTTP status codes instead of nonsense
Bryan O'Sullivan <bos@serpentine.com>
parents: 4462
diff changeset
234 except TypeError:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
235 raise ErrorResponse(HTTP_SERVER_ERROR, b'illegal filename')
25660
328739ea70c3 global: mass rewrite to use modern exception syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents: 22577
diff changeset
236 except OSError as err:
5561
22713dce19f6 hgweb: return meaningful HTTP status codes instead of nonsense
Bryan O'Sullivan <bos@serpentine.com>
parents: 4462
diff changeset
237 if err.errno == errno.ENOENT:
5993
948a41e77902 hgweb: explicit response status
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5930
diff changeset
238 raise ErrorResponse(HTTP_NOT_FOUND)
5561
22713dce19f6 hgweb: return meaningful HTTP status codes instead of nonsense
Bryan O'Sullivan <bos@serpentine.com>
parents: 4462
diff changeset
239 else:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42922
diff changeset
240 raise ErrorResponse(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42922
diff changeset
241 HTTP_SERVER_ERROR, encoding.strtolocal(err.strerror)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42922
diff changeset
242 )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42922
diff changeset
243
45380
f0735f2ce542 hgweb: minimize scope of a try-block in staticfile()
Martin von Zweigbergk <martinvonz@google.com>
parents: 45379
diff changeset
244 res.headers[b'Content-Type'] = ct
f0735f2ce542 hgweb: minimize scope of a try-block in staticfile()
Martin von Zweigbergk <martinvonz@google.com>
parents: 45379
diff changeset
245 res.setbodybytes(data)
f0735f2ce542 hgweb: minimize scope of a try-block in staticfile()
Martin von Zweigbergk <martinvonz@google.com>
parents: 45379
diff changeset
246 return res
f0735f2ce542 hgweb: minimize scope of a try-block in staticfile()
Martin von Zweigbergk <martinvonz@google.com>
parents: 45379
diff changeset
247
3276
db9d2a624521 hgweb: Search templates in templatepath/style/map, too, using a common function.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3244
diff changeset
248
4462
12e4d9524951 hgweb: use generator to count parity of horizontal stripes for easier reading.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4038
diff changeset
249 def paritygen(stripecount, offset=0):
12e4d9524951 hgweb: use generator to count parity of horizontal stripes for easier reading.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4038
diff changeset
250 """count parity of horizontal stripes for easier reading"""
12e4d9524951 hgweb: use generator to count parity of horizontal stripes for easier reading.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4038
diff changeset
251 if stripecount and offset:
12e4d9524951 hgweb: use generator to count parity of horizontal stripes for easier reading.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4038
diff changeset
252 # account for offset, e.g. due to building the list in reverse
12e4d9524951 hgweb: use generator to count parity of horizontal stripes for easier reading.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4038
diff changeset
253 count = (stripecount + offset) % stripecount
36397
7a3590e67868 py3: use '//' for integer division in hgweb/common.py
Pulkit Goyal <7895pulkit@gmail.com>
parents: 36296
diff changeset
254 parity = (stripecount + offset) // stripecount & 1
4462
12e4d9524951 hgweb: use generator to count parity of horizontal stripes for easier reading.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4038
diff changeset
255 else:
12e4d9524951 hgweb: use generator to count parity of horizontal stripes for easier reading.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4038
diff changeset
256 count = 0
12e4d9524951 hgweb: use generator to count parity of horizontal stripes for easier reading.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4038
diff changeset
257 parity = 0
12e4d9524951 hgweb: use generator to count parity of horizontal stripes for easier reading.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4038
diff changeset
258 while True:
12e4d9524951 hgweb: use generator to count parity of horizontal stripes for easier reading.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4038
diff changeset
259 yield parity
12e4d9524951 hgweb: use generator to count parity of horizontal stripes for easier reading.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4038
diff changeset
260 count += 1
12e4d9524951 hgweb: use generator to count parity of horizontal stripes for easier reading.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4038
diff changeset
261 if stripecount and count >= stripecount:
12e4d9524951 hgweb: use generator to count parity of horizontal stripes for easier reading.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4038
diff changeset
262 parity = 1 - parity
12e4d9524951 hgweb: use generator to count parity of horizontal stripes for easier reading.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4038
diff changeset
263 count = 0
12e4d9524951 hgweb: use generator to count parity of horizontal stripes for easier reading.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4038
diff changeset
264
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42922
diff changeset
265
5779
e9f68860d5ed Don't let ui.username override web.contact (issue900)
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5760
diff changeset
266 def get_contact(config):
e9f68860d5ed Don't let ui.username override web.contact (issue900)
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5760
diff changeset
267 """Return repo contact information or empty string.
e9f68860d5ed Don't let ui.username override web.contact (issue900)
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5760
diff changeset
268
e9f68860d5ed Don't let ui.username override web.contact (issue900)
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5760
diff changeset
269 web.contact is the primary source, but if that is not set, try
e9f68860d5ed Don't let ui.username override web.contact (issue900)
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5760
diff changeset
270 ui.username or $EMAIL as a fallback to display something useful.
e9f68860d5ed Don't let ui.username override web.contact (issue900)
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5760
diff changeset
271 """
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42922
diff changeset
272 return (
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
273 config(b"web", b"contact")
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
274 or config(b"ui", b"username")
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
275 or encoding.environ.get(b"EMAIL")
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
276 or b""
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42922
diff changeset
277 )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42922
diff changeset
278
12183
f64b416b0ac8 hgweb: support very simple caching model (issue1845)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 10264
diff changeset
279
30766
d7bf7d2bd5ab hgweb: support Content Security Policy
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30636
diff changeset
280 def cspvalues(ui):
d7bf7d2bd5ab hgweb: support Content Security Policy
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30636
diff changeset
281 """Obtain the Content-Security-Policy header and nonce value.
d7bf7d2bd5ab hgweb: support Content Security Policy
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30636
diff changeset
282
d7bf7d2bd5ab hgweb: support Content Security Policy
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30636
diff changeset
283 Returns a 2-tuple of the CSP header value and the nonce value.
d7bf7d2bd5ab hgweb: support Content Security Policy
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30636
diff changeset
284
d7bf7d2bd5ab hgweb: support Content Security Policy
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30636
diff changeset
285 First value is ``None`` if CSP isn't enabled. Second value is ``None``
d7bf7d2bd5ab hgweb: support Content Security Policy
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30636
diff changeset
286 if CSP isn't enabled or if the CSP header doesn't need a nonce.
d7bf7d2bd5ab hgweb: support Content Security Policy
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30636
diff changeset
287 """
34643
f42dec9c976e hgweb: do not import uuid immediately to avoid its side effect
Jun Wu <quark@fb.com>
parents: 34585
diff changeset
288 # Without demandimport, "import uuid" could have an immediate side-effect
f42dec9c976e hgweb: do not import uuid immediately to avoid its side effect
Jun Wu <quark@fb.com>
parents: 34585
diff changeset
289 # running "ldconfig" on Linux trying to find libuuid.
f42dec9c976e hgweb: do not import uuid immediately to avoid its side effect
Jun Wu <quark@fb.com>
parents: 34585
diff changeset
290 # With Python <= 2.7.12, that "ldconfig" is run via a shell and the shell
f42dec9c976e hgweb: do not import uuid immediately to avoid its side effect
Jun Wu <quark@fb.com>
parents: 34585
diff changeset
291 # may pollute the terminal with:
f42dec9c976e hgweb: do not import uuid immediately to avoid its side effect
Jun Wu <quark@fb.com>
parents: 34585
diff changeset
292 #
f42dec9c976e hgweb: do not import uuid immediately to avoid its side effect
Jun Wu <quark@fb.com>
parents: 34585
diff changeset
293 # shell-init: error retrieving current directory: getcwd: cannot access
f42dec9c976e hgweb: do not import uuid immediately to avoid its side effect
Jun Wu <quark@fb.com>
parents: 34585
diff changeset
294 # parent directories: No such file or directory
f42dec9c976e hgweb: do not import uuid immediately to avoid its side effect
Jun Wu <quark@fb.com>
parents: 34585
diff changeset
295 #
f42dec9c976e hgweb: do not import uuid immediately to avoid its side effect
Jun Wu <quark@fb.com>
parents: 34585
diff changeset
296 # Python >= 2.7.13 has fixed it by running "ldconfig" directly without a
f42dec9c976e hgweb: do not import uuid immediately to avoid its side effect
Jun Wu <quark@fb.com>
parents: 34585
diff changeset
297 # shell (hg changeset a09ae70f3489).
f42dec9c976e hgweb: do not import uuid immediately to avoid its side effect
Jun Wu <quark@fb.com>
parents: 34585
diff changeset
298 #
f42dec9c976e hgweb: do not import uuid immediately to avoid its side effect
Jun Wu <quark@fb.com>
parents: 34585
diff changeset
299 # Moved "import uuid" from here so it's executed after we know we have
f42dec9c976e hgweb: do not import uuid immediately to avoid its side effect
Jun Wu <quark@fb.com>
parents: 34585
diff changeset
300 # a sane cwd (i.e. after dispatch.py cwd check).
f42dec9c976e hgweb: do not import uuid immediately to avoid its side effect
Jun Wu <quark@fb.com>
parents: 34585
diff changeset
301 #
f42dec9c976e hgweb: do not import uuid immediately to avoid its side effect
Jun Wu <quark@fb.com>
parents: 34585
diff changeset
302 # We can move it back once we no longer need Python <= 2.7.12 support.
f42dec9c976e hgweb: do not import uuid immediately to avoid its side effect
Jun Wu <quark@fb.com>
parents: 34585
diff changeset
303 import uuid
f42dec9c976e hgweb: do not import uuid immediately to avoid its side effect
Jun Wu <quark@fb.com>
parents: 34585
diff changeset
304
30766
d7bf7d2bd5ab hgweb: support Content Security Policy
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30636
diff changeset
305 # Don't allow untrusted CSP setting since it be disable protections
d7bf7d2bd5ab hgweb: support Content Security Policy
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30636
diff changeset
306 # from a trusted/global source.
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
307 csp = ui.config(b'web', b'csp', untrusted=False)
30766
d7bf7d2bd5ab hgweb: support Content Security Policy
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30636
diff changeset
308 nonce = None
d7bf7d2bd5ab hgweb: support Content Security Policy
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30636
diff changeset
309
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
310 if csp and b'%nonce%' in csp:
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
311 nonce = base64.urlsafe_b64encode(uuid.uuid4().bytes).rstrip(b'=')
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
312 csp = csp.replace(b'%nonce%', nonce)
30766
d7bf7d2bd5ab hgweb: support Content Security Policy
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30636
diff changeset
313
d7bf7d2bd5ab hgweb: support Content Security Policy
Gregory Szorc <gregory.szorc@gmail.com>
parents: 30636
diff changeset
314 return csp, nonce