annotate upmana/mercurial/hgweb/hgweb_mod.py @ 229:1645a78a33a4 alpha

Traipse Alpha 'OpenRPG' {100612-02} Traipse is a distribution of OpenRPG that is designed to be easy to setup and go. Traipse also makes it easy for developers to work on code without fear of sacrifice. 'Ornery-Orc' continues the trend of 'Grumpy' and adds fixes to the code. 'Ornery-Orc's main goal is to offer more advanced features and enhance the productivity of the user. Update Summary (Preparing to close updates) New Features: New to Map, can re-order Grid, Miniatures, and Whiteboard layer draw order Fixes: Fix to InterParse that was causing an Infernal Loop with Namespace Internal Fix to XML data, removed old Minidom and switched to Element Tree Fix to Server that was causing eternal attempt to find a Server ID, in Register Rooms thread Fix to metaservers.xml file not being created
author sirebral
date Sat, 12 Jun 2010 04:46:16 -0500
parents 36919b8a3ef9
children
rev   line source
121
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
1 # hgweb/hgweb_mod.py - Web interface for a repository.
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
2 #
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
3 # Copyright 21 May 2005 - (c) 2005 Jake Edge <jake@edge2.net>
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
4 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
5 #
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
6 # This software may be used and distributed according to the terms of the
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
7 # GNU General Public License version 2, incorporated herein by reference.
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
8
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
9 import os
122
36919b8a3ef9 Traipse Alpha 'OpenRPG' {091031-00}
sirebral
parents: 121
diff changeset
10 from upmana.mercurial import ui, hg, hook, error, encoding, templater
121
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
11 from common import get_mtime, ErrorResponse
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
12 from common import HTTP_OK, HTTP_BAD_REQUEST, HTTP_NOT_FOUND, HTTP_SERVER_ERROR
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
13 from common import HTTP_UNAUTHORIZED, HTTP_METHOD_NOT_ALLOWED
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
14 from request import wsgirequest
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
15 import webcommands, protocol, webutil
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
16
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
17 perms = {
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
18 'changegroup': 'pull',
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
19 'changegroupsubset': 'pull',
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
20 'unbundle': 'push',
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
21 'stream_out': 'pull',
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
22 }
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
23
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
24 class hgweb(object):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
25 def __init__(self, repo, name=None):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
26 if isinstance(repo, str):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
27 u = ui.ui()
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
28 u.setconfig('ui', 'report_untrusted', 'off')
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
29 u.setconfig('ui', 'interactive', 'off')
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
30 self.repo = hg.repository(u, repo)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
31 else:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
32 self.repo = repo
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
33
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
34 hook.redirect(True)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
35 self.mtime = -1
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
36 self.reponame = name
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
37 self.archives = 'zip', 'gz', 'bz2'
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
38 self.stripecount = 1
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
39 # a repo owner may set web.templates in .hg/hgrc to get any file
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
40 # readable by the user running the CGI script
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
41 self.templatepath = self.config('web', 'templates')
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
42
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
43 # The CGI scripts are often run by a user different from the repo owner.
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
44 # Trust the settings from the .hg/hgrc files by default.
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
45 def config(self, section, name, default=None, untrusted=True):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
46 return self.repo.ui.config(section, name, default,
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
47 untrusted=untrusted)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
48
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
49 def configbool(self, section, name, default=False, untrusted=True):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
50 return self.repo.ui.configbool(section, name, default,
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
51 untrusted=untrusted)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
52
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
53 def configlist(self, section, name, default=None, untrusted=True):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
54 return self.repo.ui.configlist(section, name, default,
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
55 untrusted=untrusted)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
56
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
57 def refresh(self):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
58 mtime = get_mtime(self.repo.root)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
59 if mtime != self.mtime:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
60 self.mtime = mtime
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
61 self.repo = hg.repository(self.repo.ui, self.repo.root)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
62 self.maxchanges = int(self.config("web", "maxchanges", 10))
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
63 self.stripecount = int(self.config("web", "stripes", 1))
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
64 self.maxshortchanges = int(self.config("web", "maxshortchanges", 60))
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
65 self.maxfiles = int(self.config("web", "maxfiles", 10))
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
66 self.allowpull = self.configbool("web", "allowpull", True)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
67 encoding.encoding = self.config("web", "encoding",
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
68 encoding.encoding)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
69
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
70 def run(self):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
71 if not os.environ.get('GATEWAY_INTERFACE', '').startswith("CGI/1."):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
72 raise RuntimeError("This function is only intended to be "
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
73 "called while running as a CGI script.")
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
74 import mercurial.hgweb.wsgicgi as wsgicgi
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
75 wsgicgi.launch(self)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
76
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
77 def __call__(self, env, respond):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
78 req = wsgirequest(env, respond)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
79 return self.run_wsgi(req)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
80
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
81 def run_wsgi(self, req):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
82
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
83 self.refresh()
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
84
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
85 # work with CGI variables to create coherent structure
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
86 # use SCRIPT_NAME, PATH_INFO and QUERY_STRING as well as our REPO_NAME
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
87
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
88 req.url = req.env['SCRIPT_NAME']
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
89 if not req.url.endswith('/'):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
90 req.url += '/'
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
91 if 'REPO_NAME' in req.env:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
92 req.url += req.env['REPO_NAME'] + '/'
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
93
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
94 if 'PATH_INFO' in req.env:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
95 parts = req.env['PATH_INFO'].strip('/').split('/')
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
96 repo_parts = req.env.get('REPO_NAME', '').split('/')
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
97 if parts[:len(repo_parts)] == repo_parts:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
98 parts = parts[len(repo_parts):]
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
99 query = '/'.join(parts)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
100 else:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
101 query = req.env['QUERY_STRING'].split('&', 1)[0]
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
102 query = query.split(';', 1)[0]
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
103
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
104 # process this if it's a protocol request
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
105 # protocol bits don't need to create any URLs
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
106 # and the clients always use the old URL structure
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
107
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
108 cmd = req.form.get('cmd', [''])[0]
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
109 if cmd and cmd in protocol.__all__:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
110 if query:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
111 raise ErrorResponse(HTTP_NOT_FOUND)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
112 try:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
113 if cmd in perms:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
114 try:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
115 self.check_perm(req, perms[cmd])
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
116 except ErrorResponse, inst:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
117 if cmd == 'unbundle':
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
118 req.drain()
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
119 raise
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
120 method = getattr(protocol, cmd)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
121 return method(self.repo, req)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
122 except ErrorResponse, inst:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
123 req.respond(inst, protocol.HGTYPE)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
124 if not inst.message:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
125 return []
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
126 return '0\n%s\n' % inst.message,
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
127
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
128 # translate user-visible url structure to internal structure
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
129
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
130 args = query.split('/', 2)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
131 if 'cmd' not in req.form and args and args[0]:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
132
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
133 cmd = args.pop(0)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
134 style = cmd.rfind('-')
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
135 if style != -1:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
136 req.form['style'] = [cmd[:style]]
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
137 cmd = cmd[style+1:]
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
138
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
139 # avoid accepting e.g. style parameter as command
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
140 if hasattr(webcommands, cmd):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
141 req.form['cmd'] = [cmd]
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
142 else:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
143 cmd = ''
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
144
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
145 if cmd == 'static':
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
146 req.form['file'] = ['/'.join(args)]
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
147 else:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
148 if args and args[0]:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
149 node = args.pop(0)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
150 req.form['node'] = [node]
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
151 if args:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
152 req.form['file'] = args
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
153
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
154 if cmd == 'archive':
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
155 fn = req.form['node'][0]
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
156 for type_, spec in self.archive_specs.iteritems():
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
157 ext = spec[2]
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
158 if fn.endswith(ext):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
159 req.form['node'] = [fn[:-len(ext)]]
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
160 req.form['type'] = [type_]
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
161
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
162 # process the web interface request
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
163
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
164 try:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
165 tmpl = self.templater(req)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
166 ctype = tmpl('mimetype', encoding=encoding.encoding)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
167 ctype = templater.stringify(ctype)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
168
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
169 # check read permissions non-static content
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
170 if cmd != 'static':
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
171 self.check_perm(req, None)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
172
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
173 if cmd == '':
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
174 req.form['cmd'] = [tmpl.cache['default']]
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
175 cmd = req.form['cmd'][0]
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
176
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
177 if cmd not in webcommands.__all__:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
178 msg = 'no such method: %s' % cmd
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
179 raise ErrorResponse(HTTP_BAD_REQUEST, msg)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
180 elif cmd == 'file' and 'raw' in req.form.get('style', []):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
181 self.ctype = ctype
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
182 content = webcommands.rawfile(self, req, tmpl)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
183 else:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
184 content = getattr(webcommands, cmd)(self, req, tmpl)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
185 req.respond(HTTP_OK, ctype)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
186
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
187 return content
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
188
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
189 except error.LookupError, err:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
190 req.respond(HTTP_NOT_FOUND, ctype)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
191 msg = str(err)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
192 if 'manifest' not in msg:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
193 msg = 'revision not found: %s' % err.name
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
194 return tmpl('error', error=msg)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
195 except (error.RepoError, error.RevlogError), inst:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
196 req.respond(HTTP_SERVER_ERROR, ctype)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
197 return tmpl('error', error=str(inst))
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
198 except ErrorResponse, inst:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
199 req.respond(inst, ctype)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
200 return tmpl('error', error=inst.message)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
201
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
202 def templater(self, req):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
203
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
204 # determine scheme, port and server name
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
205 # this is needed to create absolute urls
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
206
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
207 proto = req.env.get('wsgi.url_scheme')
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
208 if proto == 'https':
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
209 proto = 'https'
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
210 default_port = "443"
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
211 else:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
212 proto = 'http'
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
213 default_port = "80"
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
214
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
215 port = req.env["SERVER_PORT"]
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
216 port = port != default_port and (":" + port) or ""
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
217 urlbase = '%s://%s%s' % (proto, req.env['SERVER_NAME'], port)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
218 staticurl = self.config("web", "staticurl") or req.url + 'static/'
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
219 if not staticurl.endswith('/'):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
220 staticurl += '/'
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
221
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
222 # some functions for the templater
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
223
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
224 def header(**map):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
225 yield tmpl('header', encoding=encoding.encoding, **map)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
226
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
227 def footer(**map):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
228 yield tmpl("footer", **map)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
229
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
230 def motd(**map):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
231 yield self.config("web", "motd", "")
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
232
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
233 # figure out which style to use
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
234
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
235 vars = {}
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
236 style = self.config("web", "style", "paper")
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
237 if 'style' in req.form:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
238 style = req.form['style'][0]
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
239 vars['style'] = style
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
240
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
241 start = req.url[-1] == '?' and '&' or '?'
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
242 sessionvars = webutil.sessionvars(vars, start)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
243 mapfile = templater.stylemap(style, self.templatepath)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
244
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
245 if not self.reponame:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
246 self.reponame = (self.config("web", "name")
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
247 or req.env.get('REPO_NAME')
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
248 or req.url.strip('/') or self.repo.root)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
249
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
250 # create the templater
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
251
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
252 tmpl = templater.templater(mapfile,
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
253 defaults={"url": req.url,
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
254 "staticurl": staticurl,
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
255 "urlbase": urlbase,
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
256 "repo": self.reponame,
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
257 "header": header,
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
258 "footer": footer,
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
259 "motd": motd,
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
260 "sessionvars": sessionvars
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
261 })
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
262 return tmpl
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
263
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
264 def archivelist(self, nodeid):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
265 allowed = self.configlist("web", "allow_archive")
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
266 for i, spec in self.archive_specs.iteritems():
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
267 if i in allowed or self.configbool("web", "allow" + i):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
268 yield {"type" : i, "extension" : spec[2], "node" : nodeid}
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
269
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
270 archive_specs = {
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
271 'bz2': ('application/x-tar', 'tbz2', '.tar.bz2', None),
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
272 'gz': ('application/x-tar', 'tgz', '.tar.gz', None),
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
273 'zip': ('application/zip', 'zip', '.zip', None),
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
274 }
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
275
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
276 def check_perm(self, req, op):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
277 '''Check permission for operation based on request data (including
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
278 authentication info). Return if op allowed, else raise an ErrorResponse
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
279 exception.'''
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
280
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
281 user = req.env.get('REMOTE_USER')
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
282
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
283 deny_read = self.configlist('web', 'deny_read')
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
284 if deny_read and (not user or deny_read == ['*'] or user in deny_read):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
285 raise ErrorResponse(HTTP_UNAUTHORIZED, 'read not authorized')
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
286
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
287 allow_read = self.configlist('web', 'allow_read')
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
288 result = (not allow_read) or (allow_read == ['*'])
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
289 if not (result or user in allow_read):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
290 raise ErrorResponse(HTTP_UNAUTHORIZED, 'read not authorized')
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
291
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
292 if op == 'pull' and not self.allowpull:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
293 raise ErrorResponse(HTTP_UNAUTHORIZED, 'pull not authorized')
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
294 elif op == 'pull' or op is None: # op is None for interface requests
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
295 return
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
296
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
297 # enforce that you can only push using POST requests
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
298 if req.env['REQUEST_METHOD'] != 'POST':
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
299 msg = 'push requires POST request'
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
300 raise ErrorResponse(HTTP_METHOD_NOT_ALLOWED, msg)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
301
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
302 # require ssl by default for pushing, auth info cannot be sniffed
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
303 # and replayed
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
304 scheme = req.env.get('wsgi.url_scheme')
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
305 if self.configbool('web', 'push_ssl', True) and scheme != 'https':
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
306 raise ErrorResponse(HTTP_OK, 'ssl required')
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
307
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
308 deny = self.configlist('web', 'deny_push')
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
309 if deny and (not user or deny == ['*'] or user in deny):
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
310 raise ErrorResponse(HTTP_UNAUTHORIZED, 'push not authorized')
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
311
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
312 allow = self.configlist('web', 'allow_push')
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
313 result = allow and (allow == ['*'] or user in allow)
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
314 if not result:
496dbf12a6cb Traipse Alpha 'OpenRPG' {091030-00}
sirebral
parents:
diff changeset
315 raise ErrorResponse(HTTP_UNAUTHORIZED, 'push not authorized')