Exemple #1
0
 def content_iter(self, lines):
     last_lines = []
     in_header = False
     in_bug = False
     attributes = {}
     title = None
     for line_no, line in enumerate(lines):
         if last_lines and line.startswith('----'):
             title = ''.join(last_lines)
             last_lines = []
             in_header = True
             attributes = {}
         elif in_header and ':' in line:
             attribute, value = line.split(':', 1)
             attributes[attribute.strip()] = value.strip()
         else:
             if in_header:
                 if in_bug:
                     yield '</div>'
                 #tags = [tag.strip() for tag in
                 #        attributes.get('tags', '').split()
                 #        if tag.strip()]
                 yield '<div id="line_%d">' % (line_no)
                 in_bug = True
                 if title:
                     yield html.h2(html(title))
                 if attributes:
                     yield '<dl>'
                     for attribute, value in attributes.items():
                         yield html.dt(html(attribute))
                         yield html.dd(html(value))
                     yield '</dl>'
                 in_header = False
             if not line.strip():
                 if last_lines:
                     if last_lines[0][0] in ' \t':
                         yield html.pre(html(''.join(last_lines)))
                     else:
                         yield html.p(html(''.join(last_lines)))
                     last_lines = []
             else:
                 last_lines.append(line)
     if last_lines:
         if last_lines[0][0] in ' \t':
             yield html.pre(html(''.join(last_lines)))
         else:
             yield html.p(html(''.join(last_lines)))
     if in_bug:
         yield '</div>'
Exemple #2
0
def diff(request, title, from_rev, to_rev):
    """Show the differences between specified revisions."""

    _ = request.wiki.gettext
    page = hatta.page.get_page(request, title)
    build = request.adapter.build
    from_url = build('revision', {'title': title, 'rev': from_rev})
    to_url = build('revision', {'title': title, 'rev': to_rev})
    a = html.a
    links = {
        'link1': a(str(from_rev)[:8], href=from_url),
        'link2': a(str(to_rev)[:8], href=to_url),
        'link': a(html(title), href=request.get_url(title)),
    }
    message = html(
        _('Differences between revisions %(link1)s and %(link2)s '
          'of page %(link)s.')) % links
    diff_content = getattr(page, 'diff_content', None)
    if diff_content:
        from_text = request.wiki.storage.get_revision(page.title,
                                                      from_rev).text
        to_text = request.wiki.storage.get_revision(page.title, to_rev).text
        content = page.diff_content(from_text, to_text, message)
    else:
        content = [
            html.p(html(_("Diff not available for this kind of pages.")))
        ]
    special_title = _('Diff for "%(title)s"') % {'title': title}
    phtml = page.template('page_special.html',
                          content=content,
                          special_title=special_title)
    resp = WikiResponse(phtml, mimetype='text/html')
    return resp
Exemple #3
0
 def _block_paragraph(self, block):
     parts = []
     first_line = None
     for self.line_no, part in block:
         if first_line is None:
             first_line = self.line_no
         parts.append(part)
     text = "".join(self.parse_line("".join(parts)))
     yield html.p(text, self.pop_to(""), id="line_%d" % first_line)
Exemple #4
0
def authenticate(token_id: str):
    """Finalize the authentication process.  It will be shown on web browser.

    :param token_id: token id created by :func:`create_access_token()`
    :type token_id: :class:`str`
    :status 400: when authentication is failed
    :status 404: when the given ``token_id`` doesn't exist
    :status 403: when the ``token_id`` is already finalized
    :status 200: when authentication is successfully done

    """
    token_store = get_token_store()
    team = get_team()
    token_expire = app.config['TOKEN_EXPIRE']
    if not isinstance(token_expire, datetime.timedelta):
        raise RuntimeError(
            'TOKEN_EXPIRE configuration must be an instance of '
            'datetime.timedelta, not {!r}'.format(token_expire)
        )
    try:
        state = token_store.get(token_id)
        current_app.logger.debug(
            'stored AuthenticationContinuation.state: %r',
            state
        )
    except TypeError:
        raise NotFound()
    if not isinstance(state, tuple) or state[0] != 'auth-state':
        raise Forbidden()
    requested_redirect_url = url_for(
        'authenticate',
        token_id=token_id,
        _external=True
    )
    try:
        identity = team.authenticate(
            state[1],
            requested_redirect_url,
            request.environ
        )
    except AuthenticationError as e:
        current_app.logger.debug(e, exc_info=1)
        raise BadRequest()
    expires_at = datetime.datetime.now(datetime.timezone.utc) + token_expire
    token_store.set(token_id, ('token', Token(identity, expires_at)),
                    timeout=int(token_expire.total_seconds()))
    return '<!DOCTYPE html>\n' + html.html(
        html.head(
            html.meta(charset='utf-8'),
            html.title('Geofront: Authentication success')
        ),
        html.body(
            html.h1(html.dfn('Geofront:'), ' Authentication success'),
            html.p('You may close the browser, and go back to the CLI.')
        )
    )
Exemple #5
0
def oauth2_callback():
    """Finalize the authentication process.  It will be shown on web browser.

    :status 400: when authentication is failed
    :status 404: when the given ``token_id`` doesn't exist
    :status 403: when the ``token_id`` is already finalized
    :status 200: when authentication is successfully done

    """
    token_id = request.args.get('token_id', '')
    token_store = get_token_store()
    team = get_team()
    token_expire = app.config['TOKEN_EXPIRE']
    if not isinstance(token_expire, datetime.timedelta):
        raise RuntimeError('TOKEN_EXPIRE configuration must be an instance of '
                           'datetime.timedelta, not {!r}'.format(token_expire))
    try:
        state = token_store.get(token_id)
        current_app.logger.debug('stored AuthenticationContinuation.state: %r',
                                 state)
    except TypeError:
        raise NotFound()
    if not isinstance(state, tuple) or state[0] != 'auth-state':
        raise Forbidden()

    if getattr(team, 'allow_callback_url_params', True):
        requested_redirect_url = url_for('authenticate',
                                         token_id=token_id,
                                         _external=True)
    else:
        requested_redirect_url = url_for('oauth2_callback',
                                         token_id=token_id,
                                         _external=True)
    try:
        identity = team.authenticate(state[1], requested_redirect_url,
                                     request.environ)
    except AuthenticationError as e:
        current_app.logger.debug(e, exc_info=1)
        raise BadRequest()
    expires_at = datetime.datetime.now(datetime.timezone.utc) + token_expire
    token_store.set(token_id, ('token', Token(identity, expires_at)),
                    timeout=int(token_expire.total_seconds()))
    return '<!DOCTYPE html>\n' + html.html(
        html.head(html.meta(charset='utf-8'),
                  html.title('Geofront: Authentication success')),
        html.body(
            html.h1(html.dfn('Geofront:'), ' Authentication success'),
            html.p('You may close the browser, and go back to the CLI.')))
Exemple #6
0
    def page_search(words, page, request):
        """Display the search results."""

        h = html
        request.wiki.index.update(request.wiki)
        result = sorted(request.wiki.index.find(words), key=lambda x: -x[0])
        yield html.p(h(_('%d page(s) containing all words:') % len(result)))
        yield '<ol id="hatta-search-results">'
        for number, (score, title) in enumerate(result):
            yield h.li(h.b(page.wiki_link(title)),
                       ' ',
                       h.i(str(score)),
                       h.div(search_snippet(title, words),
                             class_="hatta-snippet"),
                       id_="search-%d" % (number + 1))
        yield '</ol>'
Exemple #7
0
def revision(request, title, rev):
    _ = request.wiki.gettext
    text = request.wiki.storage.get_revision(title, rev).text
    link = html.a(html(title), href=request.get_url(title))
    content = [
        html.p(
            html(_('Content of revision %(rev)s of page %(title)s:')) % {
                'rev': rev[:8],
                'title': link
            }),
        html.pre(html(text)),
    ]
    special_title = _('Revision of "%(title)s"') % {'title': title}
    page = hatta.page.get_page(request, title)
    resp = page.template('page_special.html',
                         content=content,
                         special_title=special_title)
    return response(request, title, resp, rev=rev, etag='/old')
Exemple #8
0
def authenticate(token_id: str):
    """Finalize the authentication process.  It will be shown on web browser.

    :param token_id: token id created by :func:`create_access_token()`
    :type token_id: :class:`str`
    :status 400: when authentication is failed
    :status 404: when the given ``token_id`` doesn't exist
    :status 403: when the ``token_id`` is already finalized
    :status 200: when authentication is successfully done

    """
    token_store = get_token_store()
    team = get_team()
    token_expire = app.config['TOKEN_EXPIRE']
    if not isinstance(token_expire, datetime.timedelta):
        raise RuntimeError('TOKEN_EXPIRE configuration must be an instance of '
                           'datetime.timedelta, not {!r}'.format(token_expire))
    try:
        auth_nonce = token_store.get(token_id)
        current_app.logger.debug('stored auth_nonce: %r', auth_nonce)
    except TypeError:
        raise NotFound()
    if not isinstance(auth_nonce, str):
        raise Forbidden()
    requested_redirect_url = url_for('authenticate',
                                     token_id=token_id,
                                     _external=True)
    try:
        identity = team.authenticate(auth_nonce, requested_redirect_url,
                                     request.environ)
    except AuthenticationError:
        raise BadRequest()
    expires_at = datetime.datetime.now(datetime.timezone.utc) + token_expire
    token_store.set(token_id,
                    Token(identity, expires_at),
                    timeout=int(token_expire.total_seconds()))
    return '<!DOCTYPE html>\n' + html.html(
        html.head(html.meta(charset='utf-8'),
                  html.title('Geofront: Authentication success')),
        html.body(
            html.h1(html.dfn('Geofront:'), ' Authentication success'),
            html.p('You may close the browser, and go back to the CLI.')))
Exemple #9
0
def authenticate(token_id: str):
    """Finalize the authentication process.  It will be shown on web browser.

    :param token_id: token id created by :func:`create_access_token()`
    :type token_id: :class:`str`
    :status 400: when authentication is failed
    :status 404: when the given ``token_id`` doesn't exist
    :status 403: when the ``token_id`` is already finalized
    :status 200: when authentication is successfully done

    """
    token_store = get_token_store()
    team = get_team()
    token_expire = app.config["TOKEN_EXPIRE"]
    if not isinstance(token_expire, datetime.timedelta):
        raise RuntimeError(
            "TOKEN_EXPIRE configuration must be an instance of " "datetime.timedelta, not {!r}".format(token_expire)
        )
    try:
        auth_nonce = token_store.get(token_id)
        current_app.logger.debug("stored auth_nonce: %r", auth_nonce)
    except TypeError:
        raise NotFound()
    if not isinstance(auth_nonce, str):
        raise Forbidden()
    requested_redirect_url = url_for("authenticate", token_id=token_id, _external=True)
    try:
        identity = team.authenticate(auth_nonce, requested_redirect_url, request.environ)
    except AuthenticationError:
        raise BadRequest()
    expires_at = datetime.datetime.now(datetime.timezone.utc) + token_expire
    token_store.set(token_id, Token(identity, expires_at), timeout=int(token_expire.total_seconds()))
    return "<!DOCTYPE html>\n" + html.html(
        html.head(html.meta(charset="utf-8"), html.title("Geofront: Authentication success")),
        html.body(
            html.h1(html.dfn("Geofront:"), " Authentication success"),
            html.p("You may close the browser, and go back to the CLI."),
        ),
    )
Exemple #10
0
 def content_iter(self, lines=None):
     import csv
     _ = self.wiki.gettext
     # XXX Add preview support
     reader = csv.reader(csv_file)
     html_title = escape(self.title)
     yield '<table id="%s" class="csvfile">' % html_title
     with self.revision.file as csv_file:
         try:
             for row in reader:
                 yield '<tr>%s</tr>' % (''.join('<td>%s</td>' % cell
                                                for cell in row))
         except csv.Error as e:
             yield '</table>'
             yield html.p(
                 html(
                     _('Error parsing CSV file %{file}s on '
                       'line %{line}d: %{error}s') % {
                           'file': html_title,
                           'line': reader.line_num,
                           'error': e
                       }))
     yield '</table>'
Exemple #11
0
    def render_editor(self, preview=None, captcha_error=None):
        """Generate the HTML for the editor."""

        _ = self.wiki.gettext
        author = self.request.get_author()
        lines = []
        try:
            lines = self.revision.text.splitlines(True)
            rev = self.revision.rev
            old_author = self.revision.author
            old_comment = self.revision.comment
            comment = _('modified')
            if old_author == author:
                comment = old_comment
        except hatta.error.NotFoundErr:
            comment = _('created')
            rev = -1
        except hatta.error.ForbiddenErr as e:
            return html.p(html(str(e)))
        if preview:
            lines = preview
            comment = self.request.form.get('comment', comment)
        if captcha and self.wiki.recaptcha_public_key:
            recaptcha_html = captcha.displayhtml(
                self.wiki.recaptcha_public_key, error=captcha_error)
        else:
            recaptcha_html = None
        context = {
            'comment': comment,
            'preview': preview,
            'recaptcha_html': recaptcha_html,
            'help': self.get_edit_help(),
            'author': author,
            'parent': rev,
            'lines': lines,
        }
        return self.template('edit_text.html', **context)
Exemple #12
0
def save(request, title):
    _ = request.wiki.gettext
    hatta.page.check_lock(request.wiki, title)
    url = request.get_url(title)
    if request.form.get('cancel'):
        if title not in request.wiki.storage:
            url = request.get_url(request.wiki.front_page)
    if request.form.get('preview'):
        text = request.form.get("text")
        if text is not None:
            lines = text.split('\n')
        else:
            lines = [html.p(html(_('No preview for binaries.')))]
        return edit(request, title, preview=lines)
    elif request.form.get('save'):
        if captcha and request.wiki.recaptcha_private_key:
            response = captcha.submit(
                request.form.get('recaptcha_challenge_field', ''),
                request.form.get('recaptcha_response_field', ''),
                request.wiki.recaptcha_private_key, request.remote_addr)
            if not response.is_valid:
                text = request.form.get("text", '')
                return edit(request,
                            title,
                            preview=text.split('\n'),
                            captcha_error=response.error_code)
        comment = request.form.get("comment", "")
        if 'href="' in comment or 'http:' in comment:
            raise hatta.error.ForbiddenErr()
        author = request.get_author()
        text = request.form.get("text")
        try:
            parent = request.form.get("parent")
        except (ValueError, TypeError):
            parent = None
        page = hatta.page.get_page(request, title)
        saved_titles = [title]
        if text is not None:
            if title == request.wiki.locked_page:
                for link, label in page.extract_links(text):
                    if title == link:
                        raise hatta.error.ForbiddenErr(
                            _("This page is locked."))
            if text.strip() == '':
                request.wiki.storage.delete_page(title, author, comment)
                url = request.get_url(request.wiki.front_page)
            else:
                with request.wiki.storage:
                    request.wiki.storage.save_text(title, text, author,
                                                   comment, parent)
        elif page.mime == 'application/hatta+zip' and request.wiki.allow_bulk_uploads:
            # special case for uploading zip file of multiple pages
            upload = request.files.get('data')
            import zipfile, tempfile
            tfname = tempfile.mktemp()
            upload.save(tfname)
            try:
                with open(tfname, 'rb') as tf, zipfile.ZipFile(
                        tf) as zf, request.wiki.storage:
                    for name in zf.namelist():
                        if name[0] in '._/~!+=-#%&':
                            continue
                        elif name not in request.wiki.storage:
                            # can't replace existing pages
                            hatta.page.check_lock(request.wiki, name)
                            with zf.open(name) as f:
                                data = f.read()
                                if data:
                                    request.wiki.storage.save_data(
                                        name, data, author, comment)
                            url = request.get_url(name)
                            saved_titles.append(name)
            finally:
                os.unlink(tfname)
        else:
            text = ''
            upload = request.files.get('data')
            with request.wiki.storage:
                if upload and upload.stream and upload.filename:
                    f = upload.stream
                    request.wiki.storage.save_data(title, f.read(), author,
                                                   comment, parent)
                else:
                    request.wiki.storage.delete_page(title, author, comment)
                    url = request.get_url(request.wiki.front_page)
        request.wiki.index.reindex(request.wiki, saved_titles)
    response = redirect(url, code=303)
    response.set_cookie('author',
                        urls.url_quote(request.get_author()),
                        max_age=604800)
    return response