libcloud-notifications mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From to...@apache.org
Subject svn commit: r1485020 - in /libcloud/trunk/libcloud: common/openstack.py test/compute/test_openstack.py
Date Wed, 22 May 2013 00:45:33 GMT
Author: tomaz
Date: Wed May 22 00:45:33 2013
New Revision: 1485020

URL: http://svn.apache.org/r1485020
Log:
Add ability to re-use existing still valid auth token to the
OpenStackAuthConnection class.

For backward compatibility, preserve the old behavior for now and force re-auth
on every auth() call.

Modified:
    libcloud/trunk/libcloud/common/openstack.py
    libcloud/trunk/libcloud/test/compute/test_openstack.py

Modified: libcloud/trunk/libcloud/common/openstack.py
URL: http://svn.apache.org/viewvc/libcloud/trunk/libcloud/common/openstack.py?rev=1485020&r1=1485019&r2=1485020&view=diff
==============================================================================
--- libcloud/trunk/libcloud/common/openstack.py (original)
+++ libcloud/trunk/libcloud/common/openstack.py Wed May 22 00:45:33 2013
@@ -20,6 +20,8 @@ import sys
 import binascii
 import os
 
+from datetime import datetime
+
 from libcloud.utils.py3 import httplib
 from libcloud.utils.iso8601 import parse_date
 
@@ -34,6 +36,14 @@ except ImportError:
 
 AUTH_API_VERSION = '1.1'
 
+# Auth versions which contain token expiration information.
+AUTH_VERSIONS_WITH_EXPIRES = [
+    '1.1',
+    '2.0',
+    '2.0_apikey',
+    '2.0_password'
+]
+
 __all__ = [
     "OpenStackBaseConnection",
     "OpenStackAuthConnection"
@@ -110,7 +120,19 @@ class OpenStackAuthConnection(Connection
         headers['Content-Type'] = 'application/json; charset=UTF-8'
         return headers
 
-    def authenticate(self):
+    def authenticate(self, force=True):
+        """
+        Authenticate against the keystone api.
+
+        @param force: Forcefully update the token even if it's already cached
+                      and still valid.
+        @type force: C{bool}
+        """
+        if not force and self.auth_version in AUTH_VERSIONS_WITH_EXPIRES \
+           and self._is_token_valid():
+           # If token is still valid, there is no need to re-authenticate
+           return self
+
         if self.auth_version == "1.0":
             return self.authenticate_1_0()
         elif self.auth_version == "1.1":
@@ -251,6 +273,27 @@ class OpenStackAuthConnection(Connection
 
         return self
 
+    def _is_token_valid(self):
+        """
+        Return True if the current taken is already cached and hasn't expired
+        yet.
+
+        @rtype: C{bool}
+        """
+        if not self.auth_token:
+            return False
+
+        if not self.auth_token_expires:
+            return False
+
+        time_tuple_expires = self.auth_token_expires.utctimetuple()
+        time_tuple_now = datetime.utcnow().utctimetuple()
+
+        # TODO: Subtract some reasonable grace time period
+        if time_tuple_now < time_tuple_expires:
+            return True
+
+        return False
 
 class OpenStackServiceCatalog(object):
     """

Modified: libcloud/trunk/libcloud/test/compute/test_openstack.py
URL: http://svn.apache.org/viewvc/libcloud/trunk/libcloud/test/compute/test_openstack.py?rev=1485020&r1=1485019&r2=1485020&view=diff
==============================================================================
--- libcloud/trunk/libcloud/test/compute/test_openstack.py (original)
+++ libcloud/trunk/libcloud/test/compute/test_openstack.py Wed May 22 00:45:33 2013
@@ -12,14 +12,18 @@
 # 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.
+
 import sys
 import unittest
+import datetime
 
 try:
     import simplejson as json
 except ImportError:
     import json
 
+from mock import Mock
+
 from libcloud.utils.py3 import httplib
 from libcloud.utils.py3 import method_type
 from libcloud.utils.py3 import u
@@ -130,9 +134,58 @@ class OpenStackAuthConnectionTests(unitt
             if auth_version in ['2.0', '2.0_apikey', '2.0_password']:
                 self.assertTrue(osa.auth_user_info is not None)
 
-    def test_token_expiration_and_force_reuath(self):
-        # TODO
-        pass
+    def test_token_expiration_and_force_reauthentication(self):
+        user_id = OPENSTACK_PARAMS[0]
+        key = OPENSTACK_PARAMS[1]
+
+        connection = self._get_mock_connection(OpenStack_2_0_MockHttp)
+        auth_url = connection.auth_url
+        auth_version = '2.0'
+
+        yesterday = datetime.datetime.today() - datetime.timedelta(1)
+        tomorrow = datetime.datetime.today() + datetime.timedelta(1)
+
+        osa = OpenStackAuthConnection(connection, auth_url, auth_version,
+                                      user_id, key)
+
+        mocked_auth_method = Mock(wraps=osa.authenticate_2_0_with_body)
+        osa.authenticate_2_0_with_body = mocked_auth_method
+
+        # Force re-auth, expired token
+        osa.auth_token = None
+        osa.auth_token_expires = yesterday
+        count = 5
+
+        for i in range(0, count):
+            osa.authenticate(force=True)
+
+        self.assertEqual(mocked_auth_method.call_count, count)
+
+        # No force reauth, expired token
+        osa.auth_token = None
+        osa.auth_token_expires = yesterday
+
+        mocked_auth_method.call_count = 0
+        self.assertEqual(mocked_auth_method.call_count, 0)
+
+        for i in range(0, count):
+            osa.authenticate(force=False)
+
+        self.assertEqual(mocked_auth_method.call_count, count)
+
+        # No force reauth, valid / non-expired token
+        osa.auth_token = None
+
+        mocked_auth_method.call_count = 0
+        self.assertEqual(mocked_auth_method.call_count, 0)
+
+        for i in range(0, count):
+            osa.authenticate(force=False)
+
+            if i == 0:
+                osa.auth_token_expires = tomorrow
+
+        self.assertEqual(mocked_auth_method.call_count, 1)
 
     def _get_mock_connection(self, mock_http_class):
         connection = OpenStackBaseConnection(*OPENSTACK_PARAMS)
@@ -1121,7 +1174,6 @@ class OpenStack_1_1_MockHttp(MockHttpTes
 
         raise NotImplementedError()
 
-
     def _v1_1_slug_servers_12064(self, method, url, body, headers):
         if method == "GET":
             body = self.fixtures.load('_servers_12064.json')



Mime
View raw message