Projet

Général

Profil

0001-data_transfer-validate-uniqueness-of-roles-41342.patch

Benjamin Dauvergne, 09 avril 2020 17:04

Télécharger (4,51 ko)

Voir les différences:

Subject: [PATCH 1/2] data_transfer: validate uniqueness of roles (#41342)

 src/authentic2/data_transfer.py | 24 ++++++++++++++++++++++++
 src/authentic2/manager/views.py | 12 ++++++++----
 tests/test_data_transfer.py     | 17 +++++++++++++++++
 3 files changed, 49 insertions(+), 4 deletions(-)
src/authentic2/data_transfer.py
14 14
# You should have received a copy of the GNU Affero General Public License
15 15
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
16 16

  
17
from django.core.exceptions import ValidationError, NON_FIELD_ERRORS
17 18
from django.contrib.contenttypes.models import ContentType
19
from django.utils.translation import ugettext_lazy as _
18 20

  
19 21
from django_rbac.models import Operation
20 22
from django_rbac.utils import (
21 23
    get_ou_model, get_role_model, get_role_parenting_model, get_permission_model)
24

  
25
from authentic2.decorators import errorcollector
22 26
from authentic2.a2_rbac.models import RoleAttribute
23 27

  
24 28

  
25 29
def update_model(obj, d):
26 30
    for attr, value in d.items():
27 31
        setattr(obj, attr, value)
32
    errors = {}
33
    with errorcollector(errors):
34
        if hasattr(obj, 'validate'):
35
            obj.validate()
36

  
37
    with errorcollector(errors):
38
        if hasattr(obj, 'validate_unique'):
39
            obj.validate_unique()
40
    if errors:
41
        errorlist = []
42
        for key, messages in list(errors.items()):
43
            if key == NON_FIELD_ERRORS:
44
                errorlist.extend(messages)
45
            else:
46
                value = getattr(obj, key)
47
                for error in messages:
48
                    for message in error if isinstance(error, ValidationError) else [error]:
49
                        errorlist.append(_(u'%s %s="%s": %s') % (obj.__class__._meta.verbose_name, key, value, message))
50
                del errors[key]
51
        raise DataImportError(ValidationError(errorlist))
28 52
    obj.save()
29 53

  
30 54

  
src/authentic2/manager/views.py
17 17
import json
18 18
import inspect
19 19

  
20
from django.core.exceptions import PermissionDenied
20
from django.core.exceptions import PermissionDenied, ValidationError
21 21
from django.db import transaction
22 22
from django.views.generic.base import ContextMixin
23 23
from django.views.generic import (FormView, UpdateView, CreateView, DeleteView, TemplateView,
......
708 708

  
709 709
    def form_valid(self, form):
710 710
        try:
711
            json_site = json.loads(force_text(
712
                    self.request.FILES['site_json'].read()))
711
            json_site = json.loads(
712
                force_text(self.request.FILES['site_json'].read()))
713 713
        except ValueError:
714 714
            form.add_error('site_json', _('File is not in the expected JSON format.'))
715 715
            return self.form_invalid(form)
......
718 718
            with transaction.atomic():
719 719
                import_site(json_site, ImportContext())
720 720
        except DataImportError as e:
721
            form.add_error('site_json', six.text_type(e))
721
            if e.args and isinstance(e.args[0], ValidationError):
722
                e = e.args[0]
723
            else:
724
                e = six.text_type(e)
725
            form.add_error('site_json', e)
722 726
            return self.form_invalid(form)
723 727

  
724 728
        return super(SiteImportView, self).form_valid(form)
tests/test_data_transfer.py
540 540
    d = export_site(ExportContext(export_ous=False))
541 541
    assert 'ous' not in d
542 542

  
543

  
544
def test_role_validate_unique(db):
545
    ou = OU.objects.create(name='ou', slug='ou')
546
    Role.objects.create(name='role1', slug='role1', ou=ou)
547
    Role.objects.create(name='role2', slug='role2', ou=ou)
548

  
549
    data = {
550
        'roles': [
551
            {
552
                'name': 'role1',
553
                'slug': 'role2',
554
                'ou': {'slug': 'ou'},
555
            }
556
        ]
557
    }
558
    with pytest.raises(DataImportError, match=r'.*zwefew.*') as exc_info:
559
        import_site(data)
543
-