def _check_path(self, path): """ Ensure that the path is within allowed bounds. """ _ = self._ abspath = os.path.abspath(path) if os.path.islink(path) or os.path.isdir(path): raise error.ForbiddenErr( _(u"Can't use symbolic links or directories as pages")) if not abspath.startswith(self.path): raise error.ForbiddenErr( _(u"Can't read or write outside of the pages repository"))
def _check_lock(self, title): _ = self.gettext restricted_pages = [ 'scripts.js', 'robots.txt', ] if self.read_only: raise error.ForbiddenErr(_(u"This site is read-only.")) if title in restricted_pages: raise error.ForbiddenErr(_(u"""Can't edit this page. It can only be edited by the site admin directly on the disk.""")) if title in self.index.page_links(self.locked_page): raise error.ForbiddenErr(_(u"This page is locked."))
def save_data(self, title, data, author=None, comment=None, parent_rev=None): """Save a new revision of the page. If the data is None, deletes it.""" _ = self._ user = (author or _('anon')).encode('utf-8') text = (comment or _('comment')).encode('utf-8') repo_file = self._title_to_file(title).encode('utf8') parent, other = self._get_parents(repo_file, parent_rev) if data is None: if title not in self: raise error.ForbiddenErr() else: if other is not None: try: data = self._merge(repo_file, parent, other, data) except ValueError: text = _('failed merge of edit conflict').encode('utf-8') def filectxfn(repo, memctx, path): if data is None: return None return _get_memfilectx(repo, path, data, memctx=memctx) self._commit(parent, other, text, [repo_file], filectxfn, user)
def _file_to_title(self, filepath): _ = self._ if not filepath.startswith(self.repo_prefix): raise error.ForbiddenErr( _(u"Can't read or write outside of the pages repository")) name = filepath[len(self.repo_prefix):].strip('/') # Un-escape special windows filenames and dot files if name.startswith('_') and len(name) > 1: name = name[1:] if self.extension and name.endswith(self.extension): name = name[:-len(self.extension)] return werkzeug.url_unquote(name)
def die(self, request): """Terminate the standalone server if invoked from localhost.""" _ = self.gettext if not request.remote_addr.startswith('127.'): raise error.ForbiddenErr( _(u'This URL can only be called locally.')) def agony(): yield u'Oh dear!' self.dead = True return WikiResponse(agony(), mimetype='text/plain')
def hgweb(self, request, path=None): """ Serve the pages repository on the web like a normal hg repository. """ _ = self.gettext if not self.config.get_bool('hgweb', False): raise error.ForbiddenErr(_(u'Repository access disabled.')) app = mercurial.hgweb.request.wsgiapplication( lambda: mercurial.hgweb.hgweb(self.storage.repo, self.site_name)) def hg_app(env, start): env = request.environ prefix = '/+hg' if env['PATH_INFO'].startswith(prefix): env["PATH_INFO"] = env["PATH_INFO"][len(prefix):] env["SCRIPT_NAME"] += prefix return app(env, start) return hg_app
def save(self, request, title): _ = self.gettext self._check_lock(title) url = request.get_url(title) if request.form.get('cancel'): if title not in self.storage: url = request.get_url(self.front_page) if request.form.get('preview'): text = request.form.get("text") if text is not None: lines = text.split('\n') else: lines = [werkzeug.html.p(werkzeug.html( _(u'No preview for binaries.')))] return self.edit(request, title, preview=lines) elif request.form.get('save'): if captcha and self.recaptcha_private_key: response = captcha.submit( request.form.get('recaptcha_challenge_field', ''), request.form.get('recaptcha_response_field', ''), self.recaptcha_private_key, request.remote_addr) if not response.is_valid: text = request.form.get("text", '') return self.edit(request, title, preview=text.split('\n'), captcha_error=response.error_code) comment = request.form.get("comment", "") author = request.get_author() text = request.form.get("text") try: parent = int(request.form.get("parent")) except (ValueError, TypeError): parent = None self.storage.reopen() self.index.update(self) page = self.get_page(request, title) if text is not None: if title == self.locked_page: for link, label in page.extract_links(text): if title == link: raise error.ForbiddenErr( _(u"This page is locked.")) if u'href="' in comment or u'http:' in comment: raise error.ForbiddenErr() if text.strip() == '': self.storage.delete_page(title, author, comment) url = request.get_url(self.front_page) else: self.storage.save_text(title, text, author, comment, parent) else: text = u'' upload = request.files['data'] f = upload.stream if f is not None and upload.filename is not None: try: self.storage.save_file(title, f.tmpname, author, comment, parent) except AttributeError: self.storage.save_data(title, f.read(), author, comment, parent) else: self.storage.delete_page(title, author, comment) url = request.get_url(self.front_page) self.index.update_page(page, title, text=text) response = werkzeug.routing.redirect(url, code=303) response.set_cookie('author', werkzeug.url_quote(request.get_author()), max_age=604800) return response