Refactor 404's into managers & drivers (bug 968519)
The goal is to move the responsibility of reference checks away from controllers and into the underlying managers & drivers, which can handle the task with equal or greater efficiency. - Tenant references from create_user/update_user are NOT tested due to inconsistencies between backends - Additional test coverage improvements Also fixes bug 999209, bug 999608, bug 1006029, bug 1006055, bug 1006287, bug 1006334, and bug 1006344. Change-Id: I7de592e7dd4518038436b9a9fdaab559b00a0537
This commit is contained in:
parent
94f45dac51
commit
23ca656927
@ -16,7 +16,6 @@
|
||||
|
||||
|
||||
from keystone import catalog
|
||||
from keystone import exception
|
||||
from keystone.common import kvs
|
||||
|
||||
|
||||
@ -26,10 +25,7 @@ class Catalog(kvs.Base, catalog.Driver):
|
||||
return self.db.get('catalog-%s-%s' % (tenant_id, user_id))
|
||||
|
||||
def get_service(self, service_id):
|
||||
res = self.db.get('service-%s' % service_id)
|
||||
if not res:
|
||||
raise exception.ServiceNotFound(service_id=service_id)
|
||||
return res
|
||||
return self.db.get('service-%s' % service_id)
|
||||
|
||||
def list_services(self):
|
||||
return self.db.get('service_list', [])
|
||||
@ -46,14 +42,10 @@ class Catalog(kvs.Base, catalog.Driver):
|
||||
return service
|
||||
|
||||
def delete_service(self, service_id):
|
||||
if not self.db.get('service-%s' % service_id):
|
||||
raise exception.ServiceNotFound(service_id=service_id)
|
||||
|
||||
self.db.delete('service-%s' % service_id)
|
||||
service_list = set(self.db.get('service_list', []))
|
||||
service_list.remove(service_id)
|
||||
self.db.set('service_list', list(service_list))
|
||||
return None
|
||||
|
||||
# Private interface
|
||||
def _create_catalog(self, user_id, tenant_id, data):
|
||||
|
@ -93,11 +93,9 @@ class Catalog(sql.Base, catalog.Driver):
|
||||
|
||||
def delete_service(self, service_id):
|
||||
session = self.get_session()
|
||||
service_ref = session.query(Service).filter_by(id=service_id).first()
|
||||
if not service_ref:
|
||||
raise exception.ServiceNotFound(service_id=service_id)
|
||||
with session.begin():
|
||||
session.delete(service_ref)
|
||||
if not session.query(Service).filter_by(id=service_id).delete():
|
||||
raise exception.ServiceNotFound(service_id=service_id)
|
||||
session.flush()
|
||||
|
||||
def create_service(self, service_id, service_ref):
|
||||
@ -111,6 +109,7 @@ class Catalog(sql.Base, catalog.Driver):
|
||||
# Endpoints
|
||||
def create_endpoint(self, endpoint_id, endpoint_ref):
|
||||
session = self.get_session()
|
||||
self.get_service(endpoint_ref['service_id'])
|
||||
new_endpoint = Endpoint.from_dict(endpoint_ref)
|
||||
with session.begin():
|
||||
session.add(new_endpoint)
|
||||
@ -119,12 +118,9 @@ class Catalog(sql.Base, catalog.Driver):
|
||||
|
||||
def delete_endpoint(self, endpoint_id):
|
||||
session = self.get_session()
|
||||
endpoint_ref = session.query(Endpoint)
|
||||
endpoint_ref = endpoint_ref.filter_by(id=endpoint_id).first()
|
||||
if not endpoint_ref:
|
||||
raise exception.EndpointNotFound(endpoint_id=endpoint_id)
|
||||
with session.begin():
|
||||
session.delete(endpoint_ref)
|
||||
if not session.query(Endpoint).filter_by(id=endpoint_id).delete():
|
||||
raise exception.EndpointNotFound(endpoint_id=endpoint_id)
|
||||
session.flush()
|
||||
|
||||
def get_endpoint(self, endpoint_id):
|
||||
|
@ -42,13 +42,50 @@ class Manager(manager.Manager):
|
||||
def __init__(self):
|
||||
super(Manager, self).__init__(CONF.catalog.driver)
|
||||
|
||||
def get_service(self, context, service_id):
|
||||
try:
|
||||
return self.driver.get_service(service_id)
|
||||
except exception.NotFound:
|
||||
raise exception.ServiceNotFound(service_id=service_id)
|
||||
|
||||
def delete_service(self, context, service_id):
|
||||
try:
|
||||
return self.driver.delete_service(service_id)
|
||||
except exception.NotFound:
|
||||
raise exception.ServiceNotFound(service_id=service_id)
|
||||
|
||||
def create_endpoint(self, context, endpoint_id, endpoint_ref):
|
||||
try:
|
||||
return self.driver.create_endpoint(endpoint_id, endpoint_ref)
|
||||
except exception.NotFound:
|
||||
service_id = endpoint_ref.get('service_id')
|
||||
raise exception.ServiceNotFound(service_id=service_id)
|
||||
|
||||
def delete_endpoint(self, context, endpoint_id):
|
||||
try:
|
||||
return self.driver.delete_endpoint(endpoint_id)
|
||||
except exception.NotFound:
|
||||
raise exception.EndpointNotFound(endpoint_id=endpoint_id)
|
||||
|
||||
def get_endpoint(self, context, endpoint_id):
|
||||
try:
|
||||
return self.driver.get_endpoint(endpoint_id)
|
||||
except exception.NotFound:
|
||||
raise exception.EndpointNotFound(endpoint_id=endpoint_id)
|
||||
|
||||
def get_catalog(self, context, user_id, tenant_id, metadata=None):
|
||||
try:
|
||||
return self.driver.get_catalog(user_id, tenant_id, metadata)
|
||||
except exception.NotFound:
|
||||
raise exception.NotFound('Catalog not found for user and tenant')
|
||||
|
||||
|
||||
class Driver(object):
|
||||
"""Interface description for an Catalog driver."""
|
||||
def list_services(self):
|
||||
"""List all service ids in catalog.
|
||||
|
||||
Returns: list of service_ids or an empty list.
|
||||
:returns: list of service_ids or an empty list.
|
||||
|
||||
"""
|
||||
raise exception.NotImplemented()
|
||||
@ -56,27 +93,50 @@ class Driver(object):
|
||||
def get_service(self, service_id):
|
||||
"""Get service by id.
|
||||
|
||||
Returns: service_ref dict or None.
|
||||
:returns: service_ref dict
|
||||
:raises: keystone.exception.ServiceNotFound
|
||||
|
||||
"""
|
||||
raise exception.NotImplemented()
|
||||
|
||||
def delete_service(self, service_id):
|
||||
"""Deletes an existing service.
|
||||
|
||||
:raises: keystone.exception.ServiceNotFound
|
||||
|
||||
"""
|
||||
raise exception.NotImplemented()
|
||||
|
||||
def create_service(self, service_id, service_ref):
|
||||
"""Creates a new service.
|
||||
|
||||
:raises: keystone.exception.Conflict
|
||||
|
||||
"""
|
||||
raise exception.NotImplemented()
|
||||
|
||||
def create_endpoint(self, endpoint_id, endpoint_ref):
|
||||
"""Creates a new endpoint for a service.
|
||||
|
||||
:raises: keystone.exception.Conflict,
|
||||
keystone.exception.ServiceNotFound
|
||||
|
||||
"""
|
||||
raise exception.NotImplemented()
|
||||
|
||||
def delete_endpoint(self, endpoint_id):
|
||||
"""Deletes an endpoint for a service.
|
||||
|
||||
:raises: keystone.exception.EndpointNotFound
|
||||
|
||||
"""
|
||||
raise exception.NotImplemented()
|
||||
|
||||
def get_endpoint(self, endpoint_id):
|
||||
"""Get endpoint by id.
|
||||
|
||||
Returns: endpoint_ref dict or None.
|
||||
:returns: endpoint_ref dict
|
||||
:raises: keystone.exception.EndpointNotFound
|
||||
|
||||
"""
|
||||
raise exception.NotImplemented()
|
||||
@ -84,7 +144,7 @@ class Driver(object):
|
||||
def list_endpoints(self):
|
||||
"""List all endpoint ids in catalog.
|
||||
|
||||
Returns: list of endpoint_ids or an empty list.
|
||||
:returns: list of endpoint_ids or an empty list.
|
||||
|
||||
"""
|
||||
raise exception.NotImplemented()
|
||||
@ -92,10 +152,7 @@ class Driver(object):
|
||||
def get_catalog(self, user_id, tenant_id, metadata=None):
|
||||
"""Retreive and format the current service catalog.
|
||||
|
||||
Returns: A nested dict representing the service catalog or an
|
||||
empty dict.
|
||||
|
||||
Example:
|
||||
Example::
|
||||
|
||||
{ 'RegionOne':
|
||||
{'compute': {
|
||||
@ -109,6 +166,10 @@ class Driver(object):
|
||||
'name': 'EC2 Service',
|
||||
'publicURL': 'http://host:8773/services/Cloud'}}
|
||||
|
||||
:returns: A nested dict representing the service catalog or an
|
||||
empty dict.
|
||||
:raises: keystone.exception.NotFound
|
||||
|
||||
"""
|
||||
raise exception.NotImplemented()
|
||||
|
||||
@ -133,15 +194,10 @@ class ServiceController(wsgi.Application):
|
||||
def get_service(self, context, service_id):
|
||||
self.assert_admin(context)
|
||||
service_ref = self.catalog_api.get_service(context, service_id)
|
||||
if not service_ref:
|
||||
raise exception.ServiceNotFound(service_id=service_id)
|
||||
return {'OS-KSADM:service': service_ref}
|
||||
|
||||
def delete_service(self, context, service_id):
|
||||
self.assert_admin(context)
|
||||
service_ref = self.catalog_api.get_service(context, service_id)
|
||||
if not service_ref:
|
||||
raise exception.ServiceNotFound(service_id=service_id)
|
||||
self.catalog_api.delete_service(context, service_id)
|
||||
|
||||
def create_service(self, context, OS_KSADM_service):
|
||||
@ -174,11 +230,6 @@ class EndpointController(wsgi.Application):
|
||||
endpoint_id = uuid.uuid4().hex
|
||||
endpoint_ref = endpoint.copy()
|
||||
endpoint_ref['id'] = endpoint_id
|
||||
|
||||
service_id = endpoint_ref['service_id']
|
||||
if not self.catalog_api.get_service(context, service_id):
|
||||
raise exception.ServiceNotFound(service_id=service_id)
|
||||
|
||||
new_endpoint_ref = self.catalog_api.create_endpoint(
|
||||
context, endpoint_id, endpoint_ref)
|
||||
return {'endpoint': new_endpoint_ref}
|
||||
|
@ -14,8 +14,18 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from keystone import exception
|
||||
|
||||
|
||||
class DictKvs(dict):
|
||||
def get(self, key, default=None):
|
||||
try:
|
||||
return self[key]
|
||||
except KeyError:
|
||||
if default is not None:
|
||||
return default
|
||||
raise exception.NotFound(target=key)
|
||||
|
||||
def set(self, key, value):
|
||||
if isinstance(value, dict):
|
||||
self[key] = value.copy()
|
||||
@ -23,7 +33,11 @@ class DictKvs(dict):
|
||||
self[key] = value[:]
|
||||
|
||||
def delete(self, key):
|
||||
del self[key]
|
||||
"""Deletes an item, returning True on success, False otherwise."""
|
||||
try:
|
||||
del self[key]
|
||||
except KeyError:
|
||||
raise exception.NotFound(target=key)
|
||||
|
||||
|
||||
INMEMDB = DictKvs()
|
||||
|
@ -138,16 +138,22 @@ class BaseLdap(object):
|
||||
return obj
|
||||
|
||||
def affirm_unique(self, values):
|
||||
if values['name'] is not None:
|
||||
entity = self.get_by_name(values['name'])
|
||||
if entity is not None:
|
||||
if values.get('name') is not None:
|
||||
try:
|
||||
self.get_by_name(values['name'])
|
||||
except exception.NotFound:
|
||||
pass
|
||||
else:
|
||||
raise exception.Conflict(type=self.options_name,
|
||||
details='Duplicate name, %s.' %
|
||||
values['name'])
|
||||
|
||||
if values['id'] is not None:
|
||||
entity = self.get(values['id'])
|
||||
if entity is not None:
|
||||
if values.get('id') is not None:
|
||||
try:
|
||||
self.get(values['id'])
|
||||
except exception.NotFound:
|
||||
pass
|
||||
else:
|
||||
raise exception.Conflict(type=self.options_name,
|
||||
details='Duplicate ID, %s.' %
|
||||
values['id'])
|
||||
@ -198,7 +204,7 @@ class BaseLdap(object):
|
||||
def get(self, id, filter=None):
|
||||
res = self._ldap_get(id, filter)
|
||||
if res is None:
|
||||
return None
|
||||
raise exception.NotFound(target=id)
|
||||
else:
|
||||
return self._ldap_res_to_model(res)
|
||||
|
||||
|
@ -77,6 +77,12 @@ class EndpointNotFound(NotFound):
|
||||
"""Could not find endpoint: %(endpoint_id)s"""
|
||||
|
||||
|
||||
class MetadataNotFound(NotFound):
|
||||
"""An unhandled exception has occurred: Could not find metadata."""
|
||||
# (dolph): metadata is not a user-facing concept,
|
||||
# so this exception should not be exposed
|
||||
|
||||
|
||||
class RoleNotFound(NotFound):
|
||||
"""Could not find role: %(role_id)s"""
|
||||
|
||||
|
@ -45,49 +45,66 @@ class Identity(kvs.Base, identity.Driver):
|
||||
in the list of tenants on the user.
|
||||
|
||||
"""
|
||||
user_ref = self._get_user(user_id)
|
||||
user_ref = None
|
||||
tenant_ref = None
|
||||
metadata_ref = None
|
||||
if (not user_ref
|
||||
or not utils.check_password(password,
|
||||
user_ref.get('password'))):
|
||||
metadata_ref = {}
|
||||
|
||||
try:
|
||||
user_ref = self._get_user(user_id)
|
||||
except exception.UserNotFound:
|
||||
raise AssertionError('Invalid user / password')
|
||||
|
||||
tenants = self.get_tenants_for_user(user_id)
|
||||
if tenant_id and tenant_id not in tenants:
|
||||
raise AssertionError('Invalid tenant')
|
||||
if not utils.check_password(password, user_ref.get('password')):
|
||||
raise AssertionError('Invalid user / password')
|
||||
|
||||
if tenant_id is not None:
|
||||
if tenant_id not in self.get_tenants_for_user(user_id):
|
||||
raise AssertionError('Invalid tenant')
|
||||
|
||||
try:
|
||||
tenant_ref = self.get_tenant(tenant_id)
|
||||
metadata_ref = self.get_metadata(user_id, tenant_id)
|
||||
except exception.TenantNotFound:
|
||||
tenant_ref = None
|
||||
metadata_ref = {}
|
||||
except exception.MetadataNotFound:
|
||||
metadata_ref = {}
|
||||
|
||||
tenant_ref = self.get_tenant(tenant_id)
|
||||
if tenant_ref:
|
||||
metadata_ref = self.get_metadata(user_id, tenant_id)
|
||||
else:
|
||||
metadata_ref = {}
|
||||
return (_filter_user(user_ref), tenant_ref, metadata_ref)
|
||||
|
||||
def get_tenant(self, tenant_id):
|
||||
tenant_ref = self.db.get('tenant-%s' % tenant_id)
|
||||
return tenant_ref
|
||||
try:
|
||||
return self.db.get('tenant-%s' % tenant_id)
|
||||
except exception.NotFound:
|
||||
raise exception.TenantNotFound(tenant_id=tenant_id)
|
||||
|
||||
def get_tenants(self):
|
||||
tenant_keys = filter(lambda x: x.startswith("tenant-"), self.db.keys())
|
||||
return [self.db.get(key) for key in tenant_keys]
|
||||
|
||||
def get_tenant_by_name(self, tenant_name):
|
||||
tenant_ref = self.db.get('tenant_name-%s' % tenant_name)
|
||||
return tenant_ref
|
||||
try:
|
||||
return self.db.get('tenant_name-%s' % tenant_name)
|
||||
except exception.NotFound:
|
||||
raise exception.TenantNotFound(tenant_id=tenant_name)
|
||||
|
||||
def get_tenant_users(self, tenant_id):
|
||||
self.get_tenant(tenant_id)
|
||||
user_keys = filter(lambda x: x.startswith("user-"), self.db.keys())
|
||||
user_refs = [self.db.get(key) for key in user_keys]
|
||||
return filter(lambda x: tenant_id in x['tenants'], user_refs)
|
||||
|
||||
def _get_user(self, user_id):
|
||||
user_ref = self.db.get('user-%s' % user_id)
|
||||
return user_ref
|
||||
try:
|
||||
return self.db.get('user-%s' % user_id)
|
||||
except exception.NotFound:
|
||||
raise exception.UserNotFound(user_id=user_id)
|
||||
|
||||
def _get_user_by_name(self, user_name):
|
||||
user_ref = self.db.get('user_name-%s' % user_name)
|
||||
return user_ref
|
||||
try:
|
||||
return self.db.get('user_name-%s' % user_name)
|
||||
except exception.NotFound:
|
||||
raise exception.UserNotFound(user_id=user_name)
|
||||
|
||||
def get_user(self, user_id):
|
||||
return _filter_user(self._get_user(user_id))
|
||||
@ -96,10 +113,16 @@ class Identity(kvs.Base, identity.Driver):
|
||||
return _filter_user(self._get_user_by_name(user_name))
|
||||
|
||||
def get_metadata(self, user_id, tenant_id):
|
||||
return self.db.get('metadata-%s-%s' % (tenant_id, user_id)) or {}
|
||||
try:
|
||||
return self.db.get('metadata-%s-%s' % (tenant_id, user_id))
|
||||
except exception.NotFound:
|
||||
raise exception.MetadataNotFound()
|
||||
|
||||
def get_role(self, role_id):
|
||||
return self.db.get('role-%s' % role_id)
|
||||
try:
|
||||
return self.db.get('role-%s' % role_id)
|
||||
except exception.NotFound:
|
||||
raise exception.RoleNotFound(role_id=role_id)
|
||||
|
||||
def list_users(self):
|
||||
user_ids = self.db.get('user_list', [])
|
||||
@ -111,15 +134,20 @@ class Identity(kvs.Base, identity.Driver):
|
||||
|
||||
# These should probably be part of the high-level API
|
||||
def add_user_to_tenant(self, tenant_id, user_id):
|
||||
self.get_tenant(tenant_id)
|
||||
user_ref = self._get_user(user_id)
|
||||
tenants = set(user_ref.get('tenants', []))
|
||||
tenants.add(tenant_id)
|
||||
self.update_user(user_id, {'tenants': list(tenants)})
|
||||
|
||||
def remove_user_from_tenant(self, tenant_id, user_id):
|
||||
self.get_tenant(tenant_id)
|
||||
user_ref = self._get_user(user_id)
|
||||
tenants = set(user_ref.get('tenants', []))
|
||||
tenants.remove(tenant_id)
|
||||
try:
|
||||
tenants.remove(tenant_id)
|
||||
except KeyError:
|
||||
raise exception.NotFound('User not found in tenant')
|
||||
self.update_user(user_id, {'tenants': list(tenants)})
|
||||
|
||||
def get_tenants_for_user(self, user_id):
|
||||
@ -127,14 +155,21 @@ class Identity(kvs.Base, identity.Driver):
|
||||
return user_ref.get('tenants', [])
|
||||
|
||||
def get_roles_for_user_and_tenant(self, user_id, tenant_id):
|
||||
metadata_ref = self.get_metadata(user_id, tenant_id)
|
||||
if not metadata_ref:
|
||||
self.get_user(user_id)
|
||||
self.get_tenant(tenant_id)
|
||||
try:
|
||||
metadata_ref = self.get_metadata(user_id, tenant_id)
|
||||
except exception.MetadataNotFound:
|
||||
metadata_ref = {}
|
||||
return metadata_ref.get('roles', [])
|
||||
|
||||
def add_role_to_user_and_tenant(self, user_id, tenant_id, role_id):
|
||||
metadata_ref = self.get_metadata(user_id, tenant_id)
|
||||
if not metadata_ref:
|
||||
self.get_user(user_id)
|
||||
self.get_tenant(tenant_id)
|
||||
self.get_role(role_id)
|
||||
try:
|
||||
metadata_ref = self.get_metadata(user_id, tenant_id)
|
||||
except exception.MetadataNotFound:
|
||||
metadata_ref = {}
|
||||
roles = set(metadata_ref.get('roles', []))
|
||||
roles.add(role_id)
|
||||
@ -142,8 +177,9 @@ class Identity(kvs.Base, identity.Driver):
|
||||
self.update_metadata(user_id, tenant_id, metadata_ref)
|
||||
|
||||
def remove_role_from_user_and_tenant(self, user_id, tenant_id, role_id):
|
||||
metadata_ref = self.get_metadata(user_id, tenant_id)
|
||||
if not metadata_ref:
|
||||
try:
|
||||
metadata_ref = self.get_metadata(user_id, tenant_id)
|
||||
except exception.MetadataNotFound:
|
||||
metadata_ref = {}
|
||||
roles = set(metadata_ref.get('roles', []))
|
||||
if role_id not in roles:
|
||||
@ -156,12 +192,22 @@ class Identity(kvs.Base, identity.Driver):
|
||||
|
||||
# CRUD
|
||||
def create_user(self, user_id, user):
|
||||
if self.get_user(user_id):
|
||||
try:
|
||||
self.get_user(user_id)
|
||||
except exception.UserNotFound:
|
||||
pass
|
||||
else:
|
||||
msg = 'Duplicate ID, %s.' % user_id
|
||||
raise exception.Conflict(type='user', details=msg)
|
||||
if self.get_user_by_name(user['name']):
|
||||
|
||||
try:
|
||||
self.get_user_by_name(user['name'])
|
||||
except exception.UserNotFound:
|
||||
pass
|
||||
else:
|
||||
msg = 'Duplicate name, %s.' % user['name']
|
||||
raise exception.Conflict(type='user', details=msg)
|
||||
|
||||
user = _ensure_hashed_password(user)
|
||||
self.db.set('user-%s' % user_id, user)
|
||||
self.db.set('user_name-%s' % user['name'], user)
|
||||
@ -177,33 +223,49 @@ class Identity(kvs.Base, identity.Driver):
|
||||
msg = 'Duplicate name, %s.' % user['name']
|
||||
raise exception.Conflict(type='user', details=msg)
|
||||
# get the old name and delete it too
|
||||
old_user = self.db.get('user-%s' % user_id)
|
||||
try:
|
||||
old_user = self.db.get('user-%s' % user_id)
|
||||
except exception.NotFound:
|
||||
raise exception.UserNotFound(user_id=user_id)
|
||||
new_user = old_user.copy()
|
||||
user = _ensure_hashed_password(user)
|
||||
new_user.update(user)
|
||||
new_user['id'] = user_id
|
||||
if new_user['id'] != user_id:
|
||||
raise exception.ValidationError('Cannot change user ID')
|
||||
self.db.delete('user_name-%s' % old_user['name'])
|
||||
self.db.set('user-%s' % user_id, new_user)
|
||||
self.db.set('user_name-%s' % new_user['name'], new_user)
|
||||
return new_user
|
||||
|
||||
def delete_user(self, user_id):
|
||||
old_user = self.db.get('user-%s' % user_id)
|
||||
try:
|
||||
old_user = self.db.get('user-%s' % user_id)
|
||||
except exception.NotFound:
|
||||
raise exception.UserNotFound(user_id=user_id)
|
||||
self.db.delete('user_name-%s' % old_user['name'])
|
||||
self.db.delete('user-%s' % user_id)
|
||||
user_list = set(self.db.get('user_list', []))
|
||||
user_list.remove(user_id)
|
||||
self.db.set('user_list', list(user_list))
|
||||
return None
|
||||
|
||||
def create_tenant(self, tenant_id, tenant):
|
||||
tenant['name'] = clean.tenant_name(tenant['name'])
|
||||
if self.get_tenant(tenant_id):
|
||||
try:
|
||||
self.get_tenant(tenant_id)
|
||||
except exception.TenantNotFound:
|
||||
pass
|
||||
else:
|
||||
msg = 'Duplicate ID, %s.' % tenant_id
|
||||
raise exception.Conflict(type='tenant', details=msg)
|
||||
if self.get_tenant_by_name(tenant['name']):
|
||||
|
||||
try:
|
||||
self.get_tenant_by_name(tenant['name'])
|
||||
except exception.TenantNotFound:
|
||||
pass
|
||||
else:
|
||||
msg = 'Duplicate name, %s.' % tenant['name']
|
||||
raise exception.Conflict(type='tenant', details=msg)
|
||||
|
||||
self.db.set('tenant-%s' % tenant_id, tenant)
|
||||
self.db.set('tenant_name-%s' % tenant['name'], tenant)
|
||||
return tenant
|
||||
@ -211,12 +273,18 @@ class Identity(kvs.Base, identity.Driver):
|
||||
def update_tenant(self, tenant_id, tenant):
|
||||
if 'name' in tenant:
|
||||
tenant['name'] = clean.tenant_name(tenant['name'])
|
||||
existing = self.db.get('tenant_name-%s' % tenant['name'])
|
||||
if existing and tenant_id != existing['id']:
|
||||
msg = 'Duplicate name, %s.' % tenant['name']
|
||||
raise exception.Conflict(type='tenant', details=msg)
|
||||
try:
|
||||
existing = self.db.get('tenant_name-%s' % tenant['name'])
|
||||
if existing and tenant_id != existing['id']:
|
||||
msg = 'Duplicate name, %s.' % tenant['name']
|
||||
raise exception.Conflict(type='tenant', details=msg)
|
||||
except exception.NotFound:
|
||||
pass
|
||||
# get the old name and delete it too
|
||||
old_tenant = self.db.get('tenant-%s' % tenant_id)
|
||||
try:
|
||||
old_tenant = self.db.get('tenant-%s' % tenant_id)
|
||||
except exception.NotFound:
|
||||
raise exception.TenantNotFound(tenant_id=tenant_id)
|
||||
new_tenant = old_tenant.copy()
|
||||
new_tenant.update(tenant)
|
||||
new_tenant['id'] = tenant_id
|
||||
@ -226,10 +294,12 @@ class Identity(kvs.Base, identity.Driver):
|
||||
return new_tenant
|
||||
|
||||
def delete_tenant(self, tenant_id):
|
||||
old_tenant = self.db.get('tenant-%s' % tenant_id)
|
||||
try:
|
||||
old_tenant = self.db.get('tenant-%s' % tenant_id)
|
||||
except exception.NotFound:
|
||||
raise exception.TenantNotFound(tenant_id=tenant_id)
|
||||
self.db.delete('tenant_name-%s' % old_tenant['name'])
|
||||
self.db.delete('tenant-%s' % tenant_id)
|
||||
return None
|
||||
|
||||
def create_metadata(self, user_id, tenant_id, metadata):
|
||||
self.db.set('metadata-%s-%s' % (tenant_id, user_id), metadata)
|
||||
@ -241,15 +311,17 @@ class Identity(kvs.Base, identity.Driver):
|
||||
|
||||
def delete_metadata(self, user_id, tenant_id):
|
||||
self.db.delete('metadata-%s-%s' % (tenant_id, user_id))
|
||||
return None
|
||||
|
||||
def create_role(self, role_id, role):
|
||||
role_ref = self.get_role(role_id)
|
||||
if role_ref:
|
||||
try:
|
||||
self.get_role(role_id)
|
||||
except exception.RoleNotFound:
|
||||
pass
|
||||
else:
|
||||
msg = 'Duplicate ID, %s.' % role_id
|
||||
raise exception.Conflict(type='role', details=msg)
|
||||
role_refs = self.list_roles()
|
||||
for role_ref in role_refs:
|
||||
|
||||
for role_ref in self.list_roles():
|
||||
if role['name'] == role_ref['name']:
|
||||
msg = 'Duplicate name, %s.' % role['name']
|
||||
raise exception.Conflict(type='role', details=msg)
|
||||
@ -260,24 +332,26 @@ class Identity(kvs.Base, identity.Driver):
|
||||
return role
|
||||
|
||||
def update_role(self, role_id, role):
|
||||
role_refs = self.list_roles()
|
||||
old_role_ref = None
|
||||
for role_ref in role_refs:
|
||||
for role_ref in self.list_roles():
|
||||
if role['name'] == role_ref['name'] and role_id != role_ref['id']:
|
||||
msg = 'Duplicate name, %s.' % role['name']
|
||||
raise exception.Conflict(type='role', details=msg)
|
||||
if role_id == role_ref['id']:
|
||||
old_role_ref = role_ref
|
||||
if old_role_ref:
|
||||
role['id'] = role_id
|
||||
self.db.set('role-%s' % role_id, role)
|
||||
else:
|
||||
if old_role_ref is None:
|
||||
raise exception.RoleNotFound(role_id=role_id)
|
||||
new_role = old_role_ref.copy()
|
||||
new_role.update(role)
|
||||
new_role['id'] = role_id
|
||||
self.db.set('role-%s' % role_id, new_role)
|
||||
return role
|
||||
|
||||
def delete_role(self, role_id):
|
||||
self.db.delete('role-%s' % role_id)
|
||||
try:
|
||||
self.db.delete('role-%s' % role_id)
|
||||
except exception.NotFound:
|
||||
raise exception.RoleNotFound(role_id=role_id)
|
||||
role_list = set(self.db.get('role_list', []))
|
||||
role_list.remove(role_id)
|
||||
self.db.set('role_list', list(role_list))
|
||||
return None
|
||||
|
@ -77,8 +77,12 @@ class Identity(identity.Driver):
|
||||
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)
|
||||
if user_ref is None:
|
||||
tenant_ref = None
|
||||
metadata_ref = None
|
||||
|
||||
try:
|
||||
user_ref = self._get_user(user_id)
|
||||
except exception.UserNotFound:
|
||||
raise AssertionError('Invalid user / password')
|
||||
|
||||
try:
|
||||
@ -89,42 +93,49 @@ class Identity(identity.Driver):
|
||||
except Exception:
|
||||
raise AssertionError('Invalid user / password')
|
||||
|
||||
tenants = self.get_tenants_for_user(user_id)
|
||||
if tenant_id and tenant_id not in tenants:
|
||||
raise AssertionError('Invalid tenant')
|
||||
if tenant_id is not None:
|
||||
if tenant_id not in self.get_tenants_for_user(user_id):
|
||||
raise AssertionError('Invalid tenant')
|
||||
|
||||
tenant_ref = self.get_tenant(tenant_id)
|
||||
# TODO(termie): this should probably be made into a get roles call
|
||||
if tenant_ref:
|
||||
metadata_ref = self.get_metadata(user_id, tenant_id)
|
||||
else:
|
||||
metadata_ref = {}
|
||||
try:
|
||||
tenant_ref = self.get_tenant(tenant_id)
|
||||
# TODO(termie): this should probably be made into a
|
||||
# get roles call
|
||||
metadata_ref = self.get_metadata(user_id, tenant_id)
|
||||
except exception.TenantNotFound:
|
||||
tenant_ref = None
|
||||
metadata_ref = {}
|
||||
except exception.MetadataNotFound:
|
||||
metadata_ref = {}
|
||||
|
||||
return (_filter_user(user_ref), tenant_ref, metadata_ref)
|
||||
|
||||
def get_tenant(self, tenant_id):
|
||||
return self.tenant.get(tenant_id)
|
||||
try:
|
||||
return self.tenant.get(tenant_id)
|
||||
except exception.NotFound:
|
||||
raise exception.TenantNotFound(tenant_id=tenant_id)
|
||||
|
||||
def get_tenant_by_name(self, tenant_name):
|
||||
return self.tenant.get_by_name(tenant_name)
|
||||
try:
|
||||
return self.tenant.get_by_name(tenant_name)
|
||||
except exception.NotFound:
|
||||
raise exception.TenantNotFound(tenant_id=tenant_name)
|
||||
|
||||
def _get_user(self, user_id):
|
||||
user_ref = self.user.get(user_id)
|
||||
if not user_ref:
|
||||
return None
|
||||
return user_ref
|
||||
try:
|
||||
return self.user.get(user_id)
|
||||
except exception.NotFound:
|
||||
raise exception.UserNotFound(user_id=user_id)
|
||||
|
||||
def get_user(self, user_id):
|
||||
user_ref = self._get_user(user_id)
|
||||
if (not user_ref):
|
||||
return None
|
||||
return _filter_user(user_ref)
|
||||
return _filter_user(self._get_user(user_id))
|
||||
|
||||
def get_user_by_name(self, user_name):
|
||||
user_ref = self.user.get_by_name(user_name)
|
||||
if not user_ref:
|
||||
return None
|
||||
return _filter_user(user_ref)
|
||||
try:
|
||||
return _filter_user(self.user.get_by_name(user_name))
|
||||
except exception.NotFound:
|
||||
raise exception.UserNotFound(user_id=user_name)
|
||||
|
||||
def get_metadata(self, user_id, tenant_id):
|
||||
if not self.get_tenant(tenant_id) or not self.get_user(user_id):
|
||||
@ -136,19 +147,27 @@ class Identity(identity.Driver):
|
||||
return {'roles': metadata_ref}
|
||||
|
||||
def get_role(self, role_id):
|
||||
return self.role.get(role_id)
|
||||
try:
|
||||
return self.role.get(role_id)
|
||||
except exception.NotFound:
|
||||
raise exception.RoleNotFound(role_id=role_id)
|
||||
|
||||
# These should probably be part of the high-level API
|
||||
def add_user_to_tenant(self, tenant_id, user_id):
|
||||
self.get_tenant(tenant_id)
|
||||
self.get_user(user_id)
|
||||
return self.tenant.add_user(tenant_id, user_id)
|
||||
|
||||
def get_tenants_for_user(self, user_id):
|
||||
self.get_user(user_id)
|
||||
tenant_list = []
|
||||
for tenant in self.tenant.get_user_tenants(user_id):
|
||||
tenant_list.append(tenant['id'])
|
||||
return tenant_list
|
||||
|
||||
def get_roles_for_user_and_tenant(self, user_id, tenant_id):
|
||||
self.get_user(user_id)
|
||||
self.get_tenant(tenant_id)
|
||||
assignments = self.role.get_role_assignments(tenant_id)
|
||||
roles = []
|
||||
for assignment in assignments:
|
||||
@ -157,6 +176,9 @@ class Identity(identity.Driver):
|
||||
return roles
|
||||
|
||||
def add_role_to_user_and_tenant(self, user_id, tenant_id, role_id):
|
||||
self.get_user(user_id)
|
||||
self.get_tenant(tenant_id)
|
||||
self.get_role(role_id)
|
||||
self.role.add_user(role_id, user_id, tenant_id)
|
||||
|
||||
# CRUD
|
||||
@ -182,16 +204,29 @@ class Identity(identity.Driver):
|
||||
return {}
|
||||
|
||||
def create_role(self, role_id, role):
|
||||
if self.get_role(role_id):
|
||||
try:
|
||||
self.get_role(role_id)
|
||||
except exception.NotFound:
|
||||
pass
|
||||
else:
|
||||
msg = 'Duplicate ID, %s.' % role_id
|
||||
raise exception.Conflict(type='role', details=msg)
|
||||
if self.role.get_by_name(role['name']):
|
||||
|
||||
try:
|
||||
self.role.get_by_name(role['name'])
|
||||
except exception.NotFound:
|
||||
pass
|
||||
else:
|
||||
msg = 'Duplicate name, %s.' % role['name']
|
||||
raise exception.Conflict(type='role', details=msg)
|
||||
|
||||
return self.role.create(role)
|
||||
|
||||
def delete_role(self, role_id):
|
||||
return self.role.delete(role_id)
|
||||
try:
|
||||
return self.role.delete(role_id)
|
||||
except ldap.NO_SUCH_OBJECT:
|
||||
raise exception.RoleNotFound(role_id=role_id)
|
||||
|
||||
|
||||
# TODO(termie): remove this and move cross-api calls into driver
|
||||
@ -268,6 +303,13 @@ class UserApi(common_ldap.BaseLdap, ApiShimMixin):
|
||||
super(UserApi, self).__init__(conf)
|
||||
self.api = ApiShim(conf)
|
||||
|
||||
def get(self, id, filter=None):
|
||||
"""Replaces exception.NotFound with exception.UserNotFound."""
|
||||
try:
|
||||
return super(UserApi, self).get(id, filter)
|
||||
except exception.NotFound:
|
||||
raise exception.UserNotFound(user_id=id)
|
||||
|
||||
def get_by_name(self, name, filter=None):
|
||||
users = self.get_all('(%s=%s)' %
|
||||
(self.attribute_mapping['name'],
|
||||
@ -275,7 +317,7 @@ class UserApi(common_ldap.BaseLdap, ApiShimMixin):
|
||||
try:
|
||||
return users[0]
|
||||
except IndexError:
|
||||
return None
|
||||
raise exception.UserNotFound(user_id=name)
|
||||
|
||||
def create(self, values):
|
||||
self.affirm_unique(values)
|
||||
@ -288,10 +330,13 @@ class UserApi(common_ldap.BaseLdap, ApiShimMixin):
|
||||
|
||||
def update(self, id, values):
|
||||
if values['id'] != id:
|
||||
return None
|
||||
old_obj = self.get(id)
|
||||
raise exception.ValidationError('Cannot change user ID')
|
||||
try:
|
||||
old_obj = self.get(id)
|
||||
except exception.NotFound:
|
||||
raise exception.UserNotFound(user_id=id)
|
||||
if old_obj.get('name') != values['name']:
|
||||
raise exception.Error('Changing Name not permitted')
|
||||
raise exception.ValidationError('Cannot change user name')
|
||||
|
||||
try:
|
||||
new_tenant = values['tenant_id']
|
||||
@ -385,6 +430,13 @@ class TenantApi(common_ldap.BaseLdap, ApiShimMixin):
|
||||
self.member_attribute = (getattr(conf.ldap, 'tenant_member_attribute')
|
||||
or self.DEFAULT_MEMBER_ATTRIBUTE)
|
||||
|
||||
def get(self, id, filter=None):
|
||||
"""Replaces exception.NotFound with exception.TenantNotFound."""
|
||||
try:
|
||||
return super(TenantApi, self).get(id, filter)
|
||||
except exception.NotFound:
|
||||
raise exception.TenantNotFound(tenant_id=id)
|
||||
|
||||
def get_by_name(self, name, filter=None): # pylint: disable=W0221,W0613
|
||||
search_filter = ('(%s=%s)'
|
||||
% (self.attribute_mapping['name'],
|
||||
@ -393,13 +445,12 @@ class TenantApi(common_ldap.BaseLdap, ApiShimMixin):
|
||||
try:
|
||||
return tenants[0]
|
||||
except IndexError:
|
||||
return None
|
||||
raise exception.TenantNotFound(tenant_id=name)
|
||||
|
||||
def create(self, values):
|
||||
self.affirm_unique(values)
|
||||
|
||||
data = values.copy()
|
||||
if 'id' not in data or data['id'] is None:
|
||||
if data.get('id') is None:
|
||||
data['id'] = uuid.uuid4().hex
|
||||
return super(TenantApi, self).create(data)
|
||||
|
||||
@ -434,10 +485,11 @@ class TenantApi(common_ldap.BaseLdap, ApiShimMixin):
|
||||
|
||||
def add_user(self, tenant_id, user_id):
|
||||
conn = self.get_connection()
|
||||
conn.modify_s(self._id_to_dn(tenant_id),
|
||||
[(ldap.MOD_ADD,
|
||||
self.member_attribute,
|
||||
self.user_api._id_to_dn(user_id))])
|
||||
conn.modify_s(
|
||||
self._id_to_dn(tenant_id),
|
||||
[(ldap.MOD_ADD,
|
||||
self.member_attribute,
|
||||
self.user_api._id_to_dn(user_id))])
|
||||
|
||||
def remove_user(self, tenant_id, user_id):
|
||||
conn = self.get_connection()
|
||||
@ -467,9 +519,13 @@ class TenantApi(common_ldap.BaseLdap, ApiShimMixin):
|
||||
super(TenantApi, self).delete(id)
|
||||
|
||||
def update(self, id, values):
|
||||
old_obj = self.get(id)
|
||||
try:
|
||||
old_obj = self.get(id)
|
||||
except exception.NotFound:
|
||||
raise exception.TenantNotFound(tenant_id=id)
|
||||
if old_obj['name'] != values['name']:
|
||||
raise exception.Error('Changing Name not permitted')
|
||||
msg = 'Changing Name not supported by LDAP'
|
||||
raise exception.NotImplemented(message=msg)
|
||||
super(TenantApi, self).update(id, values, old_obj)
|
||||
|
||||
|
||||
@ -558,12 +614,9 @@ class RoleApi(common_ldap.BaseLdap, ApiShimMixin):
|
||||
try:
|
||||
return roles[0]
|
||||
except IndexError:
|
||||
return None
|
||||
raise exception.RoleNotFound(role_id=name)
|
||||
|
||||
def add_user(self, role_id, user_id, tenant_id=None):
|
||||
user = self.user_api.get(user_id)
|
||||
if user is None:
|
||||
raise exception.UserNotFound(user_id=user_id)
|
||||
role_dn = self._subrole_id_to_dn(role_id, tenant_id)
|
||||
conn = self.get_connection()
|
||||
user_dn = self.user_api._id_to_dn(user_id)
|
||||
|
@ -157,38 +157,50 @@ class Identity(sql.Base, identity.Driver):
|
||||
in the list of tenants on the user.
|
||||
|
||||
"""
|
||||
user_ref = self._get_user(user_id)
|
||||
if (not user_ref
|
||||
or not self._check_password(password, user_ref)):
|
||||
user_ref = None
|
||||
tenant_ref = None
|
||||
metadata_ref = {}
|
||||
|
||||
try:
|
||||
user_ref = self._get_user(user_id)
|
||||
except exception.UserNotFound:
|
||||
raise AssertionError('Invalid user / password')
|
||||
|
||||
tenants = self.get_tenants_for_user(user_id)
|
||||
if tenant_id and tenant_id not in tenants:
|
||||
raise AssertionError('Invalid tenant')
|
||||
if not utils.check_password(password, user_ref.get('password')):
|
||||
raise AssertionError('Invalid user / password')
|
||||
|
||||
if tenant_id is not None:
|
||||
if tenant_id not in self.get_tenants_for_user(user_id):
|
||||
raise AssertionError('Invalid tenant')
|
||||
|
||||
try:
|
||||
tenant_ref = self.get_tenant(tenant_id)
|
||||
metadata_ref = self.get_metadata(user_id, tenant_id)
|
||||
except exception.TenantNotFound:
|
||||
tenant_ref = None
|
||||
metadata_ref = {}
|
||||
except exception.MetadataNotFound:
|
||||
metadata_ref = {}
|
||||
|
||||
tenant_ref = self.get_tenant(tenant_id)
|
||||
if tenant_ref:
|
||||
metadata_ref = self.get_metadata(user_id, tenant_id)
|
||||
else:
|
||||
metadata_ref = {}
|
||||
return (_filter_user(user_ref), tenant_ref, metadata_ref)
|
||||
|
||||
def get_tenant(self, tenant_id):
|
||||
session = self.get_session()
|
||||
tenant_ref = session.query(Tenant).filter_by(id=tenant_id).first()
|
||||
if not tenant_ref:
|
||||
return
|
||||
if tenant_ref is None:
|
||||
raise exception.TenantNotFound(tenant_id=tenant_id)
|
||||
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()
|
||||
if not tenant_ref:
|
||||
return
|
||||
raise exception.TenantNotFound(tenant_id=tenant_name)
|
||||
return tenant_ref.to_dict()
|
||||
|
||||
def get_tenant_users(self, tenant_id):
|
||||
session = self.get_session()
|
||||
self.get_tenant(tenant_id)
|
||||
user_refs = session.query(User)\
|
||||
.join(UserTenantMembership)\
|
||||
.filter(UserTenantMembership.tenant_id ==
|
||||
@ -200,14 +212,14 @@ class Identity(sql.Base, identity.Driver):
|
||||
session = self.get_session()
|
||||
user_ref = session.query(User).filter_by(id=user_id).first()
|
||||
if not user_ref:
|
||||
return
|
||||
raise exception.UserNotFound(user_id=user_id)
|
||||
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()
|
||||
if not user_ref:
|
||||
return
|
||||
raise exception.UserNotFound(user_id=user_name)
|
||||
return user_ref.to_dict()
|
||||
|
||||
def get_user(self, user_id):
|
||||
@ -222,11 +234,16 @@ class Identity(sql.Base, identity.Driver):
|
||||
.filter_by(user_id=user_id)\
|
||||
.filter_by(tenant_id=tenant_id)\
|
||||
.first()
|
||||
return getattr(metadata_ref, 'data', {})
|
||||
if metadata_ref is None:
|
||||
raise exception.MetadataNotFound()
|
||||
return metadata_ref.data
|
||||
|
||||
def get_role(self, role_id):
|
||||
session = self.get_session()
|
||||
return session.query(Role).filter_by(id=role_id).first()
|
||||
role_ref = session.query(Role).filter_by(id=role_id).first()
|
||||
if role_ref is None:
|
||||
raise exception.RoleNotFound(role_id=role_id)
|
||||
return role_ref
|
||||
|
||||
def list_users(self):
|
||||
session = self.get_session()
|
||||
@ -241,6 +258,8 @@ class Identity(sql.Base, identity.Driver):
|
||||
# These should probably be part of the high-level API
|
||||
def add_user_to_tenant(self, tenant_id, user_id):
|
||||
session = self.get_session()
|
||||
self.get_tenant(tenant_id)
|
||||
self.get_user(user_id)
|
||||
q = session.query(UserTenantMembership)\
|
||||
.filter_by(user_id=user_id)\
|
||||
.filter_by(tenant_id=tenant_id)
|
||||
@ -255,10 +274,14 @@ class Identity(sql.Base, identity.Driver):
|
||||
|
||||
def remove_user_from_tenant(self, tenant_id, user_id):
|
||||
session = self.get_session()
|
||||
self.get_tenant(tenant_id)
|
||||
self.get_user(user_id)
|
||||
membership_ref = session.query(UserTenantMembership)\
|
||||
.filter_by(user_id=user_id)\
|
||||
.filter_by(tenant_id=tenant_id)\
|
||||
.first()
|
||||
if membership_ref is None:
|
||||
raise exception.NotFound('User not found in tenant')
|
||||
with session.begin():
|
||||
session.delete(membership_ref)
|
||||
session.flush()
|
||||
@ -270,37 +293,46 @@ class Identity(sql.Base, identity.Driver):
|
||||
|
||||
def get_tenants_for_user(self, user_id):
|
||||
session = self.get_session()
|
||||
self.get_user(user_id)
|
||||
membership_refs = session.query(UserTenantMembership)\
|
||||
.filter_by(user_id=user_id)\
|
||||
.all()
|
||||
return [x.tenant_id for x in membership_refs]
|
||||
|
||||
def get_roles_for_user_and_tenant(self, user_id, tenant_id):
|
||||
metadata_ref = self.get_metadata(user_id, tenant_id)
|
||||
if not metadata_ref:
|
||||
self.get_user(user_id)
|
||||
self.get_tenant(tenant_id)
|
||||
try:
|
||||
metadata_ref = self.get_metadata(user_id, tenant_id)
|
||||
except exception.MetadataNotFound:
|
||||
metadata_ref = {}
|
||||
return metadata_ref.get('roles', [])
|
||||
|
||||
def add_role_to_user_and_tenant(self, user_id, tenant_id, role_id):
|
||||
metadata_ref = self.get_metadata(user_id, tenant_id)
|
||||
is_new = False
|
||||
if not metadata_ref:
|
||||
is_new = True
|
||||
self.get_user(user_id)
|
||||
self.get_tenant(tenant_id)
|
||||
self.get_role(role_id)
|
||||
try:
|
||||
metadata_ref = self.get_metadata(user_id, tenant_id)
|
||||
is_new = False
|
||||
except exception.MetadataNotFound:
|
||||
metadata_ref = {}
|
||||
is_new = True
|
||||
roles = set(metadata_ref.get('roles', []))
|
||||
roles.add(role_id)
|
||||
metadata_ref['roles'] = list(roles)
|
||||
if not is_new:
|
||||
self.update_metadata(user_id, tenant_id, metadata_ref)
|
||||
else:
|
||||
if is_new:
|
||||
self.create_metadata(user_id, tenant_id, metadata_ref)
|
||||
else:
|
||||
self.update_metadata(user_id, tenant_id, metadata_ref)
|
||||
|
||||
def remove_role_from_user_and_tenant(self, user_id, tenant_id, role_id):
|
||||
metadata_ref = self.get_metadata(user_id, tenant_id)
|
||||
is_new = False
|
||||
if not metadata_ref:
|
||||
is_new = True
|
||||
try:
|
||||
metadata_ref = self.get_metadata(user_id, tenant_id)
|
||||
is_new = False
|
||||
except exception.MetadataNotFound:
|
||||
metadata_ref = {}
|
||||
is_new = True
|
||||
roles = set(metadata_ref.get('roles', []))
|
||||
if role_id not in roles:
|
||||
msg = 'Cannot remove role that has not been granted, %s' % role_id
|
||||
@ -308,10 +340,10 @@ class Identity(sql.Base, identity.Driver):
|
||||
|
||||
roles.remove(role_id)
|
||||
metadata_ref['roles'] = list(roles)
|
||||
if not is_new:
|
||||
self.update_metadata(user_id, tenant_id, metadata_ref)
|
||||
else:
|
||||
if is_new:
|
||||
self.create_metadata(user_id, tenant_id, metadata_ref)
|
||||
else:
|
||||
self.update_metadata(user_id, tenant_id, metadata_ref)
|
||||
|
||||
# CRUD
|
||||
@handle_conflicts(type='user')
|
||||
@ -327,8 +359,12 @@ class Identity(sql.Base, identity.Driver):
|
||||
@handle_conflicts(type='user')
|
||||
def update_user(self, user_id, user):
|
||||
session = self.get_session()
|
||||
if user_id != user['id']:
|
||||
raise exception.ValidationError('Cannot change user ID')
|
||||
with session.begin():
|
||||
user_ref = session.query(User).filter_by(id=user_id).first()
|
||||
if user_ref is None:
|
||||
raise exception.UserNotFound(user_id=user_id)
|
||||
old_user_dict = user_ref.to_dict()
|
||||
user = _ensure_hashed_password(user)
|
||||
for k in user:
|
||||
@ -343,6 +379,8 @@ class Identity(sql.Base, identity.Driver):
|
||||
def delete_user(self, user_id):
|
||||
session = self.get_session()
|
||||
user_ref = session.query(User).filter_by(id=user_id).first()
|
||||
if not user_ref:
|
||||
raise exception.UserNotFound(user_id=user_id)
|
||||
membership_refs = session.query(UserTenantMembership)\
|
||||
.filter_by(user_id=user_id)\
|
||||
.all()
|
||||
@ -379,6 +417,8 @@ class Identity(sql.Base, identity.Driver):
|
||||
session = self.get_session()
|
||||
with session.begin():
|
||||
tenant_ref = session.query(Tenant).filter_by(id=tenant_id).first()
|
||||
if tenant_ref is None:
|
||||
raise exception.TenantNotFound(tenant_id=tenant_id)
|
||||
old_tenant_dict = tenant_ref.to_dict()
|
||||
for k in tenant:
|
||||
old_tenant_dict[k] = tenant[k]
|
||||
@ -392,6 +432,8 @@ class Identity(sql.Base, identity.Driver):
|
||||
def delete_tenant(self, tenant_id):
|
||||
session = self.get_session()
|
||||
tenant_ref = session.query(Tenant).filter_by(id=tenant_id).first()
|
||||
if not tenant_ref:
|
||||
raise exception.TenantNotFound(tenant_id=tenant_id)
|
||||
membership_refs = session.query(UserTenantMembership)\
|
||||
.filter_by(tenant_id=tenant_id)\
|
||||
.all()
|
||||
@ -452,6 +494,8 @@ class Identity(sql.Base, identity.Driver):
|
||||
session = self.get_session()
|
||||
with session.begin():
|
||||
role_ref = session.query(Role).filter_by(id=role_id).first()
|
||||
if role_ref is None:
|
||||
raise exception.RoleNotFound(role_id=role_id)
|
||||
for k in role:
|
||||
role_ref[k] = role[k]
|
||||
session.flush()
|
||||
@ -459,6 +503,7 @@ class Identity(sql.Base, identity.Driver):
|
||||
|
||||
def delete_role(self, role_id):
|
||||
session = self.get_session()
|
||||
role_ref = session.query(Role).filter_by(id=role_id).first()
|
||||
with session.begin():
|
||||
session.delete(role_ref)
|
||||
if not session.query(Role).filter_by(id=role_id).delete():
|
||||
raise exception.RoleNotFound(role_id=role_id)
|
||||
session.flush()
|
||||
|
@ -52,7 +52,8 @@ class Driver(object):
|
||||
def authenticate(self, user_id=None, tenant_id=None, password=None):
|
||||
"""Authenticate a given user, tenant and password.
|
||||
|
||||
Returns: (user, tenant, metadata).
|
||||
:returns: (user_ref, tenant_ref, metadata_ref)
|
||||
:raises: AssertionError
|
||||
|
||||
"""
|
||||
raise exception.NotImplemented()
|
||||
@ -60,7 +61,8 @@ class Driver(object):
|
||||
def get_tenant(self, tenant_id):
|
||||
"""Get a tenant by id.
|
||||
|
||||
Returns: tenant_ref or None.
|
||||
:returns: tenant_ref
|
||||
:raises: keystone.exception.TenantNotFound
|
||||
|
||||
"""
|
||||
raise exception.NotImplemented()
|
||||
@ -68,7 +70,8 @@ class Driver(object):
|
||||
def get_tenant_by_name(self, tenant_name):
|
||||
"""Get a tenant by name.
|
||||
|
||||
Returns: tenant_ref or None.
|
||||
:returns: tenant_ref
|
||||
:raises: keystone.exception.TenantNotFound
|
||||
|
||||
"""
|
||||
raise exception.NotImplemented()
|
||||
@ -76,7 +79,8 @@ class Driver(object):
|
||||
def get_user(self, user_id):
|
||||
"""Get a user by id.
|
||||
|
||||
Returns: user_ref or None.
|
||||
:returns: user_ref
|
||||
:raises: keystone.exception.UserNotFound
|
||||
|
||||
"""
|
||||
raise exception.NotImplemented()
|
||||
@ -84,7 +88,8 @@ class Driver(object):
|
||||
def get_user_by_name(self, user_name):
|
||||
"""Get a user by name.
|
||||
|
||||
Returns: user_ref or None.
|
||||
:returns: user_ref
|
||||
:raises: keystone.exception.UserNotFound
|
||||
|
||||
"""
|
||||
raise exception.NotImplemented()
|
||||
@ -92,7 +97,8 @@ class Driver(object):
|
||||
def get_role(self, role_id):
|
||||
"""Get a role by id.
|
||||
|
||||
Returns: role_ref or None.
|
||||
:returns: role_ref
|
||||
:raises: keystone.exception.RoleNotFound
|
||||
|
||||
"""
|
||||
raise exception.NotImplemented()
|
||||
@ -103,7 +109,7 @@ class Driver(object):
|
||||
NOTE(termie): I'd prefer if this listed only the users for a given
|
||||
tenant.
|
||||
|
||||
Returns: a list of user_refs or an empty list.
|
||||
:returns: a list of user_refs or an empty list
|
||||
|
||||
"""
|
||||
raise exception.NotImplemented()
|
||||
@ -111,7 +117,7 @@ class Driver(object):
|
||||
def list_roles(self):
|
||||
"""List all roles in the system.
|
||||
|
||||
Returns: a list of role_refs or an empty list.
|
||||
:returns: a list of role_refs or an empty list.
|
||||
|
||||
"""
|
||||
raise exception.NotImplemented()
|
||||
@ -119,18 +125,50 @@ class Driver(object):
|
||||
# NOTE(termie): seven calls below should probably be exposed by the api
|
||||
# more clearly when the api redesign happens
|
||||
def add_user_to_tenant(self, tenant_id, user_id):
|
||||
"""Add user to a tenant without an explicit role relationship.
|
||||
|
||||
:raises: keystone.exception.TenantNotFound,
|
||||
keystone.exception.UserNotFound
|
||||
|
||||
"""
|
||||
raise exception.NotImplemented()
|
||||
|
||||
def remove_user_from_tenant(self, tenant_id, user_id):
|
||||
"""Remove user from a tenant without an explicit role relationship.
|
||||
|
||||
:raises: keystone.exception.TenantNotFound,
|
||||
keystone.exception.UserNotFound
|
||||
|
||||
"""
|
||||
raise exception.NotImplemented()
|
||||
|
||||
def get_all_tenants(self):
|
||||
"""FIXME(dolph): Lists all tenants in the system? I'm not sure how this
|
||||
is different from get_tenants, why get_tenants isn't
|
||||
documented as part of the driver, or why it's called
|
||||
get_tenants instead of list_tenants (i.e. list_roles
|
||||
and list_users)...
|
||||
|
||||
:returns: a list of ... FIXME(dolph): tenant_refs or tenant_id's?
|
||||
|
||||
"""
|
||||
raise exception.NotImplemented()
|
||||
|
||||
def get_tenant_users(self, tenant_id):
|
||||
"""FIXME(dolph): Lists all users with a relationship to the specified
|
||||
tenant?
|
||||
|
||||
:returns: a list of ... FIXME(dolph): user_refs or user_id's?
|
||||
:raises: keystone.exception.UserNotFound
|
||||
|
||||
"""
|
||||
raise exception.NotImplemented()
|
||||
|
||||
def get_tenants_for_user(self, user_id):
|
||||
"""Get the tenants associated with a given user.
|
||||
|
||||
Returns: a list of tenant ids.
|
||||
:returns: a list of tenant_id's.
|
||||
:raises: keystone.exception.UserNotFound
|
||||
|
||||
"""
|
||||
raise exception.NotImplemented()
|
||||
@ -138,41 +176,83 @@ class Driver(object):
|
||||
def get_roles_for_user_and_tenant(self, user_id, tenant_id):
|
||||
"""Get the roles associated with a user within given tenant.
|
||||
|
||||
Returns: a list of role ids.
|
||||
:returns: a list of role ids.
|
||||
:raises: keystone.exception.UserNotFound,
|
||||
keystone.exception.TenantNotFound
|
||||
|
||||
"""
|
||||
raise exception.NotImplemented()
|
||||
|
||||
def add_role_to_user_and_tenant(self, user_id, tenant_id, role_id):
|
||||
"""Add a role to a user within given tenant."""
|
||||
"""Add a role to a user within given tenant.
|
||||
|
||||
:raises: keystone.exception.UserNotFound,
|
||||
keystone.exception.TenantNotFound,
|
||||
keystone.exception.RoleNotFound
|
||||
"""
|
||||
raise exception.NotImplemented()
|
||||
|
||||
def remove_role_from_user_and_tenant(self, user_id, tenant_id, role_id):
|
||||
"""Remove a role from a user within given tenant."""
|
||||
"""Remove a role from a user within given tenant.
|
||||
|
||||
:raises: keystone.exception.UserNotFound,
|
||||
keystone.exception.TenantNotFound,
|
||||
keystone.exception.RoleNotFound
|
||||
|
||||
"""
|
||||
raise exception.NotImplemented()
|
||||
|
||||
# user crud
|
||||
def create_user(self, user_id, user):
|
||||
"""Creates a new user.
|
||||
|
||||
:raises: keystone.exception.Conflict
|
||||
|
||||
"""
|
||||
raise exception.NotImplemented()
|
||||
|
||||
def update_user(self, user_id, user):
|
||||
"""Updates an existing user.
|
||||
|
||||
:raises: keystone.exception.UserNotFound, keystone.exception.Conflict
|
||||
|
||||
"""
|
||||
raise exception.NotImplemented()
|
||||
|
||||
def delete_user(self, user_id):
|
||||
"""Deletes an existing user.
|
||||
|
||||
:raises: keystone.exception.UserNotFound
|
||||
|
||||
"""
|
||||
raise exception.NotImplemented()
|
||||
|
||||
# tenant crud
|
||||
def create_tenant(self, tenant_id, tenant):
|
||||
"""Creates a new tenant.
|
||||
|
||||
:raises: keystone.exception.Conflict
|
||||
|
||||
"""
|
||||
raise exception.NotImplemented()
|
||||
|
||||
def update_tenant(self, tenant_id, tenant):
|
||||
"""Updates an existing tenant.
|
||||
|
||||
:raises: keystone.exception.TenantNotFound, keystone.exception.Conflict
|
||||
|
||||
"""
|
||||
raise exception.NotImplemented()
|
||||
|
||||
def delete_tenant(self, tenant_id, tenant):
|
||||
def delete_tenant(self, tenant_id):
|
||||
"""Deletes an existing tenant.
|
||||
|
||||
:raises: keystone.exception.TenantNotFound
|
||||
|
||||
"""
|
||||
raise exception.NotImplemented()
|
||||
|
||||
# metadata crud
|
||||
|
||||
def get_metadata(self, user_id, tenant_id):
|
||||
raise exception.NotImplemented()
|
||||
|
||||
@ -182,17 +262,32 @@ class Driver(object):
|
||||
def update_metadata(self, user_id, tenant_id, metadata):
|
||||
raise exception.NotImplemented()
|
||||
|
||||
def delete_metadata(self, user_id, tenant_id, metadata):
|
||||
def delete_metadata(self, user_id, tenant_id):
|
||||
raise exception.NotImplemented()
|
||||
|
||||
# role crud
|
||||
def create_role(self, role_id, role):
|
||||
"""Creates a new role.
|
||||
|
||||
:raises: keystone.exception.Conflict
|
||||
|
||||
"""
|
||||
raise exception.NotImplemented()
|
||||
|
||||
def update_role(self, role_id, role):
|
||||
"""Updates an existing role.
|
||||
|
||||
:raises: keystone.exception.RoleNotFound, keystone.exception.Conflict
|
||||
|
||||
"""
|
||||
raise exception.NotImplemented()
|
||||
|
||||
def delete_role(self, role_id):
|
||||
"""Deletes an existing role.
|
||||
|
||||
:raises: keystone.exception.RoleNotFound
|
||||
|
||||
"""
|
||||
raise exception.NotImplemented()
|
||||
|
||||
|
||||
@ -286,11 +381,7 @@ class TenantController(wsgi.Application):
|
||||
def get_tenant(self, context, tenant_id):
|
||||
# TODO(termie): this stuff should probably be moved to middleware
|
||||
self.assert_admin(context)
|
||||
tenant = self.identity_api.get_tenant(context, tenant_id)
|
||||
if tenant is None:
|
||||
raise exception.TenantNotFound(tenant_id=tenant_id)
|
||||
|
||||
return {'tenant': tenant}
|
||||
return {'tenant': self.identity_api.get_tenant(context, tenant_id)}
|
||||
|
||||
# CRUD Extension
|
||||
def create_tenant(self, context, tenant):
|
||||
@ -301,36 +392,23 @@ class TenantController(wsgi.Application):
|
||||
raise exception.ValidationError(message=msg)
|
||||
|
||||
self.assert_admin(context)
|
||||
tenant_id = (tenant_ref.get('id')
|
||||
and tenant_ref.get('id')
|
||||
or uuid.uuid4().hex)
|
||||
tenant_ref['id'] = tenant_id
|
||||
|
||||
tenant_ref['id'] = tenant_ref.get('id', uuid.uuid4().hex)
|
||||
tenant = self.identity_api.create_tenant(
|
||||
context, tenant_id, tenant_ref)
|
||||
context, tenant_ref['id'], tenant_ref)
|
||||
return {'tenant': tenant}
|
||||
|
||||
def update_tenant(self, context, tenant_id, tenant):
|
||||
self.assert_admin(context)
|
||||
if self.identity_api.get_tenant(context, tenant_id) is None:
|
||||
raise exception.TenantNotFound(tenant_id=tenant_id)
|
||||
|
||||
tenant_ref = self.identity_api.update_tenant(
|
||||
context, tenant_id, tenant)
|
||||
return {'tenant': tenant_ref}
|
||||
|
||||
def delete_tenant(self, context, tenant_id, **kw):
|
||||
def delete_tenant(self, context, tenant_id):
|
||||
self.assert_admin(context)
|
||||
if self.identity_api.get_tenant(context, tenant_id) is None:
|
||||
raise exception.TenantNotFound(tenant_id=tenant_id)
|
||||
|
||||
self.identity_api.delete_tenant(context, tenant_id)
|
||||
|
||||
def get_tenant_users(self, context, tenant_id, **kw):
|
||||
self.assert_admin(context)
|
||||
if self.identity_api.get_tenant(context, tenant_id) is None:
|
||||
raise exception.TenantNotFound(tenant_id=tenant_id)
|
||||
|
||||
user_refs = self.identity_api.get_tenant_users(context, tenant_id)
|
||||
return {'users': user_refs}
|
||||
|
||||
@ -376,18 +454,13 @@ class UserController(wsgi.Application):
|
||||
|
||||
def get_user(self, context, user_id):
|
||||
self.assert_admin(context)
|
||||
user_ref = self.identity_api.get_user(context, user_id)
|
||||
if not user_ref:
|
||||
raise exception.UserNotFound(user_id=user_id)
|
||||
|
||||
return {'user': user_ref}
|
||||
return {'user': self.identity_api.get_user(context, user_id)}
|
||||
|
||||
def get_users(self, context):
|
||||
# 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_refs = self.identity_api.list_users(context)
|
||||
return {'users': user_refs}
|
||||
return {'users': self.identity_api.list_users(context)}
|
||||
|
||||
# CRUD extension
|
||||
def create_user(self, context, user):
|
||||
@ -414,9 +487,6 @@ class UserController(wsgi.Application):
|
||||
def update_user(self, context, user_id, user):
|
||||
# NOTE(termie): this is really more of a patch than a put
|
||||
self.assert_admin(context)
|
||||
if self.identity_api.get_user(context, user_id) is None:
|
||||
raise exception.UserNotFound(user_id=user_id)
|
||||
|
||||
user_ref = self.identity_api.update_user(context, user_id, user)
|
||||
|
||||
# If the password was changed or the user was disabled we clear tokens
|
||||
@ -433,9 +503,6 @@ class UserController(wsgi.Application):
|
||||
|
||||
def delete_user(self, context, user_id):
|
||||
self.assert_admin(context)
|
||||
if self.identity_api.get_user(context, user_id) is None:
|
||||
raise exception.UserNotFound(user_id=user_id)
|
||||
|
||||
self.identity_api.delete_user(context, user_id)
|
||||
|
||||
def set_user_enabled(self, context, user_id, user):
|
||||
@ -472,13 +539,6 @@ class RoleController(wsgi.Application):
|
||||
raise exception.NotImplemented(message='User roles not supported: '
|
||||
'tenant ID required')
|
||||
|
||||
user = self.identity_api.get_user(context, user_id)
|
||||
if user is None:
|
||||
raise exception.UserNotFound(user_id=user_id)
|
||||
tenant = self.identity_api.get_tenant(context, tenant_id)
|
||||
if tenant is None:
|
||||
raise exception.TenantNotFound(tenant_id=tenant_id)
|
||||
|
||||
roles = self.identity_api.get_roles_for_user_and_tenant(
|
||||
context, user_id, tenant_id)
|
||||
return {'roles': [self.identity_api.get_role(context, x)
|
||||
@ -487,10 +547,7 @@ class RoleController(wsgi.Application):
|
||||
# CRUD extension
|
||||
def get_role(self, context, role_id):
|
||||
self.assert_admin(context)
|
||||
role_ref = self.identity_api.get_role(context, role_id)
|
||||
if not role_ref:
|
||||
raise exception.RoleNotFound(role_id=role_id)
|
||||
return {'role': role_ref}
|
||||
return {'role': self.identity_api.get_role(context, role_id)}
|
||||
|
||||
def create_role(self, context, role):
|
||||
role = self._normalize_dict(role)
|
||||
@ -507,14 +564,11 @@ class RoleController(wsgi.Application):
|
||||
|
||||
def delete_role(self, context, role_id):
|
||||
self.assert_admin(context)
|
||||
self.get_role(context, role_id)
|
||||
self.identity_api.delete_role(context, role_id)
|
||||
|
||||
def get_roles(self, context):
|
||||
self.assert_admin(context)
|
||||
roles = self.identity_api.list_roles(context)
|
||||
# TODO(termie): probably inefficient at some point
|
||||
return {'roles': roles}
|
||||
return {'roles': self.identity_api.list_roles(context)}
|
||||
|
||||
def add_role_to_user(self, context, user_id, role_id, tenant_id=None):
|
||||
"""Add a role to a user and tenant pair.
|
||||
@ -527,12 +581,6 @@ class RoleController(wsgi.Application):
|
||||
if tenant_id is None:
|
||||
raise exception.NotImplemented(message='User roles not supported: '
|
||||
'tenant_id required')
|
||||
if self.identity_api.get_user(context, user_id) is None:
|
||||
raise exception.UserNotFound(user_id=user_id)
|
||||
if self.identity_api.get_tenant(context, tenant_id) is None:
|
||||
raise exception.TenantNotFound(tenant_id=tenant_id)
|
||||
if self.identity_api.get_role(context, role_id) is None:
|
||||
raise exception.RoleNotFound(role_id=role_id)
|
||||
|
||||
# This still has the weird legacy semantics that adding a role to
|
||||
# a user also adds them to a tenant
|
||||
@ -553,12 +601,6 @@ class RoleController(wsgi.Application):
|
||||
if tenant_id is None:
|
||||
raise exception.NotImplemented(message='User roles not supported: '
|
||||
'tenant_id required')
|
||||
if self.identity_api.get_user(context, user_id) is None:
|
||||
raise exception.UserNotFound(user_id=user_id)
|
||||
if self.identity_api.get_tenant(context, tenant_id) is None:
|
||||
raise exception.TenantNotFound(tenant_id=tenant_id)
|
||||
if self.identity_api.get_role(context, role_id) is None:
|
||||
raise exception.RoleNotFound(role_id=role_id)
|
||||
|
||||
# This still has the weird legacy semantics that adding a role to
|
||||
# a user also adds them to a tenant, so we must follow up on that
|
||||
|
@ -249,25 +249,28 @@ class TokenController(wsgi.Application):
|
||||
|
||||
token_id = uuid.uuid4().hex
|
||||
if 'passwordCredentials' in auth:
|
||||
user_id = auth['passwordCredentials'].get('userId', None)
|
||||
username = auth['passwordCredentials'].get('username', '')
|
||||
password = auth['passwordCredentials'].get('password', '')
|
||||
tenant_name = auth.get('tenantName', None)
|
||||
|
||||
user_id = auth['passwordCredentials'].get('userId', None)
|
||||
if username:
|
||||
user_ref = self.identity_api.get_user_by_name(
|
||||
context=context,
|
||||
user_name=username)
|
||||
if user_ref:
|
||||
try:
|
||||
user_ref = self.identity_api.get_user_by_name(
|
||||
context=context, user_name=username)
|
||||
user_id = user_ref['id']
|
||||
except exception.UserNotFound:
|
||||
raise exception.Unauthorized()
|
||||
|
||||
# more compat
|
||||
tenant_id = auth.get('tenantId', None)
|
||||
if tenant_name:
|
||||
tenant_ref = self.identity_api.get_tenant_by_name(
|
||||
context=context, tenant_name=tenant_name)
|
||||
if tenant_ref:
|
||||
try:
|
||||
tenant_ref = self.identity_api.get_tenant_by_name(
|
||||
context=context, tenant_name=tenant_name)
|
||||
tenant_id = tenant_ref['id']
|
||||
except exception.TenantNotFound:
|
||||
raise exception.Unauthorized()
|
||||
|
||||
try:
|
||||
auth_info = self.identity_api.authenticate(context=context,
|
||||
@ -330,12 +333,13 @@ class TokenController(wsgi.Application):
|
||||
|
||||
tenants = self.identity_api.get_tenants_for_user(context,
|
||||
user_ref['id'])
|
||||
if tenant_id:
|
||||
assert tenant_id in tenants
|
||||
if tenant_id and tenant_id not in tenants:
|
||||
raise exception.Unauthorized()
|
||||
|
||||
tenant_ref = self.identity_api.get_tenant(context=context,
|
||||
tenant_id=tenant_id)
|
||||
if tenant_ref:
|
||||
try:
|
||||
tenant_ref = self.identity_api.get_tenant(
|
||||
context=context,
|
||||
tenant_id=tenant_id)
|
||||
metadata_ref = self.identity_api.get_metadata(
|
||||
context=context,
|
||||
user_id=user_ref['id'],
|
||||
@ -345,7 +349,8 @@ class TokenController(wsgi.Application):
|
||||
user_id=user_ref['id'],
|
||||
tenant_id=tenant_ref['id'],
|
||||
metadata=metadata_ref)
|
||||
else:
|
||||
except exception.TenantNotFound:
|
||||
tenant_ref = None
|
||||
metadata_ref = {}
|
||||
catalog_ref = {}
|
||||
|
||||
|
@ -25,9 +25,12 @@ from keystone import token
|
||||
class Token(kvs.Base, token.Driver):
|
||||
# Public interface
|
||||
def get_token(self, token_id):
|
||||
token = self.db.get('token-%s' % token_id)
|
||||
if (token and (token['expires'] is None
|
||||
or token['expires'] > datetime.datetime.utcnow())):
|
||||
try:
|
||||
token = self.db.get('token-%s' % token_id)
|
||||
except exception.NotFound:
|
||||
raise exception.TokenNotFound(token_id=token_id)
|
||||
if (token['expires'] is None
|
||||
or token['expires'] > datetime.datetime.utcnow()):
|
||||
return token
|
||||
else:
|
||||
raise exception.TokenNotFound(token_id=token_id)
|
||||
@ -41,8 +44,8 @@ class Token(kvs.Base, token.Driver):
|
||||
|
||||
def delete_token(self, token_id):
|
||||
try:
|
||||
return self.db.delete('token-%s' % token_id)
|
||||
except KeyError:
|
||||
self.db.delete('token-%s' % token_id)
|
||||
except exception.NotFound:
|
||||
raise exception.TokenNotFound(token_id=token_id)
|
||||
|
||||
def list_tokens(self, user_id):
|
||||
|
@ -72,14 +72,9 @@ class Token(sql.Base, token.Driver):
|
||||
|
||||
def delete_token(self, token_id):
|
||||
session = self.get_session()
|
||||
token_ref = session.query(TokenModel)\
|
||||
.filter_by(id=token_id)\
|
||||
.first()
|
||||
if not token_ref:
|
||||
raise exception.TokenNotFound(token_id=token_id)
|
||||
|
||||
with session.begin():
|
||||
session.delete(token_ref)
|
||||
if not session.query(TokenModel).filter_by(id=token_id).delete():
|
||||
raise exception.TokenNotFound(token_id=token_id)
|
||||
session.flush()
|
||||
|
||||
def list_tokens(self, user_id):
|
||||
|
@ -24,7 +24,7 @@ class IdentityTests(object):
|
||||
def test_authenticate_bad_user(self):
|
||||
self.assertRaises(AssertionError,
|
||||
self.identity_api.authenticate,
|
||||
user_id=self.user_foo['id'] + 'WRONG',
|
||||
user_id=uuid.uuid4().hex,
|
||||
tenant_id=self.tenant_bar['id'],
|
||||
password=self.user_foo['password'])
|
||||
|
||||
@ -33,13 +33,13 @@ class IdentityTests(object):
|
||||
self.identity_api.authenticate,
|
||||
user_id=self.user_foo['id'],
|
||||
tenant_id=self.tenant_bar['id'],
|
||||
password=self.user_foo['password'] + 'WRONG')
|
||||
password=uuid.uuid4().hex)
|
||||
|
||||
def test_authenticate_invalid_tenant(self):
|
||||
def test_authenticate_bad_tenant(self):
|
||||
self.assertRaises(AssertionError,
|
||||
self.identity_api.authenticate,
|
||||
user_id=self.user_foo['id'],
|
||||
tenant_id=self.tenant_bar['id'] + 'WRONG',
|
||||
tenant_id=uuid.uuid4().hex,
|
||||
password=self.user_foo['password'])
|
||||
|
||||
def test_authenticate_no_tenant(self):
|
||||
@ -86,30 +86,30 @@ class IdentityTests(object):
|
||||
user_ref = self.identity_api._get_user(self.user_foo['id'])
|
||||
self.assertNotEqual(user_ref['password'], self.user_foo['password'])
|
||||
|
||||
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.assertDictEqual(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_404(self):
|
||||
self.assertRaises(exception.TenantNotFound,
|
||||
self.identity_api.get_tenant,
|
||||
tenant_id=uuid.uuid4().hex)
|
||||
|
||||
def test_get_tenant_by_name(self):
|
||||
tenant_ref = self.identity_api.get_tenant_by_name(
|
||||
tenant_name=self.tenant_bar['name'])
|
||||
self.assertDictEqual(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_tenant_by_name_404(self):
|
||||
self.assertRaises(exception.TenantNotFound,
|
||||
self.identity_api.get_tenant,
|
||||
tenant_id=uuid.uuid4().hex)
|
||||
|
||||
def test_get_tenant_users_404(self):
|
||||
self.assertRaises(exception.TenantNotFound,
|
||||
self.identity_api.get_tenant_users,
|
||||
tenant_id=uuid.uuid4().hex)
|
||||
|
||||
def test_get_user(self):
|
||||
user_ref = self.identity_api.get_user(user_id=self.user_foo['id'])
|
||||
@ -119,6 +119,11 @@ class IdentityTests(object):
|
||||
self.user_foo.pop('password')
|
||||
self.assertDictEqual(user_ref, self.user_foo)
|
||||
|
||||
def test_get_user_404(self):
|
||||
self.assertRaises(exception.UserNotFound,
|
||||
self.identity_api.get_user,
|
||||
user_id=uuid.uuid4().hex)
|
||||
|
||||
def test_get_user_by_name(self):
|
||||
user_ref = self.identity_api.get_user_by_name(
|
||||
user_name=self.user_foo['name'])
|
||||
@ -128,17 +133,10 @@ class IdentityTests(object):
|
||||
self.user_foo.pop('password')
|
||||
self.assertDictEqual(user_ref, self.user_foo)
|
||||
|
||||
def test_get_metadata_bad_user(self):
|
||||
metadata_ref = self.identity_api.get_metadata(
|
||||
user_id=self.user_foo['id'] + 'WRONG',
|
||||
tenant_id=self.tenant_bar['id'])
|
||||
self.assert_(metadata_ref == {})
|
||||
|
||||
def test_get_metadata_bad_tenant(self):
|
||||
metadata_ref = self.identity_api.get_metadata(
|
||||
user_id=self.user_foo['id'],
|
||||
tenant_id=self.tenant_bar['id'] + 'WRONG')
|
||||
self.assert_(metadata_ref == {})
|
||||
def test_get_user_by_name_404(self):
|
||||
self.assertRaises(exception.UserNotFound,
|
||||
self.identity_api.get_user_by_name,
|
||||
user_name=uuid.uuid4().hex)
|
||||
|
||||
def test_get_metadata(self):
|
||||
metadata_ref = self.identity_api.get_metadata(
|
||||
@ -146,12 +144,29 @@ class IdentityTests(object):
|
||||
tenant_id=self.tenant_bar['id'])
|
||||
self.assertDictEqual(metadata_ref, self.metadata_foobar)
|
||||
|
||||
def test_get_metadata_404(self):
|
||||
# FIXME(dolph): these exceptions could be more specific
|
||||
self.assertRaises(exception.NotFound,
|
||||
self.identity_api.get_metadata,
|
||||
user_id=uuid.uuid4().hex,
|
||||
tenant_id=self.tenant_bar['id'])
|
||||
|
||||
self.assertRaises(exception.NotFound,
|
||||
self.identity_api.get_metadata,
|
||||
user_id=self.user_foo['id'],
|
||||
tenant_id=uuid.uuid4().hex)
|
||||
|
||||
def test_get_role(self):
|
||||
role_ref = self.identity_api.get_role(
|
||||
role_id=self.role_keystone_admin['id'])
|
||||
role_ref_dict = dict((x, role_ref[x]) for x in role_ref)
|
||||
self.assertDictEqual(role_ref_dict, self.role_keystone_admin)
|
||||
|
||||
def test_get_role_404(self):
|
||||
self.assertRaises(exception.RoleNotFound,
|
||||
self.identity_api.get_role,
|
||||
role_id=uuid.uuid4().hex)
|
||||
|
||||
def test_create_duplicate_role_name_fails(self):
|
||||
role = {'id': 'fake1',
|
||||
'name': 'fake1name'}
|
||||
@ -170,7 +185,7 @@ class IdentityTests(object):
|
||||
self.identity_api.create_role('fake1', role1)
|
||||
self.identity_api.create_role('fake2', role2)
|
||||
role1['name'] = 'fake2name'
|
||||
self.assertRaises(exception.Error,
|
||||
self.assertRaises(exception.Conflict,
|
||||
self.identity_api.update_role,
|
||||
'fake1',
|
||||
role1)
|
||||
@ -211,23 +226,27 @@ class IdentityTests(object):
|
||||
self.identity_api.create_user('fake1', user1)
|
||||
self.identity_api.create_user('fake2', user2)
|
||||
user2['name'] = 'fake1'
|
||||
self.assertRaises(exception.Error,
|
||||
self.assertRaises(exception.Conflict,
|
||||
self.identity_api.update_user,
|
||||
'fake2',
|
||||
user2)
|
||||
|
||||
def test_update_user_id_does_nothing(self):
|
||||
def test_update_user_id_fails(self):
|
||||
user = {'id': 'fake1',
|
||||
'name': 'fake1',
|
||||
'password': 'fakepass',
|
||||
'tenants': ['bar']}
|
||||
self.identity_api.create_user('fake1', user)
|
||||
user['id'] = 'fake2'
|
||||
self.identity_api.update_user('fake1', user)
|
||||
self.assertRaises(exception.ValidationError,
|
||||
self.identity_api.update_user,
|
||||
'fake1',
|
||||
user)
|
||||
user_ref = self.identity_api.get_user('fake1')
|
||||
self.assertEqual(user_ref['id'], 'fake1')
|
||||
user_ref = self.identity_api.get_user('fake2')
|
||||
self.assert_(user_ref is None)
|
||||
self.assertRaises(exception.UserNotFound,
|
||||
self.identity_api.get_user,
|
||||
'fake2')
|
||||
|
||||
def test_create_duplicate_tenant_id_fails(self):
|
||||
tenant = {'id': 'fake1', 'name': 'fake1'}
|
||||
@ -265,8 +284,9 @@ class IdentityTests(object):
|
||||
self.identity_api.update_tenant('fake1', tenant)
|
||||
tenant_ref = self.identity_api.get_tenant('fake1')
|
||||
self.assertEqual(tenant_ref['id'], 'fake1')
|
||||
tenant_ref = self.identity_api.get_tenant('fake2')
|
||||
self.assert_(tenant_ref is None)
|
||||
self.assertRaises(exception.TenantNotFound,
|
||||
self.identity_api.get_tenant,
|
||||
'fake2')
|
||||
|
||||
def test_get_role_by_user_and_tenant(self):
|
||||
roles_ref = self.identity_api.get_roles_for_user_and_tenant(
|
||||
@ -286,22 +306,160 @@ class IdentityTests(object):
|
||||
self.assertIn('keystone_admin', roles_ref)
|
||||
self.assertIn('useless', roles_ref)
|
||||
|
||||
def test_delete_role(self):
|
||||
role_id = 'test_role_delete'
|
||||
new_role = {'id': role_id, 'name': 'Role to Delete'}
|
||||
self.identity_api.create_role(role_id, new_role)
|
||||
role_ref = self.identity_api.get_role(role_id)
|
||||
def test_get_roles_for_user_and_tenant_404(self):
|
||||
self.assertRaises(exception.UserNotFound,
|
||||
self.identity_api.get_roles_for_user_and_tenant,
|
||||
uuid.uuid4().hex,
|
||||
self.tenant_bar['id'])
|
||||
|
||||
self.assertRaises(exception.TenantNotFound,
|
||||
self.identity_api.get_roles_for_user_and_tenant,
|
||||
self.user_foo['id'],
|
||||
uuid.uuid4().hex)
|
||||
|
||||
def test_add_role_to_user_and_tenant_404(self):
|
||||
self.assertRaises(exception.UserNotFound,
|
||||
self.identity_api.add_role_to_user_and_tenant,
|
||||
uuid.uuid4().hex,
|
||||
self.tenant_bar['id'],
|
||||
'keystone_admin')
|
||||
|
||||
self.assertRaises(exception.TenantNotFound,
|
||||
self.identity_api.add_role_to_user_and_tenant,
|
||||
self.user_foo['id'],
|
||||
uuid.uuid4().hex,
|
||||
'keystone_admin')
|
||||
|
||||
self.assertRaises(exception.RoleNotFound,
|
||||
self.identity_api.add_role_to_user_and_tenant,
|
||||
self.user_foo['id'],
|
||||
self.tenant_bar['id'],
|
||||
uuid.uuid4().hex)
|
||||
|
||||
def test_remove_role_from_user_and_tenant(self):
|
||||
self.identity_api.add_role_to_user_and_tenant(
|
||||
self.user_foo['id'], self.tenant_bar['id'], 'useless')
|
||||
self.identity_api.remove_role_from_user_and_tenant(
|
||||
self.user_foo['id'], self.tenant_bar['id'], 'useless')
|
||||
roles_ref = self.identity_api.get_roles_for_user_and_tenant(
|
||||
self.user_foo['id'], self.tenant_bar['id'])
|
||||
self.assertNotIn('useless', roles_ref)
|
||||
self.assertRaises(exception.NotFound,
|
||||
self.identity_api.remove_role_from_user_and_tenant,
|
||||
self.user_foo['id'],
|
||||
self.tenant_bar['id'],
|
||||
'useless')
|
||||
|
||||
def test_role_crud(self):
|
||||
role = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex}
|
||||
self.identity_api.create_role(role['id'], role)
|
||||
role_ref = self.identity_api.get_role(role['id'])
|
||||
role_ref_dict = dict((x, role_ref[x]) for x in role_ref)
|
||||
self.assertDictEqual(role_ref_dict, new_role)
|
||||
self.identity_api.delete_role(role_id)
|
||||
role_ref = self.identity_api.get_role(role_id)
|
||||
self.assertIsNone(role_ref)
|
||||
self.assertDictEqual(role_ref_dict, role)
|
||||
|
||||
role['name'] = uuid.uuid4().hex
|
||||
self.identity_api.update_role(role['id'], role)
|
||||
role_ref = self.identity_api.get_role(role['id'])
|
||||
role_ref_dict = dict((x, role_ref[x]) for x in role_ref)
|
||||
self.assertDictEqual(role_ref_dict, role)
|
||||
|
||||
self.identity_api.delete_role(role['id'])
|
||||
self.assertRaises(exception.RoleNotFound,
|
||||
self.identity_api.get_role,
|
||||
role['id'])
|
||||
|
||||
def test_update_role_404(self):
|
||||
role = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex}
|
||||
self.assertRaises(exception.RoleNotFound,
|
||||
self.identity_api.update_role,
|
||||
role['id'],
|
||||
role)
|
||||
|
||||
def test_add_user_to_tenant(self):
|
||||
tenant_id = 'tenent4add'
|
||||
self.identity_api.add_user_to_tenant(tenant_id, 'foo')
|
||||
tenants = self.identity_api.get_tenants_for_user('foo')
|
||||
self.assertIn(tenant_id, tenants)
|
||||
self.identity_api.add_user_to_tenant(self.tenant_bar['id'],
|
||||
self.user_foo['id'])
|
||||
tenants = self.identity_api.get_tenants_for_user(self.user_foo['id'])
|
||||
self.assertIn(self.tenant_bar['id'], tenants)
|
||||
|
||||
def test_add_user_to_tenant_404(self):
|
||||
self.assertRaises(exception.TenantNotFound,
|
||||
self.identity_api.add_user_to_tenant,
|
||||
uuid.uuid4().hex,
|
||||
self.user_foo['id'])
|
||||
|
||||
self.assertRaises(exception.UserNotFound,
|
||||
self.identity_api.add_user_to_tenant,
|
||||
self.tenant_bar['id'],
|
||||
uuid.uuid4().hex)
|
||||
|
||||
def test_remove_user_from_tenant(self):
|
||||
self.identity_api.add_user_to_tenant(self.tenant_bar['id'],
|
||||
self.user_foo['id'])
|
||||
self.identity_api.remove_user_from_tenant(self.tenant_bar['id'],
|
||||
self.user_foo['id'])
|
||||
tenants = self.identity_api.get_tenants_for_user(self.user_foo['id'])
|
||||
self.assertNotIn(self.tenant_bar['id'], tenants)
|
||||
|
||||
def test_remove_user_from_tenant_404(self):
|
||||
self.assertRaises(exception.TenantNotFound,
|
||||
self.identity_api.remove_user_from_tenant,
|
||||
uuid.uuid4().hex,
|
||||
self.user_foo['id'])
|
||||
|
||||
self.assertRaises(exception.UserNotFound,
|
||||
self.identity_api.remove_user_from_tenant,
|
||||
self.tenant_bar['id'],
|
||||
uuid.uuid4().hex)
|
||||
|
||||
self.assertRaises(exception.NotFound,
|
||||
self.identity_api.remove_user_from_tenant,
|
||||
self.tenant_baz['id'],
|
||||
self.user_foo['id'])
|
||||
|
||||
def test_get_tenants_for_user_404(self):
|
||||
self.assertRaises(exception.UserNotFound,
|
||||
self.identity_api.get_tenants_for_user,
|
||||
uuid.uuid4().hex)
|
||||
|
||||
def test_update_tenant_404(self):
|
||||
self.assertRaises(exception.TenantNotFound,
|
||||
self.identity_api.update_tenant,
|
||||
uuid.uuid4().hex,
|
||||
dict())
|
||||
|
||||
def test_delete_tenant_404(self):
|
||||
self.assertRaises(exception.TenantNotFound,
|
||||
self.identity_api.delete_tenant,
|
||||
uuid.uuid4().hex)
|
||||
|
||||
def test_update_user_404(self):
|
||||
user_id = uuid.uuid4().hex
|
||||
self.assertRaises(exception.UserNotFound,
|
||||
self.identity_api.update_user,
|
||||
user_id,
|
||||
{'id': user_id})
|
||||
|
||||
def test_delete_user_with_tenant_association(self):
|
||||
user = {'id': uuid.uuid4().hex,
|
||||
'name': uuid.uuid4().hex,
|
||||
'password': uuid.uuid4().hex}
|
||||
self.identity_api.create_user(user['id'], user)
|
||||
self.identity_api.add_user_to_tenant(self.tenant_bar['id'],
|
||||
user['id'])
|
||||
self.identity_api.delete_user(user['id'])
|
||||
self.assertRaises(exception.UserNotFound,
|
||||
self.identity_api.get_tenants_for_user,
|
||||
user['id'])
|
||||
|
||||
def test_delete_user_404(self):
|
||||
self.assertRaises(exception.UserNotFound,
|
||||
self.identity_api.delete_user,
|
||||
uuid.uuid4().hex)
|
||||
|
||||
def test_delete_role_404(self):
|
||||
self.assertRaises(exception.RoleNotFound,
|
||||
self.identity_api.delete_role,
|
||||
uuid.uuid4().hex)
|
||||
|
||||
def test_create_tenant_long_name_fails(self):
|
||||
tenant = {'id': 'fake1', 'name': 'a' * 65}
|
||||
@ -378,10 +536,20 @@ class TokenTests(object):
|
||||
self.assertEquals(new_data_ref, data)
|
||||
|
||||
self.token_api.delete_token(token_id)
|
||||
self.assertRaises(exception.TokenNotFound,
|
||||
self.token_api.delete_token, token_id)
|
||||
self.assertRaises(exception.TokenNotFound,
|
||||
self.token_api.get_token, token_id)
|
||||
self.assertRaises(exception.TokenNotFound,
|
||||
self.token_api.delete_token, token_id)
|
||||
|
||||
def test_get_token_404(self):
|
||||
self.assertRaises(exception.TokenNotFound,
|
||||
self.token_api.get_token,
|
||||
uuid.uuid4().hex)
|
||||
|
||||
def test_delete_token_404(self):
|
||||
self.assertRaises(exception.TokenNotFound,
|
||||
self.token_api.delete_token,
|
||||
uuid.uuid4().hex)
|
||||
|
||||
def test_expired_token(self):
|
||||
token_id = uuid.uuid4().hex
|
||||
@ -403,7 +571,6 @@ class TokenTests(object):
|
||||
|
||||
|
||||
class CatalogTests(object):
|
||||
|
||||
def test_service_crud(self):
|
||||
new_service = {'id': 'MY_SERVICE', 'type': 'myservice',
|
||||
'name': 'My Service', 'description': 'My description'}
|
||||
@ -413,9 +580,41 @@ class CatalogTests(object):
|
||||
service_id = new_service['id']
|
||||
self.catalog_api.delete_service(service_id)
|
||||
self.assertRaises(exception.ServiceNotFound,
|
||||
self.catalog_api.delete_service, service_id)
|
||||
self.catalog_man.delete_service, {}, service_id)
|
||||
self.assertRaises(exception.ServiceNotFound,
|
||||
self.catalog_api.get_service, service_id)
|
||||
self.catalog_man.get_service, {}, service_id)
|
||||
|
||||
def test_get_service_404(self):
|
||||
self.assertRaises(exception.ServiceNotFound,
|
||||
self.catalog_man.get_service,
|
||||
{},
|
||||
uuid.uuid4().hex)
|
||||
|
||||
def test_delete_service_404(self):
|
||||
self.assertRaises(exception.ServiceNotFound,
|
||||
self.catalog_man.delete_service,
|
||||
{},
|
||||
uuid.uuid4().hex)
|
||||
|
||||
def test_create_endpoint_404(self):
|
||||
endpoint = {
|
||||
'id': uuid.uuid4().hex,
|
||||
'service_id': uuid.uuid4().hex,
|
||||
}
|
||||
self.assertRaises(exception.ServiceNotFound,
|
||||
self.catalog_api.create_endpoint,
|
||||
endpoint['id'],
|
||||
endpoint)
|
||||
|
||||
def test_get_endpoint_404(self):
|
||||
self.assertRaises(exception.EndpointNotFound,
|
||||
self.catalog_api.get_endpoint,
|
||||
uuid.uuid4().hex)
|
||||
|
||||
def test_delete_endpoint_404(self):
|
||||
self.assertRaises(exception.EndpointNotFound,
|
||||
self.catalog_api.delete_endpoint,
|
||||
uuid.uuid4().hex)
|
||||
|
||||
def test_service_list(self):
|
||||
services = self.catalog_api.list_services()
|
||||
|
@ -13,11 +13,14 @@
|
||||
# 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 uuid
|
||||
|
||||
from keystone import exception
|
||||
from keystone import test
|
||||
from keystone.identity.backends import kvs as identity_kvs
|
||||
from keystone.token.backends import kvs as token_kvs
|
||||
from keystone.catalog.backends import kvs as catalog_kvs
|
||||
from keystone import catalog
|
||||
|
||||
import test_backend
|
||||
import default_fixtures
|
||||
@ -40,6 +43,7 @@ class KvsCatalog(test.TestCase, test_backend.CatalogTests):
|
||||
def setUp(self):
|
||||
super(KvsCatalog, self).setUp()
|
||||
self.catalog_api = catalog_kvs.Catalog(db={})
|
||||
self.catalog_man = catalog.Manager()
|
||||
self.load_fixtures(default_fixtures)
|
||||
self._load_fake_catalog()
|
||||
|
||||
@ -48,14 +52,35 @@ class KvsCatalog(test.TestCase, test_backend.CatalogTests):
|
||||
'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_404(self):
|
||||
# FIXME(dolph): this test should be moved up to test_backend
|
||||
# FIXME(dolph): exceptions should be UserNotFound and TenantNotFound
|
||||
self.assertRaises(exception.NotFound,
|
||||
self.catalog_api.get_catalog,
|
||||
uuid.uuid4().hex,
|
||||
'bar')
|
||||
|
||||
def test_get_catalog_bad_tenant(self):
|
||||
catalog_ref = self.catalog_api.get_catalog('foo', 'bar' + 'WRONG')
|
||||
self.assert_(catalog_ref is None)
|
||||
self.assertRaises(exception.NotFound,
|
||||
self.catalog_api.get_catalog,
|
||||
'foo',
|
||||
uuid.uuid4().hex)
|
||||
|
||||
def test_get_catalog(self):
|
||||
catalog_ref = self.catalog_api.get_catalog('foo', 'bar')
|
||||
self.assertDictEqual(catalog_ref, self.catalog_foobar)
|
||||
|
||||
def test_create_endpoint_404(self):
|
||||
self.assertRaises(exception.NotImplemented,
|
||||
self.catalog_api.create_endpoint,
|
||||
uuid.uuid4().hex,
|
||||
{})
|
||||
|
||||
def test_get_endpoint_404(self):
|
||||
self.assertRaises(exception.NotImplemented,
|
||||
self.catalog_api.get_endpoint,
|
||||
uuid.uuid4().hex)
|
||||
|
||||
def test_delete_endpoint_404(self):
|
||||
self.assertRaises(exception.NotImplemented,
|
||||
self.catalog_api.delete_endpoint,
|
||||
uuid.uuid4().hex)
|
||||
|
@ -14,7 +14,10 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import uuid
|
||||
|
||||
from keystone import config
|
||||
from keystone import exception
|
||||
from keystone import test
|
||||
from keystone.common.ldap import fakeldap
|
||||
from keystone.identity.backends import ldap as identity_ldap
|
||||
@ -41,5 +44,94 @@ class LDAPIdentity(test.TestCase, test_backend.IdentityTests):
|
||||
self.identity_api = identity_ldap.Identity()
|
||||
self.load_fixtures(default_fixtures)
|
||||
|
||||
def tearDown(self):
|
||||
test.TestCase.tearDown(self)
|
||||
def test_delete_tenant_404(self):
|
||||
self.assertRaises(exception.NotImplemented,
|
||||
self.identity_api.delete_tenant,
|
||||
uuid.uuid4().hex)
|
||||
|
||||
def test_delete_user_404(self):
|
||||
self.assertRaises(exception.NotImplemented,
|
||||
self.identity_api.delete_user,
|
||||
uuid.uuid4().hex)
|
||||
|
||||
def test_rename_duplicate_role_name_fails(self):
|
||||
role1 = {'id': 'fake1',
|
||||
'name': 'fake1name'}
|
||||
role2 = {'id': 'fake2',
|
||||
'name': 'fake2name'}
|
||||
self.identity_api.create_role('fake1', role1)
|
||||
self.identity_api.create_role('fake2', role2)
|
||||
role1['name'] = 'fake2name'
|
||||
self.assertRaises(exception.NotImplemented,
|
||||
self.identity_api.update_role,
|
||||
'fake1',
|
||||
role1)
|
||||
|
||||
def test_rename_duplicate_user_name_fails(self):
|
||||
user1 = {'id': 'fake1',
|
||||
'name': 'fake1',
|
||||
'password': 'fakepass',
|
||||
'tenants': ['bar']}
|
||||
user2 = {'id': 'fake2',
|
||||
'name': 'fake2',
|
||||
'password': 'fakepass',
|
||||
'tenants': ['bar']}
|
||||
self.identity_api.create_user('fake1', user1)
|
||||
self.identity_api.create_user('fake2', user2)
|
||||
user2['name'] = 'fake1'
|
||||
self.assertRaises(exception.ValidationError,
|
||||
self.identity_api.update_user,
|
||||
'fake2',
|
||||
user2)
|
||||
|
||||
def test_delete_user_with_tenant_association(self):
|
||||
self.assertRaises(exception.NotImplemented,
|
||||
self.identity_api.delete_user,
|
||||
uuid.uuid4().hex)
|
||||
|
||||
def test_remove_user_from_tenant(self):
|
||||
self.assertRaises(exception.NotImplemented,
|
||||
self.identity_api.remove_user_from_tenant,
|
||||
self.tenant_bar['id'],
|
||||
self.user_foo['id'])
|
||||
|
||||
def test_remove_user_from_tenant_404(self):
|
||||
self.assertRaises(exception.NotImplemented,
|
||||
self.identity_api.remove_user_from_tenant,
|
||||
self.tenant_bar['id'],
|
||||
self.user_foo['id'])
|
||||
|
||||
def test_remove_role_from_user_and_tenant(self):
|
||||
self.assertRaises(exception.NotImplemented,
|
||||
self.identity_api.remove_role_from_user_and_tenant,
|
||||
self.tenant_bar['id'],
|
||||
self.user_foo['id'],
|
||||
'useless')
|
||||
|
||||
def test_role_crud(self):
|
||||
role = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex}
|
||||
self.identity_api.create_role(role['id'], role)
|
||||
role_ref = self.identity_api.get_role(role['id'])
|
||||
role_ref_dict = dict((x, role_ref[x]) for x in role_ref)
|
||||
self.assertDictEqual(role_ref_dict, role)
|
||||
|
||||
self.assertRaises(exception.NotImplemented,
|
||||
self.identity_api.update_role,
|
||||
role['id'],
|
||||
role)
|
||||
|
||||
self.identity_api.delete_role(role['id'])
|
||||
self.assertRaises(exception.RoleNotFound,
|
||||
self.identity_api.get_role,
|
||||
role['id'])
|
||||
|
||||
def test_update_role_404(self):
|
||||
self.assertRaises(exception.NotImplemented,
|
||||
self.identity_api.update_role,
|
||||
uuid.uuid4().hex,
|
||||
{})
|
||||
|
||||
def test_get_tenant_users_404(self):
|
||||
self.assertRaises(exception.NotImplemented,
|
||||
self.identity_api.get_tenant_users,
|
||||
tenant_id=uuid.uuid4().hex)
|
||||
|
@ -41,15 +41,16 @@ class SqlIdentity(test.TestCase, test_backend.IdentityTests):
|
||||
self.load_fixtures(default_fixtures)
|
||||
|
||||
def test_delete_user_with_tenant_association(self):
|
||||
user = {'id': 'fake',
|
||||
'name': 'fakeuser',
|
||||
'password': 'passwd'}
|
||||
self.identity_api.create_user('fake', user)
|
||||
user = {'id': uuid.uuid4().hex,
|
||||
'name': uuid.uuid4().hex,
|
||||
'password': uuid.uuid4().hex}
|
||||
self.identity_api.create_user(user['id'], user)
|
||||
self.identity_api.add_user_to_tenant(self.tenant_bar['id'],
|
||||
user['id'])
|
||||
self.identity_api.delete_user(user['id'])
|
||||
tenants = self.identity_api.get_tenants_for_user(user['id'])
|
||||
self.assertEquals(tenants, [])
|
||||
self.assertRaises(exception.UserNotFound,
|
||||
self.identity_api.get_tenants_for_user,
|
||||
user['id'])
|
||||
|
||||
def test_create_null_user_name(self):
|
||||
user = {'id': uuid.uuid4().hex,
|
||||
@ -59,13 +60,12 @@ class SqlIdentity(test.TestCase, test_backend.IdentityTests):
|
||||
self.identity_api.create_user,
|
||||
user['id'],
|
||||
user)
|
||||
# TODO(dolph): can be uncommented pending bug 968519
|
||||
#self.assertRaises(exception.UserNotFound,
|
||||
# self.identity_api.get_user,
|
||||
# user['id'])
|
||||
#self.assertRaises(exception.UserNotFound,
|
||||
# self.identity_api.get_user_by_name,
|
||||
# user['name'])
|
||||
self.assertRaises(exception.UserNotFound,
|
||||
self.identity_api.get_user,
|
||||
user['id'])
|
||||
self.assertRaises(exception.UserNotFound,
|
||||
self.identity_api.get_user_by_name,
|
||||
user['name'])
|
||||
|
||||
def test_create_null_tenant_name(self):
|
||||
tenant = {'id': uuid.uuid4().hex,
|
||||
@ -74,13 +74,12 @@ class SqlIdentity(test.TestCase, test_backend.IdentityTests):
|
||||
self.identity_api.create_tenant,
|
||||
tenant['id'],
|
||||
tenant)
|
||||
# TODO(dolph): can be uncommented pending bug 968519
|
||||
#self.assertRaises(exception.TenantNotFound,
|
||||
# self.identity_api.get_tenant,
|
||||
# tenant['id'])
|
||||
#self.assertRaises(exception.TenantNotFound,
|
||||
# self.identity_api.get_tenant_by_name,
|
||||
# tenant['name'])
|
||||
self.assertRaises(exception.TenantNotFound,
|
||||
self.identity_api.get_tenant,
|
||||
tenant['id'])
|
||||
self.assertRaises(exception.TenantNotFound,
|
||||
self.identity_api.get_tenant_by_name,
|
||||
tenant['name'])
|
||||
|
||||
def test_create_null_role_name(self):
|
||||
role = {'id': uuid.uuid4().hex,
|
||||
@ -89,10 +88,9 @@ class SqlIdentity(test.TestCase, test_backend.IdentityTests):
|
||||
self.identity_api.create_role,
|
||||
role['id'],
|
||||
role)
|
||||
# TODO(dolph): can be uncommented pending bug 968519
|
||||
#self.assertRaises(exception.RoleNotFound,
|
||||
# self.identity_api.get_role,
|
||||
# role['id'])
|
||||
self.assertRaises(exception.RoleNotFound,
|
||||
self.identity_api.get_role,
|
||||
role['id'])
|
||||
|
||||
def test_delete_tenant_with_user_association(self):
|
||||
user = {'id': 'fake',
|
||||
@ -114,9 +112,10 @@ class SqlIdentity(test.TestCase, test_backend.IdentityTests):
|
||||
self.tenant_bar['id'],
|
||||
{'extra': 'extra'})
|
||||
self.identity_api.delete_user(user['id'])
|
||||
metadata = self.identity_api.get_metadata(user['id'],
|
||||
self.tenant_bar['id'])
|
||||
self.assertEquals(metadata, {})
|
||||
self.assertRaises(exception.MetadataNotFound,
|
||||
self.identity_api.get_metadata,
|
||||
user['id'],
|
||||
self.tenant_bar['id'])
|
||||
|
||||
def test_delete_tenant_with_metadata(self):
|
||||
user = {'id': 'fake',
|
||||
@ -127,9 +126,10 @@ class SqlIdentity(test.TestCase, test_backend.IdentityTests):
|
||||
self.tenant_bar['id'],
|
||||
{'extra': 'extra'})
|
||||
self.identity_api.delete_tenant(self.tenant_bar['id'])
|
||||
metadata = self.identity_api.get_metadata(user['id'],
|
||||
self.tenant_bar['id'])
|
||||
self.assertEquals(metadata, {})
|
||||
self.assertRaises(exception.MetadataNotFound,
|
||||
self.identity_api.get_metadata,
|
||||
user['id'],
|
||||
self.tenant_bar['id'])
|
||||
|
||||
|
||||
class SqlToken(test.TestCase, test_backend.TokenTests):
|
||||
|
@ -15,9 +15,12 @@
|
||||
# under the License.
|
||||
|
||||
import os
|
||||
import uuid
|
||||
|
||||
from keystone import exception
|
||||
from keystone import test
|
||||
from keystone.catalog.backends import templated as catalog_templated
|
||||
from keystone import catalog
|
||||
|
||||
import test_backend
|
||||
import default_fixtures
|
||||
@ -50,8 +53,25 @@ class TestTemplatedCatalog(test.TestCase, test_backend.CatalogTests):
|
||||
super(TestTemplatedCatalog, self).setUp()
|
||||
self.opt_in_group('catalog', template_file=DEFAULT_CATALOG_TEMPLATES)
|
||||
self.catalog_api = catalog_templated.TemplatedCatalog()
|
||||
self.catalog_man = catalog.Manager()
|
||||
self.load_fixtures(default_fixtures)
|
||||
|
||||
def test_get_catalog(self):
|
||||
catalog_ref = self.catalog_api.get_catalog('foo', 'bar')
|
||||
self.assertDictEqual(catalog_ref, self.DEFAULT_FIXTURE)
|
||||
|
||||
def test_create_endpoint_404(self):
|
||||
self.assertRaises(exception.NotImplemented,
|
||||
self.catalog_api.create_endpoint,
|
||||
uuid.uuid4().hex,
|
||||
{})
|
||||
|
||||
def test_get_endpoint_404(self):
|
||||
self.assertRaises(exception.NotImplemented,
|
||||
self.catalog_api.get_endpoint,
|
||||
uuid.uuid4().hex)
|
||||
|
||||
def test_delete_endpoint_404(self):
|
||||
self.assertRaises(exception.NotImplemented,
|
||||
self.catalog_api.delete_endpoint,
|
||||
uuid.uuid4().hex)
|
||||
|
@ -133,8 +133,9 @@ class KeystoneClientTests(object):
|
||||
from keystoneclient import exceptions as client_exceptions
|
||||
client = self.get_client()
|
||||
token = client.auth_token
|
||||
self.assertRaises(client_exceptions.AuthorizationFailure,
|
||||
self._client, token=token, tenant_id='baz')
|
||||
self.assertRaises(client_exceptions.Unauthorized,
|
||||
self._client, token=token,
|
||||
tenant_id=uuid.uuid4().hex)
|
||||
|
||||
def test_authenticate_token_tenant_name(self):
|
||||
client = self.get_client()
|
||||
@ -284,15 +285,15 @@ class KeystoneClientTests(object):
|
||||
self.assertRaises(client_exceptions.Unauthorized,
|
||||
self._client,
|
||||
username=self.user_foo['name'],
|
||||
password='invalid')
|
||||
password=uuid.uuid4().hex)
|
||||
|
||||
def test_invalid_user_password(self):
|
||||
def test_invalid_user_and_password(self):
|
||||
from keystoneclient import exceptions as client_exceptions
|
||||
|
||||
self.assertRaises(client_exceptions.Unauthorized,
|
||||
self._client,
|
||||
username='blah',
|
||||
password='blah')
|
||||
username=uuid.uuid4().hex,
|
||||
password=uuid.uuid4().hex)
|
||||
|
||||
def test_change_password_invalidates_token(self):
|
||||
from keystoneclient import exceptions as client_exceptions
|
||||
@ -674,17 +675,6 @@ class KeystoneClientTests(object):
|
||||
client.services.get,
|
||||
id=uuid.uuid4().hex)
|
||||
|
||||
def test_endpoint_create_404(self):
|
||||
from keystoneclient import exceptions as client_exceptions
|
||||
client = self.get_client(admin=True)
|
||||
self.assertRaises(client_exceptions.NotFound,
|
||||
client.endpoints.create,
|
||||
region=uuid.uuid4().hex,
|
||||
service_id=uuid.uuid4().hex,
|
||||
publicurl=uuid.uuid4().hex,
|
||||
adminurl=uuid.uuid4().hex,
|
||||
internalurl=uuid.uuid4().hex)
|
||||
|
||||
def test_endpoint_delete_404(self):
|
||||
# the catalog backend is expected to return Not Implemented
|
||||
from keystoneclient import exceptions as client_exceptions
|
||||
|
@ -74,6 +74,17 @@ class KcMasterSqlTestCase(test_keystoneclient.KcMasterTestCase):
|
||||
self.assertRaises(client_exceptions.NotFound, client.endpoints.delete,
|
||||
id=endpoint.id)
|
||||
|
||||
def test_endpoint_create_404(self):
|
||||
from keystoneclient import exceptions as client_exceptions
|
||||
client = self.get_client(admin=True)
|
||||
self.assertRaises(client_exceptions.NotFound,
|
||||
client.endpoints.create,
|
||||
region=uuid.uuid4().hex,
|
||||
service_id=uuid.uuid4().hex,
|
||||
publicurl=uuid.uuid4().hex,
|
||||
adminurl=uuid.uuid4().hex,
|
||||
internalurl=uuid.uuid4().hex)
|
||||
|
||||
def test_endpoint_delete_404(self):
|
||||
from keystoneclient import exceptions as client_exceptions
|
||||
client = self.get_client(admin=True)
|
||||
|
Loading…
Reference in New Issue
Block a user