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
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
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
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)
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)
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
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
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
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
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
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
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))
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)
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
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
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
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
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)
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