diff --git a/CHANGELOG.rst b/CHANGELOG.rst index c02b5bab2f67a37d68ff97ee8fbfb4f981412d1e..948b02c22eaa30bdf29c39920d55c8af5e9beafe 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -28,6 +28,13 @@ Fixed * Users were able to edit the linked user if self-editing was activated. * Users weren't able to edit the allowed fields although they were configured correctly. + +Removed +~~~~~~~ + +* Remove mass linking of persons to accounts, bevcause the view had performance issues, + but was practically unused. + `2.0rc7`_ - 2021-10-18 ---------------------- diff --git a/aleksis/core/forms.py b/aleksis/core/forms.py index f789386bc31c369d44efb28edddf1ae39ca91fcd..740fd24b3b5d82c1df5c50d2ad78aa7d71a92292 100644 --- a/aleksis/core/forms.py +++ b/aleksis/core/forms.py @@ -33,54 +33,6 @@ from .registries import ( from .util.core_helpers import get_site_preferences -class PersonAccountForm(forms.ModelForm): - """Form to assign user accounts to persons in the frontend.""" - - class Meta: - model = Person - fields = ["last_name", "first_name", "user"] - widgets = {"user": Select2Widget(attrs={"class": "browser-default"})} - - new_user = forms.CharField(required=False) - - def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs) - - # Fields displayed only for informational purposes - self.fields["first_name"].disabled = True - self.fields["last_name"].disabled = True - - def clean(self) -> None: - user = get_user_model() - - if self.cleaned_data.get("new_user", None): - if self.cleaned_data.get("user", None): - # The user selected both an existing user and provided a name to create a new one - self.add_error( - "new_user", - _("You cannot set a new username when also selecting an existing user."), - ) - elif user.objects.filter(username=self.cleaned_data["new_user"]).exists(): - # The user tried to create a new user with the name of an existing user - self.add_error("new_user", _("This username is already in use.")) - else: - # Create new User object and assign to form field for existing user - new_user_obj = user.objects.create_user( - self.cleaned_data["new_user"], - self.instance.email, - first_name=self.instance.first_name, - last_name=self.instance.last_name, - ) - - self.cleaned_data["user"] = new_user_obj - - -# Formset for batch-processing of assignments of users to persons -PersonsAccountsFormSet = forms.modelformset_factory( - Person, form=PersonAccountForm, max_num=0, extra=0 -) - - class PersonForm(ExtensibleForm): """Form to edit or add a person object in the frontend.""" @@ -162,8 +114,28 @@ class PersonForm(ExtensibleForm): self.fields[field].disabled = False def clean(self) -> None: - # Use code implemented in dedicated form to verify user selection - return PersonAccountForm.clean(self) + user = get_user_model() + + if self.cleaned_data.get("new_user", None): + if self.cleaned_data.get("user", None): + # The user selected both an existing user and provided a name to create a new one + self.add_error( + "new_user", + _("You cannot set a new username when also selecting an existing user."), + ) + elif user.objects.filter(username=self.cleaned_data["new_user"]).exists(): + # The user tried to create a new user with the name of an existing user + self.add_error("new_user", _("This username is already in use.")) + else: + # Create new User object and assign to form field for existing user + new_user_obj = user.objects.create_user( + self.cleaned_data["new_user"], + self.instance.email, + first_name=self.instance.first_name, + last_name=self.instance.last_name, + ) + + self.cleaned_data["user"] = new_user_obj class EditGroupForm(SchoolTermRelatedExtensibleForm): diff --git a/aleksis/core/menus.py b/aleksis/core/menus.py index b368a6c702e4b2514afc903fb5ff48417ef22bfa..d9fd84b0f78a1ce141537725d233f57b43a4fbea 100644 --- a/aleksis/core/menus.py +++ b/aleksis/core/menus.py @@ -267,17 +267,6 @@ MENUS = { ) ], }, - { - "name": _("Persons and accounts"), - "url": "persons_accounts", - "icon": "person_add", - "validators": [ - ( - "aleksis.core.util.predicates.permission_validator", - "core.link_persons_accounts_rule", - ) - ], - }, { "name": _("Groups and child groups"), "url": "groups_child_groups", diff --git a/aleksis/core/migrations/0021_drop_persons_accounts_perm.py b/aleksis/core/migrations/0021_drop_persons_accounts_perm.py new file mode 100644 index 0000000000000000000000000000000000000000..576efcec16e706a27059d80d9c256052c0e74dab --- /dev/null +++ b/aleksis/core/migrations/0021_drop_persons_accounts_perm.py @@ -0,0 +1,17 @@ +# Generated by Django 3.2.8 on 2021-10-24 13:43 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('core', '0020_pdf_file_person_optional'), + ] + + operations = [ + migrations.AlterModelOptions( + name='globalpermissions', + options={'default_permissions': (), 'managed': False, 'permissions': (('view_system_status', 'Can view system status'), ('manage_data', 'Can manage data'), ('impersonate', 'Can impersonate'), ('search', 'Can use search'), ('change_site_preferences', 'Can change site preferences'), ('change_person_preferences', 'Can change person preferences'), ('change_group_preferences', 'Can change group preferences'), ('add_oauth_applications', 'Can add oauth applications'), ('list_oauth_applications', 'Can list oauth applications'), ('view_oauth_applications', 'Can view oauth applications'), ('update_oauth_applications', 'Can update oauth applications'), ('delete_oauth_applications', 'Can delete oauth applications'), ('test_pdf', 'Can test PDF generation'))}, + ), + ] diff --git a/aleksis/core/models.py b/aleksis/core/models.py index f391fd02fedc22d31e1b96c78e7c8509e7a54b33..1264b645ef56da31c215f3b42b0e59162935b6a0 100644 --- a/aleksis/core/models.py +++ b/aleksis/core/models.py @@ -969,7 +969,6 @@ class GlobalPermissions(GlobalPermissionModel): class Meta(GlobalPermissionModel.Meta): permissions = ( ("view_system_status", _("Can view system status")), - ("link_persons_accounts", _("Can link persons to accounts")), ("manage_data", _("Can manage data")), ("impersonate", _("Can impersonate")), ("search", _("Can use search")), diff --git a/aleksis/core/rules.py b/aleksis/core/rules.py index 99c0493620f4411847e142ff986292e9947436d7..e8e5443e15396554befa1f14c2536c66231c76cf 100644 --- a/aleksis/core/rules.py +++ b/aleksis/core/rules.py @@ -79,10 +79,6 @@ delete_person_predicate = has_person & ( ) rules.add_perm("core.delete_person_rule", delete_person_predicate) -# Link persons with accounts -link_persons_accounts_predicate = has_person & has_global_perm("core.link_persons_accounts") -rules.add_perm("core.link_persons_accounts_rule", link_persons_accounts_predicate) - # View groups view_groups_predicate = has_person & ( has_global_perm("core.view_group") | has_any_object("core.view_group", Group) @@ -157,12 +153,7 @@ rules.add_perm("core.view_system_status_rule", view_system_status_predicate) rules.add_perm( "core.view_people_menu_rule", has_person - & ( - view_persons_predicate - | view_groups_predicate - | link_persons_accounts_predicate - | assign_child_groups_to_groups_predicate - ), + & (view_persons_predicate | view_groups_predicate | assign_child_groups_to_groups_predicate), ) # View person personal details diff --git a/aleksis/core/templates/core/person/accounts.html b/aleksis/core/templates/core/person/accounts.html deleted file mode 100644 index 03725518dfcbf8552a53199790daa44d541bac32..0000000000000000000000000000000000000000 --- a/aleksis/core/templates/core/person/accounts.html +++ /dev/null @@ -1,65 +0,0 @@ -{# -*- engine:django -*- #} - -{% extends "core/base.html" %} - -{% load i18n any_js %} - -{% block extra_head %} - {{ persons_accounts_formset.media.css }} - {% include_css "select2-materialize" %} -{% endblock %} - -{% block browser_title %}{% blocktrans %}Link persons to accounts{% endblocktrans %}{% endblock %} -{% block page_title %} - {% blocktrans %}Link persons to accounts{% endblocktrans %} -{% endblock %} - -{% block content %} - <div class="alert info"> - <p> - <i class="material-icons left">info</i> - {% blocktrans %} - You can use this form to assign user accounts to persons. Use the - dropdowns to select existing accounts; use the text fields to create new - accounts on-the-fly. The latter will create a new account with the - entered username and copy all other details from the person. - {% endblocktrans %} - </p> - </div> - - <form method="post"> - {% csrf_token %} - {{ persons_accounts_formset.management_form }} - - <button type="submit" class="btn green waves-effect waves-light"> - <i class="material-icons left">save</i> - {% blocktrans %}Update{% endblocktrans %} - </button> - - <table> - <tr> - <th>{% blocktrans %}Person{% endblocktrans %}</th> - <th>{% blocktrans %}Existing account{% endblocktrans %}</th> - <th>{% blocktrans %}New account{% endblocktrans %}</th> - </tr> - {% for form in persons_accounts_formset %} - {{ form.id }} - <tr> - <td> - {{ form.last_name }} - {{ form.first_name }} - </td> - <td>{{ form.user }}</td> - <td>{{ form.new_user }}</td> - </tr> - {% endfor %} - </table> - - <button type="submit" class="btn green waves-effect waves-light"> - <i class="material-icons left">save</i> - {% blocktrans %}Update{% endblocktrans %} - </button> - </form> - {% include_js "select2-materialize" %} - {{ persons_accounts_formset.media.js }} -{% endblock %} diff --git a/aleksis/core/urls.py b/aleksis/core/urls.py index 92107e30f5a237ef0efd834f3e5bd4279e19b705..b3c2cc468aded72fe1b9e64af88e58b4fb936192 100644 --- a/aleksis/core/urls.py +++ b/aleksis/core/urls.py @@ -46,7 +46,6 @@ urlpatterns = [ path("school_terms/create/", views.SchoolTermCreateView.as_view(), name="create_school_term"), path("school_terms/<int:pk>/", views.SchoolTermEditView.as_view(), name="edit_school_term"), path("persons", views.persons, name="persons"), - path("persons/accounts", views.persons_accounts, name="persons_accounts"), path("person/", views.person, name="person"), path("person/create/", views.CreatePersonView.as_view(), name="create_person"), path("person/<int:id_>/", views.person, name="person_by_id"), diff --git a/aleksis/core/views.py b/aleksis/core/views.py index 7e7fd7739b68c30fb8d8de6c268fd6a4bf21a521..8918f3c35d9ef661ae711faecbac6fb054fdb526 100644 --- a/aleksis/core/views.py +++ b/aleksis/core/views.py @@ -62,7 +62,6 @@ from .forms import ( GroupPreferenceForm, PersonForm, PersonPreferenceForm, - PersonsAccountsFormSet, SchoolTermForm, SitePreferenceForm, ) @@ -360,27 +359,6 @@ def groups(request: HttpRequest) -> HttpResponse: return render(request, "core/group/list.html", context) -@never_cache -@permission_required("core.link_persons_accounts_rule") -def persons_accounts(request: HttpRequest) -> HttpResponse: - """View allowing to batch-process linking of users to persons.""" - context = {} - - # Get all persons - persons_qs = Person.objects.all() - - # Form set with one form per known person - persons_accounts_formset = PersonsAccountsFormSet(request.POST or None, queryset=persons_qs) - - if request.method == "POST": - if persons_accounts_formset.is_valid(): - persons_accounts_formset.save() - - context["persons_accounts_formset"] = persons_accounts_formset - - return render(request, "core/person/accounts.html", context) - - @never_cache @permission_required("core.assign_child_groups_to_groups_rule") def groups_child_groups(request: HttpRequest) -> HttpResponse: