Skip to content

Commit

Permalink
Merge "User shouldn't remove their own roles on project"
Browse files Browse the repository at this point in the history
  • Loading branch information
Jenkins authored and openstack-gerrit committed Oct 13, 2012
2 parents 76e6740 + 35a6708 commit 28f9edb
Show file tree
Hide file tree
Showing 3 changed files with 124 additions and 120 deletions.
186 changes: 83 additions & 103 deletions openstack_dashboard/dashboards/admin/projects/tests.py
Expand Up @@ -139,10 +139,10 @@ def test_add_project_post(self):
for role in roles:
if "role_" + role.id in workflow_data:
ulist = workflow_data["role_" + role.id]
for user in ulist:
for user_id in ulist:
api.add_tenant_user_role(IsA(http.HttpRequest),
tenant_id=self.tenant.id,
user_id=user,
user_id=user_id,
role_id=role.id)

api.nova.tenant_quota_update(IsA(http.HttpRequest),
Expand Down Expand Up @@ -261,10 +261,10 @@ def test_add_project_quota_update_error(self):
for role in roles:
if "role_" + role.id in workflow_data:
ulist = workflow_data["role_" + role.id]
for user in ulist:
for user_id in ulist:
api.add_tenant_user_role(IsA(http.HttpRequest),
tenant_id=self.tenant.id,
user_id=user,
user_id=user_id,
role_id=role.id)

api.nova.tenant_quota_update(IsA(http.HttpRequest),
Expand Down Expand Up @@ -320,10 +320,10 @@ def test_add_project_user_update_error(self):
for role in roles:
if "role_" + role.id in workflow_data:
ulist = workflow_data["role_" + role.id]
for user in ulist:
for user_id in ulist:
api.add_tenant_user_role(IsA(http.HttpRequest),
tenant_id=self.tenant.id,
user_id=user,
user_id=user_id,
role_id=role.id) \
.AndRaise(self.exceptions.keystone)
break
Expand Down Expand Up @@ -443,13 +443,12 @@ def test_update_project_get(self):
'add_tenant_user_role'),
api.keystone: ('user_list',
'role_list',)})
def test_update_project_post(self):
def test_update_project_save(self):
project = self.tenants.first()
quota = self.quotas.first()
default_role = self.roles.first()
users = self.users.list()
roles = self.roles.list()
current_roles = self.roles.list()

# get/init
api.tenant_get(IsA(http.HttpRequest), self.tenant.id, admin=True) \
Expand All @@ -466,10 +465,9 @@ def test_update_project_post(self):
api.roles_for_user(IsA(http.HttpRequest),
user.id,
self.tenant.id).AndReturn(roles)
role_ids = [role.id for role in roles]
if role_ids:
workflow_data.setdefault("role_" + role_ids[0], []) \
.append(user.id)

workflow_data["role_1"] = ['3'] # admin role
workflow_data["role_2"] = ['2'] # member role

# update some fields
project._info["name"] = "updated name"
Expand All @@ -494,40 +492,41 @@ def test_update_project_post(self):
api.keystone.user_list(IsA(http.HttpRequest),
tenant_id=self.tenant.id).AndReturn(users)

for user in users:
api.roles_for_user(IsA(http.HttpRequest),
user.id,
self.tenant.id) \
.AndReturn(current_roles)
for role in roles:
if "role_" + role.id in workflow_data:
ulist = workflow_data["role_" + role.id]
if role not in current_roles:
api.add_tenant_user_role(IsA(http.HttpRequest),
tenant_id=self.tenant.id,
user_id=user,
role_id=role.id)
else:
current_roles.pop(current_roles.index(role))
for to_delete in current_roles:
api.remove_tenant_user_role(IsA(http.HttpRequest),
tenant_id=self.tenant.id,
user_id=user.id,
role_id=to_delete.id)
for role in roles:
if "role_" + role.id in workflow_data:
ulist = workflow_data["role_" + role.id]
for user in ulist:
if not filter(lambda x: user == x.id, users):
api.add_tenant_user_role(IsA(http.HttpRequest),
tenant_id=self.tenant.id,
user_id=user,
role_id=role.id)
# admin user - try to remove all roles on current project, warning
api.roles_for_user(IsA(http.HttpRequest), '1', self.tenant.id) \
.AndReturn(roles)

# member user 1 - has role 1, will remove it
api.roles_for_user(IsA(http.HttpRequest), '2', self.tenant.id) \
.AndReturn((roles[0],))
# remove role 1
api.remove_tenant_user_role(IsA(http.HttpRequest),
tenant_id=self.tenant.id,
user_id='2',
role_id='1')
# add role 2
api.add_tenant_user_role(IsA(http.HttpRequest),
tenant_id=self.tenant.id,
user_id='2',
role_id='2')

# member user 3 - has role 2
api.roles_for_user(IsA(http.HttpRequest), '3', self.tenant.id) \
.AndReturn((roles[1],))
# remove role 2
api.remove_tenant_user_role(IsA(http.HttpRequest),
tenant_id=self.tenant.id,
user_id='3',
role_id='2')
# add role 1
api.add_tenant_user_role(IsA(http.HttpRequest),
tenant_id=self.tenant.id,
user_id='3',
role_id='1')

api.tenant_quota_update(IsA(http.HttpRequest),
project.id,
**updated_quota)

self.mox.ReplayAll()

# submit form data
Expand All @@ -542,6 +541,7 @@ def test_update_project_post(self):
res = self.client.post(url, workflow_data)

self.assertNoFormErrors(res)
self.assertMessageCount(error=0, warning=1)
self.assertRedirectsNoFollow(res, INDEX_URL)

@test.create_stubs({api: ('tenant_get',)})
Expand Down Expand Up @@ -646,7 +646,6 @@ def test_update_project_quota_update_error(self):
default_role = self.roles.first()
users = self.users.list()
roles = self.roles.list()
current_roles = self.roles.list()

# get/init
api.tenant_get(IsA(http.HttpRequest), self.tenant.id, admin=True) \
Expand All @@ -659,14 +658,14 @@ def test_update_project_quota_update_error(self):
api.keystone.role_list(IsA(http.HttpRequest)).AndReturn(roles)

workflow_data = {}

for user in users:
api.roles_for_user(IsA(http.HttpRequest),
user.id,
self.tenant.id).AndReturn(roles)
role_ids = [role.id for role in roles]
if role_ids:
workflow_data.setdefault("role_" + role_ids[0], []) \
.append(user.id)

workflow_data["role_1"] = ['1', '3'] # admin role
workflow_data["role_2"] = ['1', '2', '3'] # member role

# update some fields
project._info["name"] = "updated name"
Expand All @@ -692,35 +691,22 @@ def test_update_project_quota_update_error(self):
api.keystone.user_list(IsA(http.HttpRequest),
tenant_id=self.tenant.id).AndReturn(users)

for user in users:
api.roles_for_user(IsA(http.HttpRequest),
user.id,
self.tenant.id) \
.AndReturn(current_roles)
for role in roles:
if "role_" + role.id in workflow_data:
ulist = workflow_data["role_" + role.id]
if role not in current_roles:
api.add_tenant_user_role(IsA(http.HttpRequest),
tenant_id=self.tenant.id,
user_id=user,
role_id=role.id)
else:
current_roles.pop(current_roles.index(role))
for to_delete in current_roles:
api.remove_tenant_user_role(IsA(http.HttpRequest),
tenant_id=self.tenant.id,
user_id=user.id,
role_id=to_delete.id)
for role in roles:
if "role_" + role.id in workflow_data:
ulist = workflow_data["role_" + role.id]
for user in ulist:
if not filter(lambda x: user == x.id, users):
api.add_tenant_user_role(IsA(http.HttpRequest),
tenant_id=self.tenant.id,
user_id=user,
role_id=role.id)
# admin user - try to remove all roles on current project, warning
api.roles_for_user(IsA(http.HttpRequest), '1', self.tenant.id) \
.AndReturn(roles)

# member user 1 - has role 1, will remove it
api.roles_for_user(IsA(http.HttpRequest), '2', self.tenant.id) \
.AndReturn((roles[1],))

# member user 3 - has role 2
api.roles_for_user(IsA(http.HttpRequest), '3', self.tenant.id) \
.AndReturn((roles[0],))
# add role 2
api.add_tenant_user_role(IsA(http.HttpRequest),
tenant_id=self.tenant.id,
user_id='3',
role_id='2')

api.tenant_quota_update(IsA(http.HttpRequest),
project.id,
Expand All @@ -740,6 +726,7 @@ def test_update_project_quota_update_error(self):
res = self.client.post(url, workflow_data)

self.assertNoFormErrors(res)
self.assertMessageCount(error=1, warning=0)
self.assertRedirectsNoFollow(res, INDEX_URL)

@test.create_stubs({api: ('tenant_get',
Expand All @@ -757,7 +744,6 @@ def test_update_project_member_update_error(self):
default_role = self.roles.first()
users = self.users.list()
roles = self.roles.list()
current_roles = self.roles.list()

# get/init
api.tenant_get(IsA(http.HttpRequest), self.tenant.id, admin=True) \
Expand All @@ -774,10 +760,8 @@ def test_update_project_member_update_error(self):
api.roles_for_user(IsA(http.HttpRequest),
user.id,
self.tenant.id).AndReturn(roles)
role_ids = [role.id for role in roles]
if role_ids:
workflow_data.setdefault("role_" + role_ids[0], []) \
.append(user.id)
workflow_data["role_1"] = ['1', '3'] # admin role
workflow_data["role_2"] = ['1', '2', '3'] # member role

# update some fields
project._info["name"] = "updated name"
Expand All @@ -802,28 +786,23 @@ def test_update_project_member_update_error(self):
api.keystone.user_list(IsA(http.HttpRequest),
tenant_id=self.tenant.id).AndReturn(users)

for user in users:
api.roles_for_user(IsA(http.HttpRequest),
user.id,
self.tenant.id) \
.AndReturn(current_roles)
for role in roles:
if "role_" + role.id in workflow_data:
if role not in current_roles:
api.add_tenant_user_role(IsA(http.HttpRequest),
tenant_id=self.tenant.id,
user_id=user,
role_id=role.id)
else:
current_roles.pop(current_roles.index(role))
for to_delete in current_roles:
api.remove_tenant_user_role(IsA(http.HttpRequest),
tenant_id=self.tenant.id,
user_id=user.id,
role_id=to_delete.id) \
.AndRaise(self.exceptions.nova)
break
break
# admin user - try to remove all roles on current project, warning
api.roles_for_user(IsA(http.HttpRequest), '1', self.tenant.id) \
.AndReturn(roles)

# member user 1 - has role 1, will remove it
api.roles_for_user(IsA(http.HttpRequest), '2', self.tenant.id) \
.AndReturn((roles[1],))

# member user 3 - has role 2
api.roles_for_user(IsA(http.HttpRequest), '3', self.tenant.id) \
.AndReturn((roles[0],))
# add role 2
api.add_tenant_user_role(IsA(http.HttpRequest),
tenant_id=self.tenant.id,
user_id='3',
role_id='2')\
.AndRaise(self.exceptions.nova)

self.mox.ReplayAll()

Expand All @@ -839,4 +818,5 @@ def test_update_project_member_update_error(self):
res = self.client.post(url, workflow_data)

self.assertNoFormErrors(res)
self.assertMessageCount(error=1, warning=0)
self.assertRedirectsNoFollow(res, INDEX_URL)
38 changes: 26 additions & 12 deletions openstack_dashboard/dashboards/admin/projects/workflows.py
Expand Up @@ -25,6 +25,7 @@
from horizon import exceptions
from horizon import workflows
from horizon import forms
from horizon import messages

from openstack_dashboard import api

Expand Down Expand Up @@ -299,12 +300,15 @@ def handle(self, request, data):
tenant_id=project_id)
users_to_modify = len(project_members)
for user in project_members:
current_roles = api.roles_for_user(self.request,
user.id,
project_id)
current_roles = [role for role in
api.roles_for_user(self.request,
user.id,
project_id)]
effective_roles = []
for role in available_roles:
role_list = data["role_" + role.id]
if user.id in role_list:
effective_roles.append(role)
if role not in current_roles:
# user role has changed
api.add_tenant_user_role(request,
Expand All @@ -314,12 +318,22 @@ def handle(self, request, data):
else:
# user role is unchanged
current_roles.pop(current_roles.index(role))
# delete user's removed roles
for to_delete in current_roles:
api.remove_tenant_user_role(request,
tenant_id=project_id,
user_id=user.id,
role_id=to_delete.id)
if user.id == request.user.id and \
project_id == request.user.tenant_id and \
any(x.name == 'admin' for x in current_roles):
# Cannot remove "admin" role on current(admin) project
msg = _('You cannot remove the "admin" role from the '
'project you are currently logged into. Please '
'switch to another project with admin permissions '
'or remove the role manually via the CLI')
messages.warning(request, msg)
else:
# delete user's removed roles
for to_delete in current_roles:
api.remove_tenant_user_role(request,
tenant_id=project_id,
user_id=user.id,
role_id=to_delete.id)
users_to_modify -= 1

# add new roles to project
Expand All @@ -330,11 +344,11 @@ def handle(self, request, data):
for role in available_roles:
role_list = data["role_" + role.id]
users_added = 0
for user in role_list:
if not filter(lambda x: user == x.id, project_members):
for user_id in role_list:
if not filter(lambda x: user_id == x.id, project_members):
api.add_tenant_user_role(request,
tenant_id=project_id,
user_id=user,
user_id=user_id,
role_id=role.id)
users_added += 1
users_to_modify -= users_added
Expand Down

0 comments on commit 28f9edb

Please sign in to comment.