Ejemplo n.º 1
0
    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"))
Ejemplo n.º 2
0
    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."))
Ejemplo n.º 3
0
    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)
Ejemplo n.º 4
0
 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)
Ejemplo n.º 5
0
    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')
Ejemplo n.º 6
0
    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
Ejemplo n.º 7
0
 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