Add CRUD operations for Federated Protocols.
Add relevant methods for adding, updating, listing, getting, and deleting Federated Protocol objects. Change-Id: Ibd8488158619d1689fbdfe21df114433c41c91f8 Implements: blueprint federation-crud-operations
This commit is contained in:
		 Marek Denis
					Marek Denis
				
			
				
					committed by
					
						 Steve Martinelli
						Steve Martinelli
					
				
			
			
				
	
			
			
			 Steve Martinelli
						Steve Martinelli
					
				
			
						parent
						
							90abb4cfb2
						
					
				
				
					commit
					9dbdb3a651
				
			| @@ -10,13 +10,16 @@ | ||||
| # License for the specific language governing permissions and limitations | ||||
| # under the License. | ||||
|  | ||||
| import copy | ||||
| import uuid | ||||
|  | ||||
| import httpretty | ||||
|  | ||||
| from keystoneclient import exceptions | ||||
| from keystoneclient.tests.v3 import utils | ||||
| from keystoneclient.v3.contrib.federation import identity_providers | ||||
| from keystoneclient.v3.contrib.federation import mappings | ||||
| from keystoneclient.v3.contrib.federation import protocols | ||||
|  | ||||
|  | ||||
| class IdentityProviderTests(utils.TestCase, utils.CrudTests): | ||||
| @@ -125,3 +128,198 @@ class MappingTests(utils.TestCase, utils.CrudTests): | ||||
|                 req_ref[attr], | ||||
|                 'Expected different %s' % attr) | ||||
|         self.assertEntityRequestBodyIs(manager_ref) | ||||
|  | ||||
|  | ||||
| class ProtocolTests(utils.TestCase, utils.CrudTests): | ||||
|     def setUp(self): | ||||
|         super(ProtocolTests, self).setUp() | ||||
|         self.key = 'protocol' | ||||
|         self.collection_key = 'protocols' | ||||
|         self.model = protocols.Protocol | ||||
|         self.manager = self.client.federation.protocols | ||||
|         self.path_prefix = 'OS-FEDERATION/identity_providers' | ||||
|  | ||||
|     def _transform_to_response(self, ref): | ||||
|         """Rebuild dictionary so it can be used as a | ||||
|         reference response body. | ||||
|  | ||||
|         """ | ||||
|         response = copy.deepcopy(ref) | ||||
|         response['id'] = response.pop('protocol_id') | ||||
|         del response['identity_provider'] | ||||
|         return response | ||||
|  | ||||
|     def new_ref(self, **kwargs): | ||||
|         kwargs.setdefault('mapping', uuid.uuid4().hex) | ||||
|         kwargs.setdefault('identity_provider', uuid.uuid4().hex) | ||||
|         kwargs.setdefault('protocol_id', uuid.uuid4().hex) | ||||
|         return kwargs | ||||
|  | ||||
|     def build_parts(self, identity_provider, protocol_id=None): | ||||
|         """Build array used to construct httpretty URL/ | ||||
|  | ||||
|         Construct and return array with URL parts later used | ||||
|         by methods like utils.TestCase.stub_entity(). | ||||
|         Example of URL: | ||||
|         ``OS-FEDERATION/identity_providers/{idp_id}/ | ||||
|         protocols/{protocol_id}`` | ||||
|  | ||||
|         """ | ||||
|         parts = ['OS-FEDERATION', 'identity_providers', | ||||
|                  identity_provider, 'protocols'] | ||||
|         if protocol_id: | ||||
|             parts.append(protocol_id) | ||||
|         return parts | ||||
|  | ||||
|     def test_build_url_provide_base_url(self): | ||||
|         base_url = uuid.uuid4().hex | ||||
|         parameters = {'base_url': base_url} | ||||
|         url = self.manager.build_url(dict_args_in_out=parameters) | ||||
|         self.assertEqual('/'.join([base_url, self.collection_key]), url) | ||||
|  | ||||
|     def test_build_url_w_idp_id(self): | ||||
|         """Test whether kwargs ``base_url`` discards object's base_url | ||||
|  | ||||
|         This test shows, that when ``base_url`` is specified in the | ||||
|         dict_args_in_out dictionary,  values like ``identity_provider_id`` | ||||
|         are not taken into consideration while building the url. | ||||
|  | ||||
|         """ | ||||
|         base_url, identity_provider_id = uuid.uuid4().hex, uuid.uuid4().hex | ||||
|         parameters = { | ||||
|             'base_url': base_url, | ||||
|             'identity_provider_id': identity_provider_id | ||||
|         } | ||||
|         url = self.manager.build_url(dict_args_in_out=parameters) | ||||
|         self.assertEqual('/'.join([base_url, self.collection_key]), url) | ||||
|  | ||||
|     def test_build_url_default_base_url(self): | ||||
|         identity_provider_id = uuid.uuid4().hex | ||||
|         parameters = { | ||||
|             'identity_provider_id': identity_provider_id | ||||
|         } | ||||
|  | ||||
|         url = self.manager.build_url(dict_args_in_out=parameters) | ||||
|         self.assertEqual( | ||||
|             '/'.join([self.manager.base_url, identity_provider_id, | ||||
|                       self.manager.collection_key]), url) | ||||
|  | ||||
|     @httpretty.activate | ||||
|     def test_create(self): | ||||
|         """Test creating federation protocol tied to an Identity Provider. | ||||
|  | ||||
|         URL to be tested: PUT /OS-FEDERATION/identity_providers/ | ||||
|         $identity_provider/protocols/$protocol | ||||
|  | ||||
|         """ | ||||
|         request_args = self.new_ref() | ||||
|         expected = self._transform_to_response(request_args) | ||||
|         parts = self.build_parts(request_args['identity_provider'], | ||||
|                                  request_args['protocol_id']) | ||||
|         self.stub_entity(httpretty.PUT, entity=expected, | ||||
|                          parts=parts, status=201) | ||||
|         returned = self.manager.create(**request_args) | ||||
|         self.assertEqual(expected, returned.to_dict()) | ||||
|         request_body = {'mapping_id': request_args['mapping']} | ||||
|         self.assertEntityRequestBodyIs(request_body) | ||||
|  | ||||
|     @httpretty.activate | ||||
|     def test_get(self): | ||||
|         """Fetch federation protocol object. | ||||
|  | ||||
|         URL to be tested: GET /OS-FEDERATION/identity_providers/ | ||||
|         $identity_provider/protocols/$protocol | ||||
|  | ||||
|         """ | ||||
|         request_args = self.new_ref() | ||||
|         expected = self._transform_to_response(request_args) | ||||
|  | ||||
|         parts = self.build_parts(request_args['identity_provider'], | ||||
|                                  request_args['protocol_id']) | ||||
|         self.stub_entity(httpretty.GET, entity=expected, | ||||
|                          parts=parts, status=201) | ||||
|  | ||||
|         returned = self.manager.get(request_args['identity_provider'], | ||||
|                                     request_args['protocol_id']) | ||||
|         self.assertIsInstance(returned, self.model) | ||||
|         self.assertEqual(expected, returned.to_dict()) | ||||
|  | ||||
|     @httpretty.activate | ||||
|     def test_delete(self): | ||||
|         """Delete federation protocol object. | ||||
|  | ||||
|         URL to be tested: DELETE /OS-FEDERATION/identity_providers/ | ||||
|         $identity_provider/protocols/$protocol | ||||
|  | ||||
|         """ | ||||
|         request_args = self.new_ref() | ||||
|         parts = self.build_parts(request_args['identity_provider'], | ||||
|                                  request_args['protocol_id']) | ||||
|  | ||||
|         self.stub_entity(httpretty.DELETE, parts=parts, status=204) | ||||
|  | ||||
|         self.manager.delete(request_args['identity_provider'], | ||||
|                             request_args['protocol_id']) | ||||
|  | ||||
|     @httpretty.activate | ||||
|     def test_list(self): | ||||
|         """Test listing all federation protocols tied to the Identity Provider. | ||||
|  | ||||
|         URL to be tested: GET /OS-FEDERATION/identity_providers/ | ||||
|         $identity_provider/protocols | ||||
|  | ||||
|         """ | ||||
|         def _ref_protocols(): | ||||
|             return { | ||||
|                 'id': uuid.uuid4().hex, | ||||
|                 'mapping_id': uuid.uuid4().hex | ||||
|             } | ||||
|  | ||||
|         request_args = self.new_ref() | ||||
|         expected = [_ref_protocols() for _ in range(3)] | ||||
|         parts = self.build_parts(request_args['identity_provider']) | ||||
|         self.stub_entity(httpretty.GET, parts=parts, | ||||
|                          entity=expected, status=200) | ||||
|  | ||||
|         returned = self.manager.list(request_args['identity_provider']) | ||||
|         for obj, ref_obj in zip(returned, expected): | ||||
|             self.assertEqual(obj.to_dict(), ref_obj) | ||||
|  | ||||
|     @httpretty.activate | ||||
|     def test_list_params(self): | ||||
|         request_args = self.new_ref() | ||||
|         filter_kwargs = {uuid.uuid4().hex: uuid.uuid4().hex} | ||||
|         parts = self.build_parts(request_args['identity_provider']) | ||||
|  | ||||
|         # Return HTTP 401 as we don't accept such requests. | ||||
|         self.stub_entity(httpretty.GET, parts=parts, status=401) | ||||
|         self.assertRaises(exceptions.Unauthorized, | ||||
|                           self.manager.list, | ||||
|                           request_args['identity_provider'], | ||||
|                           **filter_kwargs) | ||||
|         self.assertQueryStringContains(**filter_kwargs) | ||||
|  | ||||
|     @httpretty.activate | ||||
|     def test_update(self): | ||||
|         """Test updating federation protocol | ||||
|  | ||||
|         URL to be tested: PATCH /OS-FEDERATION/identity_providers/ | ||||
|         $identity_provider/protocols/$protocol | ||||
|  | ||||
|         """ | ||||
|         request_args = self.new_ref() | ||||
|         expected = self._transform_to_response(request_args) | ||||
|  | ||||
|         parts = self.build_parts(request_args['identity_provider'], | ||||
|                                  request_args['protocol_id']) | ||||
|  | ||||
|         self.stub_entity(httpretty.PATCH, parts=parts, | ||||
|                          entity=expected, status=200) | ||||
|  | ||||
|         returned = self.manager.update(request_args['identity_provider'], | ||||
|                                        request_args['protocol_id'], | ||||
|                                        mapping=request_args['mapping']) | ||||
|         self.assertIsInstance(returned, self.model) | ||||
|         self.assertEqual(expected, returned.to_dict()) | ||||
|         request_body = {'mapping_id': request_args['mapping']} | ||||
|         self.assertEntityRequestBodyIs(request_body) | ||||
|   | ||||
| @@ -12,6 +12,7 @@ | ||||
|  | ||||
| from keystoneclient.v3.contrib.federation import identity_providers | ||||
| from keystoneclient.v3.contrib.federation import mappings | ||||
| from keystoneclient.v3.contrib.federation import protocols | ||||
|  | ||||
|  | ||||
| class FederationManager(object): | ||||
| @@ -19,3 +20,4 @@ class FederationManager(object): | ||||
|         self.identity_providers = identity_providers.IdentityProviderManager( | ||||
|             api) | ||||
|         self.mappings = mappings.MappingManager(api) | ||||
|         self.protocols = protocols.ProtocolManager(api) | ||||
|   | ||||
							
								
								
									
										145
									
								
								keystoneclient/v3/contrib/federation/protocols.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										145
									
								
								keystoneclient/v3/contrib/federation/protocols.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,145 @@ | ||||
| #    Licensed under the Apache License, Version 2.0 (the "License"); you may | ||||
| #    not use this file except in compliance with the License. You may obtain | ||||
| #    a copy of the License at | ||||
| # | ||||
| #         http://www.apache.org/licenses/LICENSE-2.0 | ||||
| # | ||||
| #    Unless required by applicable law or agreed to in writing, software | ||||
| #    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||||
| #    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||||
| #    License for the specific language governing permissions and limitations | ||||
| #    under the License. | ||||
|  | ||||
| from keystoneclient import base | ||||
| from keystoneclient import utils | ||||
|  | ||||
|  | ||||
| class Protocol(base.Resource): | ||||
|     """An object representing federation protocol container. | ||||
|  | ||||
|     Attributes: | ||||
|         * id: user-defined unique per Identity Provider string identifying | ||||
|               federation protocol. | ||||
|  | ||||
|     """ | ||||
|     pass | ||||
|  | ||||
|  | ||||
| class ProtocolManager(base.CrudManager): | ||||
|     """Manager class for manipulating federation protocols.""" | ||||
|  | ||||
|     resource_class = Protocol | ||||
|     collection_key = 'protocols' | ||||
|     key = 'protocol' | ||||
|     base_url = 'OS-FEDERATION/identity_providers' | ||||
|  | ||||
|     def build_url(self, dict_args_in_out=None): | ||||
|         """Build URL for federation protocols.""" | ||||
|  | ||||
|         if dict_args_in_out is None: | ||||
|             dict_args_in_out = {} | ||||
|  | ||||
|         identity_provider_id = dict_args_in_out.pop('identity_provider_id', | ||||
|                                                     None) | ||||
|         if identity_provider_id: | ||||
|             base_url = '/'.join([self.base_url, identity_provider_id]) | ||||
|         else: | ||||
|             base_url = self.base_url | ||||
|  | ||||
|         dict_args_in_out.setdefault('base_url', base_url) | ||||
|         return super(ProtocolManager, self).build_url(dict_args_in_out) | ||||
|  | ||||
|     def _build_url_and_put(self, request_body=None, **kwargs): | ||||
|         url = self.build_url(dict_args_in_out=kwargs) | ||||
|         body = {self.key: request_body} | ||||
|         return self._update(url, body=body, | ||||
|                             response_key=self.key, | ||||
|                             method='PUT') | ||||
|  | ||||
|     @utils.positional.method(3) | ||||
|     def create(self, protocol_id, identity_provider, mapping, **kwargs): | ||||
|         """Create federation protocol object and tie to the Identity Provider. | ||||
|  | ||||
|         Utilize Identity API operation: | ||||
|         PUT /OS-FEDERATION/identity_providers/ | ||||
|         $identity_provider/protocols/$protocol | ||||
|  | ||||
|         :param protocol_id: a string type parameter identifying a federation | ||||
|             protocol | ||||
|         :param identity_provider: a string type parameter identifying an | ||||
|             Identity Provider | ||||
|         :param mapping: a base.Resource object with federation mapping id | ||||
|  | ||||
|         """ | ||||
|         return self._build_url_and_put( | ||||
|             request_body={'mapping_id': base.getid(mapping)}, | ||||
|             identity_provider_id=base.getid(identity_provider), | ||||
|             protocol_id=protocol_id, **kwargs) | ||||
|  | ||||
|     def get(self, identity_provider, protocol, **kwargs): | ||||
|         """Fetch federation protocol object tied to the Identity Provider. | ||||
|  | ||||
|         Utilize Identity API operation: | ||||
|         GET /OS-FEDERATION/identity_providers/ | ||||
|         $identity_provider/protocols/$protocol | ||||
|  | ||||
|         :param identity_provider: a base.Resource type object with Identity | ||||
|                                   Provider id stored inside | ||||
|         :param protocol: a base.Resource type object with federation protocol | ||||
|                          id stored inside | ||||
|  | ||||
|         """ | ||||
|         return super(ProtocolManager, self).get( | ||||
|             identity_provider_id=base.getid(identity_provider), | ||||
|             protocol_id=base.getid(protocol), **kwargs) | ||||
|  | ||||
|     def list(self, identity_provider, **kwargs): | ||||
|         """List all federation protocol objects tied to the Identity Provider. | ||||
|  | ||||
|         Utilize Identity API operation: | ||||
|         GET /OS-FEDERATION/identity_providers/ | ||||
|         $identity_provider/protocols | ||||
|  | ||||
|         :param identity_provider: a base.Resource type object with Identity | ||||
|             Provider id stored inside | ||||
|  | ||||
|         """ | ||||
|         return super(ProtocolManager, self).list( | ||||
|             identity_provider_id=base.getid(identity_provider), **kwargs) | ||||
|  | ||||
|     def update(self, identity_provider, protocol, mapping, **kwargs): | ||||
|         """Update Protocol object tied to the Identity Provider. | ||||
|  | ||||
|         Utilize Identity API operation: | ||||
|         PATCH /OS-FEDERATION/identity_providers/ | ||||
|         $identity_provider/protocols/$protocol | ||||
|  | ||||
|         :param identity_provider: a base.Resource type object with Identity | ||||
|             Provider id stored inside | ||||
|         :param protocol: a base.Resource type object with federation protocol | ||||
|             id stored inside | ||||
|         :param mapping: a base.Resource object with federation mapping id | ||||
|  | ||||
|  | ||||
|         """ | ||||
|         return super(ProtocolManager, self).update( | ||||
|             identity_provider_id=base.getid(identity_provider), | ||||
|             protocol_id=base.getid(protocol), mapping_id=base.getid(mapping), | ||||
|             **kwargs) | ||||
|  | ||||
|     def delete(self, identity_provider, protocol): | ||||
|         """Delete Protocol object tied to the Identity Provider. | ||||
|  | ||||
|         Utilize Identity API operation: | ||||
|         DELETE /OS-FEDERATION/identity_providers/ | ||||
|         $identity_provider/protocols/$protocol | ||||
|  | ||||
|         :param identity_provider: a base.Resource type object with | ||||
|             Identity Provider id stored inside | ||||
|         :param protocol: a base.Resource type object with federation | ||||
|             protocol id stored inside | ||||
|  | ||||
|         """ | ||||
|         return super(ProtocolManager, self).delete( | ||||
|             identity_provider_id=base.getid(identity_provider), | ||||
|             protocol_id=base.getid(protocol)) | ||||
		Reference in New Issue
	
	Block a user