hotpocket/services/backend/hotpocket_backend/apps/ui/views/accounts/settings.py
Tomek Wójcik b6d02dbe78 BTHLABS-50: Safari Web extension
Co-authored-by: Tomek Wójcik <labs@tomekwojcik.pl>
Co-committed-by: Tomek Wójcik <labs@tomekwojcik.pl>
2025-09-08 18:11:36 +00:00

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