Mercurial > public > mercurial-scm > hg-stable
comparison mercurial/hgweb/protocol.py @ 6779:d3147b4e3e8a
hgweb: centralize permission checks for protocol commands
Consistently enforces authorization checks set up in hgrc up front, so that
the actual commands don't have to worry about them and implementers of
hgweb alternatives can easily implement their own permission checks.
author | Dirkjan Ochtman <dirkjan@ochtman.nl> |
---|---|
date | Sun, 29 Jun 2008 11:35:06 +0200 |
parents | 8542fac26f63 |
children | 4c1d67e0fa8c |
comparison
equal
deleted
inserted
replaced
6778:959efdac4a9c | 6779:d3147b4e3e8a |
---|---|
60 req.write(resp) | 60 req.write(resp) |
61 | 61 |
62 def changegroup(web, req): | 62 def changegroup(web, req): |
63 req.respond(HTTP_OK, HGTYPE) | 63 req.respond(HTTP_OK, HGTYPE) |
64 nodes = [] | 64 nodes = [] |
65 if not web.allowpull: | |
66 return | |
67 | 65 |
68 if 'roots' in req.form: | 66 if 'roots' in req.form: |
69 nodes = map(bin, req.form['roots'][0].split(" ")) | 67 nodes = map(bin, req.form['roots'][0].split(" ")) |
70 | 68 |
71 z = zlib.compressobj() | 69 z = zlib.compressobj() |
80 | 78 |
81 def changegroupsubset(web, req): | 79 def changegroupsubset(web, req): |
82 req.respond(HTTP_OK, HGTYPE) | 80 req.respond(HTTP_OK, HGTYPE) |
83 bases = [] | 81 bases = [] |
84 heads = [] | 82 heads = [] |
85 if not web.allowpull: | |
86 return | |
87 | 83 |
88 if 'bases' in req.form: | 84 if 'bases' in req.form: |
89 bases = [bin(x) for x in req.form['bases'][0].split(' ')] | 85 bases = [bin(x) for x in req.form['bases'][0].split(' ')] |
90 if 'heads' in req.form: | 86 if 'heads' in req.form: |
91 heads = [bin(x) for x in req.form['heads'][0].split(' ')] | 87 heads = [bin(x) for x in req.form['heads'][0].split(' ')] |
118 req.header(headers.items()) | 114 req.header(headers.items()) |
119 req.respond(status, HGTYPE) | 115 req.respond(status, HGTYPE) |
120 req.write('0\n') | 116 req.write('0\n') |
121 req.write(response) | 117 req.write(response) |
122 | 118 |
123 # enforce that you can only unbundle with POST requests | 119 proto = req.env.get('wsgi.url_scheme') or 'http' |
124 if req.env['REQUEST_METHOD'] != 'POST': | |
125 headers = {'status': '405 Method Not Allowed'} | |
126 bail('unbundle requires POST request\n', headers) | |
127 return | |
128 | |
129 # require ssl by default, auth info cannot be sniffed and | |
130 # replayed | |
131 ssl_req = web.configbool('web', 'push_ssl', True) | |
132 if ssl_req: | |
133 if req.env.get('wsgi.url_scheme') != 'https': | |
134 bail('ssl required\n') | |
135 return | |
136 proto = 'https' | |
137 else: | |
138 proto = 'http' | |
139 | |
140 # do not allow push unless explicitly allowed | |
141 if not web.check_perm(req, 'push', False): | |
142 bail('push not authorized\n', headers={'status': '401 Unauthorized'}) | |
143 return | |
144 | |
145 their_heads = req.form['heads'][0].split(' ') | 120 their_heads = req.form['heads'][0].split(' ') |
146 | 121 |
147 def check_heads(): | 122 def check_heads(): |
148 heads = map(hex, web.repo.heads()) | 123 heads = map(hex, web.repo.heads()) |
149 return their_heads == [hex('force')] or their_heads == heads | 124 return their_heads == [hex('force')] or their_heads == heads |
222 finally: | 197 finally: |
223 fp.close() | 198 fp.close() |
224 os.unlink(tempname) | 199 os.unlink(tempname) |
225 | 200 |
226 def stream_out(web, req): | 201 def stream_out(web, req): |
227 if not web.allowpull: | |
228 return | |
229 req.respond(HTTP_OK, HGTYPE) | 202 req.respond(HTTP_OK, HGTYPE) |
230 streamclone.stream_out(web.repo, req, untrusted=True) | 203 streamclone.stream_out(web.repo, req, untrusted=True) |