From 3ce5f3141171d5279ff514d465c5420c7c6819d8 Mon Sep 17 00:00:00 2001 From: Yohann D'ANELLO Date: Mon, 17 Feb 2020 11:21:05 +0100 Subject: [PATCH] Cannot set username that is similar to an alias we don't own --- apps/member/views.py | 30 ++++++++++++++++++++++++++++-- apps/note/models/notes.py | 7 ++++++- 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/apps/member/views.py b/apps/member/views.py index 2070d7a0..ec7a3e0c 100644 --- a/apps/member/views.py +++ b/apps/member/views.py @@ -4,6 +4,7 @@ # SPDX-License-Identifier: GPL-3.0-or-later from dal import autocomplete from django.contrib.auth.mixins import LoginRequiredMixin +from django.core.exceptions import ValidationError from django.utils.translation import gettext_lazy as _ from django.views.generic import CreateView, ListView, DetailView, UpdateView from django.http import HttpResponseRedirect @@ -14,7 +15,7 @@ from django.db.models import Q from django_tables2.views import SingleTableView - +from note.models import Alias, Note, NoteUser from .models import Profile, Club, Membership from .forms import SignUpForm, ProfileForm, ClubForm,MembershipForm, MemberFormSet,FormSetHelper from .tables import ClubTable,UserTable @@ -57,13 +58,38 @@ class UserUpdateView(LoginRequiredMixin,UpdateView): second_form = ProfileForm def get_context_data(self,**kwargs): context = super().get_context_data(**kwargs) - context["profile_form"] = self.second_form(instance=context['user'].profile) + context['user_modified'] = context['user'] + context['user'] = self.request.user + context["profile_form"] = self.second_form(instance=context['user_modified'].profile) return context + def get_form(self, form_class=None): + from django.forms import forms + form: forms.Form = super().get_form(form_class) + if 'username' not in form.data: + return form + + new_username = form.data['username'] + + note = NoteUser.objects.filter(alias__normalized_name=Alias.normalize(new_username)) + if note.exists() and note.get().user != self.request.user: + form.add_error('username', _("An alias with a similar name already exists.")) + + return form + + def form_valid(self, form): profile_form = ProfileForm(data=self.request.POST,instance=self.request.user.profile) if form.is_valid() and profile_form.is_valid(): + new_username = form.data['username'] + alias = Alias.objects.filter(name=new_username) + if not alias.exists(): + similar = Alias.objects.filter(normalized_name=Alias.normalize(new_username)) + if similar.exists(): + similar.delete() + note = NoteUser.objects.filter(alias__normalized_name=Alias.normalize(self.request.user.username)).get() + Alias(name=new_username, note=note).save() user = form.save() profile = profile_form.save(commit=False) profile.user = user diff --git a/apps/note/models/notes.py b/apps/note/models/notes.py index e3ab7931..6a0c5ebe 100644 --- a/apps/note/models/notes.py +++ b/apps/note/models/notes.py @@ -85,7 +85,7 @@ class Note(PolymorphicModel): """ Verify alias (simulate save) """ - aliases = Alias.objects.filter(name=str(self)) + aliases = Alias.objects.filter(normalized_name=Alias.normalize(str(self))) if aliases.exists(): # Alias exists, so check if it is linked to this note if aliases.first().note != self: @@ -233,3 +233,8 @@ class Alias(models.Model): 'already exists.')) except Alias.DoesNotExist: pass + + def delete(self, using=None, keep_parents=False): + if self.name == str(self.note): + raise ValidationError(_("You can't delete your main alias.")) + return super().delete(using, keep_parents)