From bd6c729d4e11aba0b2be059c3183759412c7b219 Mon Sep 17 00:00:00 2001 From: Benjamin Dauvergne Date: Mon, 20 Mar 2023 16:17:23 +0100 Subject: [PATCH] manager: check slug of roles on CSV import (#75603) --- src/authentic2/manager/forms.py | 13 +++++++++++-- tests/test_role_manager.py | 6 +++++- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/src/authentic2/manager/forms.py b/src/authentic2/manager/forms.py index 37207c99b..631910883 100644 --- a/src/authentic2/manager/forms.py +++ b/src/authentic2/manager/forms.py @@ -25,6 +25,7 @@ from django import forms from django.contrib.auth import get_user_model from django.contrib.contenttypes.models import ContentType from django.core.exceptions import ValidationError +from django.core.validators import validate_slug from django.urls import reverse from django.utils.translation import gettext from django.utils.translation import gettext_lazy as _ @@ -819,6 +820,7 @@ class RolesCsvImportForm(LimitQuerysetFormMixin, forms.Form): roles_by_names[role.ou][role.name] = role self.roles = [] + errors = [] for i, csvline in enumerate(csv.reader(StringIO(content), dialect=dialect, delimiter=',')): if not csvline: continue @@ -835,8 +837,13 @@ class RolesCsvImportForm(LimitQuerysetFormMixin, forms.Form): continue slug = '' - if len(csvline) > 1: - slug = csvline[1] + if len(csvline) > 1 and csvline[1]: + try: + validate_slug(csvline[1]) + slug = csvline[1] + except ValidationError: + self.add_line_error(_('Invalid slug "%s".') % csvline[1], i) + continue ou = self.cleaned_data['ou'] if len(csvline) > 2 and csvline[2]: @@ -863,6 +870,8 @@ class RolesCsvImportForm(LimitQuerysetFormMixin, forms.Form): role.ou = ou self.roles.append(role) + if errors: + raise ValidationError(errors) def add_line_error(self, error, line): error = _('%(error)s (line %(number)d)') % {'error': error, 'number': line + 1} diff --git a/tests/test_role_manager.py b/tests/test_role_manager.py index ee8df7c94..adec7514a 100644 --- a/tests/test_role_manager.py +++ b/tests/test_role_manager.py @@ -369,12 +369,16 @@ def test_manager_role_csv_import(app, admin, ou1, ou2): assert 'Invalid file header' in resp.text csv_content = ',slug-but-no-name,\nRole,,unknown-ou' - resp = app.get('/manage/roles/csv-import/') resp.form['import_file'] = Upload('t.csv', csv_header + csv_content.encode(), 'text/csv') resp = resp.form.submit() assert 'Name is required. (line 2)' in resp.text assert 'Organizational Unit unknown-ou does not exist. (line 3)' in resp.text + csv_content = 'Role 5,invalid slug,%s\nRole 6,,' % ou1.slug + resp.form['import_file'] = Upload('t.csv', csv_header + csv_content.encode(), 'text/csv') + resp = resp.form.submit() + assert 'Invalid slug "invalid slug". (line 2)' in resp.pyquery('.error').text() + resp = app.get('/manage/roles/csv-import/') resp = resp.click('Download sample') assert 'name,slug,ou' in resp.text -- 2.39.2