From dc02e517db65d0bada2b24825c62069a2cc81630 Mon Sep 17 00:00:00 2001 From: Ostap Zherebetskyi Date: Fri, 27 Mar 2026 10:56:31 +0200 Subject: [PATCH 1/3] Add get_sso_institutions method to InstitutionManager and update InstitutionList queryset filtering --- api/institutions/views.py | 4 +++- osf/models/institution.py | 3 +++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/api/institutions/views.py b/api/institutions/views.py index b63b5efaa8d..6272cfbe59c 100644 --- a/api/institutions/views.py +++ b/api/institutions/views.py @@ -88,7 +88,9 @@ class InstitutionList(JSONAPIBaseView, generics.ListAPIView, ListFilterMixin): ordering = ('name',) def get_default_queryset(self): - return Institution.objects.filter(_id__isnull=False, is_deleted=False) + if 'filter[sso_availability]' in self.request.query_params: + return Institution.objects.filter(_id__isnull=False, is_deleted=False) + return Institution.objects.get_sso_institutions().filter(_id__isnull=False, is_deleted=False) # overrides ListAPIView def get_queryset(self): diff --git a/osf/models/institution.py b/osf/models/institution.py index 4ebb8752217..c60563bac63 100644 --- a/osf/models/institution.py +++ b/osf/models/institution.py @@ -63,6 +63,9 @@ def get_queryset(self): def get_all_institutions(self): return super().get_queryset() + def get_sso_institutions(self): + return super().get_queryset().filter(deactivated__isnull=True, sso_availability__in=[SSOAvailability.PUBLIC.value, SSOAvailability.UNAVAILABLE.value]) + class Institution(DirtyFieldsMixin, Loggable, ObjectIDMixin, BaseModel, GuardianMixin): objects = InstitutionManager() From 51ed7711179b9d3dfe750d23ec3cf1a9791d8081 Mon Sep 17 00:00:00 2001 From: Ostap Zherebetskyi Date: Fri, 27 Mar 2026 11:24:19 +0200 Subject: [PATCH 2/3] Add test for default filter excluding institutions with hidden SSO availability --- .../views/test_institution_list.py | 21 +++++++++++++++++++ osf_tests/factories.py | 2 ++ 2 files changed, 23 insertions(+) diff --git a/api_tests/institutions/views/test_institution_list.py b/api_tests/institutions/views/test_institution_list.py index d203b2b9313..60e63056b7a 100644 --- a/api_tests/institutions/views/test_institution_list.py +++ b/api_tests/institutions/views/test_institution_list.py @@ -80,3 +80,24 @@ def test_sso_availability_filter( assert institution_one._id in ids assert institution_three._id in ids assert institution_two._id not in ids + + def test_default_filter_excludes_institutions_with_sso_availability_hidden( + self, app, institution_one, institution_two, institution_three, url_institution + ): + institution_one.sso_availability = 'Unavailable' + institution_one.save() + + institution_two.sso_availability = 'Public' + institution_two.save() + + institution_three.sso_availability = 'Hidden' + institution_three.save() + + res = app.get(url_institution) + assert res.status_code == 200 + + ids = [each['id'] for each in res.json['data']] + assert len(res.json['data']) == 2 + assert institution_one._id in ids + assert institution_two._id in ids + assert institution_three._id not in ids diff --git a/osf_tests/factories.py b/osf_tests/factories.py index 0b357aed1aa..0d5e5ad0c32 100644 --- a/osf_tests/factories.py +++ b/osf_tests/factories.py @@ -28,6 +28,7 @@ from osf import models from osf.models.sanctions import Sanction from osf.models.storage import PROVIDER_ASSET_NAME_CHOICES +from osf.models.institution import SSOAvailability from osf.utils.names import impute_names_model from osf.utils.workflows import ( DefaultStates, @@ -258,6 +259,7 @@ class InstitutionFactory(DjangoModelFactory): orcid_record_verified_source = '' delegation_protocol = '' institutional_request_access_enabled = False + sso_availability = SSOAvailability.PUBLIC.value class Meta: model = models.Institution From 417473d457e471ec89b9073c4e1f2b38127ea89d Mon Sep 17 00:00:00 2001 From: Ostap Zherebetskyi Date: Mon, 30 Mar 2026 16:43:09 +0300 Subject: [PATCH 3/3] Rename get_sso_institutions to get_non_hidden_institutions --- api/institutions/views.py | 2 +- osf/models/institution.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/api/institutions/views.py b/api/institutions/views.py index 6272cfbe59c..d653f5b4e77 100644 --- a/api/institutions/views.py +++ b/api/institutions/views.py @@ -90,7 +90,7 @@ class InstitutionList(JSONAPIBaseView, generics.ListAPIView, ListFilterMixin): def get_default_queryset(self): if 'filter[sso_availability]' in self.request.query_params: return Institution.objects.filter(_id__isnull=False, is_deleted=False) - return Institution.objects.get_sso_institutions().filter(_id__isnull=False, is_deleted=False) + return Institution.objects.get_non_hidden_institutions().filter(_id__isnull=False, is_deleted=False) # overrides ListAPIView def get_queryset(self): diff --git a/osf/models/institution.py b/osf/models/institution.py index c60563bac63..379f301a966 100644 --- a/osf/models/institution.py +++ b/osf/models/institution.py @@ -63,7 +63,7 @@ def get_queryset(self): def get_all_institutions(self): return super().get_queryset() - def get_sso_institutions(self): + def get_non_hidden_institutions(self): return super().get_queryset().filter(deactivated__isnull=True, sso_availability__in=[SSOAvailability.PUBLIC.value, SSOAvailability.UNAVAILABLE.value])