Ejemplo n.º 1
0
 def process_view(self, request, view_func, view_args, view_kwargs):
     login_type = request.POST.get("mezzanine_login_interface")
     if login_type and not is_authenticated(request.user):
         response = view_func(request, *view_args, **view_kwargs)
         if is_authenticated(request.user):
             if login_type == "admin":
                 next = next_url(request) or request.get_full_path()
                 username = request.user.get_username()
                 if username == DEFAULT_USERNAME and request.user.check_password(
                     DEFAULT_PASSWORD
                 ):
                     error(
                         request,
                         mark_safe(
                             _(
                                 "Your account is using the default password, "
                                 "please <a href='%s'>change it</a> immediately."
                             )
                             % reverse(
                                 "user_change_password", args=(request.user.id,)
                             )
                         ),
                     )
             else:
                 next = "/"
             return HttpResponseRedirect(next)
         else:
             return response
     return None
Ejemplo n.º 2
0
 def __init__(self, request, *args, **kwargs):
     self.request = request
     super(RatingForm, self).__init__(*args, **kwargs)
     if request and is_authenticated(request.user):
         current = self.rating_manager.filter(user=request.user).first()
         if current:
             self.initial["value"] = current.value
Ejemplo n.º 3
0
 def __init__(self, request, *args, **kwargs):
     self.request = request
     super(RatingForm, self).__init__(*args, **kwargs)
     if request and is_authenticated(request.user):
         current = self.rating_manager.filter(user=request.user).first()
         if current:
             self.initial['value'] = current.value
Ejemplo n.º 4
0
    def process_view(self, request, view_func, view_args, view_kwargs, **foo):
        """
        Per-request mechanics for the current page object.
        """

        # Load the closest matching page by slug, and assign it to the
        # request object. If none found, skip all further processing.
        slug = path_to_slug(request.path_info)
        pages = Page.objects.with_ascendants_for_slug(slug,
                        for_user=request.user, include_login_required=True)
        if pages:
            page = pages[0]
            setattr(request, "page", page)
            context_processors.page(request)
        else:
            return

        # Handle ``page.login_required``.
        if page.login_required and not is_authenticated(request.user):
            return redirect_to_login(request.get_full_path())

        # If the view isn't Mezzanine's page view, try to return the result
        # immediately. In the case of a 404 with an URL slug that matches a
        # page exactly, swallow the exception and try Mezzanine's page view.
        #
        # This allows us to set up pages with URLs that also match non-page
        # urlpatterns. For example, a page could be created with the URL
        # /blog/about/, which would match the blog urlpattern, and assuming
        # there wasn't a blog post with the slug "about", would raise a 404
        # and subsequently be rendered by Mezzanine's page view.
        if view_func != page_view:
            try:
                return view_func(request, *view_args, **view_kwargs)
            except Http404:
                if page.slug != slug:
                    raise

        # Run page processors.
        extra_context = request.resolver_match.kwargs.get("extra_context", {})
        model_processors = page_processors.processors[page.content_model]
        slug_processors = page_processors.processors["slug:%s" % page.slug]
        for (processor, exact_page) in slug_processors + model_processors:
            if exact_page and not page.is_current:
                continue
            processor_response = processor(request, page)
            if isinstance(processor_response, HttpResponse):
                return processor_response
            elif processor_response:
                try:
                    for k, v in processor_response.items():
                        if k not in extra_context:
                            extra_context[k] = v
                except (TypeError, ValueError):
                    name = "%s.%s" % (processor.__module__, processor.__name__)
                    error = ("The page processor %s returned %s but must "
                             "return HttpResponse or dict." %
                             (name, type(processor_response)))
                    raise ValueError(error)

        return page_view(request, slug, extra_context=extra_context)
Ejemplo n.º 5
0
    def process_view(self, request, view_func, view_args, view_kwargs):
        """
        Per-request mechanics for the current page object.
        """

        # Load the closest matching page by slug, and assign it to the
        # request object. If none found, skip all further processing.
        slug = path_to_slug(request.path_info)
        pages = Page.objects.with_ascendants_for_slug(slug,
                        for_user=request.user, include_login_required=True)
        if pages:
            page = pages[0]
            setattr(request, "page", page)
            context_processors.page(request)
        else:
            return

        # Handle ``page.login_required``.
        if page.login_required and not is_authenticated(request.user):
            return redirect_to_login(request.get_full_path())

        # If the view isn't Mezzanine's page view, try to return the result
        # immediately. In the case of a 404 with an URL slug that matches a
        # page exactly, swallow the exception and try Mezzanine's page view.
        #
        # This allows us to set up pages with URLs that also match non-page
        # urlpatterns. For example, a page could be created with the URL
        # /blog/about/, which would match the blog urlpattern, and assuming
        # there wasn't a blog post with the slug "about", would raise a 404
        # and subsequently be rendered by Mezzanine's page view.
        if view_func != page_view:
            try:
                return view_func(request, *view_args, **view_kwargs)
            except Http404:
                if page.slug != slug:
                    raise

        # Run page processors.
        extra_context = {}
        model_processors = page_processors.processors[page.content_model]
        slug_processors = page_processors.processors["slug:%s" % page.slug]
        for (processor, exact_page) in slug_processors + model_processors:
            if exact_page and not page.is_current:
                continue
            processor_response = processor(request, page)
            if isinstance(processor_response, HttpResponse):
                return processor_response
            elif processor_response:
                try:
                    for k, v in processor_response.items():
                        if k not in extra_context:
                            extra_context[k] = v
                except (TypeError, ValueError):
                    name = "%s.%s" % (processor.__module__, processor.__name__)
                    error = ("The page processor %s returned %s but must "
                             "return HttpResponse or dict." %
                             (name, type(processor_response)))
                    raise ValueError(error)

        return page_view(request, slug, extra_context=extra_context)
Ejemplo n.º 6
0
    def save(self):
        """
        Saves a new rating - authenticated users can update the
        value if they've previously rated.
        """
        user = self.request.user
        self.undoing = False
        rating_value = self.cleaned_data["value"]
        manager = self.rating_manager

        if is_authenticated(user):
            rating_instance, created = manager.get_or_create(user=user,
                defaults={'value': rating_value})
            if not created:
                if rating_instance.value == int(rating_value):
                    # User submitted the same rating as previously,
                    # which we treat as undoing the rating (like a toggle).
                    rating_instance.delete()
                    self.undoing = True
                else:
                    rating_instance.value = rating_value
                    rating_instance.save()
        else:
            rating_instance = manager.create(value=rating_value)
        return rating_instance
Ejemplo n.º 7
0
    def save(self):
        """
        Saves a new rating - authenticated users can update the
        value if they've previously rated.
        """
        user = self.request.user
        self.undoing = False
        rating_value = self.cleaned_data["value"]
        manager = self.rating_manager

        if is_authenticated(user):
            rating_instance, created = manager.get_or_create(
                user=user, defaults={"value": rating_value})
            if not created:
                if rating_instance.value == int(rating_value):
                    # User submitted the same rating as previously,
                    # which we treat as undoing the rating (like a toggle).
                    rating_instance.delete()
                    self.undoing = True
                else:
                    rating_instance.value = rating_value
                    rating_instance.save()
        else:
            rating_instance = manager.create(value=rating_value)
        return rating_instance
Ejemplo n.º 8
0
 def process_view(self, request, view_func, view_args, view_kwargs):
     login_type = request.POST.get("mezzanine_login_interface")
     if login_type and not is_authenticated(request.user):
         response = view_func(request, *view_args, **view_kwargs)
         if is_authenticated(request.user):
             if login_type == "admin":
                 next = next_url(request) or request.get_full_path()
                 username = request.user.get_username()
                 if (username == DEFAULT_USERNAME and
                         request.user.check_password(DEFAULT_PASSWORD)):
                     error(request, mark_safe(_(
                           "Your account is using the default password, "
                           "please <a href='%s'>change it</a> immediately.")
                           % reverse("user_change_password",
                                     args=(request.user.id,))))
             else:
                 next = "/"
             return HttpResponseRedirect(next)
         else:
             return response
     return None
Ejemplo n.º 9
0
 def clean(self):
     """
     Check unauthenticated user's cookie as a light check to
     prevent duplicate votes.
     """
     bits = (self.data["content_type"], self.data["object_pk"])
     request = self.request
     self.current = "%s.%s" % bits
     self.previous = request.COOKIES.get("mezzanine-rating", "").split(",")
     already_rated = self.current in self.previous
     if already_rated and not is_authenticated(self.request.user):
         raise forms.ValidationError(ugettext("Already rated."))
     return self.cleaned_data
Ejemplo n.º 10
0
 def clean(self):
     """
     Check unauthenticated user's cookie as a light check to
     prevent duplicate votes.
     """
     bits = (self.data["content_type"], self.data["object_pk"])
     request = self.request
     self.current = "%s.%s" % bits
     self.previous = request.COOKIES.get("mezzanine-rating", "").split(",")
     already_rated = self.current in self.previous
     if already_rated and not is_authenticated(self.request.user):
         raise forms.ValidationError(ugettext("Already rated."))
     return self.cleaned_data
Ejemplo n.º 11
0
def disqus_sso_script(context):
    """
    Provides a generic context variable which adds single-sign-on
    support to DISQUS if ``COMMENTS_DISQUS_API_PUBLIC_KEY`` and
    ``COMMENTS_DISQUS_API_SECRET_KEY`` are specified.
    """
    settings = context["settings"]
    public_key = getattr(settings, "COMMENTS_DISQUS_API_PUBLIC_KEY", "")
    secret_key = getattr(settings, "COMMENTS_DISQUS_API_SECRET_KEY", "")
    user = context["request"].user
    if public_key and secret_key and is_authenticated(user):
        context["public_key"] = public_key
        context["sso_data"] = _get_disqus_sso(user, public_key, secret_key)
    return context
Ejemplo n.º 12
0
def disqus_sso_script(context):
    """
    Provides a generic context variable which adds single-sign-on
    support to DISQUS if ``COMMENTS_DISQUS_API_PUBLIC_KEY`` and
    ``COMMENTS_DISQUS_API_SECRET_KEY`` are specified.
    """
    settings = context["settings"]
    public_key = getattr(settings, "COMMENTS_DISQUS_API_PUBLIC_KEY", "")
    secret_key = getattr(settings, "COMMENTS_DISQUS_API_SECRET_KEY", "")
    user = context["request"].user
    if public_key and secret_key and is_authenticated(user):
        context["public_key"] = public_key
        context["sso_data"] = _get_disqus_sso(user, public_key, secret_key)
    return context
Ejemplo n.º 13
0
def initial_validation(request, prefix):
    """
    Returns the related model instance and post data to use in the
    comment/rating views below.

    Both comments and ratings have a ``prefix_ACCOUNT_REQUIRED``
    setting. If this is ``True`` and the user is unauthenticated, we
    store their post data in their session, and redirect to login with
    the view's url (also defined by the prefix arg) as the ``next``
    param. We can then check the session data once they log in,
    and complete the action authenticated.

    On successful post, we pass the related object and post data back,
    which may have come from the session, for each of the comments and
    ratings view functions to deal with as needed.
    """
    post_data = request.POST
    login_required_setting_name = prefix.upper() + "S_ACCOUNT_REQUIRED"
    posted_session_key = "unauthenticated_" + prefix
    redirect_url = ""
    if getattr(settings, login_required_setting_name, False):
        if not is_authenticated(request.user):
            if request.method == "POST":
                request.session[posted_session_key] = request.POST
                error(
                    request,
                    _(
                        "You must be logged in. Please log in or "
                        "sign up to complete this action."
                    ),
                )
            redirect_url = f"{settings.LOGIN_URL}?next={reverse(prefix)}"
        elif posted_session_key in request.session:
            post_data = request.session.pop(posted_session_key)
    if not redirect_url:
        model_data = post_data.get("content_type", "").split(".", 1)
        if len(model_data) != 2:
            return HttpResponseBadRequest()
        try:
            model = apps.get_model(*model_data)
            obj = model.objects.get(id=post_data.get("object_pk", None))
        except (TypeError, ObjectDoesNotExist, LookupError, ValueError):
            redirect_url = "/"
    if redirect_url:
        if request_is_ajax(request):
            return HttpResponse(dumps({"location": redirect_url}))
        else:
            return redirect(redirect_url)
    return obj, post_data
Ejemplo n.º 14
0
def is_editable(obj, request):
    """
    Returns ``True`` if the object is editable for the request. First
    check for a custom ``editable`` handler on the object, otherwise
    use the logged in user and check change permissions for the
    object's model.
    """
    if hasattr(obj, "is_editable"):
        return obj.is_editable(request)
    else:
        codename = get_permission_codename("change", obj._meta)
        perm = "%s.%s" % (obj._meta.app_label, codename)
        return (is_authenticated(request.user)
                and has_site_permission(request.user)
                and request.user.has_perm(perm))
Ejemplo n.º 15
0
def is_editable(obj, request):
    """
    Returns ``True`` if the object is editable for the request. First
    check for a custom ``editable`` handler on the object, otherwise
    use the logged in user and check change permissions for the
    object's model.
    """
    if hasattr(obj, "is_editable"):
        return obj.is_editable(request)
    else:
        codename = get_permission_codename("change", obj._meta)
        perm = "%s.%s" % (obj._meta.app_label, codename)
        return (is_authenticated(request.user) and
                has_site_permission(request.user) and
                request.user.has_perm(perm))
Ejemplo n.º 16
0
 def process_request(self, request):
     if (cache_installed() and request.method == "GET"
             and not is_authenticated(request.user)):
         cache_key = cache_key_prefix(request) + request.get_full_path()
         response = cache_get(cache_key)
         # We need to force a csrf token here, as new sessions
         # won't receieve one on their first request, with cache
         # middleware running.
         if csrf_middleware_installed():
             csrf_mw = CsrfViewMiddleware()
             csrf_mw.process_view(request, lambda x: None, None, None)
             get_token(request)
         if response is None:
             request._update_cache = True
         else:
             return HttpResponse(response)
Ejemplo n.º 17
0
 def process_request(self, request):
     if (cache_installed() and request.method == "GET" and
             not is_authenticated(request.user)):
         cache_key = cache_key_prefix(request) + request.get_full_path()
         response = cache_get(cache_key)
         # We need to force a csrf token here, as new sessions
         # won't receieve one on their first request, with cache
         # middleware running.
         if csrf_middleware_installed():
             csrf_mw = CsrfViewMiddleware()
             csrf_mw.process_view(request, lambda x: None, None, None)
             get_token(request)
         if response is None:
             request._update_cache = True
         else:
             return HttpResponse(response)
Ejemplo n.º 18
0
    def save(self, request):
        """
        Saves a new comment and sends any notification emails.
        """
        comment = self.get_comment_object()
        obj = comment.content_object
        if is_authenticated(request.user):
            comment.user = request.user
        comment.by_author = request.user == getattr(obj, "user", None)
        comment.ip_address = ip_for_request(request)
        comment.replied_to_id = self.data.get("replied_to")

        # Mezzanine's duplicate check that also checks `replied_to_id`.
        lookup = {
            "content_type": comment.content_type,
            "object_pk": comment.object_pk,
            "user_name": comment.user_name,
            "user_email": comment.user_email,
            "user_url": comment.user_url,
            "replied_to_id": comment.replied_to_id,
        }
        for duplicate in self.get_comment_model().objects.filter(**lookup):
            if (duplicate.submit_date.date() == comment.submit_date.date()
                    and duplicate.comment == comment.comment):
                return duplicate

        comment.save()
        comment_was_posted.send(sender=comment.__class__,
                                comment=comment,
                                request=request)
        notify_emails = split_addresses(settings.COMMENTS_NOTIFICATION_EMAILS)
        if notify_emails:
            subject = ugettext("New comment for: ") + str(obj)
            context = {
                "comment": comment,
                "comment_url": add_cache_bypass(comment.get_absolute_url()),
                "request": request,
                "obj": obj,
            }
            send_mail_template(
                subject,
                "email/comment_notification",
                settings.DEFAULT_FROM_EMAIL,
                notify_emails,
                context,
            )
        return comment
Ejemplo n.º 19
0
def initial_validation(request, prefix):
    """
    Returns the related model instance and post data to use in the
    comment/rating views below.

    Both comments and ratings have a ``prefix_ACCOUNT_REQUIRED``
    setting. If this is ``True`` and the user is unauthenticated, we
    store their post data in their session, and redirect to login with
    the view's url (also defined by the prefix arg) as the ``next``
    param. We can then check the session data once they log in,
    and complete the action authenticated.

    On successful post, we pass the related object and post data back,
    which may have come from the session, for each of the comments and
    ratings view functions to deal with as needed.
    """
    post_data = request.POST
    login_required_setting_name = prefix.upper() + "S_ACCOUNT_REQUIRED"
    posted_session_key = "unauthenticated_" + prefix
    redirect_url = ""
    if getattr(settings, login_required_setting_name, False):
        if not is_authenticated(request.user):
            if request.method == "POST":
                request.session[posted_session_key] = request.POST
                error(request, _("You must be logged in. Please log in or "
                                 "sign up to complete this action."))
            redirect_url = "%s?next=%s" % (settings.LOGIN_URL, reverse(prefix))
        elif posted_session_key in request.session:
            post_data = request.session.pop(posted_session_key)
    if not redirect_url:
        model_data = post_data.get("content_type", "").split(".", 1)
        if len(model_data) != 2:
            return HttpResponseBadRequest()
        try:
            model = apps.get_model(*model_data)
            obj = model.objects.get(id=post_data.get("object_pk", None))
        except (TypeError, ObjectDoesNotExist, LookupError):
            redirect_url = "/"
    if redirect_url:
        if request.is_ajax():
            return HttpResponse(dumps({"location": redirect_url}))
        else:
            return redirect(redirect_url)
    return obj, post_data
Ejemplo n.º 20
0
    def published(self, for_user=None, include_login_required=False):
        """
        Override ``DisplayableManager.published`` to exclude
        pages with ``login_required`` set to ``True``. if the
        user is unauthenticated and the setting
        ``PAGES_PUBLISHED_INCLUDE_LOGIN_REQUIRED`` is ``False``.

        The extra ``include_login_required`` arg allows callers to
        override the ``PAGES_PUBLISHED_INCLUDE_LOGIN_REQUIRED``
        behaviour in special cases where they want to deal with the
        ``login_required`` field manually, such as the case in
        ``PageMiddleware``.
        """
        published = super(PageManager, self).published(for_user=for_user)
        unauthenticated = for_user and not is_authenticated(for_user)
        if (unauthenticated and not include_login_required
                and not settings.PAGES_PUBLISHED_INCLUDE_LOGIN_REQUIRED):
            published = published.exclude(login_required=True)
        return published
Ejemplo n.º 21
0
    def save(self, request):
        """
        Saves a new comment and sends any notification emails.
        """
        comment = self.get_comment_object()
        obj = comment.content_object
        if is_authenticated(request.user):
            comment.user = request.user
        comment.by_author = request.user == getattr(obj, "user", None)
        comment.ip_address = ip_for_request(request)
        comment.replied_to_id = self.data.get("replied_to")

        # Mezzanine's duplicate check that also checks `replied_to_id`.
        lookup = {
            "content_type": comment.content_type,
            "object_pk": comment.object_pk,
            "user_name": comment.user_name,
            "user_email": comment.user_email,
            "user_url": comment.user_url,
            "replied_to_id": comment.replied_to_id,
        }
        for duplicate in self.get_comment_model().objects.filter(**lookup):
            if (duplicate.submit_date.date() == comment.submit_date.date() and
                    duplicate.comment == comment.comment):
                return duplicate

        comment.save()
        comment_was_posted.send(sender=comment.__class__, comment=comment,
                                request=request)
        notify_emails = split_addresses(settings.COMMENTS_NOTIFICATION_EMAILS)
        if notify_emails:
            subject = ugettext("New comment for: ") + str(obj)
            context = {
                "comment": comment,
                "comment_url": add_cache_bypass(comment.get_absolute_url()),
                "request": request,
                "obj": obj,
            }
            send_mail_template(subject, "email/comment_notification",
                               settings.DEFAULT_FROM_EMAIL, notify_emails,
                               context)
        return comment
Ejemplo n.º 22
0
 def __init__(self, request, *args, **kwargs):
     """
     Set some initial field values from cookies or the logged in
     user, and apply some HTML5 attributes to the fields if the
     ``FORMS_USE_HTML5`` setting is ``True``.
     """
     kwargs.setdefault("initial", {})
     user = request.user
     for field in ThreadedCommentForm.cookie_fields:
         cookie_name = ThreadedCommentForm.cookie_prefix + field
         value = request.COOKIES.get(cookie_name, "")
         if not value and is_authenticated(user):
             if field == "name":
                 value = user.get_full_name()
                 if not value and user.username != user.email:
                     value = user.username
             elif field == "email":
                 value = user.email
         kwargs["initial"][field] = value
     super(ThreadedCommentForm, self).__init__(*args, **kwargs)
Ejemplo n.º 23
0
 def __init__(self, request, *args, **kwargs):
     """
     Set some initial field values from cookies or the logged in
     user, and apply some HTML5 attributes to the fields if the
     ``FORMS_USE_HTML5`` setting is ``True``.
     """
     kwargs.setdefault("initial", {})
     user = request.user
     for field in ThreadedCommentForm.cookie_fields:
         cookie_name = ThreadedCommentForm.cookie_prefix + field
         value = request.COOKIES.get(cookie_name, "")
         if not value and is_authenticated(user):
             if field == "name":
                 value = user.get_full_name()
                 if not value and user.username != user.email:
                     value = user.username
             elif field == "email":
                 value = user.email
         kwargs["initial"][field] = value
     super(ThreadedCommentForm, self).__init__(*args, **kwargs)
Ejemplo n.º 24
0
    def process_response(self, request, response):

        # Caching is only applicable for text-based, non-streaming
        # responses. We also skip it for non-200 statuses during
        # development, so that stack traces are correctly rendered.
        is_text = response.get("content-type", "").startswith("text")
        valid_status = response.status_code == 200
        streaming = getattr(response, "streaming", False)
        if not is_text or streaming or (settings.DEBUG and not valid_status):
            return response

        # Cache the response if all the required conditions are met.
        # Response must be marked for updating by the
        # ``FetchFromCacheMiddleware`` having a cache get miss, the
        # user must not be authenticated, the HTTP status must be OK
        # and the response mustn't include an expiry age, indicating it
        # shouldn't be cached.
        marked_for_update = getattr(request, "_update_cache", False)
        anon = hasattr(request, "user") and not is_authenticated(request.user)
        timeout = get_max_age(response)
        if timeout is None:
            timeout = settings.CACHE_MIDDLEWARE_SECONDS
        if anon and valid_status and marked_for_update and timeout:
            cache_key = cache_key_prefix(request) + request.get_full_path()
            _cache_set = lambda r: cache_set(cache_key, r.content, timeout)
            if callable(getattr(response, "render", None)):
                response.add_post_render_callback(_cache_set)
            else:
                _cache_set(response)

        # Second phase rendering for non-cached template code and
        # content. Split on the delimiter the ``nevercache`` tag
        # wrapped its contents in, and render only the content
        # enclosed by it, to avoid possible template code injection.
        token = nevercache_token()
        try:
            token = token.encode('utf-8')
        except AttributeError:
            pass
        parts = response.content.split(token)
        # Restore csrf token from cookie - check the response
        # first as it may be being set for the first time.
        csrf_token = None
        try:
            csrf_token = response.cookies[settings.CSRF_COOKIE_NAME].value
        except KeyError:
            try:
                csrf_token = request.COOKIES[settings.CSRF_COOKIE_NAME]
            except KeyError:
                pass
        if csrf_token:
            request.META["CSRF_COOKIE"] = csrf_token
        context = RequestContext(request)
        for i, part in enumerate(parts):
            if i % 2:
                part = Template(part).render(context).encode("utf-8")
            parts[i] = part
        response.content = b"".join(parts)
        response["Content-Length"] = len(response.content)
        if hasattr(request, '_messages'):
            # Required to clear out user messages.
            request._messages.update(response)
        # Response needs to be run-through the CSRF middleware again so
        # that if there was a {% csrf_token %} inside of the nevercache
        # the cookie will be correctly set for the the response
        csrf_mw_name = "django.middleware.csrf.CsrfViewMiddleware"
        if csrf_mw_name in get_middleware_setting():
            response.csrf_processing_done = False
            csrf_mw = CsrfViewMiddleware()
            csrf_mw.process_response(request, response)
        return response
Ejemplo n.º 25
0
    def process_response(self, request, response):

        # Caching is only applicable for text-based, non-streaming
        # responses. We also skip it for non-200 statuses during
        # development, so that stack traces are correctly rendered.
        is_text = response.get("content-type", "").startswith("text")
        valid_status = response.status_code == 200
        streaming = getattr(response, "streaming", False)
        if not is_text or streaming or (settings.DEBUG and not valid_status):
            return response

        # Cache the response if all the required conditions are met.
        # Response must be marked for updating by the
        # ``FetchFromCacheMiddleware`` having a cache get miss, the
        # user must not be authenticated, the HTTP status must be OK
        # and the response mustn't include an expiry age, indicating it
        # shouldn't be cached.
        marked_for_update = getattr(request, "_update_cache", False)
        anon = hasattr(request, "user") and not is_authenticated(request.user)
        timeout = get_max_age(response)
        if timeout is None:
            timeout = settings.CACHE_MIDDLEWARE_SECONDS
        if anon and valid_status and marked_for_update and timeout:
            cache_key = cache_key_prefix(request) + request.get_full_path()
            _cache_set = lambda r: cache_set(cache_key, r.content, timeout)
            if callable(getattr(response, "render", None)):
                response.add_post_render_callback(_cache_set)
            else:
                _cache_set(response)

        # Second phase rendering for non-cached template code and
        # content. Split on the delimiter the ``nevercache`` tag
        # wrapped its contents in, and render only the content
        # enclosed by it, to avoid possible template code injection.
        token = nevercache_token()
        try:
            token = token.encode('utf-8')
        except AttributeError:
            pass
        parts = response.content.split(token)
        # Restore csrf token from cookie - check the response
        # first as it may be being set for the first time.
        csrf_token = None
        try:
            csrf_token = response.cookies[settings.CSRF_COOKIE_NAME].value
        except KeyError:
            try:
                csrf_token = request.COOKIES[settings.CSRF_COOKIE_NAME]
            except KeyError:
                pass
        if csrf_token:
            request.META["CSRF_COOKIE"] = csrf_token
        context = RequestContext(request)
        for i, part in enumerate(parts):
            if i % 2:
                part = Template(part).render(context).encode("utf-8")
            parts[i] = part
        response.content = b"".join(parts)
        response["Content-Length"] = len(response.content)
        if hasattr(request, '_messages'):
            # Required to clear out user messages.
            request._messages.update(response)
        # Response needs to be run-through the CSRF middleware again so
        # that if there was a {% csrf_token %} inside of the nevercache
        # the cookie will be correctly set for the the response
        csrf_mw_name = "django.middleware.csrf.CsrfViewMiddleware"
        if csrf_mw_name in get_middleware_setting():
            response.csrf_processing_done = False
            csrf_mw = CsrfViewMiddleware()
            csrf_mw.process_response(request, response)
        return response