Changeset View
Changeset View
Standalone View
Standalone View
bid_main/views/normal_pages.py
| """Normal stuff, like index, profile editing, etc. | """Normal stuff, like index, profile editing, etc. | ||||
| No error handlers, no usually-one-off things like registration and | No error handlers, no usually-one-off things like registration and | ||||
| email confirmation. | email confirmation. | ||||
| """ | """ | ||||
| import logging | import logging | ||||
| import urllib.parse | import urllib.parse | ||||
| from django.conf import settings | from django.conf import settings | ||||
| from django.contrib.auth import views as auth_views, logout | from django.contrib.auth import views as auth_views, logout, get_user_model | ||||
| from django.contrib.auth.mixins import LoginRequiredMixin | from django.contrib.auth.mixins import LoginRequiredMixin | ||||
| from django.core.exceptions import ValidationError | |||||
| from django.utils.translation import gettext as _ | |||||
| from django.db import transaction, IntegrityError | |||||
| from django.db.models import Count | from django.db.models import Count | ||||
| from django.http import HttpResponseRedirect | from django.http import HttpResponseRedirect | ||||
| from django.shortcuts import resolve_url, render | from django.shortcuts import resolve_url, render | ||||
| from django.urls import reverse_lazy | from django.urls import reverse_lazy | ||||
| from django.utils import timezone | from django.utils import timezone | ||||
| from django.utils.decorators import method_decorator | from django.utils.decorators import method_decorator | ||||
| from django.views.decorators.cache import never_cache | from django.views.decorators.cache import never_cache | ||||
| from django.views.decorators.csrf import csrf_exempt | from django.views.decorators.csrf import csrf_exempt | ||||
| from django.views.decorators.debug import sensitive_post_parameters | from django.views.decorators.debug import sensitive_post_parameters | ||||
| from django.views.generic import TemplateView, FormView | from django.views.generic import TemplateView, FormView | ||||
| from django.views.generic.edit import UpdateView | from django.views.generic.edit import UpdateView | ||||
| import loginas.utils | import loginas.utils | ||||
| import oauth2_provider.models as oauth2_models | import oauth2_provider.models as oauth2_models | ||||
| from .. import forms, email | from .. import forms, email | ||||
| from ..models import User | |||||
| from . import mixins | from . import mixins | ||||
| from bid_main.email import send_verify_address | |||||
| User = get_user_model() | |||||
| log = logging.getLogger(__name__) | log = logging.getLogger(__name__) | ||||
| class IndexView(LoginRequiredMixin, mixins.PageIdMixin, TemplateView): | class IndexView(LoginRequiredMixin, mixins.PageIdMixin, TemplateView): | ||||
| page_id = "index" | page_id = "index" | ||||
| template_name = "bid_main/index.html" | template_name = "bid_main/index.html" | ||||
| login_url = reverse_lazy("bid_main:login") | login_url = reverse_lazy("bid_main:login") | ||||
| redirect_field_name = None | redirect_field_name = None | ||||
| ▲ Show 20 Lines • Show All 85 Lines • ▼ Show 20 Lines | def find_oauth_flow(self, ctx: dict): | ||||
| except app_model.DoesNotExist: | except app_model.DoesNotExist: | ||||
| return | return | ||||
| ctx["is_oauth_flow"] = True | ctx["is_oauth_flow"] = True | ||||
| ctx["oauth_app"] = oauth_app | ctx["oauth_app"] = oauth_app | ||||
| return ctx | return ctx | ||||
| class RegistrationView(LoginView): | |||||
| """Register a user and log them in immediately, handling redirects same way LoginView does.""" | |||||
| page_id = "register" | |||||
| template_name = "bid_main/register.html" | |||||
| authentication_form = forms.RegistrationForm | |||||
| def form_valid(self, form): | |||||
| """Save the newly registered user and send out a verification email.""" | |||||
| try: | |||||
| with transaction.atomic(): | |||||
| email = form.instance.email | |||||
| full_name = form.instance.full_name | |||||
| nickname = User.generate_nickname(email=email, full_name=full_name) | |||||
| user = User.objects.create_user( | |||||
| email, | |||||
| password=form.instance.password, | |||||
| full_name=full_name, | |||||
| nickname=nickname, | |||||
| privacy_policy_agreed=timezone.now(), | |||||
| ) | |||||
| ok = send_verify_address(user, self.request.scheme) | |||||
| if not ok: | |||||
| raise ValidationError('Unable to send email confirmation') | |||||
| except ValidationError as err: | |||||
| form.add_error(None, err) | |||||
| log.warning("Got a ValidationError while trying to register user %s: %s", form.instance, err) | |||||
| return self.render_to_response(self.get_context_data(form=form)) | |||||
| except IntegrityError as ex: | |||||
| err = ValidationError( | |||||
| _( | |||||
| "There was an error registering your account: %(ex)s. " | |||||
| "This probably means you were already registered. If this is not the case, " | |||||
| "and the error remains, contact us at cloudsupport@blender.org. Otherwise " | |||||
| "just log in on your account." | |||||
| ), | |||||
| params={"ex": str(ex)}, | |||||
| code="register-integrity-error", | |||||
| ) | |||||
| form.add_error("email", err) | |||||
| log.warning("Integrity error trying to save user %s: %s", form.instance, ex) | |||||
| return self.render_to_response(self.get_context_data(form=form)) | |||||
| except OSError as ex: | |||||
| log.exception("Error sending registration email") | |||||
| err = ValidationError( | |||||
| _( | |||||
| "There was an error sending your registration email (%(ex)s). " | |||||
| "Your registration has been aborted and this error was logged. " | |||||
| "Please try again later. If the error remains, contact us at " | |||||
| "cloudsupport@blender.org" | |||||
| ), | |||||
| params={"ex": str(ex)}, | |||||
| code="mail-error", | |||||
| ) | |||||
| form.add_error(None, err) | |||||
| return self.render_to_response(self.get_context_data(form=form)) | |||||
| return super().form_valid(form) | |||||
| class LogoutView(auth_views.LogoutView): | class LogoutView(auth_views.LogoutView): | ||||
| """Logout view with support for django-loginas. | """Logout view with support for django-loginas. | ||||
| By default django-loginas registers the logout view at /admin/logout, | By default django-loginas registers the logout view at /admin/logout, | ||||
| which I don't like. I don't want to have /admin/ used by non-admin | which I don't like. I don't want to have /admin/ used by non-admin | ||||
| users. | users. | ||||
| """ | """ | ||||
| ▲ Show 20 Lines • Show All 229 Lines • Show Last 20 Lines | |||||