Beispiel #1
0
    def get(self, request, project_slug, type_, version_slug):
        """
        Download a specific piece of media.

        Perform an auth check if serving in private mode.

        .. warning:: This is linked directly from the HTML pages.
                     It should only care about the Version permissions,
                     not the actual Project permissions.
        """
        version = get_object_or_404(
            Version.objects.public(user=request.user),
            project__slug=project_slug,
            slug=version_slug,
        )

        # Send media download to analytics - sensitive data is anonymized
        analytics_event.delay(
            event_category='Build Media',
            event_action=f'Download {type_}',
            event_label=str(version),
            ua=request.META.get('HTTP_USER_AGENT'),
            uip=get_client_ip(request),
        )

        storage = get_storage_class(settings.RTD_BUILD_MEDIA_STORAGE)()
        storage_path = version.project.get_storage_path(
            type_=type_,
            version_slug=version_slug,
            version_type=version.type,
        )

        # URL without scheme and domain to perform an NGINX internal redirect
        url = storage.url(storage_path)
        url = urlparse(url)._replace(scheme='', netloc='').geturl()

        return self._serve_docs(
            request,
            final_project=version.project,
            version_slug=version.slug,
            path=url,
            download=True,
        )
Beispiel #2
0
def project_download_media(request, project_slug, type_, version_slug):
    """
    Download a specific piece of media.

    Perform an auth check if serving in private mode.

    .. warning:: This is linked directly from the HTML pages.
                 It should only care about the Version permissions,
                 not the actual Project permissions.
    """
    version = get_object_or_404(
        Version.objects.public(user=request.user),
        project__slug=project_slug,
        slug=version_slug,
    )

    # Send media download to analytics - sensitive data is anonymized
    analytics_event.delay(
        event_category='Build Media',
        event_action=f'Download {type_}',
        event_label=str(version),
        ua=request.META.get('HTTP_USER_AGENT'),
        uip=get_client_ip(request),
    )

    if settings.DEFAULT_PRIVACY_LEVEL == 'public' or settings.DEBUG:

        if settings.RTD_BUILD_MEDIA_STORAGE:
            storage = get_storage_class(settings.RTD_BUILD_MEDIA_STORAGE)()
            storage_path = version.project.get_storage_path(
                type_=type_,
                version_slug=version_slug,
                version_type=version.type,
            )
            if storage.exists(storage_path):
                return HttpResponseRedirect(storage.url(storage_path))

        media_path = os.path.join(
            settings.MEDIA_URL,
            type_,
            project_slug,
            version_slug,
            '%s.%s' % (project_slug, type_.replace('htmlzip', 'zip')),
        )
        return HttpResponseRedirect(media_path)

    # Get relative media path
    path = (version.project.get_production_media_path(
        type_=type_,
        version_slug=version_slug,
    ).replace(settings.PRODUCTION_ROOT, '/prod_artifacts'))
    content_type, encoding = mimetypes.guess_type(path)
    content_type = content_type or 'application/octet-stream'
    response = HttpResponse(content_type=content_type)
    if encoding:
        response['Content-Encoding'] = encoding
    response['X-Accel-Redirect'] = path
    # Include version in filename; this fixes a long-standing bug
    filename = '{}-{}.{}'.format(
        project_slug,
        version_slug,
        path.split('.')[-1],
    )
    response['Content-Disposition'] = 'filename=%s' % filename
    return response
Beispiel #3
0
    def get(
        self,
        request,
        project_slug=None,
        type_=None,
        version_slug=None,
        lang_slug=None,
        subproject_slug=None,
    ):
        """
        Download a specific piece of media.

        Perform an auth check if serving in private mode.

        This view is used to download a file using old-style URLs (download from
        the dashboard) and new-style URLs (download from the same domain as
        docs). Basically, the parameters received by the GET view are different
        (``project_slug`` does not come in the new-style URLs, for example) and
        we need to take it from the request. Once we get the final ``version``
        to be served, everything is the same for both paths.

        .. warning:: This is linked directly from the HTML pages.
                     It should only care about the Version permissions,
                     not the actual Project permissions.
        """
        if self.same_domain_url:
            # It uses the request to get the ``project``. The rest of arguments come
            # from the URL.
            final_project, lang_slug, version_slug, filename = _get_project_data_from_request(  # noqa
                request,
                project_slug=None,
                subproject_slug=subproject_slug,
                lang_slug=lang_slug,
                version_slug=version_slug,
            )

            if not self.allowed_user(request, final_project, version_slug):
                return self.get_unauthed_response(request, final_project)

            # We don't use ``.public`` in this filter because the access
            # permission was already granted by ``.allowed_user``
            version = get_object_or_404(
                final_project.versions,
                slug=version_slug,
            )

        else:
            # All the arguments come from the URL.
            version = get_object_or_404(
                Version.objects.public(user=request.user),
                project__slug=project_slug,
                slug=version_slug,
            )

        # Send media download to analytics - sensitive data is anonymized
        analytics_event.delay(
            event_category='Build Media',
            event_action=f'Download {type_}',
            event_label=str(version),
            ua=request.META.get('HTTP_USER_AGENT'),
            uip=get_client_ip(request),
        )

        storage = get_storage_class(settings.RTD_BUILD_MEDIA_STORAGE)()
        storage_path = version.project.get_storage_path(
            type_=type_,
            version_slug=version_slug,
            version_type=version.type,
        )

        # URL without scheme and domain to perform an NGINX internal redirect
        url = storage.url(storage_path)
        url = urlparse(url)._replace(scheme='', netloc='').geturl()

        return self._serve_docs(
            request,
            final_project=version.project,
            version_slug=version.slug,
            path=url,
            download=True,
        )
Beispiel #4
0
    def get(
        self,
        request,
        project_slug=None,
        type_=None,
        version_slug=None,
        lang_slug=None,
        subproject_slug=None,
    ):
        """
        Download a specific piece of media.

        Perform an auth check if serving in private mode.

        This view is used to download a file using old-style URLs (download from
        the dashboard) and new-style URLs (download from the same domain as
        docs). Basically, the parameters received by the GET view are different
        (``project_slug`` does not come in the new-style URLs, for example) and
        we need to take it from the request. Once we get the final ``version``
        to be served, everything is the same for both paths.

        .. warning:: This is linked directly from the HTML pages.
                     It should only care about the Version permissions,
                     not the actual Project permissions.
        """
        if self.same_domain_url:
            version = self._version_same_domain_url(
                request,
                type_,
                lang_slug,
                version_slug,
                subproject_slug,
            )
        else:
            version = self._version_dashboard_url(
                request,
                project_slug,
                type_,
                version_slug,
            )

        # Send media download to analytics - sensitive data is anonymized
        analytics_event.delay(
            event_category='Build Media',
            event_action=f'Download {type_}',
            event_label=str(version),
            ua=request.META.get('HTTP_USER_AGENT'),
            uip=get_client_ip(request),
        )

        storage = get_storage_class(settings.RTD_BUILD_MEDIA_STORAGE)()
        storage_path = version.project.get_storage_path(
            type_=type_,
            version_slug=version_slug,
            version_type=version.type,
        )

        # URL without scheme and domain to perform an NGINX internal redirect
        url = storage.url(storage_path)
        url = urlparse(url)._replace(scheme='', netloc='').geturl()

        return self._serve_docs(
            request,
            final_project=version.project,
            version_slug=version.slug,
            path=url,
            download=True,
        )