diff options
author | Étienne Loks <etienne.loks@iggdrasil.net> | 2018-04-19 18:22:21 +0200 |
---|---|---|
committer | Étienne Loks <etienne.loks@iggdrasil.net> | 2018-06-12 08:43:31 +0200 |
commit | 8f73502c249f8b190a7638dfdd94535f987aeefc (patch) | |
tree | bc1e1f4349a10489a489a5b52d515c196d20fda9 /archaeological_operations | |
parent | 149adde9e905380bfc6d633dd379be323a098dd4 (diff) | |
download | Ishtar-8f73502c249f8b190a7638dfdd94535f987aeefc.tar.bz2 Ishtar-8f73502c249f8b190a7638dfdd94535f987aeefc.zip |
Manage own permissions with areas for operations
Diffstat (limited to 'archaeological_operations')
-rw-r--r-- | archaeological_operations/models.py | 9 | ||||
-rw-r--r-- | archaeological_operations/tests.py | 105 | ||||
-rw-r--r-- | archaeological_operations/views.py | 14 |
3 files changed, 121 insertions, 7 deletions
diff --git a/archaeological_operations/models.py b/archaeological_operations/models.py index c342fb2a4..9655ca387 100644 --- a/archaeological_operations/models.py +++ b/archaeological_operations/models.py @@ -698,11 +698,18 @@ class Operation(ClosedItem, BaseHistorizedItem, ImageModel, OwnPerms, @classmethod def get_query_owns(cls, ishtaruser): + profile = ishtaruser.current_profile + town_ids = [] + if profile: + town_ids = [town['pk'] + for town in profile.query_towns.values('pk').all()] return ( Q(in_charge=ishtaruser.person) | Q(scientist=ishtaruser.person) | Q(collaborators__pk=ishtaruser.person.pk) | - Q(history_creator=ishtaruser.user_ptr)) & Q(end_date__isnull=True) + Q(history_creator=ishtaruser.user_ptr) | + Q(towns__pk__in=town_ids) + ) & Q(end_date__isnull=True) def is_active(self): return not bool(self.end_date) diff --git a/archaeological_operations/tests.py b/archaeological_operations/tests.py index 7cfa83435..299ed49f8 100644 --- a/archaeological_operations/tests.py +++ b/archaeological_operations/tests.py @@ -41,7 +41,8 @@ from ishtar_common.models import OrganizationType, Organization, ItemKey, \ ImporterType, IshtarUser, TargetKey, ImporterModel, IshtarSiteProfile, \ Town, ImporterColumn, Person, Author, SourceType, AuthorType, \ DocumentTemplate, PersonType, TargetKeyGroup, JsonDataField, \ - JsonDataSection, ImportTarget, FormaterType, CustomForm, ExcludedField + JsonDataSection, ImportTarget, FormaterType, CustomForm, ExcludedField, \ + UserProfile, ProfileType, Area from archaeological_files.models import File, FileType from archaeological_context_records.models import Unit, ContextRecord @@ -1372,6 +1373,20 @@ class OperationSearchTest(TestCase, OperationInitTest): self.alt_username, self.alt_password, self.alt_user = create_user() self.alt_user.user_permissions.add(Permission.objects.get( codename='view_own_operation')) + self.alt_user.user_permissions.add(Permission.objects.get( + codename='change_own_operation')) + self.alt_username2, self.alt_password2, self.alt_user2 = create_user( + username='luke', password='iamyourfather' + ) + profile = UserProfile.objects.create( + profile_type=ProfileType.objects.get(txt_idx='collaborator'), + person=self.alt_user2.ishtaruser.person + ) + town = Town.objects.create(name='Tatouine', numero_insee='66000') + area = Area.objects.create(label='Galaxie', txt_idx='galaxie') + area.towns.add(town) + profile.areas.add(area) + self.orgas = self.create_orgas(self.user) self.operations = self.create_operation(self.user, self.orgas[0]) self.operations += self.create_operation(self.alt_user, self.orgas[0]) @@ -1407,7 +1422,6 @@ class OperationSearchTest(TestCase, OperationInitTest): result = json.loads(response.content) self.assertEqual(result['recordsTotal'], 1) - def create_relations(self): rel1 = models.RelationType.objects.create( symmetrical=True, label='Include', txt_idx='include') @@ -1504,19 +1518,102 @@ class OperationSearchTest(TestCase, OperationInitTest): self.assertEqual(response.status_code, 200) self.assertEqual(json.loads(response.content)['recordsTotal'], 1) - def testOwnSearch(self): + +class OperationPermissionTest(TestCase, OperationInitTest): + fixtures = FILE_FIXTURES + + def setUp(self): + IshtarSiteProfile.objects.get_or_create( + slug='default', active=True) + self.username, self.password, self.user = create_superuser() + self.alt_username, self.alt_password, self.alt_user = create_user() + self.alt_user.user_permissions.add(Permission.objects.get( + codename='view_own_operation')) + self.alt_user.user_permissions.add(Permission.objects.get( + codename='change_own_operation')) + self.alt_username2, self.alt_password2, self.alt_user2 = create_user( + username='luke', password='iamyourfather' + ) + profile = UserProfile.objects.create( + profile_type=ProfileType.objects.get(txt_idx='collaborator'), + person=self.alt_user2.ishtaruser.person, + current=True + ) + town = Town.objects.create(name='Tatouine', numero_insee='66000') + area = Area.objects.create(label='Galaxie', txt_idx='galaxie') + area.towns.add(town) + profile.areas.add(area) + + self.orgas = self.create_orgas(self.user) + self.operations = self.create_operation(self.user, self.orgas[0]) + self.operations += self.create_operation(self.alt_user, self.orgas[0]) + self.operations[1].towns.add(town) + self.item = self.operations[0] + + def test_own_search(self): + # no result when no authentification c = Client() response = c.get(reverse('get-operation'), {'year': '2010'}) - # no result when no authentification self.assertTrue(not json.loads(response.content)) + + # possession + c = Client() c.login(username=self.alt_username, password=self.alt_password) response = c.get(reverse('get-operation'), {'year': '2010'}) # only one "own" operation available + self.assertTrue(json.loads(response.content)) + self.assertTrue(json.loads(response.content)['recordsTotal'] == 1) + response = c.get(reverse('get-operation'), + {'operator': self.orgas[0].pk}) + self.assertTrue(json.loads(response.content)['recordsTotal'] == 1) + + # area filter + c = Client() + c.login(username=self.alt_username2, password=self.alt_password2) + response = c.get(reverse('get-operation'), {'year': '2010'}) + # only one "own" operation available + self.assertTrue(json.loads(response.content)) self.assertTrue(json.loads(response.content)['recordsTotal'] == 1) response = c.get(reverse('get-operation'), {'operator': self.orgas[0].pk}) self.assertTrue(json.loads(response.content)['recordsTotal'] == 1) + def test_own_modify(self): + operation_pk1 = self.operations[0].pk + operation_pk2 = self.operations[1].pk + + # no result when no authentification + c = Client() + response = c.get(reverse('operation_modify', args=[operation_pk2])) + self.assertRedirects(response, "/") + + modif_url = '/operation_modification/general-operation_modification' + + # possession + c = Client() + c.login(username=self.alt_username, password=self.alt_password) + response = c.get(reverse('operation_modify', args=[operation_pk2]), + follow=True) + self.assertRedirects(response, modif_url) + response = c.get(modif_url) + self.assertEqual(response.status_code, 200) + response = c.get(reverse('operation_modify', args=[operation_pk1]), + follow=True) + self.assertRedirects(response, "/") + + # area filter + c = Client() + c.login(username=self.alt_username2, password=self.alt_password2) + response = c.get(reverse('operation_modify', args=[operation_pk2]), + follow=True) + self.assertRedirects(response, modif_url) + response = c.get(modif_url) + self.assertEqual(response.status_code, 200) + response = c.get(reverse('operation_modify', args=[operation_pk1]), + follow=True) + self.assertRedirects(response, "/") + + class DashboardTest(TestCase, OperationInitTest): fixtures = FILE_FIXTURES diff --git a/archaeological_operations/views.py b/archaeological_operations/views.py index fcd6c3252..e7e624c05 100644 --- a/archaeological_operations/views.py +++ b/archaeological_operations/views.py @@ -22,7 +22,7 @@ import json from django.conf import settings from django.core.urlresolvers import reverse from django.db.models import Q -from django.http import HttpResponse +from django.http import HttpResponse, HttpResponseRedirect from django.shortcuts import render, redirect from django.utils.translation import ugettext_lazy as _, pgettext_lazy @@ -58,6 +58,8 @@ from archaeological_operations.wizards import has_associated_file, \ AdministrativeActDeletionWizard, SiteWizard, SiteModificationWizard, \ SiteDeletionWizard +from ishtar_common.utils import put_session_message + def autocomplete_patriarche(request): if (not request.user.has_perm('ishtar_common.view_operation', @@ -303,7 +305,15 @@ operation_modification_wizard = OperationModificationWizard.as_view( def operation_modify(request, pk): - operation_modification_wizard(request) + try: + operation_modification_wizard(request) + except IndexError: # no step available + put_session_message( + request.session.session_key, + _(u"You don't have sufficient permissions to do this action."), + 'warning' + ) + return HttpResponseRedirect("/") OperationModificationWizard.session_set_value( request, 'selec-operation_modification', 'pk', pk, reset=True) return redirect(reverse('operation_modification', |