summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.rst11
-rw-r--r--keystonelight/backends/kvs.py28
-rw-r--r--keystonelight/keystone_compat.py1
-rw-r--r--keystonelight/service.py5
-rw-r--r--keystonelight/test.py19
-rw-r--r--tests/default.conf19
-rw-r--r--tests/test_backend_kvs.py157
7 files changed, 221 insertions, 19 deletions
diff --git a/README.rst b/README.rst
index d78646819..344be5a92 100644
--- a/README.rst
+++ b/README.rst
@@ -91,8 +91,9 @@ Diagram: keystone_compat_flows.sdx_
Still To Do
-----------
-* Dev and testing setups would do well with some user/tenant/etc CRUD, for the
- KVS backends at least.
-* Fixture loading functionality would also be killer tests and dev.
-* LDAP backend.
-* Keystone import.
+ * Dev and testing setups would do well with some user/tenant/etc CRUD, for the
+ KVS backends at least.
+ * Fixture loading functionality would also be killer tests and dev.
+ * LDAP backend.
+ * Keystone import.
+ * Admin-only interface
diff --git a/keystonelight/backends/kvs.py b/keystonelight/backends/kvs.py
index a9221124b..caa6e4c3d 100644
--- a/keystonelight/backends/kvs.py
+++ b/keystonelight/backends/kvs.py
@@ -6,25 +6,36 @@ class DictKvs(dict):
def delete(self, key):
del self[key]
+
INMEMDB = DictKvs()
+
class KvsIdentity(object):
def __init__(self, options, db=None):
if db is None:
db = INMEMDB
+ elif type(db) is type({}):
+ db = DictKvs(db)
self.db = db
# Public interface
def authenticate(self, user_id=None, tenant_id=None, password=None):
+ """Authenticate based on a user, tenant and password.
+
+ Expects the user object to have a password field and the tenant to be
+ in the list of tenants on the user.
+
+ """
user_ref = self.get_user(user_id)
tenant_ref = None
extras_ref = None
- if user_ref['password'] != password:
+ if not user_ref or user_ref.get('password') != password:
raise AssertionError('Invalid user / password')
+ if tenant_id and tenant_id not in user_ref['tenants']:
+ raise AssertionError('Invalid tenant')
- if tenant_id and tenant_id in user_ref['tenants']:
- tenant_ref = self.get_tenant(tenant_id)
- extras_ref = self.get_extras(user_id, tenant_id)
+ tenant_ref = self.get_tenant(tenant_id)
+ extras_ref = self.get_extras(user_id, tenant_id)
return (user_ref, tenant_ref, extras_ref)
def get_tenant(self, tenant_id):
@@ -61,6 +72,8 @@ class KvsToken(object):
def __init__(self, options, db=None):
if db is None:
db = INMEMDB
+ elif type(db) is type({}):
+ db = DictKvs(db)
self.db = db
# Public interface
@@ -79,12 +92,15 @@ class KvsCatalog(object):
def __init__(self, options, db=None):
if db is None:
db = INMEMDB
+ elif type(db) is type({}):
+ db = DictKvs(db)
self.db = db
# Public interface
def get_catalog(self, user_id, tenant_id, extras=None):
- return self.db.get('catalog-%s' % tenant_id)
+ return self.db.get('catalog-%s-%s' % (tenant_id, user_id))
# Private interface
def _create_catalog(self, user_id, tenant_id, data):
- self.db.set('catalog-%s' % tenant_id, data)
+ self.db.set('catalog-%s-%s' % (tenant_id, user_id), data)
+ return data
diff --git a/keystonelight/keystone_compat.py b/keystonelight/keystone_compat.py
index 86746d74e..cf99244c0 100644
--- a/keystonelight/keystone_compat.py
+++ b/keystonelight/keystone_compat.py
@@ -17,7 +17,6 @@ class KeystoneRouter(wsgi.Router):
self.options = options
self.keystone_controller = KeystoneController(options)
-
mapper = routes.Mapper()
mapper.connect('/v2.0/tokens',
controller=self.keystone_controller,
diff --git a/keystonelight/service.py b/keystonelight/service.py
index c607f8aa7..1db788698 100644
--- a/keystonelight/service.py
+++ b/keystonelight/service.py
@@ -198,3 +198,8 @@ def identity_app_factory(global_conf, **local_conf):
conf.update(local_conf)
return Router(conf)
+
+def app_factory(global_conf, **local_conf):
+ conf = global_conf.copy()
+ conf.update(local_conf)
+ return Router(conf)
diff --git a/keystonelight/test.py b/keystonelight/test.py
index a710203f1..9a24883c6 100644
--- a/keystonelight/test.py
+++ b/keystonelight/test.py
@@ -1,6 +1,8 @@
import ConfigParser
+import logging
import os
import unittest
+import subprocess
import sys
from paste import deploy
@@ -24,13 +26,16 @@ def checkout_vendor(repo, rev):
name = name[:-4]
revdir = os.path.join(VENDOR, '%s-%s' % (name, rev.replace('/', '_')))
-
- if not os.path.exists(revdir):
- utils.git('clone', repo, revdir)
-
- cd(revdir)
- utils.git('pull')
- utils.git('checkout', '-q', rev)
+ try:
+ if not os.path.exists(revdir):
+ utils.git('clone', repo, revdir)
+
+ cd(revdir)
+ utils.git('pull')
+ utils.git('checkout', '-q', rev)
+ except subprocess.CalledProcessError as e:
+ logging.warning('Failed to checkout %s', repo)
+ pass
return revdir
diff --git a/tests/default.conf b/tests/default.conf
new file mode 100644
index 000000000..fa6ac28b5
--- /dev/null
+++ b/tests/default.conf
@@ -0,0 +1,19 @@
+[DEFAULT]
+catalog_driver = keystonelight.backends.kvs.KvsCatalog
+identity_driver = keystonelight.backends.kvs.KvsIdentity
+token_driver = keystonelight.backends.kvs.KvsToken
+
+[filter:debug]
+paste.filter_factory = keystonelight.wsgi:Debug.factory
+
+[filter:token_auth]
+paste.filter_factory = keystonelight.service:TokenAuthMiddleware.factory
+
+[filter:json_body]
+paste.filter_factory = keystonelight.service:JsonBodyMiddleware.factory
+
+[app:keystonelight]
+paste.app_factory = keystonelight.service:app_factory
+
+[pipeline:main]
+pipeline = token_auth json_body debug keystonelight
diff --git a/tests/test_backend_kvs.py b/tests/test_backend_kvs.py
new file mode 100644
index 000000000..3561a13c5
--- /dev/null
+++ b/tests/test_backend_kvs.py
@@ -0,0 +1,157 @@
+import uuid
+
+from keystonelight import models
+from keystonelight import test
+from keystonelight.backends import kvs
+
+
+class KvsIdentity(test.TestCase):
+ def setUp(self):
+ super(KvsIdentity, self).setUp()
+ options = self.appconfig('default')
+ self.identity_api = kvs.KvsIdentity(options=options, db={})
+ self._load_fixtures()
+
+ def _load_fixtures(self):
+ self.tenant_bar = self.identity_api._create_tenant(
+ 'bar',
+ models.Tenant(id='bar', name='BAR'))
+ self.user_foo = self.identity_api._create_user(
+ 'foo',
+ models.User(id='foo',
+ name='FOO',
+ password='foo2',
+ tenants=[self.tenant_bar['id']]))
+ self.extras_foobar = self.identity_api._create_extras(
+ 'foo', 'bar',
+ {'extra': 'extra'})
+
+ def test_authenticate_bad_user(self):
+ self.assertRaises(AssertionError,
+ self.identity_api.authenticate,
+ user_id=self.user_foo['id'] + 'WRONG',
+ tenant_id=self.tenant_bar['id'],
+ password=self.user_foo['password'])
+
+ def test_authenticate_bad_password(self):
+ self.assertRaises(AssertionError,
+ self.identity_api.authenticate,
+ user_id=self.user_foo['id'],
+ tenant_id=self.tenant_bar['id'],
+ password=self.user_foo['password'] + 'WRONG')
+
+ def test_authenticate_invalid_tenant(self):
+ self.assertRaises(AssertionError,
+ self.identity_api.authenticate,
+ user_id=self.user_foo['id'],
+ tenant_id=self.tenant_bar['id'] + 'WRONG',
+ password=self.user_foo['password'])
+
+ def test_authenticate_no_tenant(self):
+ user_ref, tenant_ref, extras_ref = self.identity_api.authenticate(
+ user_id=self.user_foo['id'],
+ password=self.user_foo['password'])
+ self.assertDictEquals(user_ref, self.user_foo)
+ self.assert_(tenant_ref is None)
+ self.assert_(extras_ref is None)
+
+ def test_authenticate(self):
+ user_ref, tenant_ref, extras_ref = self.identity_api.authenticate(
+ user_id=self.user_foo['id'],
+ tenant_id=self.tenant_bar['id'],
+ password=self.user_foo['password'])
+ self.assertDictEquals(user_ref, self.user_foo)
+ self.assertDictEquals(tenant_ref, self.tenant_bar)
+ self.assertDictEquals(extras_ref, self.extras_foobar)
+
+ def test_get_tenant_bad_tenant(self):
+ tenant_ref = self.identity_api.get_tenant(
+ tenant_id=self.tenant_bar['id'] + 'WRONG')
+ self.assert_(tenant_ref is None)
+
+ def test_get_tenant(self):
+ tenant_ref = self.identity_api.get_tenant(tenant_id=self.tenant_bar['id'])
+ self.assertDictEquals(tenant_ref, self.tenant_bar)
+
+ def test_get_tenant_by_name_bad_tenant(self):
+ tenant_ref = self.identity_api.get_tenant(
+ tenant_id=self.tenant_bar['name'] + 'WRONG')
+ self.assert_(tenant_ref is None)
+
+ def test_get_tenant_by_name(self):
+ tenant_ref = self.identity_api.get_tenant_by_name(
+ tenant_name=self.tenant_bar['name'])
+ self.assertDictEquals(tenant_ref, self.tenant_bar)
+
+ def test_get_user_bad_user(self):
+ user_ref = self.identity_api.get_user(
+ user_id=self.user_foo['id'] + 'WRONG')
+ self.assert_(user_ref is None)
+
+ def test_get_user(self):
+ user_ref = self.identity_api.get_user(user_id=self.user_foo['id'])
+ self.assertDictEquals(user_ref, self.user_foo)
+
+ def test_get_extras_bad_user(self):
+ extras_ref = self.identity_api.get_extras(
+ user_id=self.user_foo['id'] + 'WRONG',
+ tenant_id=self.tenant_bar['id'])
+ self.assert_(extras_ref is None)
+
+ def test_get_extras_bad_tenant(self):
+ extras_ref = self.identity_api.get_extras(
+ user_id=self.user_foo['id'],
+ tenant_id=self.tenant_bar['id'] + 'WRONG')
+ self.assert_(extras_ref is None)
+
+ def test_get_extras(self):
+ extras_ref = self.identity_api.get_extras(
+ user_id=self.user_foo['id'],
+ tenant_id=self.tenant_bar['id'])
+ self.assertDictEquals(extras_ref, self.extras_foobar)
+
+
+class KvsToken(test.TestCase):
+ def setUp(self):
+ super(KvsToken, self).setUp()
+ options = self.appconfig('default')
+ self.token_api = kvs.KvsToken(options=options, db={})
+
+ def test_token_crud(self):
+ token_id = uuid.uuid4().hex
+ data = {'id': token_id,
+ 'a': 'b'}
+ data_ref = self.token_api.create_token(token_id, data)
+ self.assertDictEquals(data_ref, data)
+
+ new_data_ref = self.token_api.get_token(token_id)
+ self.assertEquals(new_data_ref, data)
+
+ self.token_api.delete_token(token_id)
+ deleted_data_ref = self.token_api.get_token(token_id)
+ self.assert_(deleted_data_ref is None)
+
+
+class KvsCatalog(test.TestCase):
+ def setUp(self):
+ super(KvsCatalog, self).setUp()
+ options = self.appconfig('default')
+ self.catalog_api = kvs.KvsCatalog(options=options, db={})
+ self._load_fixtures()
+
+ def _load_fixtures(self):
+ self.catalog_foobar = self.catalog_api._create_catalog(
+ 'foo', 'bar',
+ {'RegionFoo': {'service_bar': {'foo': 'bar'}}})
+
+ def test_get_catalog_bad_user(self):
+ catalog_ref = self.catalog_api.get_catalog('foo' + 'WRONG', 'bar')
+ self.assert_(catalog_ref is None)
+
+ def test_get_catalog_bad_tenant(self):
+ catalog_ref = self.catalog_api.get_catalog('foo', 'bar' + 'WRONG')
+ self.assert_(catalog_ref is None)
+
+ def test_get_catalog(self):
+ catalog_ref = self.catalog_api.get_catalog('foo', 'bar')
+ self.assertDictEquals(catalog_ref, self.catalog_foobar)