Add user group assignment support in identity
Add possibility to add/remove/check user into/from group. Change-Id: I1e012471badcf6264dced53354472abd8312f62c
This commit is contained in:
parent
21795acff6
commit
d7d6464c6d
@ -42,7 +42,8 @@ Group Operations
|
||||
.. autoclass:: openstack.identity.v3._proxy.Proxy
|
||||
:noindex:
|
||||
:members: create_group, update_group, delete_group, get_group, find_group,
|
||||
groups
|
||||
groups, add_user_to_group, remove_user_from_group,
|
||||
check_user_in_group
|
||||
|
||||
Policy Operations
|
||||
^^^^^^^^^^^^^^^^^
|
||||
|
@ -295,11 +295,7 @@ class IdentityCloudMixin(_normalize.Normalizer):
|
||||
"""
|
||||
user, group = self._get_user_and_group(name_or_id, group_name_or_id)
|
||||
|
||||
error_msg = "Error adding user {user} to group {group}".format(
|
||||
user=name_or_id, group=group_name_or_id)
|
||||
self._identity_client.put(
|
||||
'/groups/{g}/users/{u}'.format(g=group['id'], u=user['id']),
|
||||
error_message=error_msg)
|
||||
self.identity.add_user_to_group(user, group)
|
||||
|
||||
def is_user_in_group(self, name_or_id, group_name_or_id):
|
||||
"""Check to see if a user is in a group.
|
||||
@ -314,14 +310,7 @@ class IdentityCloudMixin(_normalize.Normalizer):
|
||||
"""
|
||||
user, group = self._get_user_and_group(name_or_id, group_name_or_id)
|
||||
|
||||
try:
|
||||
self._identity_client.head(
|
||||
'/groups/{g}/users/{u}'.format(g=group['id'], u=user['id']))
|
||||
return True
|
||||
except exc.OpenStackCloudURINotFound:
|
||||
# NOTE(samueldmq): knowing this URI exists, let's interpret this as
|
||||
# user not found in group rather than URI not found.
|
||||
return False
|
||||
return self.identity.check_user_in_group(user, group)
|
||||
|
||||
def remove_user_from_group(self, name_or_id, group_name_or_id):
|
||||
"""Remove a user from a group.
|
||||
@ -334,11 +323,7 @@ class IdentityCloudMixin(_normalize.Normalizer):
|
||||
"""
|
||||
user, group = self._get_user_and_group(name_or_id, group_name_or_id)
|
||||
|
||||
error_msg = "Error removing user {user} from group {group}".format(
|
||||
user=name_or_id, group=group_name_or_id)
|
||||
self._identity_client.delete(
|
||||
'/groups/{g}/users/{u}'.format(g=group['id'], u=user['id']),
|
||||
error_message=error_msg)
|
||||
self.identity.remove_user_from_group(user, group)
|
||||
|
||||
@_utils.valid_kwargs('type', 'service_type', 'description')
|
||||
def create_service(self, name, enabled=True, **kwargs):
|
||||
|
@ -362,6 +362,45 @@ class Proxy(proxy.Proxy):
|
||||
"""
|
||||
return self._update(_group.Group, group, **attrs)
|
||||
|
||||
def add_user_to_group(self, user, group):
|
||||
"""Add user to group
|
||||
|
||||
:param user: Either the ID of a user or a
|
||||
:class:`~openstack.identity.v3.user.User` instance.
|
||||
:param group: Either the ID of a group or a
|
||||
:class:`~openstack.identity.v3.group.Group` instance.
|
||||
:return: ``None``
|
||||
"""
|
||||
user = self._get_resource(_user.User, user)
|
||||
group = self._get_resource(_group.Group, group)
|
||||
group.add_user(self, user)
|
||||
|
||||
def remove_user_from_group(self, user, group):
|
||||
"""Remove user to group
|
||||
|
||||
:param user: Either the ID of a user or a
|
||||
:class:`~openstack.identity.v3.user.User` instance.
|
||||
:param group: Either the ID of a group or a
|
||||
:class:`~openstack.identity.v3.group.Group` instance.
|
||||
:return: ``None``
|
||||
"""
|
||||
user = self._get_resource(_user.User, user)
|
||||
group = self._get_resource(_group.Group, group)
|
||||
group.remove_user(self, user)
|
||||
|
||||
def check_user_in_group(self, user, group):
|
||||
"""Check whether user belongsto group
|
||||
|
||||
:param user: Either the ID of a user or a
|
||||
:class:`~openstack.identity.v3.user.User` instance.
|
||||
:param group: Either the ID of a group or a
|
||||
:class:`~openstack.identity.v3.group.Group` instance.
|
||||
:return: A boolean representing current relation
|
||||
"""
|
||||
user = self._get_resource(_user.User, user)
|
||||
group = self._get_resource(_group.Group, group)
|
||||
return group.check_user(self, user)
|
||||
|
||||
def create_policy(self, **attrs):
|
||||
"""Create a new policy from attributes
|
||||
|
||||
|
@ -10,7 +10,9 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from openstack import exceptions
|
||||
from openstack import resource
|
||||
from openstack import utils
|
||||
|
||||
|
||||
class Group(resource.Resource):
|
||||
@ -40,3 +42,31 @@ class Group(resource.Resource):
|
||||
domain_id = resource.Body('domain_id')
|
||||
#: Unique group name, within the owning domain. *Type: string*
|
||||
name = resource.Body('name')
|
||||
|
||||
def add_user(self, session, user):
|
||||
"""Add user to the group"""
|
||||
url = utils.urljoin(
|
||||
self.base_path, self.id, 'users', user.id)
|
||||
resp = session.put(url,)
|
||||
exceptions.raise_from_response(resp)
|
||||
|
||||
def remove_user(self, session, user):
|
||||
"""Remove user from the group"""
|
||||
url = utils.urljoin(
|
||||
self.base_path, self.id, 'users', user.id)
|
||||
resp = session.delete(url,)
|
||||
exceptions.raise_from_response(resp)
|
||||
|
||||
def check_user(self, session, user):
|
||||
"""Check whether user belongs to group"""
|
||||
url = utils.urljoin(
|
||||
self.base_path, self.id, 'users', user.id)
|
||||
resp = session.head(url,)
|
||||
if resp.status_code == 404:
|
||||
# If we recieve 404 - treat this as False,
|
||||
# rather then returning exception
|
||||
return False
|
||||
exceptions.raise_from_response(resp)
|
||||
if resp.status_code == 204:
|
||||
return True
|
||||
return False
|
||||
|
@ -10,7 +10,12 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from unittest import mock
|
||||
|
||||
from keystoneauth1 import adapter
|
||||
|
||||
from openstack.identity.v3 import group
|
||||
from openstack.identity.v3 import user
|
||||
from openstack.tests.unit import base
|
||||
|
||||
|
||||
@ -25,6 +30,16 @@ EXAMPLE = {
|
||||
|
||||
class TestGroup(base.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(TestGroup, self).setUp()
|
||||
self.sess = mock.Mock(spec=adapter.Adapter)
|
||||
self.sess.default_microversion = 1
|
||||
self.sess._get_connection = mock.Mock(return_value=self.cloud)
|
||||
self.good_resp = mock.Mock()
|
||||
self.good_resp.body = None
|
||||
self.good_resp.json = mock.Mock(return_value=self.good_resp.body)
|
||||
self.good_resp.status_code = 204
|
||||
|
||||
def test_basic(self):
|
||||
sot = group.Group()
|
||||
self.assertEqual('group', sot.resource_key)
|
||||
@ -52,3 +67,38 @@ class TestGroup(base.TestCase):
|
||||
self.assertEqual(EXAMPLE['domain_id'], sot.domain_id)
|
||||
self.assertEqual(EXAMPLE['id'], sot.id)
|
||||
self.assertEqual(EXAMPLE['name'], sot.name)
|
||||
|
||||
def test_add_user(self):
|
||||
sot = group.Group(**EXAMPLE)
|
||||
resp = self.good_resp
|
||||
self.sess.put = mock.Mock(return_value=resp)
|
||||
|
||||
sot.add_user(
|
||||
self.sess, user.User(id='1'))
|
||||
|
||||
self.sess.put.assert_called_with(
|
||||
'groups/IDENTIFIER/users/1')
|
||||
|
||||
def test_remove_user(self):
|
||||
sot = group.Group(**EXAMPLE)
|
||||
resp = self.good_resp
|
||||
self.sess.delete = mock.Mock(return_value=resp)
|
||||
|
||||
sot.remove_user(
|
||||
self.sess, user.User(id='1'))
|
||||
|
||||
self.sess.delete.assert_called_with(
|
||||
'groups/IDENTIFIER/users/1')
|
||||
|
||||
def test_check_user(self):
|
||||
sot = group.Group(**EXAMPLE)
|
||||
resp = self.good_resp
|
||||
self.sess.head = mock.Mock(return_value=resp)
|
||||
|
||||
self.assertTrue(
|
||||
sot.check_user(
|
||||
self.sess,
|
||||
user.User(id='1')))
|
||||
|
||||
self.sess.head.assert_called_with(
|
||||
'groups/IDENTIFIER/users/1')
|
||||
|
@ -35,7 +35,7 @@ class TestIdentityProxyBase(test_proxy_base.TestProxyBase):
|
||||
self.proxy = _proxy.Proxy(self.session)
|
||||
|
||||
|
||||
class TestIdentityProxy(TestIdentityProxyBase):
|
||||
class TestIdentityProxyCredential(TestIdentityProxyBase):
|
||||
|
||||
def test_credential_create_attrs(self):
|
||||
self.verify_create(self.proxy.create_credential,
|
||||
@ -61,6 +61,9 @@ class TestIdentityProxy(TestIdentityProxyBase):
|
||||
def test_credential_update(self):
|
||||
self.verify_update(self.proxy.update_credential, credential.Credential)
|
||||
|
||||
|
||||
class TestIdentityProxyDomain(TestIdentityProxyBase):
|
||||
|
||||
def test_domain_create_attrs(self):
|
||||
self.verify_create(self.proxy.create_domain, domain.Domain)
|
||||
|
||||
@ -82,6 +85,9 @@ class TestIdentityProxy(TestIdentityProxyBase):
|
||||
def test_domain_update(self):
|
||||
self.verify_update(self.proxy.update_domain, domain.Domain)
|
||||
|
||||
|
||||
class TestIdentityProxyEndpoint(TestIdentityProxyBase):
|
||||
|
||||
def test_endpoint_create_attrs(self):
|
||||
self.verify_create(self.proxy.create_endpoint, endpoint.Endpoint)
|
||||
|
||||
@ -105,6 +111,9 @@ class TestIdentityProxy(TestIdentityProxyBase):
|
||||
def test_endpoint_update(self):
|
||||
self.verify_update(self.proxy.update_endpoint, endpoint.Endpoint)
|
||||
|
||||
|
||||
class TestIdentityProxyGroup(TestIdentityProxyBase):
|
||||
|
||||
def test_group_create_attrs(self):
|
||||
self.verify_create(self.proxy.create_group, group.Group)
|
||||
|
||||
@ -126,6 +135,42 @@ class TestIdentityProxy(TestIdentityProxyBase):
|
||||
def test_group_update(self):
|
||||
self.verify_update(self.proxy.update_group, group.Group)
|
||||
|
||||
def test_add_user_to_group(self):
|
||||
self._verify(
|
||||
"openstack.identity.v3.group.Group.add_user",
|
||||
self.proxy.add_user_to_group,
|
||||
method_args=['uid', 'gid'],
|
||||
expected_args=[
|
||||
self.proxy,
|
||||
self.proxy._get_resource(user.User, 'uid'),
|
||||
]
|
||||
)
|
||||
|
||||
def test_remove_user_from_group(self):
|
||||
self._verify(
|
||||
"openstack.identity.v3.group.Group.remove_user",
|
||||
self.proxy.remove_user_from_group,
|
||||
method_args=['uid', 'gid'],
|
||||
expected_args=[
|
||||
self.proxy,
|
||||
self.proxy._get_resource(user.User, 'uid'),
|
||||
]
|
||||
)
|
||||
|
||||
def test_check_user_in_group(self):
|
||||
self._verify(
|
||||
"openstack.identity.v3.group.Group.check_user",
|
||||
self.proxy.check_user_in_group,
|
||||
method_args=['uid', 'gid'],
|
||||
expected_args=[
|
||||
self.proxy,
|
||||
self.proxy._get_resource(user.User, 'uid'),
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
class TestIdentityProxyPolicy(TestIdentityProxyBase):
|
||||
|
||||
def test_policy_create_attrs(self):
|
||||
self.verify_create(self.proxy.create_policy, policy.Policy)
|
||||
|
||||
@ -147,6 +192,9 @@ class TestIdentityProxy(TestIdentityProxyBase):
|
||||
def test_policy_update(self):
|
||||
self.verify_update(self.proxy.update_policy, policy.Policy)
|
||||
|
||||
|
||||
class TestIdentityProxyProject(TestIdentityProxyBase):
|
||||
|
||||
def test_project_create_attrs(self):
|
||||
self.verify_create(self.proxy.create_project, project.Project)
|
||||
|
||||
@ -176,6 +224,9 @@ class TestIdentityProxy(TestIdentityProxyBase):
|
||||
def test_project_update(self):
|
||||
self.verify_update(self.proxy.update_project, project.Project)
|
||||
|
||||
|
||||
class TestIdentityProxyService(TestIdentityProxyBase):
|
||||
|
||||
def test_service_create_attrs(self):
|
||||
self.verify_create(self.proxy.create_service, service.Service)
|
||||
|
||||
@ -197,6 +248,9 @@ class TestIdentityProxy(TestIdentityProxyBase):
|
||||
def test_service_update(self):
|
||||
self.verify_update(self.proxy.update_service, service.Service)
|
||||
|
||||
|
||||
class TestIdentityProxyUser(TestIdentityProxyBase):
|
||||
|
||||
def test_user_create_attrs(self):
|
||||
self.verify_create(self.proxy.create_user, user.User)
|
||||
|
||||
@ -218,6 +272,9 @@ class TestIdentityProxy(TestIdentityProxyBase):
|
||||
def test_user_update(self):
|
||||
self.verify_update(self.proxy.update_user, user.User)
|
||||
|
||||
|
||||
class TestIdentityProxyTrust(TestIdentityProxyBase):
|
||||
|
||||
def test_trust_create_attrs(self):
|
||||
self.verify_create(self.proxy.create_trust, trust.Trust)
|
||||
|
||||
@ -236,6 +293,9 @@ class TestIdentityProxy(TestIdentityProxyBase):
|
||||
def test_trusts(self):
|
||||
self.verify_list(self.proxy.trusts, trust.Trust)
|
||||
|
||||
|
||||
class TestIdentityProxyRegion(TestIdentityProxyBase):
|
||||
|
||||
def test_region_create_attrs(self):
|
||||
self.verify_create(self.proxy.create_region, region.Region)
|
||||
|
||||
@ -257,6 +317,9 @@ class TestIdentityProxy(TestIdentityProxyBase):
|
||||
def test_region_update(self):
|
||||
self.verify_update(self.proxy.update_region, region.Region)
|
||||
|
||||
|
||||
class TestIdentityProxyRole(TestIdentityProxyBase):
|
||||
|
||||
def test_role_create_attrs(self):
|
||||
self.verify_create(self.proxy.create_role, role.Role)
|
||||
|
||||
|
@ -0,0 +1,4 @@
|
||||
---
|
||||
features:
|
||||
- |
|
||||
Add support for user group assignments in identity service.
|
Loading…
Reference in New Issue
Block a user