From 894e4d38246f3c7630db7898f1a8fd36aba31199 Mon Sep 17 00:00:00 2001 From: Dimitri Mazmanov Date: Sat, 18 Apr 2015 02:59:05 +0200 Subject: [PATCH] Fix error message on project create Added a concrete project name validation error in case a project with such name already exists. Change-Id: I089970cfa5d512469c3f73987e21d4c7cbadc04c Closes-Bug: #1445055 --- .../dashboards/identity/projects/tests.py | 54 +++++++++++++++++++ .../dashboards/identity/projects/workflows.py | 27 ++++++++++ 2 files changed, 81 insertions(+) diff --git a/openstack_dashboard/dashboards/identity/projects/tests.py b/openstack_dashboard/dashboards/identity/projects/tests.py index a860a63125..c74b14d724 100644 --- a/openstack_dashboard/dashboards/identity/projects/tests.py +++ b/openstack_dashboard/dashboards/identity/projects/tests.py @@ -720,6 +720,60 @@ class CreateProjectWorkflowTests(test.BaseAdminViewTests): domain_context_name=domain.name) self.test_add_project_missing_field_error() + @test.create_stubs({api.keystone: ('user_list', + 'role_list', + 'group_list', + 'get_default_domain', + 'get_default_role', + 'tenant_list'), + quotas: ('get_default_quota_data', + 'get_disabled_quotas', + 'tenant_quota_usages')}) + def test_add_project_name_already_in_use_error(self): + keystone_api_version = api.keystone.VERSIONS.active + + if keystone_api_version < 3: + return + + project = self.tenants.first() + quota = self.quotas.first() + default_role = self.roles.first() + default_domain = self._get_default_domain() + domain_id = default_domain.id + users = self._get_all_users(domain_id) + groups = self._get_all_groups(domain_id) + roles = self.roles.list() + + # init + api.keystone.tenant_list(IgnoreArg(), + domain=domain_id, + filters={"name": project.name})\ + .AndReturn(project) + + api.keystone.get_default_domain(IsA(http.HttpRequest)) \ + .AndReturn(default_domain) + quotas.get_disabled_quotas(IsA(http.HttpRequest)) \ + .AndReturn(self.disabled_quotas.first()) + quotas.get_default_quota_data(IsA(http.HttpRequest)).AndReturn(quota) + + api.keystone.get_default_role(IsA(http.HttpRequest)) \ + .MultipleTimes().AndReturn(default_role) + api.keystone.user_list(IsA(http.HttpRequest), domain=domain_id) \ + .AndReturn(users) + api.keystone.role_list(IsA(http.HttpRequest)) \ + .MultipleTimes().AndReturn(roles) + api.keystone.group_list(IsA(http.HttpRequest), domain=domain_id) \ + .AndReturn(groups) + + self.mox.ReplayAll() + + workflow_data = self._get_workflow_data(project, quota) + + url = reverse('horizon:identity:projects:create') + res = self.client.post(url, workflow_data) + + self.assertContains(res, 'already in use') + class UpdateProjectWorkflowTests(test.BaseAdminViewTests): def _get_quota_info(self, quota): diff --git a/openstack_dashboard/dashboards/identity/projects/workflows.py b/openstack_dashboard/dashboards/identity/projects/workflows.py index dc8f7d09b3..8b99e6a5af 100644 --- a/openstack_dashboard/dashboards/identity/projects/workflows.py +++ b/openstack_dashboard/dashboards/identity/projects/workflows.py @@ -164,6 +164,27 @@ class CreateProjectInfoAction(workflows.Action): self.fields["domain_id"].widget = readonlyInput self.fields["domain_name"].widget = readonlyInput + def clean_name(self): + project_name = self.cleaned_data['name'] + domain_id = self.cleaned_data['domain_id'] + + # Due to potential performance issues project name validation + # for the keystone.v2 is omitted + try: + if keystone.VERSIONS.active >= 3: + tenant = api.keystone.tenant_list( + self.request, + domain=domain_id, + filters={'name': project_name}) + + if tenant: + msg = _('Project name is already in use. Please use a ' + 'different name.') + raise forms.ValidationError(msg) + except Exception: + exceptions.handle(self.request, ignore=True) + return project_name + class Meta(object): name = _("Project Information") help_text = _("Create a project to organize users.") @@ -552,6 +573,12 @@ class UpdateProjectInfoAction(CreateProjectInfoAction): cleaned_data['enabled'] = True return cleaned_data + def clean_name(self): + project_name = self.cleaned_data['name'] + if self.initial['name'] == project_name: + return project_name + return super(UpdateProjectInfoAction, self).clean_name() + class Meta(object): name = _("Project Information") slug = 'update_info'