diff --git a/CHANGELOG.md b/CHANGELOG.md index 429b2c47..c43067fb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,7 +8,7 @@ ### Changed -- nothing changed +- Change staff to manager in CRUD_LEVELS ### Removed diff --git a/concrete_datastore/concrete/constants.py b/concrete_datastore/concrete/constants.py index 884b2566..d5b646cf 100644 --- a/concrete_datastore/concrete/constants.py +++ b/concrete_datastore/concrete/constants.py @@ -39,7 +39,7 @@ }, } -CRUD_LEVEL = ["anonymous", "authenticated", "admin", "superuser", "staff"] +CRUD_LEVEL = ["anonymous", "authenticated", "admin", "superuser", "manager"] LIST_USER_LEVEL = ["blocked", "simpleuser", "manager", "admin", "superuser"] diff --git a/concrete_datastore/concrete/models.py b/concrete_datastore/concrete/models.py index d6b9e38f..2450af93 100644 --- a/concrete_datastore/concrete/models.py +++ b/concrete_datastore/concrete/models.py @@ -697,6 +697,15 @@ def get_divider_notification_fields(model): } +def get_minimum_level(meta_model, prop_name, default_value): + level = meta_model.get_property( + prop_name=prop_name, default_value=default_value + ) + if level not in CRUD_LEVEL: + return default_value + return level + + def make_django_model(meta_model, divider): class Meta: verbose_name = _(meta_model.get_verbose_name()) @@ -716,22 +725,28 @@ class Meta: ): raise ValueError('Unknown modelisation format') - creation_level = meta_model.get_property( - prop_name='m_creation_minimum_level', default_value='authenticated' + creation_level = get_minimum_level( + meta_model=meta_model, + prop_name='m_creation_minimum_level', + default_value='authenticated', ) - retrieve_level = meta_model.get_property( - prop_name='m_retrieve_minimum_level', default_value='authenticated' + retrieve_level = get_minimum_level( + meta_model=meta_model, + prop_name='m_retrieve_minimum_level', + default_value='authenticated', ) - if retrieve_level not in CRUD_LEVEL: - retrieve_level = "authenticated" - update_level = meta_model.get_property( - prop_name='m_update_minimum_level', default_value='authenticated' + update_level = get_minimum_level( + meta_model=meta_model, + prop_name='m_update_minimum_level', + default_value='authenticated', ) - delete_level = meta_model.get_property( - prop_name='m_delete_minimum_level', default_value='superuser' + delete_level = get_minimum_level( + meta_model=meta_model, + prop_name='m_delete_minimum_level', + default_value='superuser', ) attrs = { diff --git a/tests/migrations/0006_publicmodelmanagerretrieve.py b/tests/migrations/0006_publicmodelmanagerretrieve.py new file mode 100644 index 00000000..2cf8bc17 --- /dev/null +++ b/tests/migrations/0006_publicmodelmanagerretrieve.py @@ -0,0 +1,38 @@ +# Generated by Django 2.2.15 on 2021-01-13 10:55 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion +import uuid + + +class Migration(migrations.Migration): + + dependencies = [ + ('concrete', '0005_auto_20200526_1210'), + ] + + operations = [ + migrations.CreateModel( + name='PublicModelManagerRetrieve', + fields=[ + ('uid', models.UUIDField(default=uuid.uuid4, primary_key=True, serialize=False)), + ('modification_date', models.DateTimeField(auto_now=True)), + ('creation_date', models.DateTimeField(auto_now_add=True)), + ('public', models.BooleanField(default=True)), + ('name', models.CharField(default='', max_length=255)), + ('additional_filtering', models.BooleanField(default=False)), + ('can_admin_groups', models.ManyToManyField(blank=True, related_name='group_administrable_publicmodelmanagerretrieves', to='concrete.Group')), + ('can_admin_users', models.ManyToManyField(blank=True, related_name='administrable_publicmodelmanagerretrieves', to=settings.AUTH_USER_MODEL)), + ('can_view_groups', models.ManyToManyField(blank=True, related_name='group_viewable_publicmodelmanagerretrieves', to='concrete.Group')), + ('can_view_users', models.ManyToManyField(blank=True, related_name='viewable_publicmodelmanagerretrieves', to=settings.AUTH_USER_MODEL)), + ('created_by', models.ForeignKey(null=True, on_delete=django.db.models.deletion.PROTECT, related_name='owned_publicmodelmanagerretrieves', to=settings.AUTH_USER_MODEL)), + ('defaultdivider', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='divider_publicmodelmanagerretrieves', to='concrete.DefaultDivider')), + ], + options={ + 'verbose_name': 'PublicModelManagerRetrieve', + 'verbose_name_plural': 'PublicModelManagerRetrieves', + 'ordering': ('-modification_date', '-creation_date'), + }, + ), + ] diff --git a/tests/tests_api_v1_1/test_api_v1_1_permission.py b/tests/tests_api_v1_1/test_api_v1_1_permission.py index 569414d5..1513560a 100644 --- a/tests/tests_api_v1_1/test_api_v1_1_permission.py +++ b/tests/tests_api_v1_1/test_api_v1_1_permission.py @@ -1,10 +1,47 @@ # coding: utf-8 from rest_framework.test import APITestCase from rest_framework import status -from concrete_datastore.concrete.models import User, UserConfirmation, Project +from concrete_datastore.concrete.models import ( + User, + UserConfirmation, + Project, + PublicModelManagerRetrieve, +) from django.test import override_settings +@override_settings(DEBUG=True) +class MinimumLevelCrossPublicTestCase(APITestCase): + def setUp(self): + # User A + self.user = User.objects.create_user('user_a@netsach.org') + self.user.set_password('userA') + self.user.save() + UserConfirmation.objects.create(user=self.user, confirmed=True).save() + url_login = '/api/v1.1/auth/login/' + resp = self.client.post( + url_login, {"email": "user_a@netsach.org", "password": "userA"} + ) + self.token_user_a = resp.data['token'] + + def test_public_minimum_retrieve_manager(self): + self.assertEqual(self.user.level, 'simpleuser') + url = '/api/v1.1/public-model-manager-retrieve/' + obj = PublicModelManagerRetrieve.objects.create(name='test') + self.assertEqual(PublicModelManagerRetrieve.objects.count(), 1) + #: List + resp = self.client.get( + url, HTTP_AUTHORIZATION=f'Token {self.token_user_a}' + ) + self.assertEqual(resp.status_code, status.HTTP_403_FORBIDDEN) + + #: Retrieve + resp = self.client.get( + f'{url}{obj.uid}/', HTTP_AUTHORIZATION=f'Token {self.token_user_a}' + ) + self.assertEqual(resp.status_code, status.HTTP_403_FORBIDDEN) + + @override_settings(DEBUG=True) class PermissionTestCase(APITestCase): def setUp(self): diff --git a/tests/unittest_settings.py b/tests/unittest_settings.py index b7999539..1863af2c 100644 --- a/tests/unittest_settings.py +++ b/tests/unittest_settings.py @@ -180,6 +180,41 @@ "ext.m_unicode": "None", "ext.m_export_fields": [], }, + { + "ext.m_search_fields": ["name"], + "ext.m_filter_fields": ["name"], + "ext.m_list_display": ["name"], + "std.verbose_name": "PublicModelManagerRetrieve", + "ext.m_unique_together": [], + "ext.m_creation_minimum_level": "admin", + "ext.m_is_default_public": True, + "std.description": "", + "std.fields": [ + { + "std.specifier": "Field", + "ext.f_args": { + "default": "", + "null": False, + "blank": False, + "max_length": 255, + }, + "std.verbose_name": "name", + "ext.force_nested": False, + "std.name": "name", + "std.type": "data", + "std.description": "name", + "ext.f_type": "CharField", + } + ], + "std.specifier": "Model", + "std.verbose_name_plural": "PublicModelManagerRetrieves", + "ext.m_delete_minimum_level": "superuser", + "std.name": "PublicModelManagerRetrieve", + "ext.m_retrieve_minimum_level": "manager", + "ext.m_update_minimum_level": "manager", + "ext.m_unicode": "None", + "ext.m_export_fields": [], + }, { "std.name": "Group", "std.specifier": "Model",