You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@libcloud.apache.org by to...@apache.org on 2014/08/14 11:58:42 UTC

[2/2] git commit: Allow user to scope a token to either project or a domain by passing "scope_to" (and "domain_name") argument to Identity v3 class constructor.

Allow user to scope a token to either project or a domain by passing "scope_to"
(and "domain_name") argument to Identity v3 class constructor.


Project: http://git-wip-us.apache.org/repos/asf/libcloud/repo
Commit: http://git-wip-us.apache.org/repos/asf/libcloud/commit/23d4355a
Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/23d4355a
Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/23d4355a

Branch: refs/heads/trunk
Commit: 23d4355a1c86cefdeb04936265a820723a3f5c15
Parents: 9910bd5
Author: Tomaz Muraus <to...@apache.org>
Authored: Thu Aug 14 11:30:08 2014 +0200
Committer: Tomaz Muraus <to...@apache.org>
Committed: Thu Aug 14 11:48:40 2014 +0200

----------------------------------------------------------------------
 libcloud/common/openstack_identity.py           | 61 +++++++++++++++-----
 libcloud/test/common/test_openstack_identity.py | 49 +++++++++++++++-
 2 files changed, 92 insertions(+), 18 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/libcloud/blob/23d4355a/libcloud/common/openstack_identity.py
----------------------------------------------------------------------
diff --git a/libcloud/common/openstack_identity.py b/libcloud/common/openstack_identity.py
index dec8f43..f208258 100644
--- a/libcloud/common/openstack_identity.py
+++ b/libcloud/common/openstack_identity.py
@@ -879,8 +879,24 @@ class OpenStackIdentity_3_0_Connection(OpenStackIdentityConnection):
     name = 'OpenStack Identity API v3.x'
     auth_version = '3.0'
 
-    def __init__(self, auth_url, user_id, key, tenant_name=None, timeout=None,
-                 parent_conn=None):
+    def __init__(self, auth_url, user_id, key, tenant_name=None,
+                 domain_name='Default', scope_to='project',
+                 timeout=None, parent_conn=None):
+        """
+        :param tenant_name: Name of the project this user belongs to. Note:
+                            When scope_to is set to project, this argument
+                            control to which project to scope the token to.
+        :type tenant_name: ``str``
+
+        :param domain_name: Domain the user belongs to. Note: Then scope_to
+                            is set to token, this argument controls to which
+                            domain to scope the token to.
+        :type domain_name: ``str``
+
+        :param scope_to: Whether to scope a token to a "project" or a
+                         "domain"
+        :type scope_to: ``str``
+        """
         super(OpenStackIdentity_3_0_Connection,
               self).__init__(auth_url=auth_url,
                              user_id=user_id,
@@ -888,6 +904,19 @@ class OpenStackIdentity_3_0_Connection(OpenStackIdentityConnection):
                              tenant_name=tenant_name,
                              timeout=timeout,
                              parent_conn=parent_conn)
+        if scope_to not in ['project', 'domain']:
+            raise ValueError('Invalid value for "scope_to" argument: %s' %
+                             (scope_to))
+
+        if scope_to == 'project' and (not tenant_name or not domain_name):
+            raise ValueError('Must provide tenant_name and domain_name '
+                             'argument')
+        elif scope_to == 'domain' and not domain_name:
+            raise ValueError('Must provide domain_name argument')
+
+        self.tenant_name = tenant_name
+        self.domain_name = domain_name
+        self.scope_to = scope_to
         self.auth_user_roles = None
 
     def authenticate(self, force=False):
@@ -897,9 +926,6 @@ class OpenStackIdentity_3_0_Connection(OpenStackIdentityConnection):
         if not self._is_authentication_needed(force=force):
             return self
 
-        # TODO: Support for custom domain
-        domain = 'Default'
-
         data = {
             'auth': {
                 'identity': {
@@ -907,33 +933,36 @@ class OpenStackIdentity_3_0_Connection(OpenStackIdentityConnection):
                     'password': {
                         'user': {
                             'domain': {
-                                'name': domain
+                                'name': self.domain_name
                             },
                             'name': self.user_id,
                             'password': self.key
                         }
                     }
-                },
-                'scope': {
-                    'project': {
-                        'domain': {
-                            'name': domain
-                        },
-                        'name': self.tenant_name
-                    }
                 }
             }
         }
 
-        if self.tenant_name:
+        if self.scope_to == 'project':
+            # Scope token to project (tenant)
             data['auth']['scope'] = {
                 'project': {
                     'domain': {
-                        'name': domain
+                        'name': self.domain_name
                     },
                     'name': self.tenant_name
                 }
             }
+        elif self.domain_name:
+            # Scope token to domain
+            data['auth']['scope'] = {
+                'domain': {
+                    'name': self.domain_name
+                }
+            }
+        else:
+            raise ValueError('Token needs to be scoped either to project or '
+                             'a domain')
 
         data = json.dumps(data)
         response = self.request('/v3/auth/tokens', data=data,

http://git-wip-us.apache.org/repos/asf/libcloud/blob/23d4355a/libcloud/test/common/test_openstack_identity.py
----------------------------------------------------------------------
diff --git a/libcloud/test/common/test_openstack_identity.py b/libcloud/test/common/test_openstack_identity.py
index e84222b..6057401 100644
--- a/libcloud/test/common/test_openstack_identity.py
+++ b/libcloud/test/common/test_openstack_identity.py
@@ -14,7 +14,6 @@
 # limitations under the License.
 
 import sys
-import unittest
 import datetime
 
 try:
@@ -33,6 +32,7 @@ from libcloud.common.openstack_identity import OpenStackServiceCatalog
 from libcloud.common.openstack_identity import OpenStackIdentity_3_0_Connection
 from libcloud.compute.drivers.openstack import OpenStack_1_0_NodeDriver
 
+from libcloud.test import unittest
 from libcloud.test import MockHttp
 from libcloud.test.secrets import OPENSTACK_PARAMS
 from libcloud.test.file_fixtures import ComputeFileFixtures
@@ -229,9 +229,54 @@ class OpenStackIdentity_3_0_ConnectionTests(unittest.TestCase):
 
         self.auth_instance = OpenStackIdentity_3_0_Connection(auth_url='http://none',
                                                               user_id='test',
-                                                              key='test')
+                                                              key='test',
+                                                              tenant_name='test')
         self.auth_instance.auth_token = 'mock'
 
+    def test_scope_to_argument(self):
+        # Invalid scope_to value
+        expected_msg = 'Invalid value for "scope_to" argument: foo'
+        self.assertRaisesRegexp(ValueError, expected_msg,
+                                OpenStackIdentity_3_0_Connection,
+                                auth_url='http://none',
+                                user_id='test',
+                                key='test',
+                                scope_to='foo')
+
+        # Missing tenant_name
+        expected_msg = 'Must provide tenant_name and domain_name argument'
+        self.assertRaisesRegexp(ValueError, expected_msg,
+                                OpenStackIdentity_3_0_Connection,
+                                auth_url='http://none',
+                                user_id='test',
+                                key='test',
+                                scope_to='project')
+
+        # Missing domain_name
+        expected_msg = 'Must provide domain_name argument'
+        self.assertRaisesRegexp(ValueError, expected_msg,
+                                OpenStackIdentity_3_0_Connection,
+                                auth_url='http://none',
+                                user_id='test',
+                                key='test',
+                                scope_to='domain',
+                                domain_name=None)
+
+        # Scope to project all ok
+        OpenStackIdentity_3_0_Connection(auth_url='http://none',
+                                         user_id='test',
+                                         key='test',
+                                         scope_to='project',
+                                         tenant_name='test',
+                                         domain_name='Default')
+        # Scope to domain
+        OpenStackIdentity_3_0_Connection(auth_url='http://none',
+                                         user_id='test',
+                                         key='test',
+                                         scope_to='domain',
+                                         tenant_name=None,
+                                         domain_name='Default')
+
     def test_list_supported_versions(self):
         OpenStackIdentity_3_0_MockHttp.type = 'v3'