Exemplo n.º 1
0
    def process_request(self, request):
        # https://bugzil.la/1189222
        # Don't redirect POST $subscribe requests to GET zone url
        if request.method == "POST" and ("$subscribe" in request.path or "$files" in request.path):
            return None

        remaps = DocumentZoneURLRemapsJob().get(request.LANGUAGE_CODE)
        for original_path, new_path in remaps:

            if request.path_info == original_path or request.path_info.startswith(u"".join([original_path, "/"])):
                # Is this a request for the "original" wiki path? Redirect to
                # new URL root, if so.
                new_path = request.path_info.replace(original_path, new_path, 1)
                new_path = "/%s%s" % (request.LANGUAGE_CODE, new_path)

                query = request.GET.copy()
                new_path = urlparams(new_path, query_dict=query)

                return HttpResponseRedirect(new_path)

            elif request.path_info == u"/docs{}".format(new_path):
                # Is this a request for a DocumentZone, but with /docs/ wedged
                # in the url path between the language code and the zone's url_root?
                new_path = u"/{}{}".format(request.LANGUAGE_CODE, new_path)
                query = request.GET.copy()
                new_path = urlparams(new_path, query_dict=query)

                return HttpResponsePermanentRedirect(new_path)

            elif request.path_info.startswith(new_path):
                # Is this a request for the relocated wiki path? If so, rewrite
                # the path as a request for the proper wiki view.
                request.path_info = request.path_info.replace(new_path, original_path, 1)
                break
Exemplo n.º 2
0
    def test_known_authors_filter(self):
        # There are a total of 11 revisions
        url = urlparams(reverse('dashboards.revisions', locale='en-US'),
                        authors=RevisionDashboardForm.ALL_AUTHORS)
        response = self.client.get(url, HTTP_X_REQUESTED_WITH='XMLHttpRequest')
        eq_(response.status_code, 200)

        page = pq(response.content)
        revisions = page.find('.dashboard-row')

        eq_(11, revisions.length)

        # Only testuser01 is in the Known Authors group, and has 2 revisions
        url = urlparams(reverse('dashboards.revisions', locale='en-US'),
                        authors=RevisionDashboardForm.KNOWN_AUTHORS)
        response = self.client.get(url, HTTP_X_REQUESTED_WITH='XMLHttpRequest')
        eq_(response.status_code, 200)

        page = pq(response.content)
        revisions = page.find('.dashboard-row')

        eq_(2, revisions.length)

        # Of the 11 revisions, 9 are by users not in the Known Authors group
        url = urlparams(reverse('dashboards.revisions', locale='en-US'),
                        authors=RevisionDashboardForm.UNKNOWN_AUTHORS)
        response = self.client.get(url, HTTP_X_REQUESTED_WITH='XMLHttpRequest')
        eq_(response.status_code, 200)

        page = pq(response.content)
        revisions = page.find('.dashboard-row')

        eq_(9, revisions.length)
Exemplo n.º 3
0
    def test_compare_revisions_missing_query_param(self):
        """Try to compare two revisions, with a missing query string param."""
        url = reverse('wiki.compare_revisions', args=[self.document.slug])
        query = {'from': self.revision1.id}
        url = urlparams(url, **query)
        response = self.client.get(url)
        eq_(404, response.status_code)

        url = reverse('wiki.compare_revisions', args=[self.document.slug])
        query = {'to': self.revision1.id}
        url = urlparams(url, **query)
        response = self.client.get(url)
        eq_(404, response.status_code)
Exemplo n.º 4
0
    def process_request(self, request):
        # https://bugzil.la/1189222
        # Don't redirect POST $subscribe requests to GET zone url
        if (request.method == 'POST' and
                ('$subscribe' in request.path or '$files' in request.path)):
            return None

        # Skip slugs that don't have locales, and won't be in a zone
        request_slug = request.path_info.lstrip('/')
        if any(request_slug.startswith(slug)
               for slug in settings.LANGUAGE_URL_IGNORED_PATHS):
            return None

        remaps = DocumentZoneURLRemapsJob().get(request.LANGUAGE_CODE)
        for original_path, new_path in remaps:

            if (
                request.path_info == original_path or
                request.path_info.startswith(u''.join([original_path, '/']))
            ):
                # Is this a request for the "original" wiki path? Redirect to
                # new URL root, if so.
                new_path = request.path_info.replace(original_path,
                                                     new_path,
                                                     1)
                new_path = '/%s%s' % (request.LANGUAGE_CODE, new_path)

                query = request.GET.copy()
                new_path = urlparams(new_path, query_dict=query)

                return HttpResponseRedirect(new_path)

            elif request.path_info == u'/docs{}'.format(new_path):
                # Is this a request for a DocumentZone, but with /docs/ wedged
                # in the url path between the language code and the zone's url_root?
                new_path = u'/{}{}'.format(request.LANGUAGE_CODE, new_path)
                query = request.GET.copy()
                new_path = urlparams(new_path, query_dict=query)

                return HttpResponsePermanentRedirect(new_path)

            elif request.path_info.startswith(new_path):
                # Is this a request for the relocated wiki path? If so, rewrite
                # the path as a request for the proper wiki view.
                request.path_info = request.path_info.replace(new_path,
                                                              original_path,
                                                              1)
                break
Exemplo n.º 5
0
 def revisions(self, obj):
     """HTML link to user's revisions with count"""
     link = urlparams(reverse('dashboards.revisions'),
                      user=obj.username)
     count = obj.created_revisions.count()
     return ('<a href="%(link)s"><strong>%(count)s</strong></a>' %
             {'link': link, 'count': count})
Exemplo n.º 6
0
def test_compare_revisions_only_one_param(create_revision, client, param):
    """If a compare query parameter is missing, a 404 is returned."""
    doc = create_revision.document
    url = urlparams(reverse('wiki.compare_revisions', args=[doc.slug]),
                    **{param: create_revision.id})
    response = client.get(url)
    assert response.status_code == 404
Exemplo n.º 7
0
    def test_spam_submission_filled(self):
        admin = User.objects.get(username='******')
        revision = admin.created_revisions.all()[0]
        url = urlparams(
            reverse('admin:wiki_revisionakismetsubmission_add'),
            revision=revision.id,
            type='ham',
        )
        self.client.login(username='******', password='******')
        response = self.client.get(url)
        self.assertEqual(response.status_code, 200)

        page = pq(response.content)
        revision_inputs = page.find('input#id_revision')
        self.assertEqual(len(revision_inputs), 1)
        self.assertEqual(revision_inputs[0].value, str(revision.id))

        type_inputs = page.find('input[name=type]')
        self.assertEqual(len(type_inputs), 2)

        for type_input in type_inputs:
            if type_input.value == 'spam':
                self.assertTrue(not type_input.checked)
            elif type_input.value == 'ham':
                self.assertTrue(type_input.checked)
Exemplo n.º 8
0
def test_revisions_all_params_as_anon_user_is_forbidden(root_doc, client):
    """Anonymous users are forbidden to request all revisions."""
    url = reverse('wiki.document_revisions', args=(root_doc.slug,))
    all_url = urlparams(url, limit='all')
    resp = client.get(all_url)
    assert resp.status_code == 403
    assert_shared_cache_header(resp)
Exemplo n.º 9
0
 def test_bad_parameters(self):
     """Ensure badly-formed revision parameters do not cause errors"""
     url = reverse('wiki.compare_revisions', args=[self.document.slug])
     query = {'from': '1e309', 'to': u'1e309'}
     url = urlparams(url, **query)
     response = self.client.get(url)
     eq_(404, response.status_code)
Exemplo n.º 10
0
 def test_bad_parameters(self):
     """Ensure badly-formed revision parameters do not cause errors"""
     url = reverse("wiki.compare_revisions", args=[self.document.slug])
     query = {"from": "1e309", "to": u"1e309"}
     url = urlparams(url, **query)
     response = self.client.get(url)
     eq_(404, response.status_code)
Exemplo n.º 11
0
def _default_locale_fallback(request, document_slug, document_locale):
    """
    If we're falling back to a Document in the default locale, figure
    out why and whether we can redirect to a translation in the
    requested locale.

    """
    fallback_doc = None
    redirect_url = None
    fallback_reason = None

    try:
        fallback_doc = Document.objects.get(locale=settings.WIKI_DEFAULT_LANGUAGE,
                                            slug=document_slug)

        # If there's a translation to the requested locale, take it:
        translation = fallback_doc.translated_to(document_locale)

        if translation and translation.current_revision:
            url = translation.get_absolute_url()
            redirect_url = urlparams(url, query_dict=request.GET)
        elif translation and fallback_doc.current_revision:
            # Found a translation but its current_revision is None
            # and OK to fall back to parent (parent is approved).
            fallback_reason = 'translation_not_approved'
        elif fallback_doc.current_revision:
            # There is no translation
            # and OK to fall back to parent (parent is approved).
            fallback_reason = 'no_translation'
    except Document.DoesNotExist:
        pass

    return fallback_doc, fallback_reason, redirect_url
Exemplo n.º 12
0
 def test_compare_revisions_invalid_to_int(self):
     """Provide invalid 'to' int for revision ids."""
     url = reverse("wiki.compare_revisions", args=[self.document.slug])
     query = {"from": "", "to": "invalid"}
     url = urlparams(url, **query)
     response = self.client.get(url)
     eq_(404, response.status_code)
Exemplo n.º 13
0
Arquivo: admin.py Projeto: runt18/kuma
 def revisions(self, obj):
     """HTML link to user's revisions with count"""
     link = urlparams(reverse('dashboards.revisions'),
                      user=obj.username)
     count = obj.created_revisions.count()
     return ('<a href="{link!s}"><strong>{count!s}</strong></a>'.format(**
             {'link': link, 'count': count}))
Exemplo n.º 14
0
def test_compare_revisions_invalid_ids(root_doc, client, id1, id2):
    """Comparing badly-formed revision parameters return 404, not error."""
    url = urlparams(reverse('wiki.compare_revisions', args=[root_doc.slug],
                            locale=root_doc.locale),
                    **{'from': id1, 'to': id2})
    response = client.get(url)
    assert response.status_code == 404
Exemplo n.º 15
0
    def test_intermediate(self):
        """
        Test that the intermediate DocumentAttachment gets created
        correctly when adding an Attachment with a document_id.

        """
        doc = document(locale='en', slug='attachment-test-intermediate')
        doc.save()
        rev = revision(document=doc, is_approved=True)
        rev.save()

        file_for_upload = make_test_file(
            content='A file for testing intermediate attachment model.')

        post_data = {
            'title': 'Intermediate test file',
            'description': 'Intermediate test file',
            'comment': 'Initial upload',
            'file': file_for_upload,
        }

        add_url = urlparams(reverse('attachments.new_attachment'),
                            document_id=doc.id)
        resp = self.client.post(add_url, data=post_data)
        eq_(302, resp.status_code)

        eq_(1, doc.files.count())

        intermediates = DocumentAttachment.objects.filter(document__pk=doc.id)
        eq_(1, intermediates.count())

        intermediate = intermediates[0]
        eq_('admin', intermediate.attached_by.username)
        eq_(file_for_upload.name.split('/')[-1], intermediate.name)
Exemplo n.º 16
0
    def process_request(self, request):
        # https://bugzil.la/1189222
        # Don't redirect POST $subscribe requests to GET zone url
        if request.method == 'POST' and '$subscribe' in request.path:
            return None

        remaps = DocumentZoneURLRemapsJob().get(request.LANGUAGE_CODE)
        for original_path, new_path in remaps:

            if (
                request.path_info == original_path or
                request.path_info.startswith(u''.join([original_path, '/']))
            ):
                # Is this a request for the "original" wiki path? Redirect to
                # new URL root, if so.
                new_path = request.path_info.replace(original_path,
                                                     new_path,
                                                     1)
                new_path = '/{0!s}{1!s}'.format(request.LANGUAGE_CODE, new_path)

                query = request.GET.copy()
                if 'lang' in query:
                    query.pop('lang')
                new_path = urlparams(new_path, query_dict=query)

                return HttpResponseRedirect(new_path)

            elif request.path_info.startswith(new_path):
                # Is this a request for the relocated wiki path? If so, rewrite
                # the path as a request for the proper wiki view.
                request.path_info = request.path_info.replace(new_path,
                                                              original_path,
                                                              1)
                break
Exemplo n.º 17
0
    def test_intermediate(self):
        """
        Test that the intermediate DocumentAttachment gets created
        correctly when adding an Attachment with a document_id.

        """
        doc = document(locale="en", slug="attachment-test-intermediate")
        doc.save()
        rev = revision(document=doc, is_approved=True)
        rev.save()

        file_for_upload = make_test_file(content="A file for testing intermediate attachment model.")

        post_data = {
            "title": "Intermediate test file",
            "description": "Intermediate test file",
            "comment": "Initial upload",
            "file": file_for_upload,
        }

        add_url = urlparams(reverse("attachments.new_attachment"), document_id=doc.id)
        resp = self.client.post(add_url, data=post_data)
        eq_(302, resp.status_code)

        eq_(1, doc.files.count())

        intermediates = DocumentAttachment.objects.filter(document__pk=doc.id)
        eq_(1, intermediates.count())

        intermediate = intermediates[0]
        eq_("admin", intermediate.attached_by.username)
        eq_(file_for_upload.name.split("/")[-1], intermediate.name)
Exemplo n.º 18
0
 def test_compare_revisions_invalid_from_int(self):
     """Provide invalid 'from' int for revision ids."""
     url = reverse('wiki.compare_revisions', args=[self.document.slug])
     query = {'from': 'invalid', 'to': ''}
     url = urlparams(url, **query)
     response = self.client.get(url)
     eq_(404, response.status_code)
Exemplo n.º 19
0
def _document_redirect_to_create(document_slug, document_locale, slug_dict):
    """
    When a Document doesn't exist but the user can create it, return
    the creation URL to redirect to.
    """
    url = reverse('wiki.create', locale=document_locale)
    if slug_dict['length'] > 1:
        parent_doc = get_object_or_404(Document,
                                       locale=document_locale,
                                       slug=slug_dict['parent'],
                                       is_template=0)
        url = urlparams(url, parent=parent_doc.id,
                        slug=slug_dict['specific'])
    else:
        # This is a "base level" redirect, i.e. no parent
        url = urlparams(url, slug=document_slug)
    return url
Exemplo n.º 20
0
 def test_compare_unmatched_document_url(self):
     """Comparing two revisions of unlinked document should cause error."""
     unmatched_document = _create_document(title='Invalid document')
     url = reverse('wiki.compare_revisions', args=[unmatched_document.slug])
     query = {'from': self.revision1.id, 'to': self.revision2.id}
     url = urlparams(url, **query)
     response = self.client.get(url)
     eq_(404, response.status_code)
Exemplo n.º 21
0
def test_revisions_request_large_pages(root_doc, client):
    """$history?limit=(more than revisions) works, removes pagination."""
    rev_count = root_doc.revisions.count()
    url = reverse('wiki.document_revisions', args=(root_doc.slug,))
    limit_url = urlparams(url, limit=rev_count + 1)
    resp = client.get(limit_url)
    assert resp.status_code == 200
    page = pq(resp.content)
    assert len(page.find('ol.pagination')) == 0
Exemplo n.º 22
0
 def test_compare_revisions(self):
     """Compare two revisions"""
     url = reverse("wiki.compare_revisions", args=[self.document.slug])
     query = {"from": self.revision1.id, "to": self.revision2.id}
     url = urlparams(url, **query)
     response = self.client.get(url)
     eq_(200, response.status_code)
     doc = pq(response.content)
     eq_("Dolor", doc("span.diff_add").text())
Exemplo n.º 23
0
def test_revisions_all_params_as_user_is_allowed(root_doc, wiki_user, client):
    """Users are allowed to request all revisions."""
    url = reverse('wiki.document_revisions', args=(root_doc.slug,))
    all_url = urlparams(url, limit='all')
    wiki_user.set_password('password')
    wiki_user.save()
    client.login(username=wiki_user.username, password='******')
    resp = client.get(all_url)
    assert resp.status_code == 200
Exemplo n.º 24
0
 def test_create_no_revision(self):
     url = urlparams(
         reverse('admin:wiki_revisionakismetsubmission_add'),
         type='ham',
     )
     self.client.login(username='******', password='******')
     response = self.client.get(url)
     self.assertEqual(response.status_code, 200)
     self.assertIn(SUBMISSION_NOT_AVAILABLE, response.content)
Exemplo n.º 25
0
 def test_compare_revisions(self):
     """Compare two revisions"""
     url = reverse('wiki.compare_revisions', args=[self.document.slug])
     query = {'from': self.revision1.id, 'to': self.revision2.id}
     url = urlparams(url, **query)
     response = self.client.get(url)
     eq_(200, response.status_code)
     doc = pq(response.content)
     eq_('Dolor', doc('span.diff_add').text())
Exemplo n.º 26
0
def test_revisions_request_tiny_pages(edit_revision, client):
    """$history will paginate the revisions."""
    doc = edit_revision.document
    assert doc.revisions.count() > 1
    url = reverse('wiki.document_revisions', args=(doc.slug,))
    limit_url = urlparams(url, limit=1)
    resp = client.get(limit_url)
    assert resp.status_code == 200
    page = pq(resp.content)
    assert len(page.find('ol.pagination')) == 1
Exemplo n.º 27
0
def test_compare_revisions_wrong_document(edit_revision, client):
    """If the revision is for the wrong document, a 404 is returned."""
    doc = edit_revision.document
    first_revision = doc.revisions.first()
    other_doc = Document.objects.create(locale='en-US', slug='Other',
                                        title='Other Document')
    url = urlparams(reverse('wiki.compare_revisions', args=[other_doc.slug]),
                    **{'from': first_revision.id, 'to': edit_revision.id})
    response = client.get(url)
    assert response.status_code == 404
Exemplo n.º 28
0
    def test_topic_filter(self):
        url = urlparams(reverse("dashboards.revisions", locale="en-US"), topic="article-with-revisions")
        response = self.client.get(url, HTTP_X_REQUESTED_WITH="XMLHttpRequest")
        eq_(response.status_code, 200)

        page = pq(response.content)
        revisions = page.find(".dashboard-row")

        eq_(revisions.length, 7)
        for revision in revisions:
            ok_("lorem" not in pq(revision).find(".dashboard-title").html())
Exemplo n.º 29
0
    def test_topic_filter(self):
        url = urlparams(reverse('dashboards.revisions', locale='en-US'),
                        topic='article-with-revisions')
        response = self.client.get(url, HTTP_X_REQUESTED_WITH='XMLHttpRequest')
        eq_(response.status_code, 200)

        page = pq(response.content)
        revisions = page.find('.dashboard-row')

        eq_(revisions.length, 7)
        for revision in revisions:
            ok_('lorem' not in pq(revision).find('.dashboard-title').html())
Exemplo n.º 30
0
def test_compare_revisions(edit_revision, client, raw):
    """Comparing two valid revisions of the same document works."""
    doc = edit_revision.document
    first_revision = doc.revisions.first()
    params = {'from': first_revision.id, 'to': edit_revision.id}
    if raw:
        params['raw'] = '1'
    url = urlparams(reverse('wiki.compare_revisions', args=[doc.slug],
                            locale=doc.locale), **params)

    response = client.get(url)
    assert response.status_code == 200
Exemplo n.º 31
0
def react_document(request, document_slug, document_locale):
    """
    View a wiki document.
    """
    slug_dict = split_slug(document_slug)

    # Is there a document at this slug, in this locale?
    doc, _ = _get_doc_and_fallback_reason(document_locale, document_slug)

    if doc is None:
        # We can throw a 404 immediately if the request type is HEAD.
        # TODO: take a shortcut if the document was found?
        if request.method == 'HEAD':
            raise Http404

        # Check if we should fall back to default locale.
        fallback_doc, _, redirect_url = _default_locale_fallback(
            request, document_slug, document_locale)
        if fallback_doc is not None:
            doc = fallback_doc
            if redirect_url is not None:
                return redirect(redirect_url)
        else:
            raise Http404

    # We found a Document. Now we need to figure out how we're going
    # to display it.

    # If we're a redirect, and redirecting hasn't been disabled, redirect.

    # Obey explicit redirect pages:
    # Don't redirect on redirect=no (like Wikipedia), so we can link from a
    # redirected-to-page back to a "Redirected from..." link, so you can edit
    # the redirect.
    redirect_url = (None if request.GET.get('redirect') == 'no'
                    else doc.get_redirect_url())

    if redirect_url and redirect_url != doc.get_absolute_url():
        url = urlparams(redirect_url, query_dict=request.GET)
        # TODO: Re-enable the link in this message after Django >1.5 upgrade
        # Redirected from <a href="%(url)s?redirect=no">%(url)s</a>
        messages.add_message(
            request, messages.WARNING,
            mark_safe(ugettext(u'Redirected from %(url)s') % {
                "url": request.build_absolute_uri(doc.get_absolute_url())
            }), extra_tags='wiki_redirect')
        return HttpResponsePermanentRedirect(url)

    # Get the SEO summary
    seo_summary = doc.get_summary_text()

    # Get the additional title information, if necessary.
    seo_parent_title = _get_seo_parent_title(doc, slug_dict, document_locale)

    # Get the JSON data for this document
    doc_api_data = document_api_data(doc, ensure_contributors=True)
    document_data = doc_api_data['documentData']

    # Bundle it all up and, finally, return.
    context = {
        'document_data': document_data,

        # TODO: anything we're actually using in the template ought
        # to be bundled up into the json object above instead.
        'seo_summary': seo_summary,
        'seo_parent_title': seo_parent_title,
    }
    response = render(request, 'wiki/react_document.html', context)

    return _add_kuma_revision_header(doc, response)
Exemplo n.º 32
0
def test_revisions_request_invalid_pages(root_doc, client):
    """$history?limit=nonsense uses the default pagination."""
    url = reverse('wiki.document_revisions', args=(root_doc.slug, ))
    limit_url = urlparams(url, limit='nonsense')
    resp = client.get(limit_url)
    assert resp.status_code == 200
Exemplo n.º 33
0
def test_compare_revisions_invalid_ids(root_doc, client, id1, id2):
    """Comparing badly-formed revision parameters return 404, not error."""
    url = urlparams(reverse('wiki.compare_revisions', args=[root_doc.slug]),
                    **{'from': id1, 'to': id2})
    response = client.get(url, HTTP_HOST=settings.WIKI_HOST)
    assert response.status_code == 404
Exemplo n.º 34
0
def edit(request, document_slug, document_locale):
    """
    Create a new revision of a wiki document, or edit document metadata.
    """
    doc = get_object_or_404(Document, locale=document_locale, slug=document_slug)

    # If this document has a parent, then the edit is handled by the
    # translate view. Pass it on.
    if doc.parent and doc.parent.id != doc.id:
        return translate(
            request, doc.parent.slug, doc.locale, bypass_process_document_path=True
        )

    rev = doc.current_revision or doc.revisions.order_by("-created", "-id")[0]

    # Keep hold of the full post slug
    slug_dict = split_slug(document_slug)
    # Update the slug, removing the parent path, and
    # *only* using the last piece.
    # This is only for the edit form.
    rev.slug = slug_dict["specific"]

    section_id = request.GET.get("section", None)
    if section_id and not request.is_ajax():
        return HttpResponse(ugettext("Sections may only be edited inline."))
    disclose_description = bool(request.GET.get("opendescription"))

    doc_form = rev_form = None
    rev_form = RevisionForm(
        request=request,
        instance=rev,
        initial={"based_on": rev.id, "current_rev": rev.id, "comment": ""},
        section_id=section_id,
    )
    if doc.allows_editing_by(request.user):
        doc_form = DocumentForm(initial=document_form_initial(doc))

    # Need to make check *here* to see if this could have a translation parent
    show_translation_parent_block = (
        document_locale != settings.WIKI_DEFAULT_LANGUAGE
    ) and (not doc.parent_id)

    if request.method == "GET":
        if not (rev_form or doc_form):
            # You can't do anything on this page, so get lost.
            raise PermissionDenied

    else:  # POST
        is_async_submit = request.is_ajax()
        is_raw = request.GET.get("raw", False)
        need_edit_links = request.GET.get("edit_links", False)
        parent_id = request.POST.get("parent_id", "")

        # Attempt to set a parent
        if show_translation_parent_block and parent_id:
            try:
                parent_doc = get_object_or_404(Document, id=parent_id)
                doc.parent = parent_doc
            except Document.DoesNotExist:
                pass

        # Comparing against localized names for the Save button bothers me, so
        # I embedded a hidden input:
        which_form = request.POST.get("form-type")

        if which_form == "doc":
            if doc.allows_editing_by(request.user):
                post_data = request.POST.copy()

                post_data.update({"locale": document_locale})
                doc_form = DocumentForm(post_data, instance=doc)
                if doc_form.is_valid():
                    # if must be here for section edits
                    if "slug" in post_data:
                        post_data["slug"] = "/".join(
                            [slug_dict["parent"], post_data["slug"]]
                        )

                    # Get the possibly new slug for the imminent redirection:
                    doc = doc_form.save(parent=None)

                    return redirect(urlparams(doc.get_edit_url(), opendescription=1))
                disclose_description = True
            else:
                raise PermissionDenied

        elif which_form == "rev":
            post_data = request.POST.copy()

            rev_form = RevisionForm(
                request=request,
                data=post_data,
                is_async_submit=is_async_submit,
                section_id=section_id,
            )
            rev_form.instance.document = doc  # for rev_form.clean()

            # Come up with the original revision to which these changes
            # would be applied.
            orig_rev_id = request.POST.get("current_rev", False)
            if orig_rev_id is False:
                orig_rev = None
            else:
                orig_rev = Revision.objects.get(pk=orig_rev_id)
            # Get the document's actual current revision.
            curr_rev = doc.current_revision

            if not rev_form.is_valid():
                # If this was an Ajax POST, then return a JsonResponse
                if is_async_submit:
                    # Was there a mid-air collision?
                    if "current_rev" in rev_form._errors:
                        # Make the error message safe so the '<' and '>' don't
                        # get turned into '&lt;' and '&gt;', respectively
                        rev_form.errors["current_rev"][0] = mark_safe(
                            rev_form.errors["current_rev"][0]
                        )
                    errors = [rev_form.errors[key][0] for key in rev_form.errors.keys()]

                    data = {
                        "error": True,
                        "error_message": errors,
                        "new_revision_id": curr_rev.id,
                    }
                    return JsonResponse(data=data)
                    # Jump out to a function to escape indentation hell
                    return _edit_document_collision(
                        request,
                        orig_rev,
                        curr_rev,
                        is_async_submit,
                        is_raw,
                        rev_form,
                        doc_form,
                        section_id,
                        rev,
                        doc,
                    )
                # Was this an Ajax submission that was marked as spam?
                if is_async_submit and "__all__" in rev_form._errors:
                    # Return a JsonResponse
                    data = {
                        "error": True,
                        "error_message": mark_safe(rev_form.errors["__all__"][0]),
                        "new_revision_id": curr_rev.id,
                    }
                    return JsonResponse(data=data)
            if rev_form.is_valid():
                rev_form.save(doc)
                if is_raw and orig_rev is not None and curr_rev.id != orig_rev.id:
                    # If this is the raw view, and there was an original
                    # revision, but the original revision differed from the
                    # current revision at start of editing, we should tell
                    # the client to refresh the page.
                    response = HttpResponse("RESET")
                    response["X-Frame-Options"] = "SAMEORIGIN"
                    response.status_code = 205
                    return response
                # Is this an Ajax POST?
                if is_async_submit:
                    # This is the most recent revision id
                    new_rev_id = rev.document.revisions.order_by("-id").first().id
                    data = {"error": False, "new_revision_id": new_rev_id}
                    return JsonResponse(data)

                if rev_form.instance.is_approved:
                    view = "wiki.document"
                else:
                    view = "wiki.document_revisions"

                # Construct the redirect URL, adding any needed parameters
                url = reverse(view, args=[doc.slug], locale=doc.locale)
                params = {}
                if is_raw:
                    params["raw"] = "true"
                    if need_edit_links:
                        # Only need to carry over ?edit_links with ?raw,
                        # because they're on by default in the normal UI
                        params["edit_links"] = "true"
                    if section_id:
                        # If a section was edited, and we're using the raw
                        # content API, constrain to that section.
                        params["section"] = section_id
                # Parameter for the document saved, so that we can delete the cached draft on load
                params["rev_saved"] = curr_rev.id if curr_rev else ""
                url = "%s?%s" % (url, urlencode(params))
                if not is_raw and section_id:
                    # If a section was edited, jump to the section anchor
                    # if we're not getting raw content.
                    url = "%s#%s" % (url, section_id)
                return redirect(url)

    parent_path = parent_slug = ""
    if slug_dict["parent"]:
        parent_slug = slug_dict["parent"]

    if doc.parent_topic_id:
        parent_doc = Document.objects.get(pk=doc.parent_topic_id)
        parent_path = parent_doc.get_absolute_url()
        parent_slug = parent_doc.slug

    context = {
        "revision_form": rev_form,
        "document_form": doc_form,
        "section_id": section_id,
        "disclose_description": disclose_description,
        "parent_slug": parent_slug,
        "parent_path": parent_path,
        "revision": rev,
        "document": doc,
        "attachment_form": AttachmentRevisionForm(),
    }
    return render(request, "wiki/edit.html", context)
Exemplo n.º 35
0
 def revisions(self, obj):
     """HTML link to user's revisions with count"""
     link = urlparams(reverse("dashboards.revisions"), user=obj.username)
     count = obj.created_revisions.count()
     return format_html('<a href="{}"><strong>{}</strong></a>', link, count)
Exemplo n.º 36
0
def react_document(request, document_slug, document_locale):
    """
    View a wiki document.
    """
    fallback_reason = None
    slug_dict = split_slug(document_slug)

    # Is there a document at this slug, in this locale?
    doc, fallback_reason = _get_doc_and_fallback_reason(
        document_locale, document_slug)

    if doc is None:
        # We can throw a 404 immediately if the request type is HEAD.
        # TODO: take a shortcut if the document was found?
        if request.method == 'HEAD':
            raise Http404

        # Check if we should fall back to default locale.
        fallback_doc, fallback_reason, redirect_url = _default_locale_fallback(
            request, document_slug, document_locale)
        if fallback_doc is not None:
            doc = fallback_doc
            if redirect_url is not None:
                return redirect(redirect_url)
        else:
            raise Http404

    # We found a Document. Now we need to figure out how we're going
    # to display it.

    # If we're a redirect, and redirecting hasn't been disabled, redirect.

    # Obey explicit redirect pages:
    # Don't redirect on redirect=no (like Wikipedia), so we can link from a
    # redirected-to-page back to a "Redirected from..." link, so you can edit
    # the redirect.
    redirect_url = (None if request.GET.get('redirect') == 'no' else
                    doc.get_redirect_url())

    if redirect_url and redirect_url != doc.get_absolute_url():
        url = urlparams(redirect_url, query_dict=request.GET)
        # TODO: Re-enable the link in this message after Django >1.5 upgrade
        # Redirected from <a href="%(url)s?redirect=no">%(url)s</a>
        messages.add_message(
            request,
            messages.WARNING,
            mark_safe(
                ugettext(u'Redirected from %(url)s') %
                {"url": request.build_absolute_uri(doc.get_absolute_url())}),
            extra_tags='wiki_redirect')
        return HttpResponsePermanentRedirect(url)

    # Get the SEO summary
    seo_summary = doc.get_summary_text()

    # Get the additional title information, if necessary.
    seo_parent_title = _get_seo_parent_title(doc, slug_dict, document_locale)

    # Record the English slug in Google Analytics,
    # to associate translations
    if doc.locale == 'en-US':
        en_slug = doc.slug
    elif doc.parent_id and doc.parent.locale == 'en-US':
        en_slug = doc.parent.slug
    else:
        en_slug = ''

    share_text = ugettext('I learned about %(title)s on MDN.') % {
        "title": doc.title
    }

    contributors = doc.contributors
    contributors_count = len(contributors)
    has_contributors = contributors_count > 0
    other_translations = doc.get_other_translations(
        fields=['title', 'locale', 'slug', 'parent'])
    all_locales = (set([doc.locale]) | set(trans.locale
                                           for trans in other_translations))

    # Bundle it all up and, finally, return.
    context = {
        'document_api_data':
        base64.b64encode(json.dumps(document_api_data(doc))),
        # TODO: anything we're actually using in the template ought
        # to be bundled up into the json object above instead.
        'document': doc,
        'contributors': contributors,
        'contributors_count': contributors_count,
        'contributors_limit': 6,
        'has_contributors': has_contributors,
        'fallback_reason': fallback_reason,
        'seo_summary': seo_summary,
        'seo_parent_title': seo_parent_title,
        'share_text': share_text,
        'search_url': get_search_url_from_referer(request) or '',
        'analytics_page_revision': doc.current_revision_id,
        'analytics_en_slug': en_slug,
        'other_translations': other_translations,
        'all_locales': all_locales,
    }
    response = render(request, 'wiki/react_document.html', context)

    return _add_kuma_revision_header(doc, response)
Exemplo n.º 37
0
def test_revisions_request_invalid_pages(root_doc, client):
    """$history?limit=nonsense uses the default pagination."""
    url = reverse("wiki.document_revisions", args=(root_doc.slug, ))
    limit_url = urlparams(url, limit="nonsense")
    resp = client.get(limit_url, HTTP_HOST=settings.WIKI_HOST)
    assert resp.status_code == 200