From 661b90c2f5ea495fdd51ea1573780acec91a5859 Mon Sep 17 00:00:00 2001 From: henrikek Date: Sun, 7 Jun 2026 22:01:49 +0200 Subject: [PATCH 1/2] Add all_groups param to ip models --- ESSArch_Core/auth/util.py | 59 +++++++++++++++++----------------- ESSArch_Core/ip/models.py | 4 +-- ESSArch_Core/ip/views.py | 11 ++++--- ESSArch_Core/managers.py | 8 +++-- ESSArch_Core/profiles/utils.py | 4 +-- requirements/base.txt | 12 +++---- requirements/tests.txt | 2 +- 7 files changed, 53 insertions(+), 47 deletions(-) diff --git a/ESSArch_Core/auth/util.py b/ESSArch_Core/auth/util.py index 6713b9879..d30510208 100644 --- a/ESSArch_Core/auth/util.py +++ b/ESSArch_Core/auth/util.py @@ -148,24 +148,22 @@ def get_objects_for_user(user, klass, perms=None, include_no_auth_objs=True, cur ctype = ContentType.objects.get_for_model(queryset.model) handle_pk_field = _handle_pk_field(queryset) - groups_objs_total_queryset = queryset.model.objects.none() groups_objs_values = [] - groups_objs_total_field_pk = 'pk' - if current_organization: - group_objs_model = get_group_objs_model(queryset.model) - - if group_objs_model.objects.is_generic(): - groups_objs_total_queryset = group_objs_model.objects.filter(content_type=ctype) - groups_objs_total_field_pk = 'object_id' - if handle_pk_field is not None and include_no_auth_objs: - groups_objs_total_queryset = groups_objs_total_queryset.annotate( - obj_pk=handle_pk_field(expression=groups_objs_total_field_pk)) - groups_objs_total_field_pk = 'obj_pk' - else: - groups_objs_total_queryset = group_objs_model.objects.all() - groups_objs_total_field_pk = 'content_object_id' + group_objs_model = get_group_objs_model(queryset.model) + if group_objs_model.objects.is_generic(): + groups_objs_total_queryset = group_objs_model.objects.filter(content_type=ctype) + groups_objs_total_field_pk = 'object_id' + if handle_pk_field is not None and include_no_auth_objs: + groups_objs_total_queryset = groups_objs_total_queryset.annotate( + obj_pk=handle_pk_field(expression=groups_objs_total_field_pk)) + groups_objs_total_field_pk = 'obj_pk' + else: + groups_objs_total_queryset = group_objs_model.objects.all() + groups_objs_total_field_pk = 'content_object_id' + + if current_organization: if isinstance(current_organization, Group): org = current_organization else: @@ -185,20 +183,22 @@ def get_objects_for_user(user, klass, perms=None, include_no_auth_objs=True, cur roles__in=roles).values_list('codename', flat=True)) if not len(set(codenames).difference(set(role_perms_codenames))): orgs.append(org_descendant) - # print('orgs: {}'.format(orgs)) - - if group_objs_model.objects.is_generic(): - field_pk = 'object_id' - groups_objs_queryset = groups_objs_total_queryset.filter(group__in=orgs) - if handle_pk_field is not None: - groups_objs_queryset = groups_objs_queryset.annotate(obj_pk=handle_pk_field(expression=field_pk)) - field_pk = 'obj_pk' - else: - field_pk = 'content_object_id' - groups_objs_queryset = groups_objs_total_queryset.filter(group__in=orgs) - groups_objs_values = groups_objs_queryset.values_list(field_pk, flat=True) - # print('groups_objs_queryset: {}'.format(groups_objs_queryset)) + else: + orgs = list(get_user_groups(user)) + + # print('orgs: {}'.format(orgs)) + if group_objs_model.objects.is_generic(): + field_pk = 'object_id' + groups_objs_queryset = groups_objs_total_queryset.filter(group__in=orgs) + if handle_pk_field is not None: + groups_objs_queryset = groups_objs_queryset.annotate(obj_pk=handle_pk_field(expression=field_pk)) + field_pk = 'obj_pk' + else: + field_pk = 'content_object_id' + groups_objs_queryset = groups_objs_total_queryset.filter(group__in=orgs) + groups_objs_values = groups_objs_queryset.values_list(field_pk, flat=True) + # print('groups_objs_queryset: {}'.format(groups_objs_queryset)) # Now we should extract list of pk values for which we would filter # queryset user_model = get_user_obj_perms_model(queryset.model) @@ -282,8 +282,7 @@ def get_objects_for_user(user, klass, perms=None, include_no_auth_objs=True, cur # print('ids_with_no_auth: {}'.format(ids_with_no_auth)) queryset_filters = Q(pk__in=user_obj_perms_values) | Q(pk__in=groups_obj_perms_values) - if current_organization: - queryset_filters = queryset_filters | Q(pk__in=groups_objs_values) + queryset_filters = queryset_filters | Q(pk__in=groups_objs_values) if include_no_auth_objs: queryset_filters = Q(queryset_filters) | Q(pk__in=ids_with_no_auth) # print('queryset_filters: {}'.format(queryset_filters)) diff --git a/ESSArch_Core/ip/models.py b/ESSArch_Core/ip/models.py index 51db0aa9c..cc0cad769 100644 --- a/ESSArch_Core/ip/models.py +++ b/ESSArch_Core/ip/models.py @@ -363,8 +363,8 @@ class InformationPackageManager(OrganizationManager): def get_queryset(self): return InformationPackageQuerySet(self.model, using=self._db).annotate_and_prefetch() - def visible_to_user(self, user): - return self.for_user(user, 'view_informationpackage') + def visible_to_user(self, user, include_all_groups=False): + return self.for_user(user, 'view_informationpackage', include_all_groups=include_all_groups) def migratable(self, export_path='', missing_storage=False, storage_methods=None, policy='', include_inactive_ips=False): diff --git a/ESSArch_Core/ip/views.py b/ESSArch_Core/ip/views.py index 0c8378bd4..ca4890ffe 100644 --- a/ESSArch_Core/ip/views.py +++ b/ESSArch_Core/ip/views.py @@ -491,6 +491,8 @@ def get_related(self, qs, workareas): def get_queryset(self): view_type = self.request.query_params.get('view_type', 'aic') user = self.request.user + all_groups_flag = self.request.query_params.get('all_groups', 'false').lower() == 'true' + print(f'all_groups_flag: {all_groups_flag}') see_all = self.request.user.has_perm('ip.see_all_in_workspaces') workarea_params = {} @@ -505,7 +507,8 @@ def get_queryset(self): workareas = workareas.filter(user=self.request.user) if not self.detail and view_type == 'aic': - simple_inner = InformationPackage.objects.visible_to_user(user).exclude( + simple_inner = InformationPackage.objects.visible_to_user(user, + include_all_groups=all_groups_flag).exclude( Q(state='Ingest Workspace') | Q(Q(workareas__isnull=False) & Q(workareas__read_only=False) & Q(archived=False)) ) @@ -556,7 +559,7 @@ def get_queryset(self): # self.inner_queryset = simple_inner return self.queryset elif not self.detail and view_type == 'ip': - filtered = InformationPackage.objects.visible_to_user(user).exclude( + filtered = InformationPackage.objects.visible_to_user(user, include_all_groups=all_groups_flag).exclude( Q(Q(state='Ingest Workspace') | Q(package_type=InformationPackage.AIC)) | Q(Q(workareas__isnull=False) & Q(workareas__read_only=False) & Q(archived=False)) ) @@ -587,7 +590,7 @@ def get_queryset(self): self.queryset = outer return self.queryset elif not self.detail and view_type == 'flat': - filtered = InformationPackage.objects.visible_to_user(user).exclude( + filtered = InformationPackage.objects.visible_to_user(user, include_all_groups=all_groups_flag).exclude( Q(Q(state='Ingest Workspace') | Q(package_type=InformationPackage.AIC)) | Q(Q(workareas__isnull=False) & Q(workareas__read_only=False) & Q(archived=False)) ) @@ -619,7 +622,7 @@ def get_queryset(self): ).order_by().values('aic') lower_higher = lower_higher.annotate(min_gen=Min('generation'), max_gen=Max('generation')) - qs = InformationPackage.objects.visible_to_user(user).filter( + qs = InformationPackage.objects.visible_to_user(user, include_all_groups=all_groups_flag).filter( Q(Q(workareas=None) | Q(workareas__read_only=True) | Q(archived=True)), ) diff --git a/ESSArch_Core/managers.py b/ESSArch_Core/managers.py index a1b9449d8..6d2990797 100644 --- a/ESSArch_Core/managers.py +++ b/ESSArch_Core/managers.py @@ -12,7 +12,7 @@ class OrganizationManager(models.Manager): def get_queryset(self): return OrganizationQuerySet(self.model, using=self._db) - def for_user(self, user, perms=None): + def for_user(self, user, perms=None, include_all_groups=False): """ Returns objects for which a given ``users`` groups in the ``users`` current organization has all permissions in ``perms`` @@ -22,5 +22,9 @@ def for_user(self, user, perms=None): :param perms: single permission string, or sequence of permission strings which should be checked """ + if include_all_groups: + current_organization = False + else: + current_organization = True - return get_objects_for_user(user, self.model, perms) + return get_objects_for_user(user, self.model, perms, current_organization=current_organization) diff --git a/ESSArch_Core/profiles/utils.py b/ESSArch_Core/profiles/utils.py index abee3cb6e..3bffb9cbc 100644 --- a/ESSArch_Core/profiles/utils.py +++ b/ESSArch_Core/profiles/utils.py @@ -134,7 +134,7 @@ def _get_agents(ip): def _get_sip_altrecordids(ip): sip_altrecordids = {} try: - for k, v in ip.get_profile_data('AIP')['SIP_ALTRECORDIDS'].items(): + for k, v in ip.get_profile_data('aip')['SIP_ALTRECORDIDS'].items(): sip_altrecordids[k] = { '_SIP_ALTRECORDIDS_TYPE': k, '_SIP_ALTRECORDIDS_VALUE': v[0] @@ -230,7 +230,7 @@ def fill_specification_data(data=None, sa=None, ip=None, ignore=None): pass data['_AGENTS'] = (_get_agents, ip,) - data['_SIP_ALTRECORDIDS'] = _get_sip_altrecordids(ip) + data['_SIP_ALTRECORDIDS'] = (_get_sip_altrecordids, ip,) profile_ids = zip( lowercase_profile_types, diff --git a/requirements/base.txt b/requirements/base.txt index 36dcaa501..a46fad86e 100644 --- a/requirements/base.txt +++ b/requirements/base.txt @@ -1,5 +1,5 @@ asgiref==3.9.1 -boto3==1.43.14 +boto3==1.43.24 celery[tblib]==5.6.3 cffi==2.0.0 channels==4.3.2 @@ -7,9 +7,9 @@ channels-redis==4.3.0 chardet==5.2.0 click==8.4.1 cryptography==45.0.7 -daphne==4.2.1 +daphne==4.2.2 dj-rest-auth[with-social]==7.0.1 -django==5.2.14 +django==5.2.15 django-allauth==65.11.1 django-cors-headers==4.9.0 django-countries-plus==2.2.0 @@ -22,7 +22,7 @@ django-languages-plus==2.1.1 django-mptt==0.18.0 django-nested-inline==0.4.6 django-picklefield==3.4.0 -django-redis==6.0.0 +django-redis==7.0.0 django-relativity==0.2.6 djangorestframework==3.17.1 django-json-widget==1.1.1 @@ -46,8 +46,8 @@ natsort==8.4.0 opf-fido==1.6.1 pyfakefs==6.2.0 python-dateutil==2.8.2 -pywin32==311 ; platform_system=='Windows' -redis==7.4.0 +pywin32==312 ; platform_system=='Windows' +redis==7.4.1 regex==2026.5.9 requests==2.34.2 requests-toolbelt==1.0.0 diff --git a/requirements/tests.txt b/requirements/tests.txt index 6e83cb9e6..1dabe1b7d 100644 --- a/requirements/tests.txt +++ b/requirements/tests.txt @@ -1,3 +1,3 @@ -coverage==7.14.0 +coverage==7.14.1 django-test-without-migrations==0.6 selenium==4.25.0 From fd179d71b75d9fdc740e67ae39cfc3c34907ff3f Mon Sep 17 00:00:00 2001 From: henrikek Date: Sun, 7 Jun 2026 22:27:28 +0200 Subject: [PATCH 2/2] Fix tests --- ESSArch_Core/auth/util.py | 2 +- ESSArch_Core/ip/views.py | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/ESSArch_Core/auth/util.py b/ESSArch_Core/auth/util.py index d30510208..5c6ee2d17 100644 --- a/ESSArch_Core/auth/util.py +++ b/ESSArch_Core/auth/util.py @@ -149,6 +149,7 @@ def get_objects_for_user(user, klass, perms=None, include_no_auth_objs=True, cur handle_pk_field = _handle_pk_field(queryset) groups_objs_values = [] + orgs = [] group_objs_model = get_group_objs_model(queryset.model) @@ -171,7 +172,6 @@ def get_objects_for_user(user, klass, perms=None, include_no_auth_objs=True, cur if org is not None: groups_objs_queryset = group_objs_model.objects.none() - orgs = [] ctype = None for org_descendant in org.get_descendants(include_self=True): diff --git a/ESSArch_Core/ip/views.py b/ESSArch_Core/ip/views.py index ca4890ffe..4c9a527ab 100644 --- a/ESSArch_Core/ip/views.py +++ b/ESSArch_Core/ip/views.py @@ -492,7 +492,6 @@ def get_queryset(self): view_type = self.request.query_params.get('view_type', 'aic') user = self.request.user all_groups_flag = self.request.query_params.get('all_groups', 'false').lower() == 'true' - print(f'all_groups_flag: {all_groups_flag}') see_all = self.request.user.has_perm('ip.see_all_in_workspaces') workarea_params = {}