Source code for nlpmed_portal.users.views

# SPDX-FileCopyrightText: Copyright (C) 2026 Omid Jafari <omidjafari.com>
# SPDX-License-Identifier: AGPL-3.0-or-later
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.


from allauth.account.adapter import get_adapter as get_account_adapter
from allauth.account.views import PasswordChangeView
from allauth.usersessions import app_settings
from allauth.usersessions.forms import ManageUserSessionsForm
from allauth.usersessions.models import UserSession
from auditlog.models import LogEntry
from django.contrib import messages
from django.contrib.auth.mixins import LoginRequiredMixin
from django.contrib.contenttypes.models import ContentType
from django.contrib.messages.views import SuccessMessageMixin
from django.contrib.sites.models import Site
from django.core.exceptions import PermissionDenied
from django.db.models import QuerySet
from django.urls import reverse
from django.urls import reverse_lazy
from django.utils.translation import gettext_lazy as _
from django.views.generic import RedirectView
from django.views.generic import UpdateView
from django.views.generic.edit import FormView

from nlpmed_portal.users.forms import UserUpdateForm
from nlpmed_portal.users.models import User


[docs] class UserUpdateView(LoginRequiredMixin, SuccessMessageMixin, UpdateView): model = User form_class = UserUpdateForm success_message = _("Information successfully updated") template_name = "users/user_update_form.html"
[docs] def get_success_url(self) -> str: assert self.request.user.is_authenticated # type guard # ruff: ignore[assert] return self.request.user.get_absolute_url()
[docs] def get_object( self, queryset: QuerySet[User] | None = None, ) -> User: assert self.request.user.is_authenticated # type guard # ruff: ignore[assert] return self.request.user
[docs] def dispatch(self, request, *args, **kwargs): ct = ContentType.objects.get_for_model(Site) user_id = getattr(request.user, "id", None) LogEntry.objects.create( content_type=ct, object_repr=f"users | {self.__class__.__name__}" + (f" | user_id={user_id}" if user_id else ""), action=LogEntry.Action.ACCESS, ) return super().dispatch(request, *args, **kwargs)
[docs] class UserChangePwdView(LoginRequiredMixin, SuccessMessageMixin, PasswordChangeView): template_name = "users/user_changepwd_form.html"
[docs] def get_success_url(self) -> str: assert self.request.user.is_authenticated # type guard # ruff: ignore[assert] return self.request.user.get_absolute_url()
[docs] def dispatch(self, request, *args, **kwargs): ct = ContentType.objects.get_for_model(Site) user_id = getattr(request.user, "id", None) LogEntry.objects.create( content_type=ct, object_repr=f"users | {self.__class__.__name__}" + (f" | user_id={user_id}" if user_id else ""), action=LogEntry.Action.ACCESS, ) if request.user.is_superuser: msg = "Superusers cannot change their password here." raise PermissionDenied(msg) if not request.user.has_usable_password(): msg = "This account does not have a current password." raise PermissionDenied(msg) return super().dispatch(request, *args, **kwargs)
[docs] class UserRedirectView(LoginRequiredMixin, RedirectView): permanent = False
[docs] def get_redirect_url(self) -> str: return reverse("home")
# Added dispatch to CBV from allauth
[docs] class ListUserSessionsView(FormView): template_name = "users/usersession_list.html" form_class = ManageUserSessionsForm success_url = reverse_lazy("usersessions_list")
[docs] def get_context_data(self, **kwargs): ret = super().get_context_data(**kwargs) sessions = sorted( UserSession.objects.purge_and_list(self.request.user), key=lambda s: s.created_at, ) ret["sessions"] = sessions ret["session_count"] = len(sessions) ret["show_last_seen_at"] = app_settings.TRACK_ACTIVITY return ret
[docs] def get_form_kwargs(self): ret = super().get_form_kwargs() ret["request"] = self.request return ret
[docs] def form_valid(self, form): form.save(self.request) get_account_adapter().add_message( self.request, messages.INFO, "usersessions/messages/sessions_logged_out.txt", ) return super().form_valid(form)
[docs] def dispatch(self, request, *args, **kwargs): ct = ContentType.objects.get_for_model(Site) user_id = getattr(request.user, "id", None) LogEntry.objects.create( content_type=ct, object_repr=f"users | {self.__class__.__name__}" + (f" | user_id={user_id}" if user_id else ""), action=LogEntry.Action.ACCESS, ) return super().dispatch(request, *args, **kwargs)