def test_get_objects_for_user_with_group_permissions(self): group_perm = Permission.objects.create(codename='group_perm', content_type=self.ctype) perms = {'group': [get_permission_name(group_perm, self.uppsala_ip)]} self.uppsala.assign_object(self.uppsala_ip, custom_permissions=perms) six.assertCountEqual(self, list(get_objects_for_user(self.user_uppsala, InformationPackage, ['foo'])), []) six.assertCountEqual(self, list(get_objects_for_user(self.user_uppsala, InformationPackage, ['group_perm'])), [self.uppsala_ip])
def test_get_objects_for_user_with_user_permissions(self): user_perm = Permission.objects.create(codename='user_perm', content_type=self.ctype) perm = get_permission_name(user_perm, self.uppsala_ip) assign_perm(perm, self.user_uppsala, self.uppsala_ip) six.assertCountEqual(self, list(get_objects_for_user(self.user_uppsala, InformationPackage, ['foo'])), []) six.assertCountEqual(self, list(get_objects_for_user(self.user_uppsala, InformationPackage, ['user_perm'])), [self.uppsala_ip])
def test_objects_added_to_user(self): ip = InformationPackage.objects.create() perm_name = get_permission_name('view_informationpackage', ip) assign_perm(perm_name, self.user, ip) qs = InformationPackage.objects.all() self.assertFalse(get_objects_for_user(self.user, qs, []).exists()) self.assertEqual(get_objects_for_user(self.user, qs, ['view_informationpackage']).get(), ip)
def test_objects_added_to_group_with_role(self): ip = InformationPackage.objects.create() perm = Permission.objects.get(codename='view_informationpackage') role = GroupMemberRole.objects.create(codename='ip_viewer') role.permissions.add(perm) group = Group.objects.create(group_type=self.org_group_type) group.add_member(self.member, roles=[role]) group.add_object(ip) qs = InformationPackage.objects.all() self.assertFalse(get_objects_for_user(self.user, qs, ['non_existing_perm']).exists()) self.assertTrue(get_objects_for_user(self.user, qs, []).exists()) self.assertTrue(get_objects_for_user(self.user, qs, ['view_informationpackage']).exists())
def test_all_objects_available_for_superuser(self): ip = InformationPackage.objects.create() self.user.is_superuser = True self.user.save() qs = InformationPackage.objects.all() self.assertEqual(get_objects_for_user(self.user, qs, ['view_informationpackage']).get(), ip)
def for_user(self, user, perms): """ Returns objects for which a given ``users`` groups in the ``users`` current organization has all permissions in ``perms`` :param user: ``User`` instance for which objects would be returned :param perms: single permission string, or sequence of permission strings which should be checked """ return get_objects_for_user(user, self.model, perms)
def test_objects_added_to_child_group(self): ip = InformationPackage.objects.create() parent = Group.objects.create(name='parent') parent.add_member(self.member) group = Group.objects.create(parent=parent) perm_name = get_permission_name('view_informationpackage', ip) assign_perm(perm_name, parent.django_group, ip) qs = InformationPackage.objects.all() self.assertEqual(get_objects_for_user(self.user, qs, ['view_informationpackage']).get(), ip)
def test_multiple_organizations(self): ip1 = InformationPackage.objects.create() ip2 = InformationPackage.objects.create() perm = Permission.objects.get(codename='view_informationpackage') role = GroupMemberRole.objects.create(codename='ip_viewer') role.permissions.add(perm) group1 = Group.objects.create(name='group1', group_type=self.org_group_type) group1.add_member(self.member, roles=[role]) group1.add_object(ip1) group2 = Group.objects.create(name='group2', group_type=self.org_group_type) group2.add_member(self.member, roles=[role]) group2.add_object(ip2) qs = InformationPackage.objects.all() self.assertFalse(get_objects_for_user(self.user, qs, ['non_existing_perm']).exists()) self.assertEqual(get_objects_for_user(self.user, qs, []).count(), 1) self.assertEqual(get_objects_for_user(self.user, qs, ['view_informationpackage']).count(), 1) # change organization self.user.user_profile.current_organization = group2 self.user.user_profile.save() self.assertFalse(get_objects_for_user(self.user, qs, ['non_existing_perm']).exists()) self.assertEqual(get_objects_for_user(self.user, qs, []).count(), 1) self.assertEqual(get_objects_for_user(self.user, qs, ['view_informationpackage']).count(), 1)
def search(self): """ We override this to add filters on archive, start and end date We have to manually filter archives since we want to filter against a script field representing the archive which is the `archive` field on components and `_id` on archives. """ organization_archives = get_objects_for_user(self.user, TagVersion.objects.filter(elastic_index='archive'), []) organization_archives = list(organization_archives.values_list('pk', flat=True)) s = super().search() s = s.source(exclude=["attachment.content"]) s = s.filter('term', current_version=True) s = s.query(Q('bool', should=[ # no archive Q('bool', must=[Q('bool', **{'must_not': {'exists': {'field': 'archive'}}}), Q('bool', **{'must_not': {'term': {'_index': 'archive-*'}}})]), # in archive connected to organization Q('terms', archive=organization_archives), # is archive connected to organization Q('terms', _id=organization_archives) ])) if self.personal_identification_number not in EMPTY_VALUES: s = s.filter('term', personal_identification_numbers=self.personal_identification_number) if self.start_date not in EMPTY_VALUES: s = s.filter('range', end_date={'gte': self.start_date}) if self.end_date not in EMPTY_VALUES: s = s.filter('range', start_date={'lte': self.end_date}) if self.archive is not None: s = s.query(Q('bool', must=Q('script', script={ 'source': ( "(doc.containsKey('archive') && doc['archive'].value==params.archive)" "|| doc['_id'].value==params.archive" ), 'params': {'archive': self.archive}, }))) for filter_k, filter_v in self.query_params_filter.items(): if filter_v not in EMPTY_VALUES: s = s.query('match', **{filter_k: filter_v}) return s
def test_get_objects_for_user(self): self.assertCountEqual( list( get_objects_for_user(self.user_uppsala, InformationPackage, [])), [self.uppsala_ip]) self.assertCountEqual( list( get_objects_for_user(self.user_uppsala, InformationPackage, 'foo')), []) self.assertCountEqual( list( get_objects_for_user(self.user_uppsala, InformationPackage, ['foo', self.expected_user_perms[0]])), []) self.assertCountEqual( list( get_objects_for_user(self.user_uppsala, InformationPackage, self.expected_user_perms[0])), [self.uppsala_ip]) self.assertCountEqual( list( get_objects_for_user(self.user_uppsala, InformationPackage, self.expected_user_perms)), [self.uppsala_ip])
def get_tag_object(self, qs=None): # Perform the lookup filtering. lookup_url_kwarg = self.lookup_url_kwarg or self.lookup_field assert lookup_url_kwarg in self.kwargs, ( 'Expected view %s to be called with a URL keyword argument ' 'named "%s". Fix your URL conf, or set the `.lookup_field` ' 'attribute on the view correctly.' % (self.__class__.__name__, lookup_url_kwarg)) if qs is None: qs = TagVersion.objects.for_user(self.request.user, []) # Search for object in index by id id = self.kwargs[lookup_url_kwarg] prefetched_structures = TagStructure.objects.select_related( 'tag__current_version', 'parent__tag__current_version') tag_version = qs.select_related('tag').prefetch_related( Prefetch('tag__structures', prefetched_structures)) obj = get_object_or_404(tag_version, pk=id) root = obj.get_root() user_archives = get_objects_for_user( self.request.user, tag_version.filter(elastic_index='archive'), []) if root is not None: root_in_archives = user_archives.filter(pk=str(root.pk)).exists() if not root_in_archives: obj_ctype = ContentType.objects.get_for_model(root) in_any_groups = GroupGenericObjects.objects.filter( object_id=str(root.pk), content_type=obj_ctype, ).exists() if in_any_groups: raise exceptions.NotFound logger.info(f"User '{self.request.user}' accessing tag object '{obj}'") return obj
def get_tag_object(self, qs=None): # Perform the lookup filtering. lookup_url_kwarg = self.lookup_url_kwarg or self.lookup_field assert lookup_url_kwarg in self.kwargs, ( 'Expected view %s to be called with a URL keyword argument ' 'named "%s". Fix your URL conf, or set the `.lookup_field` ' 'attribute on the view correctly.' % (self.__class__.__name__, lookup_url_kwarg) ) if qs is None: qs = TagVersion.objects.all() # Search for object in index by id id = self.kwargs[lookup_url_kwarg] prefetched_structures = TagStructure.objects.select_related( 'tag__current_version', 'parent__tag__current_version' ) tag_version = qs.select_related('tag').prefetch_related(Prefetch('tag__structures', prefetched_structures)) obj = get_object_or_404(tag_version, pk=id) user_archives = get_objects_for_user( self.request.user, tag_version.filter(elastic_index='archive'), [] ).values_list('pk', flat=True) root = obj.get_root() if root is not None and root.pk not in user_archives: obj_ctype = ContentType.objects.get_for_model(root) in_any_groups = GroupGenericObjects.objects.filter(object_id=str(root.pk), content_type=obj_ctype).exists() if in_any_groups: raise exceptions.NotFound logger.info(f"User '{self.request.user}' accessing tag object '{obj}'") return obj
def get_queryset(self): user = self.request.user qs = super().get_queryset() public = qs.filter(public=True) local = get_objects_for_user(user, qs.filter(public=False), []) return public | local
def test_get_objects_for_user_with_multiple_roles(self): admin_uppsala_user_sweden = User.objects.create( username="******") self.uppsala.add_member(admin_uppsala_user_sweden.essauth_member, roles=[self.admin_role]) self.sweden.add_member(admin_uppsala_user_sweden.essauth_member, roles=[self.user_role]) admin_uppsala_user_sweden.user_profile.current_organization = self.uppsala admin_uppsala_user_sweden.user_profile.save() self.assertCountEqual( list( get_objects_for_user(admin_uppsala_user_sweden, InformationPackage, [])), [self.uppsala_ip]) self.assertCountEqual( list( get_objects_for_user(admin_uppsala_user_sweden, InformationPackage, 'foo')), []) self.assertCountEqual( list( get_objects_for_user(admin_uppsala_user_sweden, InformationPackage, ['foo'] + self.expected_user_perms)), []) self.assertCountEqual( list( get_objects_for_user(admin_uppsala_user_sweden, InformationPackage, self.expected_user_perms)), [self.uppsala_ip]) self.assertCountEqual( list( get_objects_for_user(admin_uppsala_user_sweden, InformationPackage, self.expected_admin_perms)), [self.uppsala_ip]) self.assertCountEqual( list( get_objects_for_user( admin_uppsala_user_sweden, InformationPackage, self.expected_user_perms + self.expected_admin_perms)), [self.uppsala_ip]) admin_uppsala_user_sweden.user_profile.current_organization = self.sweden admin_uppsala_user_sweden.user_profile.save() self.assertCountEqual( list( get_objects_for_user(admin_uppsala_user_sweden, InformationPackage, [])), []) self.assertCountEqual( list( get_objects_for_user(admin_uppsala_user_sweden, InformationPackage, 'foo')), []) self.assertCountEqual( list( get_objects_for_user(admin_uppsala_user_sweden, InformationPackage, ['foo'] + self.expected_user_perms)), []) self.assertCountEqual( list( get_objects_for_user(admin_uppsala_user_sweden, InformationPackage, self.expected_user_perms)), []) self.assertCountEqual( list( get_objects_for_user(admin_uppsala_user_sweden, InformationPackage, self.expected_admin_perms)), []) self.assertCountEqual( list( get_objects_for_user( admin_uppsala_user_sweden, InformationPackage, self.expected_user_perms + self.expected_admin_perms)), [])
def search(self): """ We override this to add filters on archive, start and end date We have to manually filter archives since we want to filter against a script field representing the archive which is the `archive` field on components and `_id` on archives. """ organization_archives = get_objects_for_user( self.user, TagVersion.objects.filter(elastic_index='archive'), []) organization_archives = list( organization_archives.values_list('pk', flat=True)) s = super().search() s = s.source(exclude=["attachment.content"]) s = s.filter('term', current_version=True) s = s.query( Q( 'bool', should=[ # no archive Q('bool', must=[ Q('bool', **{'must_not': { 'exists': { 'field': 'archive' } }}), Q('bool', **{'must_not': { 'term': { '_index': 'archive-*' } }}) ]), # in archive connected to organization Q('terms', archive=organization_archives), # is archive connected to organization Q('terms', _id=organization_archives) ])) if self.personal_identification_number not in EMPTY_VALUES: s = s.filter('term', personal_identification_numbers=self. personal_identification_number) if self.start_date not in EMPTY_VALUES: s = s.filter('range', end_date={'gte': self.start_date}) if self.end_date not in EMPTY_VALUES: s = s.filter('range', start_date={'lte': self.end_date}) if self.archive is not None: s = s.query( Q('bool', must=Q( 'script', script={ 'source': ("(doc.containsKey('archive') && doc['archive'].value==params.archive)" "|| doc['_id'].value==params.archive"), 'params': { 'archive': self.archive }, }))) for filter_k, filter_v in self.query_params_filter.items(): if filter_v not in EMPTY_VALUES: s = s.query('match', **{filter_k: filter_v}) return s
def test_objects_without_any_permissions_available_for_all(self): InformationPackage.objects.create() qs = InformationPackage.objects.all() self.assertTrue(get_objects_for_user(self.user, qs, []).exists())
def test_no_objects_for_user_without_permission(self): InformationPackage.objects.create() qs = InformationPackage.objects.all() self.assertFalse(get_objects_for_user(self.user, qs, []).exists())
def test_no_objects_created(self): qs = InformationPackage.objects.all() self.assertFalse(get_objects_for_user(self.user, qs, []).exists())
def for_user(self, user, perms): return get_objects_for_user(user, self, perms)