diff --git a/openstack_dashboard/dashboards/identity/groups/tests.py b/openstack_dashboard/dashboards/identity/groups/tests.py index 48d58931bc..f542681a55 100644 --- a/openstack_dashboard/dashboards/identity/groups/tests.py +++ b/openstack_dashboard/dashboards/identity/groups/tests.py @@ -308,3 +308,10 @@ class GroupsViewTests(test.BaseAdminViewTests): self.assertRedirectsNoFollow(res, GROUP_MANAGE_URL) self.assertMessageCount(success=1) + + @test.update_settings(FILTER_DATA_FIRST={'identity.groups': True}) + def test_index_with_filter_first(self): + res = self.client.get(GROUPS_INDEX_URL) + self.assertTemplateUsed(res, constants.GROUPS_INDEX_VIEW_TEMPLATE) + groups = res.context['table'].data + self.assertItemsEqual(groups, []) diff --git a/openstack_dashboard/dashboards/identity/groups/views.py b/openstack_dashboard/dashboards/identity/groups/views.py index c8069de025..13332f4c62 100644 --- a/openstack_dashboard/dashboards/identity/groups/views.py +++ b/openstack_dashboard/dashboards/identity/groups/views.py @@ -12,6 +12,7 @@ # License for the specific language governing permissions and limitations # under the License. +from django.conf import settings from django.core.urlresolvers import reverse from django.core.urlresolvers import reverse_lazy from django.utils.translation import ugettext_lazy as _ @@ -37,12 +38,28 @@ class IndexView(tables.DataTableView): template_name = constants.GROUPS_INDEX_VIEW_TEMPLATE page_title = _("Groups") + def needs_filter_first(self, table): + return self._needs_filter_first + def get_data(self): groups = [] - domain_id = api.keystone.get_effective_domain_id(self.request) filters = self.get_filters() + self._needs_filter_first = False + if policy.check((("identity", "identity:list_groups"),), self.request): + + # If filter_first is set and if there are not other filters + # selected, then search criteria must be provided and + # return an empty list + filter_first = getattr(settings, 'FILTER_DATA_FIRST', {}) + if filter_first.get('identity.groups', False) \ + and len(filters) == 0: + self._needs_filter_first = True + return groups + + domain_id = api.keystone.get_effective_domain_id(self.request) + try: groups = api.keystone.group_list(self.request, domain=domain_id, diff --git a/openstack_dashboard/dashboards/identity/projects/tests.py b/openstack_dashboard/dashboards/identity/projects/tests.py index f47ca3476e..08c476ef09 100644 --- a/openstack_dashboard/dashboards/identity/projects/tests.py +++ b/openstack_dashboard/dashboards/identity/projects/tests.py @@ -97,6 +97,13 @@ class TenantsViewTests(test.BaseAdminViewTests): self.assertItemsEqual(res.context['table'].data, domain_tenants) self.assertContains(res, "test_domain:") + @test.update_settings(FILTER_DATA_FIRST={'identity.projects': True}) + def test_index_with_filter_first(self): + res = self.client.get(INDEX_URL) + self.assertTemplateUsed(res, 'identity/projects/index.html') + projects = res.context['table'].data + self.assertItemsEqual(projects, []) + class ProjectsViewNonAdminTests(test.TestCase): @override_settings(POLICY_CHECK_FUNCTION='openstack_auth.policy.check') diff --git a/openstack_dashboard/dashboards/identity/projects/views.py b/openstack_dashboard/dashboards/identity/projects/views.py index a0a3589c7d..405c546e46 100644 --- a/openstack_dashboard/dashboards/identity/projects/views.py +++ b/openstack_dashboard/dashboards/identity/projects/views.py @@ -71,6 +71,9 @@ class IndexView(tables.DataTableView): template_name = 'identity/projects/index.html' page_title = _("Projects") + def needs_filter_first(self, table): + return self._needs_filter_first + def has_more_data(self, table): return self._more @@ -80,8 +83,22 @@ class IndexView(tables.DataTableView): project_tables.TenantsTable._meta.pagination_param, None) self._more = False filters = self.get_filters() + + self._needs_filter_first = False + if policy.check((("identity", "identity:list_projects"),), self.request): + + # If filter_first is set and if there are not other filters + # selected, then search criteria must be provided and + # return an empty list + filter_first = getattr(settings, 'FILTER_DATA_FIRST', {}) + if filter_first.get('identity.projects', False) and len( + filters) == 0: + self._needs_filter_first = True + self._more = False + return tenants + domain_context = api.keystone.get_effective_domain_id(self.request) try: tenants, self._more = api.keystone.tenant_list( diff --git a/openstack_dashboard/dashboards/identity/roles/tests.py b/openstack_dashboard/dashboards/identity/roles/tests.py index 5fa2112256..d5766f35c7 100644 --- a/openstack_dashboard/dashboards/identity/roles/tests.py +++ b/openstack_dashboard/dashboards/identity/roles/tests.py @@ -120,3 +120,10 @@ class RolesViewTests(test.BaseAdminViewTests): res = self.client.post(ROLES_INDEX_URL, formData) self.assertNoFormErrors(res) + + @test.update_settings(FILTER_DATA_FIRST={'identity.roles': True}) + def test_index_with_filter_first(self): + res = self.client.get(ROLES_INDEX_URL) + self.assertTemplateUsed(res, INDEX_TEMPLATE) + roles = res.context['table'].data + self.assertItemsEqual(roles, []) diff --git a/openstack_dashboard/dashboards/identity/roles/views.py b/openstack_dashboard/dashboards/identity/roles/views.py index 26c8d80380..d5b86e28d7 100644 --- a/openstack_dashboard/dashboards/identity/roles/views.py +++ b/openstack_dashboard/dashboards/identity/roles/views.py @@ -12,6 +12,7 @@ # License for the specific language governing permissions and limitations # under the License. +from django.conf import settings from django.core.urlresolvers import reverse from django.core.urlresolvers import reverse_lazy from django.utils.translation import ugettext_lazy as _ @@ -35,11 +36,26 @@ class IndexView(tables.DataTableView): table_class = project_tables.RolesTable page_title = _("Roles") + def needs_filter_first(self, table): + return self._needs_filter_first + def get_data(self): roles = [] filters = self.get_filters() + + self._needs_filter_first = False + if policy.check((("identity", "identity:list_roles"),), self.request): + + # If filter_first is set and if there are not other filters + # selected, then search criteria must be provided + # and return an empty list + filter_first = getattr(settings, 'FILTER_DATA_FIRST', {}) + if filter_first.get('identity.roles', False) and len(filters) == 0: + self._needs_filter_first = True + return roles + try: roles = api.keystone.role_list(self.request, filters=filters) diff --git a/openstack_dashboard/dashboards/identity/users/tests.py b/openstack_dashboard/dashboards/identity/users/tests.py index 99ae894a08..1d5ecd1bea 100644 --- a/openstack_dashboard/dashboards/identity/users/tests.py +++ b/openstack_dashboard/dashboards/identity/users/tests.py @@ -963,6 +963,13 @@ class UsersViewTests(test.BaseAdminViewTests): self.assertNoFormErrors(res) + @test.update_settings(FILTER_DATA_FIRST={'identity.users': True}) + def test_index_with_filter_first(self): + res = self.client.get(USERS_INDEX_URL) + self.assertTemplateUsed(res, 'identity/users/index.html') + users = res.context['table'].data + self.assertItemsEqual(users, []) + class SeleniumTests(test.SeleniumAdminTestCase): def _get_default_domain(self): diff --git a/openstack_dashboard/dashboards/identity/users/views.py b/openstack_dashboard/dashboards/identity/users/views.py index b48599a87b..ea7af63c39 100644 --- a/openstack_dashboard/dashboards/identity/users/views.py +++ b/openstack_dashboard/dashboards/identity/users/views.py @@ -49,11 +49,26 @@ class IndexView(tables.DataTableView): template_name = 'identity/users/index.html' page_title = _("Users") + def needs_filter_first(self, table): + return self._needs_filter_first + def get_data(self): users = [] filters = self.get_filters() + + self._needs_filter_first = False + if policy.check((("identity", "identity:list_users"),), self.request): + + # If filter_first is set and if there are not other filters + # selected, then search criteria must be provided + # and return an empty list + filter_first = getattr(settings, 'FILTER_DATA_FIRST', {}) + if filter_first.get('identity.users', False) and len(filters) == 0: + self._needs_filter_first = True + return users + domain_context = api.keystone.get_effective_domain_id(self.request) try: users = api.keystone.user_list(self.request, diff --git a/openstack_dashboard/local/local_settings.py.example b/openstack_dashboard/local/local_settings.py.example index 5c4a147e84..72483975c5 100644 --- a/openstack_dashboard/local/local_settings.py.example +++ b/openstack_dashboard/local/local_settings.py.example @@ -800,7 +800,11 @@ REST_API_REQUIRED_SETTINGS = ['OPENSTACK_HYPERVISOR_FEATURES', # 'admin.images': False, # 'admin.networks': False, # 'admin.routers': False, -# 'admin.volumes': False +# 'admin.volumes': False, +# 'identity.users': False, +# 'identity.projects': False, +# 'identity.groups': False, +# 'identity.roles': False #} # Dict used to restrict user private subnet cidr range. diff --git a/releasenotes/notes/filter-first-identity-panels-139c4a5b7a696707.yaml b/releasenotes/notes/filter-first-identity-panels-139c4a5b7a696707.yaml new file mode 100644 index 0000000000..2e093014ec --- /dev/null +++ b/releasenotes/notes/filter-first-identity-panels-139c4a5b7a696707.yaml @@ -0,0 +1,5 @@ +--- +features: + - Implements the "filter first" functionality for identity panels + such as projects, users, groups and roles. The filter first + functionality is described in `