From f9917d0aa115c512cd846d933961efc2b47c0c39 Mon Sep 17 00:00:00 2001 From: Todd Willey Date: Mon, 26 Jul 2010 15:01:42 -0400 Subject: [PATCH 1/5] Basic standup of SessionToken model for shortlived auth tokens. --- nova/tests/model_unittest.py | 52 ++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/nova/tests/model_unittest.py b/nova/tests/model_unittest.py index 1bd7e527..7823991b 100644 --- a/nova/tests/model_unittest.py +++ b/nova/tests/model_unittest.py @@ -66,6 +66,12 @@ class ModelTestCase(test.TrialTestCase): daemon.save() return daemon + def create_session_token(self): + session_token = model.SessionToken('tk12341234') + session_token['user'] = 'testuser' + session_token.save() + return session_token + @defer.inlineCallbacks def test_create_instance(self): """store with create_instace, then test that a load finds it""" @@ -204,3 +210,49 @@ class ModelTestCase(test.TrialTestCase): if x.identifier == 'testhost:nova-testdaemon': found = True self.assertTrue(found) + + @defer.inlineCallbacks + def test_create_session_token(self): + """create""" + d = yield self.create_session_token() + d = model.SessionToken(d.token) + self.assertFalse(d.is_new_record()) + + @defer.inlineCallbacks + def test_delete_session_token(self): + """create, then destroy, then make sure loads a new record""" + instance = yield self.create_session_token() + yield instance.destroy() + newinst = yield model.SessionToken(instance.token) + self.assertTrue(newinst.is_new_record()) + + @defer.inlineCallbacks + def test_session_token_added_to_set(self): + """create, then check that it is included in list""" + instance = yield self.create_session_token() + found = False + for x in model.SessionToken.all(): + if x.identifier == instance.token: + found = True + self.assert_(found) + + @defer.inlineCallbacks + def test_session_token_associates_user(self): + """create, then check that it is listed for the user""" + instance = yield self.create_session_token() + found = False + for x in model.SessionToken.associated_to('user', 'testuser'): + if x.identifier == instance.identifier: + found = True + self.assertTrue(found) + + @defer.inlineCallbacks + def test_session_token_generation(self): + instance = yield model.SessionToken.generate('username', 'TokenType') + self.assertFalse(instance.is_new_record()) + + @defer.inlineCallbacks + def test_find_generated_session_token(self): + instance = yield model.SessionToken.generate('username', 'TokenType') + found = yield model.SessionToken.lookup(instance.identifier) + self.assert_(found) From 3227f6fd4a2215a2143593a1d3742b50cf0d3c07 Mon Sep 17 00:00:00 2001 From: Todd Willey Date: Mon, 26 Jul 2010 17:00:50 -0400 Subject: [PATCH 2/5] Expiry awareness for SessionToken. --- nova/tests/model_unittest.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/nova/tests/model_unittest.py b/nova/tests/model_unittest.py index 7823991b..0755d857 100644 --- a/nova/tests/model_unittest.py +++ b/nova/tests/model_unittest.py @@ -16,6 +16,7 @@ # License for the specific language governing permissions and limitations # under the License. +from datetime import datetime import logging import time from twisted.internet import defer @@ -256,3 +257,11 @@ class ModelTestCase(test.TrialTestCase): instance = yield model.SessionToken.generate('username', 'TokenType') found = yield model.SessionToken.lookup(instance.identifier) self.assert_(found) + + def test_update_expiry(self): + instance = model.SessionToken('tk12341234') + oldtime = datetime.utcnow() + instance['expiry'] = oldtime.strftime(utils.TIME_FORMAT) + instance.update_expiry() + expiry = utils.parse_isotime(instance['expiry']) + self.assert_(expiry > datetime.utcnow()) From a476899c647ed6588b70c042637c78f8ac9291c3 Mon Sep 17 00:00:00 2001 From: Todd Willey Date: Mon, 26 Jul 2010 18:00:39 -0400 Subject: [PATCH 3/5] Lookup should only not return expired tokens. --- nova/tests/model_unittest.py | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/nova/tests/model_unittest.py b/nova/tests/model_unittest.py index 0755d857..10d3016f 100644 --- a/nova/tests/model_unittest.py +++ b/nova/tests/model_unittest.py @@ -258,10 +258,24 @@ class ModelTestCase(test.TrialTestCase): found = yield model.SessionToken.lookup(instance.identifier) self.assert_(found) - def test_update_expiry(self): + def test_update_session_token_expiry(self): instance = model.SessionToken('tk12341234') oldtime = datetime.utcnow() instance['expiry'] = oldtime.strftime(utils.TIME_FORMAT) instance.update_expiry() expiry = utils.parse_isotime(instance['expiry']) self.assert_(expiry > datetime.utcnow()) + + @defer.inlineCallbacks + def test_session_token_lookup_when_expired(self): + instance = yield model.SessionToken.generate("testuser") + instance['expiry'] = datetime.utcnow().strftime(utils.TIME_FORMAT) + instance.save() + inst = model.SessionToken.lookup(instance.identifier) + self.assertFalse(inst) + + @defer.inlineCallbacks + def test_session_token_lookup_when_not_expired(self): + instance = yield model.SessionToken.generate("testuser") + inst = model.SessionToken.lookup(instance.identifier) + self.assert_(inst) From 0c3226a51330bae8ec8d54aed4b5fb99b53074a4 Mon Sep 17 00:00:00 2001 From: Todd Willey Date: Mon, 26 Jul 2010 23:49:49 -0400 Subject: [PATCH 4/5] Give SessionToken an is_expired method --- nova/tests/model_unittest.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/nova/tests/model_unittest.py b/nova/tests/model_unittest.py index 10d3016f..88ba5e6e 100644 --- a/nova/tests/model_unittest.py +++ b/nova/tests/model_unittest.py @@ -279,3 +279,14 @@ class ModelTestCase(test.TrialTestCase): instance = yield model.SessionToken.generate("testuser") inst = model.SessionToken.lookup(instance.identifier) self.assert_(inst) + + @defer.inlineCallbacks + def test_session_token_is_expired_when_expired(self): + instance = yield model.SessionToken.generate("testuser") + instance['expiry'] = datetime.utcnow().strftime(utils.TIME_FORMAT) + self.assert_(instance.is_expired()) + + @defer.inlineCallbacks + def test_session_token_is_expired_when_not_expired(self): + instance = yield model.SessionToken.generate("testuser") + self.assertFalse(instance.is_expired()) From d25c8ae6346376236b5573d2c2403bb44ce75660 Mon Sep 17 00:00:00 2001 From: Todd Willey Date: Tue, 27 Jul 2010 01:03:05 -0400 Subject: [PATCH 5/5] Flag for SessionToken ttl setting. --- nova/flags.py | 2 ++ nova/tests/model_unittest.py | 11 ++++++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/nova/flags.py b/nova/flags.py index 06ea1e00..3c1a0aca 100644 --- a/nova/flags.py +++ b/nova/flags.py @@ -75,6 +75,8 @@ DEFINE_string('vpn_key_suffix', '-key', 'Suffix to add to project name for vpn key') +DEFINE_integer('auth_token_ttl', 3600, 'Seconds for auth tokens to linger') + # UNUSED DEFINE_string('node_availability_zone', 'nova', diff --git a/nova/tests/model_unittest.py b/nova/tests/model_unittest.py index 88ba5e6e..24c08a90 100644 --- a/nova/tests/model_unittest.py +++ b/nova/tests/model_unittest.py @@ -16,7 +16,7 @@ # License for the specific language governing permissions and limitations # under the License. -from datetime import datetime +from datetime import datetime, timedelta import logging import time from twisted.internet import defer @@ -290,3 +290,12 @@ class ModelTestCase(test.TrialTestCase): def test_session_token_is_expired_when_not_expired(self): instance = yield model.SessionToken.generate("testuser") self.assertFalse(instance.is_expired()) + + @defer.inlineCallbacks + def test_session_token_ttl(self): + instance = yield model.SessionToken.generate("testuser") + now = datetime.utcnow() + delta = timedelta(hours=1) + instance['expiry'] = (now + delta).strftime(utils.TIME_FORMAT) + # give 5 seconds of fuzziness + self.assert_(abs(instance.ttl() - FLAGS.auth_token_ttl) < 5)