summaryrefslogtreecommitdiff
path: root/openstackclient/identity
diff options
context:
space:
mode:
authorNathan Kinder <nkinder@redhat.com>2015-04-16 19:12:45 -0700
committerNathan Kinder <nkinder@redhat.com>2015-04-17 10:14:57 -0700
commit4c107e6f1b1913988e208b31206c84ab851b780c (patch)
treec5de7fd4ebb63768224af39d27d6d040fcb821dc /openstackclient/identity
parentb72f2fb7eead6287fbdd07c369c0462586f37785 (diff)
downloadpython-openstackclient-4c107e6f1b1913988e208b31206c84ab851b780c.tar.gz
Role operations should not require list object permission
When using Keystone's policy.v3cloudsample.json policy file, a project admin is supposed to be able to manage role assignments. Unfortunately, a project admin isn't allowed to perform these operations using python-openstackclient, as we attempt to perform list operations for any of the object types specified (users, groups, projects). This is done in an attempt to lookup the id of the object by name, but we perform this list operation even when the user specifies everything by id. This causes 403 errors. This patch still attempts to look up the object id by name, but we catch the 403 and assume that the user specified an id if the list operation is not allowed. This is similar to what we do with the --domain option for other commands. Closes-bug: #1445528 Change-Id: Id95a8520e935c1092d5a22ecd8ea01f572334ac8
Diffstat (limited to 'openstackclient/identity')
-rw-r--r--openstackclient/identity/common.py59
-rw-r--r--openstackclient/identity/v3/role.py81
-rw-r--r--openstackclient/identity/v3/role_assignment.py17
3 files changed, 108 insertions, 49 deletions
diff --git a/openstackclient/identity/common.py b/openstackclient/identity/common.py
index 253729bd..a1b46cb4 100644
--- a/openstackclient/identity/common.py
+++ b/openstackclient/identity/common.py
@@ -17,6 +17,9 @@
from keystoneclient import exceptions as identity_exc
from keystoneclient.v3 import domains
+from keystoneclient.v3 import groups
+from keystoneclient.v3 import projects
+from keystoneclient.v3 import users
from openstackclient.common import exceptions
from openstackclient.common import utils
@@ -56,4 +59,58 @@ def find_domain(identity_client, name_or_id):
return dom
except identity_exc.Forbidden:
pass
- return domains.Domain(None, {'id': name_or_id})
+ return domains.Domain(None, {'id': name_or_id, 'name': name_or_id})
+
+
+def find_group(identity_client, name_or_id):
+ """Find a group.
+
+ If the user does not have permissions to to perform a list groups call,
+ e.g., if the user is a project admin, assume that the group given is the
+ id rather than the name. This method is used by the role add command to
+ allow a role to be assigned to a group by a project admin who does not
+ have permission to list groups.
+ """
+ try:
+ group = utils.find_resource(identity_client.groups, name_or_id)
+ if group is not None:
+ return group
+ except identity_exc.Forbidden:
+ pass
+ return groups.Group(None, {'id': name_or_id, 'name': name_or_id})
+
+
+def find_project(identity_client, name_or_id):
+ """Find a project.
+
+ If the user does not have permissions to to perform a list projects
+ call, e.g., if the user is a project admin, assume that the project
+ given is the id rather than the name. This method is used by the role
+ add command to allow a role to be assigned to a user by a project admin
+ who does not have permission to list projects.
+ """
+ try:
+ project = utils.find_resource(identity_client.projects, name_or_id)
+ if project is not None:
+ return project
+ except identity_exc.Forbidden:
+ pass
+ return projects.Project(None, {'id': name_or_id, 'name': name_or_id})
+
+
+def find_user(identity_client, name_or_id):
+ """Find a user.
+
+ If the user does not have permissions to to perform a list users call,
+ e.g., if the user is a project admin, assume that the user given is the
+ id rather than the name. This method is used by the role add command to
+ allow a role to be assigned to a user by a project admin who does not
+ have permission to list users.
+ """
+ try:
+ user = utils.find_resource(identity_client.users, name_or_id)
+ if user is not None:
+ return user
+ except identity_exc.Forbidden:
+ pass
+ return users.User(None, {'id': name_or_id, 'name': name_or_id})
diff --git a/openstackclient/identity/v3/role.py b/openstackclient/identity/v3/role.py
index 03760709..3dd998ba 100644
--- a/openstackclient/identity/v3/role.py
+++ b/openstackclient/identity/v3/role.py
@@ -26,6 +26,7 @@ from keystoneclient import exceptions as ksc_exc
from openstackclient.common import utils
from openstackclient.i18n import _ # noqa
+from openstackclient.identity import common
class AddRole(command.Command):
@@ -78,12 +79,12 @@ class AddRole(command.Command):
)
if parsed_args.user and parsed_args.domain:
- user = utils.find_resource(
- identity_client.users,
+ user = common.find_user(
+ identity_client,
parsed_args.user,
)
- domain = utils.find_resource(
- identity_client.domains,
+ domain = common.find_domain(
+ identity_client,
parsed_args.domain,
)
identity_client.roles.grant(
@@ -92,12 +93,12 @@ class AddRole(command.Command):
domain=domain.id,
)
elif parsed_args.user and parsed_args.project:
- user = utils.find_resource(
- identity_client.users,
+ user = common.find_user(
+ identity_client,
parsed_args.user,
)
- project = utils.find_resource(
- identity_client.projects,
+ project = common.find_project(
+ identity_client,
parsed_args.project,
)
identity_client.roles.grant(
@@ -106,12 +107,12 @@ class AddRole(command.Command):
project=project.id,
)
elif parsed_args.group and parsed_args.domain:
- group = utils.find_resource(
- identity_client.groups,
+ group = common.find_group(
+ identity_client,
parsed_args.group,
)
- domain = utils.find_resource(
- identity_client.domains,
+ domain = common.find_domain(
+ identity_client,
parsed_args.domain,
)
identity_client.roles.grant(
@@ -120,12 +121,12 @@ class AddRole(command.Command):
domain=domain.id,
)
elif parsed_args.group and parsed_args.project:
- group = utils.find_resource(
- identity_client.groups,
+ group = common.find_group(
+ identity_client,
parsed_args.group,
)
- project = utils.find_resource(
- identity_client.projects,
+ project = common.find_project(
+ identity_client,
parsed_args.project,
)
identity_client.roles.grant(
@@ -240,24 +241,24 @@ class ListRole(lister.Lister):
identity_client = self.app.client_manager.identity
if parsed_args.user:
- user = utils.find_resource(
- identity_client.users,
+ user = common.find_user(
+ identity_client,
parsed_args.user,
)
elif parsed_args.group:
- group = utils.find_resource(
- identity_client.groups,
+ group = common.find_group(
+ identity_client,
parsed_args.group,
)
if parsed_args.domain:
- domain = utils.find_resource(
- identity_client.domains,
+ domain = common.find_domain(
+ identity_client,
parsed_args.domain,
)
elif parsed_args.project:
- project = utils.find_resource(
- identity_client.projects,
+ project = common.find_project(
+ identity_client,
parsed_args.project,
)
@@ -370,12 +371,12 @@ class RemoveRole(command.Command):
)
if parsed_args.user and parsed_args.domain:
- user = utils.find_resource(
- identity_client.users,
+ user = common.find_user(
+ identity_client,
parsed_args.user,
)
- domain = utils.find_resource(
- identity_client.domains,
+ domain = common.find_domain(
+ identity_client,
parsed_args.domain,
)
identity_client.roles.revoke(
@@ -384,12 +385,12 @@ class RemoveRole(command.Command):
domain=domain.id,
)
elif parsed_args.user and parsed_args.project:
- user = utils.find_resource(
- identity_client.users,
+ user = common.find_user(
+ identity_client,
parsed_args.user,
)
- project = utils.find_resource(
- identity_client.projects,
+ project = common.find_project(
+ identity_client,
parsed_args.project,
)
identity_client.roles.revoke(
@@ -398,12 +399,12 @@ class RemoveRole(command.Command):
project=project.id,
)
elif parsed_args.group and parsed_args.domain:
- group = utils.find_resource(
- identity_client.groups,
+ group = common.find_group(
+ identity_client,
parsed_args.group,
)
- domain = utils.find_resource(
- identity_client.domains,
+ domain = common.find_domain(
+ identity_client,
parsed_args.domain,
)
identity_client.roles.revoke(
@@ -412,12 +413,12 @@ class RemoveRole(command.Command):
domain=domain.id,
)
elif parsed_args.group and parsed_args.project:
- group = utils.find_resource(
- identity_client.groups,
+ group = common.find_group(
+ identity_client,
parsed_args.group,
)
- project = utils.find_resource(
- identity_client.projects,
+ project = common.find_project(
+ identity_client,
parsed_args.project,
)
identity_client.roles.revoke(
diff --git a/openstackclient/identity/v3/role_assignment.py b/openstackclient/identity/v3/role_assignment.py
index f053b608..24e3a7f7 100644
--- a/openstackclient/identity/v3/role_assignment.py
+++ b/openstackclient/identity/v3/role_assignment.py
@@ -18,6 +18,7 @@ import logging
from cliff import lister
from openstackclient.common import utils
+from openstackclient.identity import common
class ListRoleAssignment(lister.Lister):
@@ -80,29 +81,29 @@ class ListRoleAssignment(lister.Lister):
user = None
if parsed_args.user:
- user = utils.find_resource(
- identity_client.users,
+ user = common.find_user(
+ identity_client,
parsed_args.user,
)
domain = None
if parsed_args.domain:
- domain = utils.find_resource(
- identity_client.domains,
+ domain = common.find_domain(
+ identity_client,
parsed_args.domain,
)
project = None
if parsed_args.project:
- project = utils.find_resource(
- identity_client.projects,
+ project = common.find_project(
+ identity_client,
parsed_args.project,
)
group = None
if parsed_args.group:
- group = utils.find_resource(
- identity_client.groups,
+ group = common.find_group(
+ identity_client,
parsed_args.group,
)