##// END OF EJS Templates
hgweb: support for deny_read/allow_read options...
Mark Edgington -
r7336:2dc86871 default
parent child Browse files
Show More
@@ -676,6 +676,16 b' web::'
676 must be present in this list (separated by whitespace or ",").
676 must be present in this list (separated by whitespace or ",").
677 The contents of the allow_push list are examined after the
677 The contents of the allow_push list are examined after the
678 deny_push list.
678 deny_push list.
679 allow_read;;
680 If the user has not already been denied repository access due to the
681 contents of deny_read, this list determines whether to grant repository
682 access to the user. If this list is not empty, and the user is
683 unauthenticated or not present in the list (separated by whitespace or ","),
684 then access is denied for the user. If the list is empty or not set, then
685 access is permitted to all users by default. Setting allow_read to the
686 special value "*" is equivalent to it not being set (i.e. access is
687 permitted to all users). The contents of the allow_read list are examined
688 after the deny_read list.
679 allowzip;;
689 allowzip;;
680 (DEPRECATED) Whether to allow .zip downloading of repo revisions.
690 (DEPRECATED) Whether to allow .zip downloading of repo revisions.
681 Default is false. This feature creates temporary files.
691 Default is false. This feature creates temporary files.
@@ -693,6 +703,18 b' web::'
693 and any authenticated user name present in this list (separated by
703 and any authenticated user name present in this list (separated by
694 whitespace or ",") is also denied. The contents of the deny_push
704 whitespace or ",") is also denied. The contents of the deny_push
695 list are examined before the allow_push list.
705 list are examined before the allow_push list.
706 deny_read;;
707 Whether to deny reading/viewing of the repository. If this list is not
708 empty, unauthenticated users are all denied, and any authenticated user name
709 present in this list (separated by whitespace or ",") is also denied access
710 to the repository. If set to the special value "*", all remote users are
711 denied access (rarely needed ;). If deny_read is empty or not set, the
712 determination of repository access depends on the presence and content of
713 the allow_read list (see description). If both deny_read and allow_read are
714 empty or not set, then access is permitted to all users by default. If the
715 repository is being served via hgwebdir, denied users will not be able to
716 see it in the list of repositories. The contents of the deny_read list have
717 priority over (are examined before) the contents of the allow_read list.
696 description;;
718 description;;
697 Textual description of the repository's purpose or contents.
719 Textual description of the repository's purpose or contents.
698 Default is "unknown".
720 Default is "unknown".
@@ -161,11 +161,13 b' class hgweb(object):'
161 # process the web interface request
161 # process the web interface request
162
162
163 try:
163 try:
164
165 tmpl = self.templater(req)
164 tmpl = self.templater(req)
166 ctype = tmpl('mimetype', encoding=self.encoding)
165 ctype = tmpl('mimetype', encoding=self.encoding)
167 ctype = templater.stringify(ctype)
166 ctype = templater.stringify(ctype)
168
167
168 # check allow_read / deny_read config options
169 self.check_perm(req, None)
170
169 if cmd == '':
171 if cmd == '':
170 req.form['cmd'] = [tmpl.cache['default']]
172 req.form['cmd'] = [tmpl.cache['default']]
171 cmd = req.form['cmd'][0]
173 cmd = req.form['cmd'][0]
@@ -278,11 +280,24 b' class hgweb(object):'
278
280
279 def check_perm(self, req, op):
281 def check_perm(self, req, op):
280 '''Check permission for operation based on request data (including
282 '''Check permission for operation based on request data (including
281 authentication info. Return true if op allowed, else false.'''
283 authentication info). Return if op allowed, else raise an ErrorResponse
284 exception.'''
285
286 user = req.env.get('REMOTE_USER')
287
288 deny_read = self.configlist('web', 'deny_read')
289 if deny_read and (not user or deny_read == ['*'] or user in deny_read):
290 raise ErrorResponse(HTTP_UNAUTHORIZED, 'read not authorized')
291
292 allow_read = self.configlist('web', 'allow_read')
293 result = (not allow_read) or (allow_read == ['*']) or (user in allow_read)
294 if not result:
295 raise ErrorResponse(HTTP_UNAUTHORIZED, 'read not authorized')
282
296
283 if op == 'pull' and not self.allowpull:
297 if op == 'pull' and not self.allowpull:
284 raise ErrorResponse(HTTP_OK, '')
298 raise ErrorResponse(HTTP_OK, '')
285 elif op == 'pull':
299 # op is None when checking allow/deny_read permissions for a web-browser request
300 elif op == 'pull' or op is None:
286 return
301 return
287
302
288 # enforce that you can only push using POST requests
303 # enforce that you can only push using POST requests
@@ -296,8 +311,6 b' class hgweb(object):'
296 if self.configbool('web', 'push_ssl', True) and scheme != 'https':
311 if self.configbool('web', 'push_ssl', True) and scheme != 'https':
297 raise ErrorResponse(HTTP_OK, 'ssl required')
312 raise ErrorResponse(HTTP_OK, 'ssl required')
298
313
299 user = req.env.get('REMOTE_USER')
300
301 deny = self.configlist('web', 'deny_push')
314 deny = self.configlist('web', 'deny_push')
302 if deny and (not user or deny == ['*'] or user in deny):
315 if deny and (not user or deny == ['*'] or user in deny):
303 raise ErrorResponse(HTTP_UNAUTHORIZED, 'push not authorized')
316 raise ErrorResponse(HTTP_UNAUTHORIZED, 'push not authorized')
@@ -72,6 +72,28 b' class hgwebdir(object):'
72 req = wsgirequest(env, respond)
72 req = wsgirequest(env, respond)
73 return self.run_wsgi(req)
73 return self.run_wsgi(req)
74
74
75 def read_allowed(self, ui, req):
76 """Check allow_read and deny_read config options of a repo's ui object
77 to determine user permissions. By default, with neither option set (or
78 both empty), allow all users to read the repo. There are two ways a
79 user can be denied read access: (1) deny_read is not empty, and the
80 user is unauthenticated or deny_read contains user (or *), and (2)
81 allow_read is not empty and the user is not in allow_read. Return True
82 if user is allowed to read the repo, else return False."""
83
84 user = req.env.get('REMOTE_USER')
85
86 deny_read = ui.configlist('web', 'deny_read', default=None, untrusted=True)
87 if deny_read and (not user or deny_read == ['*'] or user in deny_read):
88 return False
89
90 allow_read = ui.configlist('web', 'allow_read', default=None, untrusted=True)
91 # by default, allow reading if no allow_read option has been set
92 if (not allow_read) or (allow_read == ['*']) or (user in allow_read):
93 return True
94
95 return False
96
75 def run_wsgi(self, req):
97 def run_wsgi(self, req):
76
98
77 try:
99 try:
@@ -175,6 +197,9 b' class hgwebdir(object):'
175 if u.configbool("web", "hidden", untrusted=True):
197 if u.configbool("web", "hidden", untrusted=True):
176 continue
198 continue
177
199
200 if not self.read_allowed(u, req):
201 continue
202
178 parts = [name]
203 parts = [name]
179 if 'PATH_INFO' in req.env:
204 if 'PATH_INFO' in req.env:
180 parts.insert(0, req.env['PATH_INFO'].rstrip('/'))
205 parts.insert(0, req.env['PATH_INFO'].rstrip('/'))
General Comments 0
You need to be logged in to leave comments. Login now