Skip to content

Commit

Permalink
Use CSRF token on forms to trigger a new builds (#3260)
Browse files Browse the repository at this point in the history
* Use CSRF token on forms to trigger a new builds

Avoid "This endpoint is deprecated" raised when hitting and old
endpoint with security issues.

Now, each view that shows a form with the "Build" button uses the
BuildTriggerMixin to handle the POST request and trigger the new build.

Closes #3253

* Filter project by `for_admin_user`

* Use login_required as method_decorator for BuildTriggerMixin

The user must be logged in to trigger a build.
  • Loading branch information
humitos authored and agjohnson committed Nov 15, 2017
1 parent 1e55dff commit 4de678e
Show file tree
Hide file tree
Showing 5 changed files with 32 additions and 6 deletions.
26 changes: 24 additions & 2 deletions readthedocs/builds/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,14 @@

from django.shortcuts import get_object_or_404
from django.views.generic import ListView, DetailView
from django.http import HttpResponsePermanentRedirect
from django.http import HttpResponsePermanentRedirect, HttpResponseRedirect
from django.conf import settings
from django.contrib.auth.decorators import login_required
from django.core.urlresolvers import reverse
from django.utils.decorators import method_decorator

from readthedocs.builds.models import Build, Version
from readthedocs.core.utils import trigger_build
from readthedocs.projects.models import Project

from redis import Redis, ConnectionError
Expand All @@ -33,7 +36,26 @@ def get_queryset(self):
return queryset


class BuildList(BuildBase, ListView):
class BuildTriggerMixin(object):

@method_decorator(login_required)
def post(self, request, project_slug):
project = get_object_or_404(
Project.objects.for_admin_user(self.request.user),
slug=project_slug
)
version_slug = request.POST.get('version_slug')
version = get_object_or_404(
Version,
project=project,
slug=version_slug,
)

trigger_build(project=project, version=version)
return HttpResponseRedirect(reverse('builds_project_list', args=[project.slug]))


class BuildList(BuildBase, BuildTriggerMixin, ListView):

def get_context_data(self, **kwargs):
context = super(BuildList, self).get_context_data(**kwargs)
Expand Down
3 changes: 2 additions & 1 deletion readthedocs/projects/views/public.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
from .base import ProjectOnboardMixin
from readthedocs.builds.constants import LATEST
from readthedocs.builds.models import Version
from readthedocs.builds.views import BuildTriggerMixin
from readthedocs.projects.models import Project, ImportedFile
from readthedocs.search.indexes import PageIndex
from readthedocs.search.views import LOG_TEMPLATE
Expand Down Expand Up @@ -67,7 +68,7 @@ def get_context_data(self, **kwargs):
project_index = ProjectIndex.as_view()


class ProjectDetailView(ProjectOnboardMixin, DetailView):
class ProjectDetailView(BuildTriggerMixin, ProjectOnboardMixin, DetailView):

"""Display project onboard steps"""

Expand Down
3 changes: 2 additions & 1 deletion readthedocs/templates/builds/build_list.html
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@
{% if versions %}
<div class="module-header">
<div style="float:right;">
<form method="post" action="{% url "generic_build" project.pk %}">
<form method="post" action="{% url "builds_project_list" project.slug %}">
{% csrf_token %}
<ul class="build_a_version">
<li style="display: inline-block">
<input style="display: inline-block" type="submit" value="{% trans "Build Version:" %}">
Expand Down
3 changes: 2 additions & 1 deletion readthedocs/templates/core/project_details.html
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,8 @@ <h3>{% trans "Versions" %}</h3>
<div class="build_a_version">
<h3>{% trans "Build a version" %}</h3>
<div class="version_right">
<form method="post" action="{% url "generic_build" project.pk %}">
<form method="post" action="{% url "projects_detail" project.slug %}">
{% csrf_token %}
<select id="id_version" name="version_slug">
{% for version in versions|sort_version_aware %}
<option value="{{ version.slug }}">{{ version.slug }}</option>
Expand Down
3 changes: 2 additions & 1 deletion readthedocs/templates/projects/onboard_detail.html
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ <h2>{% trans "Start building your documentation" %}</h2>
{% endblocktrans %}
</p>

<form method="post" action="{% url "generic_build" project.pk %}">
<form method="post" action="{% url "projects_detail" project.slug %}">
{% csrf_token %}
<input type="hidden" name="version_slug" value="latest" />
<input type="submit" value="{% trans "Build latest version" %}" />
</form>
Expand Down

0 comments on commit 4de678e

Please sign in to comment.