Repository: readthedocs/readthedocs.org
Issue: csrf required for triggering build via http auth authenticated webhook

## Details

Hi,

In OpenStack, we've been using authentication with the webhook endpoints to trigger builds.

The way this has been working is that projects add a common ``openstackci`` user as an admin, and then in their project configuration inside our platform they add their webhook URL.

When new releases are made, our CI system uses the ``openstackci`` account (with the password only known to it) to authenticate and trigger RTD builds for the releasing project with a POST.  The exact code that does this is https://git.openstack.org/cgit/openstack-infra/zuul-jobs/tree/roles/trigger-readthedocs/tasks/main.yaml#n11

But in essence that boils down to (for, say jenkins-job-builder project)

```
curl --request POST -u openstackci:OURPASSWORD https://readthedocs.org/api/v2/webhook/jenkins-job-builder/47271/
```

Our jobs starting failing around 2018-12-05 (http://zuul.openstack.org/builds?job_name=trigger-readthedocs-webhook).  The jobs don't log the output of this POST so we don't leak the password into logs.

However, testing manually, the responses indicate a content-length is now required, and a referer, which ends up with

```
$ curl --request POST -H "Content-Length:0" -u openstackci:PASSWORD -e https://readthedocs.org/api/v2/webhook/jenkins-jo2/webhook/jenkins-job-builder/47271/ https://readthedocs.org/api/v2/webhook/jenkins-jo2/webhook/jenkins-job-builder/47271/
{"detail":"CSRF Failed: CSRF cookie not set."}
```

So I'm guessing all this points to CSRF has been somehow enabled for webhook endpoints when using HTTP basic-auth?  Is this possibly a new configuration?

We don't use the token-based webhook method because this system means we only have one common secret to keep -- the openstackci user password -- and everything else is self-service for projects who simply add the common user as an admin and include in their configuration their endpoint URL.

Any help with this will be greatly appreciated, thanks

Changed files:
readthedocs/restapi/views/integrations.py

diff --git a/readthedocs/restapi/views/integrations.py b/readthedocs/restapi/views/integrations.py
index 7f44fb4f1..5ea947e85 100644
--- a/readthedocs/restapi/views/integrations.py
+++ b/readthedocs/restapi/views/integrations.py
@@ -349,7 +349,7 @@ class IsAuthenticatedOrHasToken(permissions.IsAuthenticated):
     """
 
     def has_permission(self, request, view):
-        has_perm = (super().has_permission(request, view))
+        has_perm = super().has_permission(request, view)
         return has_perm or 'token' in request.data
 
 
@@ -420,8 +420,18 @@ class WebhookView(APIView):
     ever get webhook requests for established webhooks on our side. The other
     views can receive webhooks for unknown webhooks, as all legacy webhooks will
     be.
+
+    .. warning::
+        We're turning off Authenication for this view.
+        This fixes a bug where we were double-authenticating these views,
+        because of the way we're passing the request along to the subviews.
+
+        If at any time we add real logic to this view,
+        it will be completely unauthenticated.
     """
 
+    authentication_classes = []
+
     VIEW_MAP = {
         Integration.GITHUB_WEBHOOK: GitHubWebhookView,
         Integration.GITLAB_WEBHOOK: GitLabWebhookView,