keystoneclient tests working against sql backend
This commit is contained in:
parent
4b4ada27ca
commit
13ec79bf48
@ -64,10 +64,12 @@ class KvsIdentity(object):
|
||||
return role_ref
|
||||
|
||||
def list_users(self):
|
||||
return self.db.get('user_list', [])
|
||||
user_ids = self.db.get('user_list', [])
|
||||
return [self.get_user(x) for x in user_ids]
|
||||
|
||||
def list_roles(self):
|
||||
return self.db.get('role_list', [])
|
||||
role_ids = self.db.get('role_list', [])
|
||||
return [self.get_role(x) for x in role_ids]
|
||||
|
||||
# These should probably be part of the high-level API
|
||||
def add_user_to_tenant(self, tenant_id, user_id):
|
||||
|
@ -63,11 +63,12 @@ class DictBase(object):
|
||||
Includes attributes from joins.
|
||||
|
||||
"""
|
||||
local = dict(self)
|
||||
joined = dict([(k, v) for k, v in self.__dict__.iteritems()
|
||||
if not k[0] == '_'])
|
||||
local.update(joined)
|
||||
return local.iteritems()
|
||||
return dict([(k, getattr(self, k)) for k in self])
|
||||
#local = dict(self)
|
||||
#joined = dict([(k, v) for k, v in self.__dict__.iteritems()
|
||||
# if not k[0] == '_'])
|
||||
#local.update(joined)
|
||||
#return local.iteritems()
|
||||
|
||||
|
||||
# Tables
|
||||
@ -75,13 +76,51 @@ class User(Base, DictBase):
|
||||
__tablename__ = 'user'
|
||||
id = sql.Column(sql.String(64), primary_key=True)
|
||||
name = sql.Column(sql.String(64), unique=True)
|
||||
password = sql.Column(sql.String(64))
|
||||
#password = sql.Column(sql.String(64))
|
||||
extra = sql.Column(JsonBlob())
|
||||
|
||||
@classmethod
|
||||
def from_dict(cls, user_dict):
|
||||
# shove any non-indexed properties into extra
|
||||
extra = {}
|
||||
for k, v in user_dict.copy().iteritems():
|
||||
# TODO(termie): infer this somehow
|
||||
if k not in ['id', 'name']:
|
||||
extra[k] = user_dict.pop(k)
|
||||
|
||||
user_dict['extra'] = extra
|
||||
return cls(**user_dict)
|
||||
|
||||
def to_dict(self):
|
||||
extra_copy = self.extra.copy()
|
||||
extra_copy['id'] = self.id
|
||||
extra_copy['name'] = self.name
|
||||
return extra_copy
|
||||
|
||||
|
||||
class Tenant(Base, DictBase):
|
||||
__tablename__ = 'tenant'
|
||||
id = sql.Column(sql.String(64), primary_key=True)
|
||||
name = sql.Column(sql.String(64), unique=True)
|
||||
extra = sql.Column(JsonBlob())
|
||||
|
||||
@classmethod
|
||||
def from_dict(cls, tenant_dict):
|
||||
# shove any non-indexed properties into extra
|
||||
extra = {}
|
||||
for k, v in tenant_dict.copy().iteritems():
|
||||
# TODO(termie): infer this somehow
|
||||
if k not in ['id', 'name']:
|
||||
extra[k] = tenant_dict.pop(k)
|
||||
|
||||
tenant_dict['extra'] = extra
|
||||
return cls(**tenant_dict)
|
||||
|
||||
def to_dict(self):
|
||||
extra_copy = self.extra.copy()
|
||||
extra_copy['id'] = self.id
|
||||
extra_copy['name'] = self.name
|
||||
return extra_copy
|
||||
|
||||
|
||||
class Role(Base, DictBase):
|
||||
@ -143,7 +182,7 @@ class SqlBase(object):
|
||||
|
||||
engine_args = {
|
||||
"pool_recycle": CONF.sql.idle_timeout,
|
||||
"echo": False,
|
||||
"echo": True,
|
||||
}
|
||||
|
||||
if "sqlite" in connection_dict.drivername:
|
||||
@ -177,6 +216,7 @@ class SqlIdentity(SqlBase):
|
||||
raise AssertionError('Invalid tenant')
|
||||
|
||||
tenant_ref = self.get_tenant(tenant_id)
|
||||
print 'ETESTSET', tenant_ref
|
||||
if tenant_ref:
|
||||
extras_ref = self.get_extras(user_id, tenant_id)
|
||||
else:
|
||||
@ -186,29 +226,37 @@ class SqlIdentity(SqlBase):
|
||||
def get_tenant(self, tenant_id):
|
||||
session = self.get_session()
|
||||
tenant_ref = session.query(Tenant).filter_by(id=tenant_id).first()
|
||||
return tenant_ref
|
||||
if not tenant_ref:
|
||||
return
|
||||
return tenant_ref.to_dict()
|
||||
|
||||
def get_tenant_by_name(self, tenant_name):
|
||||
session = self.get_session()
|
||||
tenant_ref = session.query(Tenant).filter_by(name=tenant_name).first()
|
||||
return tenant_ref
|
||||
if not tenant_ref:
|
||||
return
|
||||
return tenant_ref.to_dict()
|
||||
|
||||
def get_user(self, user_id):
|
||||
session = self.get_session()
|
||||
user_ref = session.query(User).filter_by(id=user_id).first()
|
||||
return user_ref
|
||||
if not user_ref:
|
||||
return
|
||||
return user_ref.to_dict()
|
||||
|
||||
def get_user_by_name(self, user_name):
|
||||
session = self.get_session()
|
||||
user_ref = session.query(User).filter_by(name=user_name).first()
|
||||
return user_ref
|
||||
if not user_ref:
|
||||
return
|
||||
return user_ref.to_dict()
|
||||
|
||||
def get_extras(self, user_id, tenant_id):
|
||||
session = self.get_session()
|
||||
extras_ref = session.query(Extras)\
|
||||
.filter_by(user_id=user_id)\
|
||||
.filter_by(tenant_id=tenant_id)\
|
||||
.first()
|
||||
.filter_by(user_id=user_id)\
|
||||
.filter_by(tenant_id=tenant_id)\
|
||||
.first()
|
||||
return getattr(extras_ref, 'data', None)
|
||||
|
||||
def get_role(self, role_id):
|
||||
@ -219,7 +267,7 @@ class SqlIdentity(SqlBase):
|
||||
def list_users(self):
|
||||
session = self.get_session()
|
||||
user_refs = session.query(User)
|
||||
return list(user_refs)
|
||||
return [x.to_dict() for x in user_refs]
|
||||
|
||||
def list_roles(self):
|
||||
session = self.get_session()
|
||||
@ -233,11 +281,13 @@ class SqlIdentity(SqlBase):
|
||||
session.add(UserTenantMembership(user_id=user_id, tenant_id=tenant_id))
|
||||
|
||||
def remove_user_from_tenant(self, tenant_id, user_id):
|
||||
user_ref = self.get_user(user_id)
|
||||
tenants = set(user_ref.get('tenants', []))
|
||||
tenants.remove(tenant_id)
|
||||
user_ref['tenants'] = list(tenants)
|
||||
self.update_user(user_id, user_ref)
|
||||
session = self.get_session()
|
||||
membership_ref = session.query(UserTenantMembership)\
|
||||
.filter_by(user_id=user_id)\
|
||||
.filter_by(tenant_id=tenant_id)\
|
||||
.first()
|
||||
with session.begin():
|
||||
session.delete(membership_ref)
|
||||
|
||||
def get_tenants_for_user(self, user_id):
|
||||
session = self.get_session()
|
||||
@ -255,65 +305,84 @@ class SqlIdentity(SqlBase):
|
||||
|
||||
def add_role_to_user_and_tenant(self, user_id, tenant_id, role_id):
|
||||
extras_ref = self.get_extras(user_id, tenant_id)
|
||||
is_new = False
|
||||
if not extras_ref:
|
||||
is_new = True
|
||||
extras_ref = {}
|
||||
roles = set(extras_ref.get('roles', []))
|
||||
roles.add(role_id)
|
||||
extras_ref['roles'] = list(roles)
|
||||
self.update_extras(user_id, tenant_id, extras_ref)
|
||||
if not is_new:
|
||||
self.update_extras(user_id, tenant_id, extras_ref)
|
||||
else:
|
||||
self.create_extras(user_id, tenant_id, extras_ref)
|
||||
|
||||
def remove_role_from_user_and_tenant(self, user_id, tenant_id, role_id):
|
||||
extras_ref = self.get_extras(user_id, tenant_id)
|
||||
is_new = False
|
||||
if not extras_ref:
|
||||
is_new = True
|
||||
extras_ref = {}
|
||||
roles = set(extras_ref.get('roles', []))
|
||||
roles.remove(role_id)
|
||||
extras_ref['roles'] = list(roles)
|
||||
self.update_extras(user_id, tenant_id, extras_ref)
|
||||
if not is_new:
|
||||
self.update_extras(user_id, tenant_id, extras_ref)
|
||||
else:
|
||||
self.create_extras(user_id, tenant_id, extras_ref)
|
||||
|
||||
# CRUD
|
||||
def create_user(self, id, user):
|
||||
session = self.get_session()
|
||||
with session.begin():
|
||||
session.add(User(**user))
|
||||
return user
|
||||
user_ref = User.from_dict(user)
|
||||
session.add(user_ref)
|
||||
return user_ref.to_dict()
|
||||
|
||||
def update_user(self, id, user):
|
||||
# get the old name and delete it too
|
||||
old_user = self.db.get('user-%s' % id)
|
||||
self.db.delete('user_name-%s' % old_user['name'])
|
||||
self.db.set('user-%s' % id, user)
|
||||
self.db.set('user_name-%s' % user['name'], user)
|
||||
return user
|
||||
session = self.get_session()
|
||||
with session.begin():
|
||||
user_ref = session.query(User).filter_by(id=id).first()
|
||||
old_user_dict = user_ref.to_dict()
|
||||
for k in user:
|
||||
old_user_dict[k] = user[k]
|
||||
new_user = User.from_dict(old_user_dict)
|
||||
|
||||
user_ref.name = new_user.name
|
||||
user_ref.extra = new_user.extra
|
||||
return user_ref
|
||||
|
||||
def delete_user(self, id):
|
||||
old_user = self.db.get('user-%s' % id)
|
||||
self.db.delete('user_name-%s' % old_user['name'])
|
||||
self.db.delete('user-%s' % id)
|
||||
user_list = set(self.db.get('user_list', []))
|
||||
user_list.remove(id)
|
||||
self.db.set('user_list', list(user_list))
|
||||
return None
|
||||
session = self.get_session()
|
||||
user_ref = session.query(User).filter_by(id=id).first()
|
||||
with session.begin():
|
||||
session.delete(user_ref)
|
||||
|
||||
def create_tenant(self, id, tenant):
|
||||
session = self.get_session()
|
||||
with session.begin():
|
||||
session.add(Tenant(**tenant))
|
||||
return tenant
|
||||
tenant_ref = Tenant.from_dict(tenant)
|
||||
session.add(tenant_ref)
|
||||
return tenant_ref.to_dict()
|
||||
|
||||
def update_tenant(self, id, tenant):
|
||||
# get the old name and delete it too
|
||||
old_tenant = self.db.get('tenant-%s' % id)
|
||||
self.db.delete('tenant_name-%s' % old_tenant['name'])
|
||||
self.db.set('tenant-%s' % id, tenant)
|
||||
self.db.set('tenant_name-%s' % tenant['name'], tenant)
|
||||
return tenant
|
||||
session = self.get_session()
|
||||
with session.begin():
|
||||
tenant_ref = session.query(Tenant).filter_by(id=id).first()
|
||||
old_tenant_dict = tenant_ref.to_dict()
|
||||
for k in tenant:
|
||||
old_tenant_dict[k] = tenant[k]
|
||||
new_tenant = Tenant.from_dict(old_tenant_dict)
|
||||
|
||||
tenant_ref.name = new_tenant.name
|
||||
tenant_ref.extra = new_tenant.extra
|
||||
return tenant_ref
|
||||
|
||||
def delete_tenant(self, id):
|
||||
old_tenant = self.db.get('tenant-%s' % id)
|
||||
self.db.delete('tenant_name-%s' % old_tenant['name'])
|
||||
self.db.delete('tenant-%s' % id)
|
||||
return None
|
||||
session = self.get_session()
|
||||
tenant_ref = session.query(Tenant).filter_by(id=id).first()
|
||||
with session.begin():
|
||||
session.delete(tenant_ref)
|
||||
|
||||
def create_extras(self, user_id, tenant_id, extras):
|
||||
session = self.get_session()
|
||||
@ -322,8 +391,17 @@ class SqlIdentity(SqlBase):
|
||||
return extras
|
||||
|
||||
def update_extras(self, user_id, tenant_id, extras):
|
||||
self.db.set('extras-%s-%s' % (tenant_id, user_id), extras)
|
||||
return extras
|
||||
session = self.get_session()
|
||||
with session.begin():
|
||||
extras_ref = session.query(Extras)\
|
||||
.filter_by(user_id=user_id)\
|
||||
.filter_by(tenant_id=tenant_id)\
|
||||
.first()
|
||||
data = extras_ref.data.copy()
|
||||
for k in extras:
|
||||
data[k] = extras[k]
|
||||
extras_ref.data = data
|
||||
return extras_ref
|
||||
|
||||
def delete_extras(self, user_id, tenant_id):
|
||||
self.db.delete('extras-%s-%s' % (tenant_id, user_id))
|
||||
@ -336,15 +414,18 @@ class SqlIdentity(SqlBase):
|
||||
return role
|
||||
|
||||
def update_role(self, id, role):
|
||||
self.db.set('role-%s' % id, role)
|
||||
return role
|
||||
session = self.get_session()
|
||||
with session.begin():
|
||||
role_ref = session.query(Role).filter_by(id=id).first()
|
||||
for k in role:
|
||||
role_ref[k] = role[k]
|
||||
return role_ref
|
||||
|
||||
def delete_role(self, id):
|
||||
self.db.delete('role-%s' % id)
|
||||
role_list = set(self.db.get('role_list', []))
|
||||
role_list.remove(id)
|
||||
self.db.set('role_list', list(role_list))
|
||||
return None
|
||||
session = self.get_session()
|
||||
role_ref = session.query(Role).filter_by(id=id).first()
|
||||
with session.begin():
|
||||
session.delete(role_ref)
|
||||
|
||||
|
||||
class SqlToken(SqlBase):
|
||||
|
@ -511,8 +511,10 @@ class KeystoneTenantController(service.BaseApplication):
|
||||
assert token_ref is not None
|
||||
|
||||
user_ref = token_ref['user']
|
||||
tenant_ids = self.identity_api.get_tenants_for_user(
|
||||
context, user_ref['id'])
|
||||
tenant_refs = []
|
||||
for tenant_id in user_ref['tenants']:
|
||||
for tenant_id in tenant_ids:
|
||||
tenant_refs.append(self.identity_api.get_tenant(
|
||||
context=context,
|
||||
tenant_id=tenant_id))
|
||||
@ -537,9 +539,9 @@ class KeystoneTenantController(service.BaseApplication):
|
||||
return {'tenant': tenant}
|
||||
|
||||
# CRUD Extension
|
||||
def create_tenant(self, context, **kw):
|
||||
def create_tenant(self, context, tenant):
|
||||
tenant_ref = self._normalize_dict(tenant)
|
||||
self.assert_admin(context)
|
||||
tenant_ref = kw.get('tenant')
|
||||
tenant_id = (tenant_ref.get('id')
|
||||
and tenant_ref.get('id')
|
||||
or uuid.uuid4().hex)
|
||||
@ -590,23 +592,21 @@ class KeystoneUserController(service.BaseApplication):
|
||||
# NOTE(termie): i can't imagine that this really wants all the data
|
||||
# about every single user in the system...
|
||||
self.assert_admin(context)
|
||||
user_list = self.identity_api.list_users(context)
|
||||
return {'users': [{'id': x} for x in user_list]}
|
||||
user_refs = self.identity_api.list_users(context)
|
||||
return {'users': user_refs}
|
||||
|
||||
# CRUD extension
|
||||
def create_user(self, context, user):
|
||||
user = self._normalize_dict(user)
|
||||
self.assert_admin(context)
|
||||
tenant_id = user.get('tenantId')
|
||||
tenants = []
|
||||
if tenant_id:
|
||||
tenants.append(tenant_id)
|
||||
tenant_id = user.get('tenantId', None)
|
||||
user_id = uuid.uuid4().hex
|
||||
user_ref = user.copy()
|
||||
#user_ref.pop('tenantId', None)
|
||||
user_ref['id'] = user_id
|
||||
user_ref['tenants'] = tenants
|
||||
new_user_ref = self.identity_api.create_user(
|
||||
context, user_id, user_ref)
|
||||
if tenant_id:
|
||||
self.identity_api.add_user_to_tenant(tenant_id, user_id)
|
||||
return {'user': new_user_ref}
|
||||
|
||||
# NOTE(termie): this is really more of a patch than a put
|
||||
@ -656,6 +656,8 @@ class KeystoneRoleController(service.BaseApplication):
|
||||
return {'role': role_ref}
|
||||
|
||||
def create_role(self, context, role):
|
||||
role = self._normalize_dict(role)
|
||||
self.assert_admin(context)
|
||||
role_id = uuid.uuid4().hex
|
||||
role['id'] = role_id
|
||||
role_ref = self.identity_api.create_role(context, role_id, role)
|
||||
@ -669,8 +671,7 @@ class KeystoneRoleController(service.BaseApplication):
|
||||
self.assert_admin(context)
|
||||
roles = self.identity_api.list_roles(context)
|
||||
# TODO(termie): probably inefficient at some point
|
||||
return {'roles': [self.identity_api.get_role(context, x)
|
||||
for x in roles]}
|
||||
return {'roles': roles}
|
||||
|
||||
# COMPAT(diablo): CRUD extension
|
||||
def get_role_refs(self, context, user_id):
|
||||
|
@ -47,6 +47,13 @@ URLMAP = HIGH_LEVEL_CALLS.copy()
|
||||
URLMAP.update(LOW_LEVEL_CALLS)
|
||||
|
||||
|
||||
class SmarterEncoder(json.JSONEncoder):
|
||||
def default(self, obj):
|
||||
if not isinstance(obj, dict) and hasattr(obj, 'iteritems'):
|
||||
return dict(obj.iteritems())
|
||||
return super(SmarterEncoder, self).default(obj)
|
||||
|
||||
|
||||
class BaseApplication(wsgi.Application):
|
||||
@webob.dec.wsgify
|
||||
def __call__(self, req):
|
||||
@ -76,11 +83,18 @@ class BaseApplication(wsgi.Application):
|
||||
elif isinstance(result, webob.exc.WSGIHTTPException):
|
||||
return result
|
||||
|
||||
return json.dumps(result)
|
||||
return self._serialize(result)
|
||||
|
||||
def _serialize(self, result):
|
||||
return json.dumps(result, cls=SmarterEncoder)
|
||||
|
||||
def _normalize_arg(self, arg):
|
||||
return str(arg).replace(':', '_').replace('-', '_')
|
||||
|
||||
def _normalize_dict(self, d):
|
||||
return dict([(self._normalize_arg(k), v)
|
||||
for (k, v) in d.iteritems()])
|
||||
|
||||
def assert_admin(self, context):
|
||||
if not context['is_admin']:
|
||||
user_token_ref = self.token_api.get_token(
|
||||
@ -88,6 +102,7 @@ class BaseApplication(wsgi.Application):
|
||||
creds = user_token_ref['extras'].copy()
|
||||
creds['user_id'] = user_token_ref['user'].get('id')
|
||||
creds['tenant_id'] = user_token_ref['tenant'].get('id')
|
||||
print creds
|
||||
# Accept either is_admin or the admin role
|
||||
assert self.policy_api.can_haz(context,
|
||||
('is_admin:1', 'roles:admin'),
|
||||
|
@ -8,9 +8,12 @@ import time
|
||||
|
||||
from paste import deploy
|
||||
|
||||
from keystonelight import catalog
|
||||
from keystonelight import config
|
||||
from keystonelight import identity
|
||||
from keystonelight import logging
|
||||
from keystonelight import models
|
||||
from keystonelight import token
|
||||
from keystonelight import utils
|
||||
from keystonelight import wsgi
|
||||
|
||||
@ -114,20 +117,19 @@ class TestCase(unittest.TestCase):
|
||||
# TODO(termie): doing something from json, probably based on Django's
|
||||
# loaddata will be much preferred.
|
||||
for tenant in fixtures.TENANTS:
|
||||
rv = self.identity_api.create_tenant(
|
||||
tenant['id'], models.Tenant(**tenant))
|
||||
rv = self.identity_api.create_tenant(tenant['id'], tenant)
|
||||
setattr(self, 'tenant_%s' % tenant['id'], rv)
|
||||
|
||||
for user in fixtures.USERS:
|
||||
user_copy = user.copy()
|
||||
tenants = user_copy.pop('tenants')
|
||||
rv = self.identity_api.create_user(user['id'], models.User(**user_copy))
|
||||
rv = self.identity_api.create_user(user['id'], user_copy)
|
||||
for tenant_id in tenants:
|
||||
self.identity_api.add_user_to_tenant(tenant_id, user['id'])
|
||||
setattr(self, 'user_%s' % user['id'], rv)
|
||||
|
||||
for role in fixtures.ROLES:
|
||||
rv = self.identity_api.create_role(role['id'], models.Role(**role))
|
||||
rv = self.identity_api.create_role(role['id'], role)
|
||||
setattr(self, 'role_%s' % role['id'], rv)
|
||||
|
||||
for extras in fixtures.EXTRAS:
|
||||
@ -137,7 +139,7 @@ class TestCase(unittest.TestCase):
|
||||
del extras_ref['user_id']
|
||||
del extras_ref['tenant_id']
|
||||
rv = self.identity_api.create_extras(
|
||||
extras['user_id'], extras['tenant_id'], models.Extras(**extras_ref))
|
||||
extras['user_id'], extras['tenant_id'], extras_ref)
|
||||
setattr(self,
|
||||
'extras_%s%s' % (extras['user_id'], extras['tenant_id']), rv)
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user