Show More
@@ -77,24 +77,41 b' class hgweb(object):' | |||||
77 | self.reponame = name |
|
77 | self.reponame = name | |
78 | self.archives = 'zip', 'gz', 'bz2' |
|
78 | self.archives = 'zip', 'gz', 'bz2' | |
79 | self.stripecount = 1 |
|
79 | self.stripecount = 1 | |
80 | self.templatepath = self.repo.ui.config("web", "templates", |
|
80 | # a repo owner may set web.templates in .hg/hgrc to get any file | |
81 | templater.templatepath()) |
|
81 | # readable by the user running the CGI script | |
|
82 | self.templatepath = self.config("web", "templates", | |||
|
83 | templater.templatepath(), | |||
|
84 | untrusted=False) | |||
|
85 | ||||
|
86 | # The CGI scripts are often run by a user different from the repo owner. | |||
|
87 | # Trust the settings from the .hg/hgrc files by default. | |||
|
88 | def config(self, section, name, default=None, untrusted=True): | |||
|
89 | return self.repo.ui.config(section, name, default, | |||
|
90 | untrusted=untrusted) | |||
|
91 | ||||
|
92 | def configbool(self, section, name, default=False, untrusted=True): | |||
|
93 | return self.repo.ui.configbool(section, name, default, | |||
|
94 | untrusted=untrusted) | |||
|
95 | ||||
|
96 | def configlist(self, section, name, default=None, untrusted=True): | |||
|
97 | return self.repo.ui.configlist(section, name, default, | |||
|
98 | untrusted=untrusted) | |||
82 |
|
99 | |||
83 | def refresh(self): |
|
100 | def refresh(self): | |
84 | mtime = get_mtime(self.repo.root) |
|
101 | mtime = get_mtime(self.repo.root) | |
85 | if mtime != self.mtime: |
|
102 | if mtime != self.mtime: | |
86 | self.mtime = mtime |
|
103 | self.mtime = mtime | |
87 | self.repo = hg.repository(self.repo.ui, self.repo.root) |
|
104 | self.repo = hg.repository(self.repo.ui, self.repo.root) | |
88 |
self.maxchanges = int(self |
|
105 | self.maxchanges = int(self.config("web", "maxchanges", 10)) | |
89 |
self.stripecount = int(self |
|
106 | self.stripecount = int(self.config("web", "stripes", 1)) | |
90 |
self.maxshortchanges = int(self |
|
107 | self.maxshortchanges = int(self.config("web", "maxshortchanges", 60)) | |
91 |
self.maxfiles = int(self |
|
108 | self.maxfiles = int(self.config("web", "maxfiles", 10)) | |
92 |
self.allowpull = self |
|
109 | self.allowpull = self.configbool("web", "allowpull", True) | |
93 |
|
110 | |||
94 | def archivelist(self, nodeid): |
|
111 | def archivelist(self, nodeid): | |
95 |
allowed = self |
|
112 | allowed = self.configlist("web", "allow_archive") | |
96 | for i, spec in self.archive_specs.iteritems(): |
|
113 | for i, spec in self.archive_specs.iteritems(): | |
97 |
if i in allowed or self |
|
114 | if i in allowed or self.configbool("web", "allow" + i): | |
98 | yield {"type" : i, "extension" : spec[2], "node" : nodeid} |
|
115 | yield {"type" : i, "extension" : spec[2], "node" : nodeid} | |
99 |
|
116 | |||
100 | def listfilediffs(self, files, changeset): |
|
117 | def listfilediffs(self, files, changeset): | |
@@ -169,7 +186,7 b' class hgweb(object):' | |||||
169 | modified, added, removed = map(lambda x: filterfiles(files, x), |
|
186 | modified, added, removed = map(lambda x: filterfiles(files, x), | |
170 | (modified, added, removed)) |
|
187 | (modified, added, removed)) | |
171 |
|
188 | |||
172 | diffopts = patch.diffopts(self.repo.ui) |
|
189 | diffopts = patch.diffopts(self.repo.ui, untrusted=True) | |
173 | for f in modified: |
|
190 | for f in modified: | |
174 | to = r.file(f).read(mmap1[f]) |
|
191 | to = r.file(f).read(mmap1[f]) | |
175 | tn = r.file(f).read(mmap2[f]) |
|
192 | tn = r.file(f).read(mmap2[f]) | |
@@ -571,10 +588,10 b' class hgweb(object):' | |||||
571 | end = min(count, start + self.maxchanges) |
|
588 | end = min(count, start + self.maxchanges) | |
572 |
|
589 | |||
573 | yield self.t("summary", |
|
590 | yield self.t("summary", | |
574 |
desc = self |
|
591 | desc = self.config("web", "description", "unknown"), | |
575 |
owner = (self |
|
592 | owner = (self.config("ui", "username") or # preferred | |
576 |
self |
|
593 | self.config("web", "contact") or # deprecated | |
577 |
self |
|
594 | self.config("web", "author", "unknown")), # also | |
578 | lastchange = cl.read(cl.tip())[2], |
|
595 | lastchange = cl.read(cl.tip())[2], | |
579 | tags = tagentries, |
|
596 | tags = tagentries, | |
580 | heads = heads, |
|
597 | heads = heads, | |
@@ -650,7 +667,7 b' class hgweb(object):' | |||||
650 | yield self.t("footer", **map) |
|
667 | yield self.t("footer", **map) | |
651 |
|
668 | |||
652 | def motd(**map): |
|
669 | def motd(**map): | |
653 |
yield self |
|
670 | yield self.config("web", "motd", "") | |
654 |
|
671 | |||
655 | def expand_form(form): |
|
672 | def expand_form(form): | |
656 | shortcuts = { |
|
673 | shortcuts = { | |
@@ -748,7 +765,7 b' class hgweb(object):' | |||||
748 | fields = [] |
|
765 | fields = [] | |
749 | if req.form.has_key('style'): |
|
766 | if req.form.has_key('style'): | |
750 | style = req.form['style'][0] |
|
767 | style = req.form['style'][0] | |
751 |
if style != self |
|
768 | if style != self.config('web', 'style', ''): | |
752 | fields.append(('style', style)) |
|
769 | fields.append(('style', style)) | |
753 |
|
770 | |||
754 | separator = req.url[-1] == '?' and ';' or '?' |
|
771 | separator = req.url[-1] == '?' and ';' or '?' | |
@@ -761,7 +778,7 b' class hgweb(object):' | |||||
761 | expand_form(req.form) |
|
778 | expand_form(req.form) | |
762 | rewrite_request(req) |
|
779 | rewrite_request(req) | |
763 |
|
780 | |||
764 |
style = self |
|
781 | style = self.config("web", "style", "") | |
765 | if req.form.has_key('style'): |
|
782 | if req.form.has_key('style'): | |
766 | style = req.form['style'][0] |
|
783 | style = req.form['style'][0] | |
767 | mapfile = style_map(self.templatepath, style) |
|
784 | mapfile = style_map(self.templatepath, style) | |
@@ -771,7 +788,7 b' class hgweb(object):' | |||||
771 | urlbase = 'http://%s%s' % (req.env['SERVER_NAME'], port) |
|
788 | urlbase = 'http://%s%s' % (req.env['SERVER_NAME'], port) | |
772 |
|
789 | |||
773 | if not self.reponame: |
|
790 | if not self.reponame: | |
774 |
self.reponame = (self |
|
791 | self.reponame = (self.config("web", "name") | |
775 | or req.env.get('REPO_NAME') |
|
792 | or req.env.get('REPO_NAME') | |
776 | or req.url.strip('/') or self.repo.root) |
|
793 | or req.url.strip('/') or self.repo.root) | |
777 |
|
794 | |||
@@ -985,9 +1002,9 b' class hgweb(object):' | |||||
985 | def do_archive(self, req): |
|
1002 | def do_archive(self, req): | |
986 | changeset = self.repo.lookup(req.form['node'][0]) |
|
1003 | changeset = self.repo.lookup(req.form['node'][0]) | |
987 | type_ = req.form['type'][0] |
|
1004 | type_ = req.form['type'][0] | |
988 |
allowed = self |
|
1005 | allowed = self.configlist("web", "allow_archive") | |
989 | if (type_ in self.archives and (type_ in allowed or |
|
1006 | if (type_ in self.archives and (type_ in allowed or | |
990 |
self |
|
1007 | self.configbool("web", "allow" + type_, False))): | |
991 | self.archive(req, changeset, type_) |
|
1008 | self.archive(req, changeset, type_) | |
992 | return |
|
1009 | return | |
993 |
|
1010 | |||
@@ -995,15 +1012,17 b' class hgweb(object):' | |||||
995 |
|
1012 | |||
996 | def do_static(self, req): |
|
1013 | def do_static(self, req): | |
997 | fname = req.form['file'][0] |
|
1014 | fname = req.form['file'][0] | |
998 | static = self.repo.ui.config("web", "static", |
|
1015 | # a repo owner may set web.static in .hg/hgrc to get any file | |
999 | os.path.join(self.templatepath, |
|
1016 | # readable by the user running the CGI script | |
1000 | "static")) |
|
1017 | static = self.config("web", "static", | |
|
1018 | os.path.join(self.templatepath, "static"), | |||
|
1019 | untrusted=False) | |||
1001 | req.write(staticfile(static, fname, req) |
|
1020 | req.write(staticfile(static, fname, req) | |
1002 | or self.t("error", error="%r not found" % fname)) |
|
1021 | or self.t("error", error="%r not found" % fname)) | |
1003 |
|
1022 | |||
1004 | def do_capabilities(self, req): |
|
1023 | def do_capabilities(self, req): | |
1005 | caps = ['unbundle', 'lookup', 'changegroupsubset'] |
|
1024 | caps = ['unbundle', 'lookup', 'changegroupsubset'] | |
1006 |
if self |
|
1025 | if self.configbool('server', 'uncompressed'): | |
1007 | caps.append('stream=%d' % self.repo.revlogversion) |
|
1026 | caps.append('stream=%d' % self.repo.revlogversion) | |
1008 | resp = ' '.join(caps) |
|
1027 | resp = ' '.join(caps) | |
1009 | req.httphdr("application/mercurial-0.1", length=len(resp)) |
|
1028 | req.httphdr("application/mercurial-0.1", length=len(resp)) | |
@@ -1016,11 +1035,11 b' class hgweb(object):' | |||||
1016 |
|
1035 | |||
1017 | user = req.env.get('REMOTE_USER') |
|
1036 | user = req.env.get('REMOTE_USER') | |
1018 |
|
1037 | |||
1019 |
deny = self |
|
1038 | deny = self.configlist('web', 'deny_' + op) | |
1020 | if deny and (not user or deny == ['*'] or user in deny): |
|
1039 | if deny and (not user or deny == ['*'] or user in deny): | |
1021 | return False |
|
1040 | return False | |
1022 |
|
1041 | |||
1023 |
allow = self |
|
1042 | allow = self.configlist('web', 'allow_' + op) | |
1024 | return (allow and (allow == ['*'] or user in allow)) or default |
|
1043 | return (allow and (allow == ['*'] or user in allow)) or default | |
1025 |
|
1044 | |||
1026 | def do_unbundle(self, req): |
|
1045 | def do_unbundle(self, req): | |
@@ -1036,7 +1055,7 b' class hgweb(object):' | |||||
1036 |
|
1055 | |||
1037 | # require ssl by default, auth info cannot be sniffed and |
|
1056 | # require ssl by default, auth info cannot be sniffed and | |
1038 | # replayed |
|
1057 | # replayed | |
1039 |
ssl_req = self |
|
1058 | ssl_req = self.configbool('web', 'push_ssl', True) | |
1040 | if ssl_req: |
|
1059 | if ssl_req: | |
1041 | if not req.env.get('HTTPS'): |
|
1060 | if not req.env.get('HTTPS'): | |
1042 | bail(_('ssl required\n')) |
|
1061 | bail(_('ssl required\n')) |
General Comments 0
You need to be logged in to leave comments.
Login now