Co-authored-by: Tomek Wójcik <labs@tomekwojcik.pl> Co-committed-by: Tomek Wójcik <labs@tomekwojcik.pl>
180 lines
5.1 KiB
Python
180 lines
5.1 KiB
Python
# -*- coding: utf-8 -*-
|
|
from __future__ import annotations
|
|
|
|
from django.contrib import messages
|
|
import django.db
|
|
from django.http import HttpRequest, HttpResponse
|
|
from django.shortcuts import redirect
|
|
from django.urls import reverse
|
|
from django.utils.translation import gettext_lazy as _
|
|
from django.views.generic import FormView
|
|
|
|
from hotpocket_backend.apps.accounts.decorators import account_required
|
|
from hotpocket_backend.apps.accounts.mixins import AccountRequiredMixin
|
|
from hotpocket_backend.apps.ui.forms.accounts.settings import (
|
|
FederatedPasswordForm,
|
|
FederatedProfileForm,
|
|
PasswordForm,
|
|
ProfileForm,
|
|
SettingsForm,
|
|
)
|
|
|
|
|
|
@account_required
|
|
def settings(request: HttpRequest) -> HttpResponse:
|
|
return redirect(reverse('ui.accounts.settings.profile'))
|
|
|
|
|
|
class BaseSettingsView(AccountRequiredMixin, FormView):
|
|
template_name = 'ui/accounts/settings.html'
|
|
|
|
@property
|
|
def is_federated(self) -> bool:
|
|
return all((
|
|
self.request.user.is_anonymous is False,
|
|
self.request.user.has_usable_password() is False,
|
|
))
|
|
|
|
def get_context_data(self, **kwargs) -> dict:
|
|
result = super().get_context_data(**kwargs)
|
|
|
|
result.update({
|
|
'is_federated': self.is_federated,
|
|
})
|
|
|
|
return result
|
|
|
|
|
|
class ProfileView(BaseSettingsView):
|
|
def get_form_class(self) -> type[ProfileForm]:
|
|
if self.is_federated is True:
|
|
return FederatedProfileForm
|
|
|
|
return ProfileForm
|
|
|
|
def get_initial(self) -> dict:
|
|
result = super().get_initial()
|
|
|
|
result.update({
|
|
'username': self.request.user.username,
|
|
'first_name': self.request.user.first_name,
|
|
'last_name': self.request.user.last_name,
|
|
'email': self.request.user.email,
|
|
})
|
|
|
|
return result
|
|
|
|
def get_context_data(self, **kwargs) -> dict:
|
|
result = super().get_context_data(**kwargs)
|
|
|
|
result.update({
|
|
'title': _('Profile'),
|
|
'active_tab': 'profile',
|
|
})
|
|
|
|
return result
|
|
|
|
def form_valid(self, form: ProfileForm) -> HttpResponse:
|
|
assert self.is_federated is False, (
|
|
'Refuse to save profile of a federated account: '
|
|
f'account=`{self.request.user}`'
|
|
)
|
|
|
|
with django.db.transaction.atomic():
|
|
self.request.user.first_name = form.cleaned_data['first_name']
|
|
self.request.user.last_name = form.cleaned_data['last_name']
|
|
self.request.user.email = form.cleaned_data['email']
|
|
self.request.user.save()
|
|
|
|
messages.add_message(
|
|
self.request,
|
|
messages.SUCCESS,
|
|
message=_('Your profile has been been updated!'),
|
|
)
|
|
|
|
return super().form_valid(form)
|
|
|
|
def get_success_url(self) -> str:
|
|
return reverse('ui.accounts.settings.profile')
|
|
|
|
|
|
class PasswordView(BaseSettingsView):
|
|
def get_form_class(self) -> type[PasswordForm]:
|
|
if self.is_federated is True:
|
|
return FederatedPasswordForm
|
|
|
|
return PasswordForm
|
|
|
|
def get_form(self,
|
|
form_class: type[PasswordForm] | None = None,
|
|
) -> PasswordForm:
|
|
form_class = form_class or self.get_form_class()
|
|
return form_class(self.request.user, **self.get_form_kwargs())
|
|
|
|
def get_context_data(self, **kwargs) -> dict:
|
|
result = super().get_context_data(**kwargs)
|
|
|
|
result.update({
|
|
'title': _('Password'),
|
|
'active_tab': 'password',
|
|
})
|
|
|
|
return result
|
|
|
|
def form_valid(self, form: PasswordForm) -> HttpResponse:
|
|
assert self.is_federated is False, (
|
|
'Refuse to change password of a federated account: '
|
|
f'account=`{self.request.user}`'
|
|
)
|
|
|
|
with django.db.transaction.atomic():
|
|
form.set_password_and_save(
|
|
self.request.user,
|
|
password_field_name='new_password1',
|
|
)
|
|
|
|
messages.add_message(
|
|
self.request,
|
|
messages.SUCCESS,
|
|
message=_('Your password has been changed!'),
|
|
)
|
|
|
|
return super().form_valid(form)
|
|
|
|
def get_success_url(self) -> str:
|
|
return reverse('ui.accounts.settings.password')
|
|
|
|
|
|
class SettingsView(BaseSettingsView):
|
|
form_class = SettingsForm
|
|
|
|
def get_context_data(self, **kwargs) -> dict:
|
|
result = super().get_context_data(**kwargs)
|
|
|
|
result.update({
|
|
'title': _('Settings'),
|
|
'active_tab': 'settings',
|
|
'is_federated': False,
|
|
})
|
|
|
|
return result
|
|
|
|
def get_initial(self) -> dict:
|
|
return self.request.user.settings
|
|
|
|
def form_valid(self, form: PasswordForm) -> HttpResponse:
|
|
with django.db.transaction.atomic():
|
|
self.request.user.raw_settings = form.cleaned_data
|
|
self.request.user.save()
|
|
|
|
messages.add_message(
|
|
self.request,
|
|
messages.SUCCESS,
|
|
message=_('Your settings have been updated!'),
|
|
)
|
|
|
|
return super().form_valid(form)
|
|
|
|
def get_success_url(self) -> str:
|
|
return reverse('ui.accounts.settings.settings')
|