From 661cef927e95cf87a96eea7f0f6d840f8bf4adcd Mon Sep 17 00:00:00 2001 From: Henry Nash Date: Fri, 5 Jul 2013 06:04:25 +0100 Subject: Rationalize how we get roles after authentication in the controllers Currently there is a mixture of strategies in the v2 and v3 controllers for how to get the roles assigned for the scope of the requested authentication. This duplicates code, is hard to maintain and in at least once case (where your only roles on a project are due to a group membership) is not actually correct (for v2 tokens). This change does the following: - Standardizes on using the 'get_roles_for_user_and_project()', and its domain equivalent, for how roles are obtained to build a token. This was already the case for v3 tokens. The controllers no longer need to get metadata and extract the roles. - Removes the driver level function to 'authorize_for_project' - this is now handled wihin the controller. The driver simply supports the user authentication. A nice (and planned for) sideffect of the above is that we now hide the schema of how we store roles within the driver layer - i.e. nothing outside of the driver (other than any specific-to-implementation tests) have to know about how roles are stored in the metadata. This paves the way for a re-implementation of the grant tables in IceHouse. This change also fills in missing function definitons in the assignment driver. Implements bp authenticate-role-rationalization Change-Id: I75fc7f5f728649d40ab1c696b33bbcd88ea6edee --- keystone/assignment/backends/kvs.py | 73 ++++++---------- keystone/assignment/backends/ldap.py | 31 +------ keystone/assignment/backends/sql.py | 101 ++++++---------------- keystone/assignment/core.py | 81 +++++++++++------- keystone/contrib/ec2/core.py | 10 +-- keystone/contrib/user_crud/core.py | 2 +- keystone/identity/backends/kvs.py | 4 +- keystone/identity/backends/ldap.py | 5 +- keystone/identity/backends/pam.py | 16 +--- keystone/identity/backends/sql.py | 4 +- keystone/identity/core.py | 33 +------- keystone/test.py | 13 --- keystone/token/controllers.py | 92 ++++++-------------- tests/default_fixtures.py | 11 +-- tests/test_backend.py | 68 ++------------- tests/test_backend_ldap.py | 26 +----- tests/test_backend_pam.py | 8 +- tests/test_backend_sql.py | 50 +++++++---- tests/test_content_types.py | 10 +-- tests/test_import_legacy.py | 6 +- tests/test_keystoneclient.py | 9 +- tests/test_migrate_nova_auth.py | 157 ----------------------------------- 22 files changed, 212 insertions(+), 598 deletions(-) delete mode 100644 tests/test_migrate_nova_auth.py diff --git a/keystone/assignment/backends/kvs.py b/keystone/assignment/backends/kvs.py index 9a09598f..4ed3937b 100644 --- a/keystone/assignment/backends/kvs.py +++ b/keystone/assignment/backends/kvs.py @@ -26,22 +26,6 @@ class Assignment(kvs.Base, assignment.Driver): super(Assignment, self).__init__() # Public interface - def authorize_for_project(self, user_ref, tenant_id=None): - user_id = user_ref['id'] - tenant_ref = None - metadata_ref = {} - if tenant_id is not None: - if tenant_id not in self.get_projects_for_user(user_id): - raise AssertionError('Invalid tenant') - try: - tenant_ref = self.get_project(tenant_id) - metadata_ref = self.get_metadata(user_id, tenant_id) - except exception.ProjectNotFound: - tenant_ref = None - metadata_ref = {} - except exception.MetadataNotFound: - metadata_ref = {} - return (identity.filter_user(user_ref), tenant_ref, metadata_ref) def get_project(self, tenant_id): try: @@ -79,8 +63,8 @@ class Assignment(kvs.Base, assignment.Driver): except exception.NotFound: raise exception.UserNotFound(user_id=user_name) - def get_metadata(self, user_id=None, tenant_id=None, - domain_id=None, group_id=None): + def _get_metadata(self, user_id=None, tenant_id=None, + domain_id=None, group_id=None): try: if user_id: if tenant_id: @@ -113,21 +97,12 @@ class Assignment(kvs.Base, assignment.Driver): user_ref = self._get_user(user_id) return user_ref.get('tenants', []) - def get_roles_for_user_and_project(self, user_id, tenant_id): - self.identity_api.get_user(user_id) - self.get_project(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_project(self, user_id, tenant_id, role_id): self.identity_api.get_user(user_id) self.get_project(tenant_id) self.get_role(role_id) try: - metadata_ref = self.get_metadata(user_id, tenant_id) + metadata_ref = self._get_metadata(user_id, tenant_id) except exception.MetadataNotFound: metadata_ref = {} roles = set(metadata_ref.get('roles', [])) @@ -137,11 +112,11 @@ class Assignment(kvs.Base, assignment.Driver): raise exception.Conflict(type='role grant', details=msg) roles.add(role_id) metadata_ref['roles'] = list(roles) - self.update_metadata(user_id, tenant_id, metadata_ref) + self._update_metadata(user_id, tenant_id, metadata_ref) def remove_role_from_user_and_project(self, user_id, tenant_id, role_id): try: - metadata_ref = self.get_metadata(user_id, tenant_id) + metadata_ref = self._get_metadata(user_id, tenant_id) except exception.MetadataNotFound: metadata_ref = {} roles = set(metadata_ref.get('roles', [])) @@ -160,7 +135,7 @@ class Assignment(kvs.Base, assignment.Driver): user_ref['tenants'] = list(tenants) self.identity_api.update_user(user_id, user_ref) else: - self.update_metadata(user_id, tenant_id, metadata_ref) + self._update_metadata(user_id, tenant_id, metadata_ref) def list_role_assignments(self): """List the role assignments. @@ -255,14 +230,14 @@ class Assignment(kvs.Base, assignment.Driver): self.db.delete('tenant_name-%s' % old_project['name']) self.db.delete('tenant-%s' % tenant_id) - def create_metadata(self, user_id, tenant_id, metadata, - domain_id=None, group_id=None): + def _create_metadata(self, user_id, tenant_id, metadata, + domain_id=None, group_id=None): - return self.update_metadata(user_id, tenant_id, metadata, - domain_id, group_id) + return self._update_metadata(user_id, tenant_id, metadata, + domain_id, group_id) - def update_metadata(self, user_id, tenant_id, metadata, - domain_id=None, group_id=None): + def _update_metadata(self, user_id, tenant_id, metadata, + domain_id=None, group_id=None): if user_id: if tenant_id: self.db.set('metadata-%s-%s' % (tenant_id, user_id), metadata) @@ -362,15 +337,15 @@ class Assignment(kvs.Base, assignment.Driver): self.get_project(project_id) try: - metadata_ref = self.get_metadata(user_id, project_id, - domain_id, group_id) + metadata_ref = self._get_metadata(user_id, project_id, + domain_id, group_id) except exception.MetadataNotFound: metadata_ref = {} roles = set(metadata_ref.get('roles', [])) roles.add(role_id) metadata_ref['roles'] = list(roles) - self.update_metadata(user_id, project_id, metadata_ref, - domain_id, group_id) + self._update_metadata(user_id, project_id, metadata_ref, + domain_id, group_id) def list_grants(self, user_id=None, group_id=None, domain_id=None, project_id=None): @@ -384,8 +359,8 @@ class Assignment(kvs.Base, assignment.Driver): self.get_project(project_id) try: - metadata_ref = self.get_metadata(user_id, project_id, - domain_id, group_id) + metadata_ref = self._get_metadata(user_id, project_id, + domain_id, group_id) except exception.MetadataNotFound: metadata_ref = {} return [self.get_role(x) for x in metadata_ref.get('roles', [])] @@ -403,8 +378,8 @@ class Assignment(kvs.Base, assignment.Driver): self.get_project(project_id) try: - metadata_ref = self.get_metadata(user_id, project_id, - domain_id, group_id) + metadata_ref = self._get_metadata(user_id, project_id, + domain_id, group_id) except exception.MetadataNotFound: metadata_ref = {} role_ids = set(metadata_ref.get('roles', [])) @@ -425,8 +400,8 @@ class Assignment(kvs.Base, assignment.Driver): self.get_project(project_id) try: - metadata_ref = self.get_metadata(user_id, project_id, - domain_id, group_id) + metadata_ref = self._get_metadata(user_id, project_id, + domain_id, group_id) except exception.MetadataNotFound: metadata_ref = {} roles = set(metadata_ref.get('roles', [])) @@ -435,8 +410,8 @@ class Assignment(kvs.Base, assignment.Driver): except KeyError: raise exception.RoleNotFound(role_id=role_id) metadata_ref['roles'] = list(roles) - self.update_metadata(user_id, project_id, metadata_ref, - domain_id, group_id) + self._update_metadata(user_id, project_id, metadata_ref, + domain_id, group_id) # domain crud diff --git a/keystone/assignment/backends/ldap.py b/keystone/assignment/backends/ldap.py index 500f304a..44a479bf 100644 --- a/keystone/assignment/backends/ldap.py +++ b/keystone/assignment/backends/ldap.py @@ -26,7 +26,6 @@ from keystone.common import logging from keystone.common import models from keystone import config from keystone import exception -from keystone import identity from keystone.identity.backends import ldap as ldap_identity @@ -70,29 +69,6 @@ class Assignment(assignment.Driver): #once we remove here. the getter and setter can be removed as well. self._identity_api.driver.project = self.project - def authorize_for_project(self, user_ref, tenant_id=None): - user_id = user_ref['id'] - tenant_ref = None - metadata_ref = {} - - if tenant_id is not None: - if tenant_id not in self.get_projects_for_user(user_id): - raise AssertionError('Invalid tenant') - - try: - tenant_ref = self.get_project(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.ProjectNotFound: - tenant_ref = None - metadata_ref = {} - except exception.MetadataNotFound: - metadata_ref = {} - - user_ref = self._set_default_domain(identity.filter_user(user_ref)) - return (user_ref, tenant_ref, metadata_ref) - def get_project(self, tenant_id): return self._set_default_domain(self.project.get(tenant_id)) @@ -149,8 +125,9 @@ class Assignment(assignment.Driver): tenant['name'] = clean.project_name(tenant['name']) return self._set_default_domain(self.project.update(tenant_id, tenant)) - def get_metadata(self, user_id=None, tenant_id=None, - domain_id=None, group_id=None): + def _get_metadata(self, user_id=None, tenant_id=None, + domain_id=None, group_id=None): + def _get_roles_for_just_user_and_project(user_id, tenant_id): self.identity_api.get_user(user_id) self.get_project(tenant_id) @@ -216,7 +193,7 @@ class Assignment(assignment.Driver): user_dn=user_dn, tenant_dn=tenant_dn) - def create_metadata(self, user_id, tenant_id, metadata): + def _create_metadata(self, user_id, tenant_id, metadata): return {} def create_role(self, role_id, role): diff --git a/keystone/assignment/backends/sql.py b/keystone/assignment/backends/sql.py index 65d1bbc7..57ca7834 100644 --- a/keystone/assignment/backends/sql.py +++ b/keystone/assignment/backends/sql.py @@ -19,7 +19,6 @@ from keystone import clean from keystone.common import sql from keystone.common.sql import migration from keystone import exception -from keystone import identity class Assignment(sql.Base, assignment.Driver): @@ -31,26 +30,6 @@ class Assignment(sql.Base, assignment.Driver): def db_sync(self, version=None): migration.db_sync(version=version) - def authorize_for_project(self, user_ref, tenant_id=None): - user_id = user_ref['id'] - tenant_ref = None - metadata_ref = {} - if tenant_id is not None: - # FIXME(gyee): this should really be - # get_roles_for_user_and_project() after the dusts settle - if tenant_id not in self.get_projects_for_user(user_id): - raise AssertionError('Invalid project') - try: - tenant_ref = self.get_project(tenant_id) - metadata_ref = self.get_metadata(user_id, tenant_id) - except exception.ProjectNotFound: - tenant_ref = None - metadata_ref = {} - except exception.MetadataNotFound: - metadata_ref = {} - user_ref = identity.filter_user(user_ref.to_dict()) - return (user_ref, tenant_ref, metadata_ref) - def _get_project(self, session, project_id): project_ref = session.query(Project).get(project_id) if project_ref is None: @@ -91,8 +70,8 @@ class Assignment(sql.Base, assignment.Driver): user_refs.append(user_ref) return user_refs - def get_metadata(self, user_id=None, tenant_id=None, - domain_id=None, group_id=None): + def _get_metadata(self, user_id=None, tenant_id=None, + domain_id=None, group_id=None): session = self.get_session() if user_id: @@ -130,8 +109,8 @@ class Assignment(sql.Base, assignment.Driver): self._get_project(session, project_id) try: - metadata_ref = self.get_metadata(user_id, project_id, - domain_id, group_id) + metadata_ref = self._get_metadata(user_id, project_id, + domain_id, group_id) is_new = False except exception.MetadataNotFound: metadata_ref = {} @@ -140,11 +119,11 @@ class Assignment(sql.Base, assignment.Driver): roles.add(role_id) metadata_ref['roles'] = list(roles) if is_new: - self.create_metadata(user_id, project_id, metadata_ref, - domain_id, group_id) + self._create_metadata(user_id, project_id, metadata_ref, + domain_id, group_id) else: - self.update_metadata(user_id, project_id, metadata_ref, - domain_id, group_id) + self._update_metadata(user_id, project_id, metadata_ref, + domain_id, group_id) def list_grants(self, user_id=None, group_id=None, domain_id=None, project_id=None): @@ -159,8 +138,8 @@ class Assignment(sql.Base, assignment.Driver): self._get_project(session, project_id) try: - metadata_ref = self.get_metadata(user_id, project_id, - domain_id, group_id) + metadata_ref = self._get_metadata(user_id, project_id, + domain_id, group_id) except exception.MetadataNotFound: metadata_ref = {} return [self.get_role(x) for x in metadata_ref.get('roles', [])] @@ -179,8 +158,8 @@ class Assignment(sql.Base, assignment.Driver): self._get_project(session, project_id) try: - metadata_ref = self.get_metadata(user_id, project_id, - domain_id, group_id) + metadata_ref = self._get_metadata(user_id, project_id, + domain_id, group_id) except exception.MetadataNotFound: metadata_ref = {} role_ids = set(metadata_ref.get('roles', [])) @@ -202,8 +181,8 @@ class Assignment(sql.Base, assignment.Driver): self._get_project(session, project_id) try: - metadata_ref = self.get_metadata(user_id, project_id, - domain_id, group_id) + metadata_ref = self._get_metadata(user_id, project_id, + domain_id, group_id) is_new = False except exception.MetadataNotFound: metadata_ref = {} @@ -215,11 +194,11 @@ class Assignment(sql.Base, assignment.Driver): raise exception.RoleNotFound(role_id=role_id) metadata_ref['roles'] = list(roles) if is_new: - self.create_metadata(user_id, project_id, metadata_ref, - domain_id, group_id) + self._create_metadata(user_id, project_id, metadata_ref, + domain_id, group_id) else: - self.update_metadata(user_id, project_id, metadata_ref, - domain_id, group_id) + self._update_metadata(user_id, project_id, metadata_ref, + domain_id, group_id) def list_projects(self): session = self.get_session() @@ -234,39 +213,13 @@ class Assignment(sql.Base, assignment.Driver): membership_refs = query.all() return [x.project_id for x in membership_refs] - def _get_user_group_project_roles(self, metadata_ref, user_id, project_id): - group_refs = self.identity_api.list_groups_for_user(user_id=user_id) - for x in group_refs: - try: - metadata_ref.update( - self.get_metadata(group_id=x['id'], - tenant_id=project_id)) - except exception.MetadataNotFound: - # no group grant, skip - pass - - def _get_user_project_roles(self, metadata_ref, user_id, project_id): - try: - metadata_ref.update(self.get_metadata(user_id, project_id)) - except exception.MetadataNotFound: - pass - - def get_roles_for_user_and_project(self, user_id, tenant_id): - session = self.get_session() - self.identity_api._get_user(session, user_id) - self._get_project(session, tenant_id) - metadata_ref = {} - self._get_user_project_roles(metadata_ref, user_id, tenant_id) - self._get_user_group_project_roles(metadata_ref, user_id, tenant_id) - return list(set(metadata_ref.get('roles', []))) - def add_role_to_user_and_project(self, user_id, tenant_id, role_id): session = self.get_session() self.identity_api._get_user(session, user_id) self._get_project(session, tenant_id) self._get_role(session, role_id) try: - metadata_ref = self.get_metadata(user_id, tenant_id) + metadata_ref = self._get_metadata(user_id, tenant_id) is_new = False except exception.MetadataNotFound: metadata_ref = {} @@ -279,13 +232,13 @@ class Assignment(sql.Base, assignment.Driver): roles.add(role_id) metadata_ref['roles'] = list(roles) if is_new: - self.create_metadata(user_id, tenant_id, metadata_ref) + self._create_metadata(user_id, tenant_id, metadata_ref) else: - self.update_metadata(user_id, tenant_id, metadata_ref) + self._update_metadata(user_id, tenant_id, metadata_ref) def remove_role_from_user_and_project(self, user_id, tenant_id, role_id): try: - metadata_ref = self.get_metadata(user_id, tenant_id) + metadata_ref = self._get_metadata(user_id, tenant_id) roles = set(metadata_ref.get('roles', [])) if role_id not in roles: raise exception.RoleNotFound(message=_( @@ -294,7 +247,7 @@ class Assignment(sql.Base, assignment.Driver): roles.remove(role_id) metadata_ref['roles'] = list(roles) if len(roles): - self.update_metadata(user_id, tenant_id, metadata_ref) + self._update_metadata(user_id, tenant_id, metadata_ref) else: session = self.get_session() q = session.query(UserProjectGrant) @@ -396,8 +349,8 @@ class Assignment(sql.Base, assignment.Driver): session.flush() @sql.handle_conflicts(type='metadata') - def create_metadata(self, user_id, tenant_id, metadata, - domain_id=None, group_id=None): + def _create_metadata(self, user_id, tenant_id, metadata, + domain_id=None, group_id=None): session = self.get_session() with session.begin(): if user_id: @@ -426,8 +379,8 @@ class Assignment(sql.Base, assignment.Driver): return metadata @sql.handle_conflicts(type='metadata') - def update_metadata(self, user_id, tenant_id, metadata, - domain_id=None, group_id=None): + def _update_metadata(self, user_id, tenant_id, metadata, + domain_id=None, group_id=None): session = self.get_session() with session.begin(): if user_id: diff --git a/keystone/assignment/core.py b/keystone/assignment/core.py index 251a3bc6..879fee0b 100644 --- a/keystone/assignment/core.py +++ b/keystone/assignment/core.py @@ -58,8 +58,8 @@ class Manager(manager.Manager): (user_id=user_id)) for x in group_refs: try: - metadata_ref = self.get_metadata(group_id=x['id'], - tenant_id=tenant_id) + metadata_ref = self._get_metadata(group_id=x['id'], + tenant_id=tenant_id) role_list += metadata_ref.get('roles', []) except exception.MetadataNotFound: # no group grant, skip @@ -69,8 +69,8 @@ class Manager(manager.Manager): def _get_user_project_roles(user_id, tenant_id): metadata_ref = {} try: - metadata_ref = self.get_metadata(user_id=user_id, - tenant_id=tenant_id) + metadata_ref = self._get_metadata(user_id=user_id, + tenant_id=tenant_id) except exception.MetadataNotFound: pass return metadata_ref.get('roles', []) @@ -97,8 +97,8 @@ class Manager(manager.Manager): list_groups_for_user(user_id=user_id)) for x in group_refs: try: - metadata_ref = self.get_metadata(group_id=x['id'], - domain_id=domain_id) + metadata_ref = self._get_metadata(group_id=x['id'], + domain_id=domain_id) role_list += metadata_ref.get('roles', []) except (exception.MetadataNotFound, exception.NotImplemented): # MetadataNotFound implies no group grant, so skip. @@ -110,8 +110,8 @@ class Manager(manager.Manager): def _get_user_domain_roles(user_id, domain_id): metadata_ref = {} try: - metadata_ref = self.get_metadata(user_id=user_id, - domain_id=domain_id) + metadata_ref = self._get_metadata(user_id=user_id, + domain_id=domain_id) except (exception.MetadataNotFound, exception.NotImplemented): # MetadataNotFound implies no user grants. # Ignore NotImplemented since not all backends support @@ -152,12 +152,6 @@ class Manager(manager.Manager): class Driver(object): - def authorize_for_project(self, tenant_id, user_ref): - """Authenticate a given user for a tenant. - :returns: (user_ref, tenant_ref, metadata_ref) - :raises: AssertionError - """ - raise exception.NotImplemented() def get_project_by_name(self, tenant_name, domain_id): """Get a tenant by name. @@ -205,39 +199,68 @@ class Driver(object): """ raise exception.NotImplemented() - def list_role_assignments(self): + # assignment/grant crud + + def create_grant(self, role_id, user_id=None, group_id=None, + domain_id=None, project_id=None): + """Creates a new assignment/grant. + :raises: keystone.exception.UserNotFound, + keystone.exception.GroupNotFound, + keystone.exception.ProjectNotFound, + keystone.exception.DomainNotFound, + keystone.exception.ProjectNotFound, + keystone.exception.RoleNotFound + + """ raise exception.NotImplemented() - # metadata crud - def get_metadata(self, user_id=None, tenant_id=None, - domain_id=None, group_id=None): - """Gets the metadata for the specified user/group on project/domain. + def list_grants(self, user_id=None, group_id=None, + domain_id=None, project_id=None): + """Lists assignments/grants. - :raises: keystone.exception.MetadataNotFound - :returns: metadata + :raises: keystone.exception.UserNotFound, + keystone.exception.GroupNotFound, + keystone.exception.ProjectNotFound, + keystone.exception.DomainNotFound, + keystone.exception.ProjectNotFound, + keystone.exception.RoleNotFound """ raise exception.NotImplemented() - def create_metadata(self, user_id, tenant_id, metadata, - domain_id=None, group_id=None): - """Creates the metadata for the specified user/group on project/domain. + def get_grant(self, role_id, user_id=None, group_id=None, + domain_id=None, project_id=None): + """Lists assignments/grants. - :returns: metadata created + :raises: keystone.exception.UserNotFound, + keystone.exception.GroupNotFound, + keystone.exception.ProjectNotFound, + keystone.exception.DomainNotFound, + keystone.exception.ProjectNotFound, + keystone.exception.RoleNotFound """ raise exception.NotImplemented() - def update_metadata(self, user_id, tenant_id, metadata, - domain_id=None, group_id=None): - """Updates the metadata for the specified user/group on project/domain. + def delete_grant(self, role_id, user_id=None, group_id=None, + domain_id=None, project_id=None): + """Lists assignments/grants. - :returns: metadata updated + :raises: keystone.exception.UserNotFound, + keystone.exception.GroupNotFound, + keystone.exception.ProjectNotFound, + keystone.exception.DomainNotFound, + keystone.exception.ProjectNotFound, + keystone.exception.RoleNotFound """ raise exception.NotImplemented() + def list_role_assignments(self): + + raise exception.NotImplemented() + # domain crud def create_domain(self, domain_id, domain): """Creates a new domain. diff --git a/keystone/contrib/ec2/core.py b/keystone/contrib/ec2/core.py index e8471ec6..5254b53f 100644 --- a/keystone/contrib/ec2/core.py +++ b/keystone/contrib/ec2/core.py @@ -153,16 +153,14 @@ class Ec2Controller(controller.V2Controller): token_id = uuid.uuid4().hex tenant_ref = self.identity_api.get_project(creds_ref['tenant_id']) user_ref = self.identity_api.get_user(creds_ref['user_id']) - metadata_ref = self.identity_api.get_metadata( - user_id=user_ref['id'], - tenant_id=tenant_ref['id']) + metadata_ref = {} + metadata_ref['roles'] = ( + self.identity_api.get_roles_for_user_and_project( + user_ref['id'], tenant_ref['id'])) # Validate that the auth info is valid and nothing is disabled token.validate_auth_info(self, user_ref, tenant_ref) - # TODO(termie): optimize this call at some point and put it into the - # the return for metadata - # fill out the roles in the metadata roles = metadata_ref.get('roles', []) if not roles: raise exception.Unauthorized(message='User not valid for tenant.') diff --git a/keystone/contrib/user_crud/core.py b/keystone/contrib/user_crud/core.py index 79144ae5..7b3f459f 100644 --- a/keystone/contrib/user_crud/core.py +++ b/keystone/contrib/user_crud/core.py @@ -43,7 +43,7 @@ class UserController(identity.controllers.User): try: user_ref = self.identity_api.authenticate( user_id=user_id_from_token, - password=original_password)[0] + password=original_password) if not user_ref.get('enabled', True): # NOTE(dolph): why can't you set a disabled user's password? raise exception.Unauthorized('User is disabled') diff --git a/keystone/identity/backends/kvs.py b/keystone/identity/backends/kvs.py index 4fbc1e23..83535108 100644 --- a/keystone/identity/backends/kvs.py +++ b/keystone/identity/backends/kvs.py @@ -28,7 +28,7 @@ class Identity(kvs.Base, identity.Driver): return "keystone.assignment.backends.kvs.Assignment" # Public interface - def authenticate_user(self, user_id=None, password=None): + def authenticate(self, user_id=None, password=None): user_ref = None try: user_ref = self._get_user(user_id) @@ -36,7 +36,7 @@ class Identity(kvs.Base, identity.Driver): raise AssertionError('Invalid user / password') if not utils.check_password(password, user_ref.get('password')): raise AssertionError('Invalid user / password') - return user_ref + return identity.filter_user(user_ref) def _get_user(self, user_id): try: diff --git a/keystone/identity/backends/ldap.py b/keystone/identity/backends/ldap.py index 231d857d..de447b60 100644 --- a/keystone/identity/backends/ldap.py +++ b/keystone/identity/backends/ldap.py @@ -60,7 +60,7 @@ class Identity(identity.Driver): def get_project(self, project_id): return self.assignment.get_project(project_id) - def authenticate_user(self, user_id=None, password=None): + def authenticate(self, user_id=None, password=None): try: user_ref = self._get_user(user_id) except exception.UserNotFound: @@ -74,7 +74,8 @@ class Identity(identity.Driver): raise AssertionError('Invalid user / password') except Exception: raise AssertionError('Invalid user / password') - return user_ref + return self.assignment._set_default_domain( + identity.filter_user(user_ref)) def _get_user(self, user_id): return self.user.get(user_id) diff --git a/keystone/identity/backends/pam.py b/keystone/identity/backends/pam.py index 9c4bbf38..5cfa5b16 100644 --- a/keystone/identity/backends/pam.py +++ b/keystone/identity/backends/pam.py @@ -58,21 +58,13 @@ class PamIdentity(identity.Driver): Tenant is always the same as User, root user has admin role. """ - def authenticate_user(self, user_id=None, password=None): + def authenticate(self, user_id=None, password=None): auth = pam.authenticate if pam else PAM_authenticate if not auth(user_id, password): raise AssertionError('Invalid user / password') user = {'id': user_id, 'name': user_id} return user - def authorize_for_project(self, user_ref, tenant_id=None): - user_id = user_ref['id'] - metadata = {} - if user_id == 'root': - metadata['is_admin'] = True - tenant = {'id': user_id, 'name': user_id} - return (user_ref, tenant, metadata) - def get_project(self, tenant_id): return {'id': tenant_id, 'name': tenant_id} @@ -134,16 +126,16 @@ class PamIdentity(identity.Driver): def delete_project(self, tenant_id, tenant): raise NotImplementedError() - def get_metadata(self, user_id, tenant_id): + def _get_metadata(self, user_id, tenant_id): metadata = {} if user_id == 'root': metadata['is_admin'] = True return metadata - def create_metadata(self, user_id, tenant_id, metadata): + def _create_metadata(self, user_id, tenant_id, metadata): raise NotImplementedError() - def update_metadata(self, user_id, tenant_id, metadata): + def _update_metadata(self, user_id, tenant_id, metadata): raise NotImplementedError() def create_role(self, role_id, role): diff --git a/keystone/identity/backends/sql.py b/keystone/identity/backends/sql.py index 381f547c..f82c34f8 100644 --- a/keystone/identity/backends/sql.py +++ b/keystone/identity/backends/sql.py @@ -84,7 +84,7 @@ class Identity(sql.Base, identity.Driver): return utils.check_password(password, user_ref.password) # Identity interface - def authenticate_user(self, user_id=None, password=None): + def authenticate(self, user_id=None, password=None): session = self.get_session() user_ref = None try: @@ -93,7 +93,7 @@ class Identity(sql.Base, identity.Driver): raise AssertionError('Invalid user / password') if not self._check_password(password, user_ref): raise AssertionError('Invalid user / password') - return user_ref + return identity.filter_user(user_ref.to_dict()) # user crud diff --git a/keystone/identity/core.py b/keystone/identity/core.py index 248915d6..f725589f 100644 --- a/keystone/identity/core.py +++ b/keystone/identity/core.py @@ -68,15 +68,6 @@ class Manager(manager.Manager): self.assignment = assignment_api self.driver.assignment = assignment_api - def authenticate(self, user_id=None, tenant_id=None, password=None): - """Authenticate a given user and password and - authorize them for a tenant. - :returns: (user_ref, tenant_ref, metadata_ref) - :raises: AssertionError - """ - user_ref = self.driver.authenticate_user(user_id, password) - return self.assignment_api.authorize_for_project(user_ref, tenant_id) - def create_user(self, user_id, user_ref): user = user_ref.copy() user['name'] = clean.user_name(user['name']) @@ -110,9 +101,6 @@ class Manager(manager.Manager): tenant['enabled'] = clean.project_enabled(tenant['enabled']) return self.assignment_api.update_project(tenant_id, tenant) - def authorize_for_project(self, user_ref, tenant_id=None): - return self.assignment.authorize_for_project(user_ref, tenant_id) - def get_project_by_name(self, tenant_name, domain_id): return self.assignment.get_project_by_name(tenant_name, domain_id) @@ -131,11 +119,6 @@ class Manager(manager.Manager): def _set_default_domain(self, ref): return self.assignment._set_default_domain(ref) - def get_metadata(self, user_id=None, tenant_id=None, - domain_id=None, group_id=None): - return self.assignment_api.get_metadata(user_id, tenant_id, - domain_id, group_id) - def get_role(self, role_id): return self.assignment.get_role(role_id) @@ -164,9 +147,6 @@ class Manager(manager.Manager): return (self.assignment_api.add_role_to_user_and_project (user_id, tenant_id, role_id)) - def create_metadata(self, user_id, tenant_id, metadata): - return self.assignment.create_metadata(user_id, tenant_id, metadata) - def create_role(self, role_id, role): return self.assignment.create_role(role_id, role) @@ -186,22 +166,22 @@ class Manager(manager.Manager): def create_grant(self, role_id, user_id=None, group_id=None, domain_id=None, project_id=None): - return (self.assignment_api.create_grant + return (self.assignment.create_grant (role_id, user_id, group_id, domain_id, project_id)) def list_grants(self, user_id=None, group_id=None, domain_id=None, project_id=None): - return (self.assignment_api.list_grants + return (self.assignment.list_grants (user_id, group_id, domain_id, project_id)) def get_grant(self, role_id, user_id=None, group_id=None, domain_id=None, project_id=None): - return (self.assignment_api.get_grant + return (self.assignment.get_grant (role_id, user_id, group_id, domain_id, project_id)) def delete_grant(self, role_id, user_id=None, group_id=None, domain_id=None, project_id=None): - return (self.assignment_api.delete_grant + return (self.assignment.delete_grant (role_id, user_id, group_id, domain_id, project_id)) def create_domain(self, domain_id, domain): @@ -231,11 +211,6 @@ class Manager(manager.Manager): def remove_user_from_project(self, tenant_id, user_id): return self.assignment.remove_user_from_project(tenant_id, user_id) - def update_metadata(self, user_id, tenant_id, metadata, - domain_id=None, group_id=None): - return (self.assignment_api.update_metadata - (user_id, tenant_id, metadata, domain_id, group_id)) - def list_role_assignments(self): return self.assignment_api.list_role_assignments() diff --git a/keystone/test.py b/keystone/test.py index 4d9e95e9..61b424a4 100644 --- a/keystone/test.py +++ b/keystone/test.py @@ -278,19 +278,6 @@ class TestCase(NoModule, unittest.TestCase): pass setattr(self, 'user_%s' % user['id'], user_copy) - for metadata in fixtures.METADATA: - metadata_ref = metadata.copy() - # TODO(termie): these will probably end up in the model anyway, - # so this may be futile - del metadata_ref['user_id'] - del metadata_ref['tenant_id'] - rv = self.identity_api.create_metadata(metadata['user_id'], - metadata['tenant_id'], - metadata_ref) - setattr(self, - 'metadata_%s%s' % (metadata['user_id'], - metadata['tenant_id']), rv) - def _paste_config(self, config): if not config.startswith('config:'): test_path = os.path.join(TESTSDIR, config) diff --git a/keystone/token/controllers.py b/keystone/token/controllers.py index bfffa3ad..1ada05ea 100644 --- a/keystone/token/controllers.py +++ b/keystone/token/controllers.py @@ -205,17 +205,10 @@ class Auth(controller.V2Controller): else: current_user_ref = self.identity_api.get_user(user_id) + metadata_ref = {} tenant_id = self._get_project_id_from_auth(auth) - - tenant_ref = self._get_project_ref(user_id, tenant_id) - metadata_ref = self._get_metadata_ref(user_id, tenant_id) - - # TODO(henry-nash): If no tenant was specified, instead check for a - # domain and find any related user/group roles - - self._append_roles(metadata_ref, - self._get_group_metadata_ref( - context, user_id, tenant_id)) + tenant_ref, metadata_ref['roles'] = self._get_project_roles_and_ref( + user_id, tenant_id) expiry = old_token_ref['expires'] if CONF.trust.enabled and 'trust_id' in auth: @@ -281,27 +274,17 @@ class Auth(controller.V2Controller): except exception.UserNotFound as e: raise exception.Unauthorized(e) - tenant_id = self._get_project_id_from_auth(auth) - try: - auth_info = self.identity_api.authenticate( + user_ref = self.identity_api.authenticate( user_id=user_id, - password=password, - tenant_id=tenant_id) + password=password) except AssertionError as e: raise exception.Unauthorized(e) - (user_ref, tenant_ref, metadata_ref) = auth_info - # By now we will have authorized and if a tenant/project was - # specified, we will have obtained its metadata. In this case - # we just need to add in any group roles. - # - # TODO(henry-nash): If no tenant was specified, instead check for a - # domain and find any related user/group roles - - self._append_roles(metadata_ref, - self._get_group_metadata_ref( - context, user_id, tenant_id)) + metadata_ref = {} + tenant_id = self._get_project_id_from_auth(auth) + tenant_ref, metadata_ref['roles'] = self._get_project_roles_and_ref( + user_id, tenant_id) expiry = core.default_expire_time() return (user_ref, tenant_ref, metadata_ref, expiry) @@ -322,17 +305,10 @@ class Auth(controller.V2Controller): except exception.UserNotFound as e: raise exception.Unauthorized(e) + metadata_ref = {} tenant_id = self._get_project_id_from_auth(auth) - - tenant_ref = self._get_project_ref(user_id, tenant_id) - metadata_ref = self._get_metadata_ref(user_id, tenant_id) - - # TODO(henry-nash): If no tenant was specified, instead check for a - # domain and find any related user/group roles - - self._append_roles(metadata_ref, - self._get_group_metadata_ref( - context, user_id, tenant_id)) + tenant_ref, metadata_ref['roles'] = self._get_project_roles_and_ref( + user_id, tenant_id) expiry = core.default_expire_time() return (user_ref, tenant_ref, metadata_ref, expiry) @@ -403,40 +379,26 @@ class Auth(controller.V2Controller): exception.Unauthorized(e) return tenant_ref - def _get_metadata_ref(self, user_id=None, tenant_id=None, domain_id=None, - group_id=None): - """Returns metadata_ref for a user or group in a tenant or domain.""" + def _get_project_roles_and_ref(self, user_id, tenant_id): + """Returns the project roles for this user, and the project ref.""" - metadata_ref = {} - if (user_id or group_id) and (tenant_id or domain_id): + tenant_ref = None + role_list = [] + if tenant_id: try: - metadata_ref = self.identity_api.get_metadata( - user_id=user_id, tenant_id=tenant_id, - domain_id=domain_id, group_id=group_id) - except exception.MetadataNotFound: + tenant_ref = self.identity_api.get_project(tenant_id) + role_list = self.identity_api.get_roles_for_user_and_project( + user_id, tenant_id) + except exception.ProjectNotFound: pass - return metadata_ref - def _get_group_metadata_ref(self, context, user_id, - tenant_id=None, domain_id=None): - """Return any metadata for this project/domain due to group grants.""" - group_refs = self.identity_api.list_groups_for_user(user_id) - metadata_ref = {} - for x in group_refs: - metadata_ref.update(self._get_metadata_ref( - group_id=x['id'], tenant_id=tenant_id, domain_id=domain_id)) - return metadata_ref - - def _append_roles(self, metadata, additional_metadata): - """Add additional roles to the roles in metadata. - - The final set of roles represents the union of existing roles and - additional roles. - """ + if not role_list: + msg = _('User %(u_id)s is unauthorized for tenant %(t_id)s') + msg = msg % {'u_id': user_id, 't_id': tenant_id} + LOG.warning(msg) + raise exception.Unauthorized(msg) - first = set(metadata.get('roles', [])) - second = set(additional_metadata.get('roles', [])) - metadata['roles'] = list(first.union(second)) + return (tenant_ref, role_list) def _get_token_ref(self, token_id, belongs_to=None): """Returns a token if a valid one exists. diff --git a/tests/default_fixtures.py b/tests/default_fixtures.py index 256bb4b7..a1329c22 100644 --- a/tests/default_fixtures.py +++ b/tests/default_fixtures.py @@ -54,7 +54,7 @@ TENANTS = [ } ] -# NOTE(ja): a role of keystone_admin and attribute "is_admin" is done in setUp +# NOTE(ja): a role of keystone_admin is done in setUp USERS = [ { 'id': 'foo', @@ -95,13 +95,6 @@ USERS = [ } ] -METADATA = [ - { - 'user_id': 'sna', - 'tenant_id': 'mtu', - } -] - ROLES = [ { 'id': 'admin', @@ -125,8 +118,6 @@ ROLES = [ 'id': 'service', 'name': 'Service', } - - ] DOMAINS = [ diff --git a/tests/test_backend.py b/tests/test_backend.py index 87762244..a260f2dd 100644 --- a/tests/test_backend.py +++ b/tests/test_backend.py @@ -62,39 +62,17 @@ class IdentityTests(object): self.assertRaises(AssertionError, self.identity_api.authenticate, user_id=uuid.uuid4().hex, - tenant_id=self.tenant_bar['id'], password=self.user_foo['password']) def test_authenticate_bad_password(self): self.assertRaises(AssertionError, self.identity_api.authenticate, user_id=self.user_foo['id'], - tenant_id=self.tenant_bar['id'], password=uuid.uuid4().hex) - def test_authenticate_bad_project(self): - self.assertRaises(AssertionError, - self.identity_api.authenticate, - user_id=self.user_foo['id'], - tenant_id=uuid.uuid4().hex, - password=self.user_foo['password']) - - def test_authenticate_no_project(self): - user_ref, tenant_ref, metadata_ref = self.identity_api.authenticate( - user_id=self.user_foo['id'], - password=self.user_foo['password']) - # NOTE(termie): the password field is left in user_foo to make - # it easier to authenticate in tests, but should - # not be returned by the api - self.user_foo.pop('password') - self.assertDictEqual(user_ref, self.user_foo) - self.assert_(tenant_ref is None) - self.assert_(not metadata_ref) - def test_authenticate(self): - user_ref, tenant_ref, metadata_ref = self.identity_api.authenticate( + user_ref = self.identity_api.authenticate( user_id=self.user_sna['id'], - tenant_id=self.tenant_bar['id'], password=self.user_sna['password']) # NOTE(termie): the password field is left in user_foo to make # it easier to authenticate in tests, but should @@ -102,21 +80,8 @@ class IdentityTests(object): self.user_sna.pop('password') self.user_sna['enabled'] = True self.assertDictEqual(user_ref, self.user_sna) - self.assertDictEqual(tenant_ref, self.tenant_bar) - metadata_ref.pop('roles') - self.assertDictEqual(metadata_ref, self.metadata_snamtu) - def test_authenticate_role_return(self): - self.identity_api.add_role_to_user_and_project( - self.user_foo['id'], self.tenant_baz['id'], self.role_admin['id']) - user_ref, tenant_ref, metadata_ref = self.identity_api.authenticate( - user_id=self.user_foo['id'], - tenant_id=self.tenant_baz['id'], - password=self.user_foo['password']) - self.assertIn('roles', metadata_ref) - self.assertIn(self.role_admin['id'], metadata_ref['roles']) - - def test_authenticate_no_metadata(self): + def test_authenticate_and_get_roles_no_metadata(self): user = { 'id': 'no_meta', 'name': 'NO_META', @@ -126,18 +91,18 @@ class IdentityTests(object): self.identity_api.create_user(user['id'], user) self.identity_api.add_user_to_project(self.tenant_baz['id'], user['id']) - user_ref, tenant_ref, metadata_ref = self.identity_api.authenticate( + user_ref = self.identity_api.authenticate( user_id=user['id'], - tenant_id=self.tenant_baz['id'], password=user['password']) # NOTE(termie): the password field is left in user_foo to make # it easier to authenticate in tests, but should # not be returned by the api user.pop('password') - self.assertEquals(metadata_ref, {"roles": - [CONF.member_role_id]}) self.assertDictContainsSubset(user, user_ref) - self.assertDictEqual(tenant_ref, self.tenant_baz) + role_list = self.identity_api.get_roles_for_user_and_project( + user['id'], self.tenant_baz['id']) + self.assertEqual(len(role_list), 1) + self.assertIn(CONF.member_role_id, role_list) def test_password_hashed(self): user_ref = self.identity_api._get_user(self.user_foo['id']) @@ -218,25 +183,6 @@ class IdentityTests(object): user_name=uuid.uuid4().hex, domain_id=DEFAULT_DOMAIN_ID) - def test_get_metadata(self): - metadata_ref = self.identity_api.get_metadata( - user_id=self.user_sna['id'], - tenant_id=self.tenant_bar['id']) - metadata_ref.pop('roles') - self.assertDictEqual(metadata_ref, self.metadata_snamtu) - - 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_admin['id']) diff --git a/tests/test_backend_ldap.py b/tests/test_backend_ldap.py index f52e30cc..c9a8a4ed 100644 --- a/tests/test_backend_ldap.py +++ b/tests/test_backend_ldap.py @@ -656,7 +656,7 @@ class LDAPIdentity(test.TestCase, test_backend.IdentityTests): self.identity_api.driver.user.LDAP_PASSWORD = None self.assertRaises(AssertionError, - self.identity_api.authenticate_user, + self.identity_api.authenticate, user_id=user['id'], password=None) @@ -676,30 +676,6 @@ class LDAPIdentityEnabledEmulation(LDAPIdentity): self.user_two, self.user_badguy]: obj.setdefault('enabled', True) - def test_authenticate_no_metadata(self): - user = { - 'id': 'no_meta', - 'name': 'NO_META', - 'domain_id': test_backend.DEFAULT_DOMAIN_ID, - 'password': 'no_meta2', - 'enabled': True, - } - self.identity_api.create_user(user['id'], user) - self.identity_api.add_user_to_project(self.tenant_baz['id'], - user['id']) - user_ref, tenant_ref, metadata_ref = self.identity_api.authenticate( - user_id=user['id'], - tenant_id=self.tenant_baz['id'], - password=user['password']) - # NOTE(termie): the password field is left in user_foo to make - # it easier to authenticate in tests, but should - # not be returned by the api - user.pop('password') - self.assertEquals(metadata_ref, {"roles": - [CONF.member_role_id]}) - self.assertDictEqual(user_ref, user) - self.assertDictEqual(tenant_ref, self.tenant_baz) - def test_project_crud(self): # NOTE(topol): LDAPIdentityEnabledEmulation will create an # enabled key in the project dictionary so this diff --git a/tests/test_backend_pam.py b/tests/test_backend_pam.py index 3a66f014..b66faa9c 100644 --- a/tests/test_backend_pam.py +++ b/tests/test_backend_pam.py @@ -57,12 +57,12 @@ class PamIdentity(test.TestCase): self.assertDictEqual(self.user_in, user_out) def test_get_metadata_for_non_root(self): - metadata_out = self.identity_api.get_metadata(self.user_in['id'], - self.tenant_in['id']) + metadata_out = self.identity_api._get_metadata(self.user_in['id'], + self.tenant_in['id']) self.assertDictEqual({}, metadata_out) def test_get_metadata_for_root(self): metadata = {'is_admin': True} - metadata_out = self.identity_api.get_metadata('root', - self.tenant_in['id']) + metadata_out = self.identity_api._get_metadata('root', + self.tenant_in['id']) self.assertDictEqual(metadata, metadata_out) diff --git a/tests/test_backend_sql.py b/tests/test_backend_sql.py index 46d7c013..646707c5 100644 --- a/tests/test_backend_sql.py +++ b/tests/test_backend_sql.py @@ -132,33 +132,51 @@ class SqlIdentity(SqlTests, test_backend.IdentityTests): tenants = self.identity_api.get_projects_for_user(user['id']) self.assertEquals(tenants, []) - def test_delete_user_with_metadata(self): - user = {'id': 'fake', - 'name': 'fakeuser', + def test_metadata_removed_on_delete_user(self): + # A test to check that the internal representation + # or roles is correctly updated when a user is deleted + user = {'id': uuid.uuid4().hex, + 'name': uuid.uuid4().hex, 'domain_id': DEFAULT_DOMAIN_ID, 'password': 'passwd'} - self.identity_api.create_user('fake', user) - self.identity_api.create_metadata(user['id'], - self.tenant_bar['id'], - {'extra': 'extra'}) + self.identity_api.create_user(user['id'], user) + role = {'id': uuid.uuid4().hex, + 'name': uuid.uuid4().hex} + self.identity_api.create_role(role['id'], role) + self.identity_api.add_role_to_user_and_project( + user['id'], + self.tenant_bar['id'], + role['id']) self.identity_api.delete_user(user['id']) + + # Now check whether the internal representation of roles + # has been deleted self.assertRaises(exception.MetadataNotFound, - self.identity_api.get_metadata, + self.assignment_api._get_metadata, user['id'], self.tenant_bar['id']) - def test_delete_project_with_metadata(self): - user = {'id': 'fake', - 'name': 'fakeuser', + def test_metadata_removed_on_delete_project(self): + # A test to check that the internal representation + # or roles is correctly updated when a project is deleted + user = {'id': uuid.uuid4().hex, + 'name': uuid.uuid4().hex, 'domain_id': DEFAULT_DOMAIN_ID, 'password': 'passwd'} - self.identity_api.create_user('fake', user) - self.identity_api.create_metadata(user['id'], - self.tenant_bar['id'], - {'extra': 'extra'}) + self.identity_api.create_user(user['id'], user) + role = {'id': uuid.uuid4().hex, + 'name': uuid.uuid4().hex} + self.identity_api.create_role(role['id'], role) + self.identity_api.add_role_to_user_and_project( + user['id'], + self.tenant_bar['id'], + role['id']) self.identity_api.delete_project(self.tenant_bar['id']) + + # Now check whether the internal representation of roles + # has been deleted self.assertRaises(exception.MetadataNotFound, - self.identity_api.get_metadata, + self.assignment_api._get_metadata, user['id'], self.tenant_bar['id']) diff --git a/tests/test_content_types.py b/tests/test_content_types.py index 820dc0dd..278a1098 100644 --- a/tests/test_content_types.py +++ b/tests/test_content_types.py @@ -70,14 +70,12 @@ class RestfulTestCase(test.TestCase): self.admin_app = webtest.TestApp( self.loadapp('keystone', name='admin')) - # TODO(termie): is_admin is being deprecated once the policy stuff - # is all working # TODO(termie): add an admin user to the fixtures and use that user # override the fixtures, for now - self.metadata_foobar = self.identity_api.update_metadata( + self.metadata_foobar = self.identity_api.add_role_to_user_and_project( self.user_foo['id'], self.tenant_bar['id'], - dict(roles=[self.role_admin['id']], is_admin='1')) + self.role_admin['id']) def tearDown(self): """Kill running servers and release references to avoid leaks.""" @@ -403,10 +401,10 @@ class CoreApiTests(object): self.assertValidAuthenticationResponse(r) def test_validate_token_service_role(self): - self.metadata_foobar = self.identity_api.update_metadata( + self.metadata_foobar = self.identity_api.add_role_to_user_and_project( self.user_foo['id'], self.tenant_service['id'], - dict(roles=[self.role_service['id']])) + self.role_service['id']) token = self.get_scoped_token(tenant_id='service') r = self.admin_request( diff --git a/tests/test_import_legacy.py b/tests/test_import_legacy.py index bafc076a..2642a2cf 100644 --- a/tests/test_import_legacy.py +++ b/tests/test_import_legacy.py @@ -73,7 +73,7 @@ class ImportLegacy(test.TestCase): self.assertEquals(user_ref['enabled'], True) # check password hashing - user_ref, tenant_ref, metadata_ref = self.identity_man.authenticate( + user_ref = self.identity_man.authenticate( user_id=admin_id, password='secrete') # check catalog @@ -90,7 +90,7 @@ class ImportLegacy(test.TestCase): self.assertEquals(user_ref['enabled'], True) # check password hashing - user_ref, tenant_ref, metadata_ref = self.identity_man.authenticate( + user_ref = self.identity_man.authenticate( user_id=admin_id, password='secrete') # check catalog @@ -107,7 +107,7 @@ class ImportLegacy(test.TestCase): self.assertEquals(user_ref['enabled'], True) # check password hashing - user_ref, tenant_ref, metadata_ref = self.identity_man.authenticate( + user_ref = self.identity_man.authenticate( user_id=admin_id, password='secrete') # check catalog diff --git a/tests/test_keystoneclient.py b/tests/test_keystoneclient.py index b9828559..d78e885a 100644 --- a/tests/test_keystoneclient.py +++ b/tests/test_keystoneclient.py @@ -47,13 +47,12 @@ class CompatTestCase(test.TestCase): self.public_server = self.serveapp('keystone', name='main') self.admin_server = self.serveapp('keystone', name='admin') - # TODO(termie): is_admin is being deprecated once the policy stuff - # is all working # TODO(termie): add an admin user to the fixtures and use that user # override the fixtures, for now - self.metadata_foobar = self.identity_api.update_metadata( - self.user_foo['id'], self.tenant_bar['id'], - dict(roles=[self.role_admin['id']], is_admin='1')) + self.metadata_foobar = self.identity_api.add_role_to_user_and_project( + self.user_foo['id'], + self.tenant_bar['id'], + self.role_admin['id']) def tearDown(self): self.public_server.kill() diff --git a/tests/test_migrate_nova_auth.py b/tests/test_migrate_nova_auth.py deleted file mode 100644 index bd25b18e..00000000 --- a/tests/test_migrate_nova_auth.py +++ /dev/null @@ -1,157 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2012 OpenStack LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import uuid - -from keystone import test - -from keystone.common.sql import nova -from keystone.common.sql import util as sql_util -from keystone import config -from keystone.contrib.ec2.backends import sql as ec2_sql -from keystone import identity - - -CONF = config.CONF -DEFAULT_DOMAIN_ID = CONF.identity.default_domain_id - - -FIXTURE = { - 'users': [ - {'id': 'user1', 'name': 'uname1', 'password': 'acc1'}, - {'id': 'user4', 'name': 'uname4', 'password': 'acc1'}, - {'id': 'user2', 'name': 'uname2', 'password': 'acc2'}, - {'id': 'user3', 'name': 'uname3', 'password': 'acc3'}, - ], - 'roles': ['role1', 'role2', 'role3'], - 'role_user_tenant_list': [ - {'user_id': 'user1', 'role': 'role1', 'tenant_id': 'proj1'}, - {'user_id': 'user1', 'role': 'role2', 'tenant_id': 'proj1'}, - {'user_id': 'user4', 'role': 'role1', 'tenant_id': 'proj4'}, - {'user_id': 'user2', 'role': 'role1', 'tenant_id': 'proj1'}, - {'user_id': 'user2', 'role': 'role1', 'tenant_id': 'proj2'}, - {'user_id': 'user2', 'role': 'role2', 'tenant_id': 'proj2'}, - {'user_id': 'user3', 'role': 'role3', 'tenant_id': 'proj1'}, - ], - 'user_tenant_list': [ - {'tenant_id': 'proj1', 'user_id': 'user1'}, - {'tenant_id': 'proj4', 'user_id': 'user4'}, - {'tenant_id': 'proj1', 'user_id': 'user2'}, - {'tenant_id': 'proj2', 'user_id': 'user2'}, - {'tenant_id': 'proj1', 'user_id': 'user3'}, - ], - 'ec2_credentials': [ - {'access_key': 'acc1', 'secret_key': 'sec1', 'user_id': 'user1'}, - {'access_key': 'acc4', 'secret_key': 'sec4', 'user_id': 'user4'}, - {'access_key': 'acc2', 'secret_key': 'sec2', 'user_id': 'user2'}, - {'access_key': 'acc3', 'secret_key': 'sec3', 'user_id': 'user3'}, - ], - 'tenants': [ - {'description': 'desc1', 'id': 'proj1', 'name': 'pname1'}, - {'description': 'desc4', 'id': 'proj4', 'name': 'pname4'}, - {'description': 'desc2', 'id': 'proj2', 'name': 'pname2'}, - ], -} - - -class MigrateNovaAuth(test.TestCase): - def setUp(self): - super(MigrateNovaAuth, self).setUp() - self.config([test.etcdir('keystone.conf.sample'), - test.testsdir('test_overrides.conf'), - test.testsdir('backend_sql.conf'), - test.testsdir('backend_sql_disk.conf')]) - sql_util.setup_test_database() - self.identity_api = identity.Manager() - self.ec2_api = ec2_sql.Ec2() - - def tearDown(self): - sql_util.teardown_test_database() - super(MigrateNovaAuth, self).tearDown() - - def _create_role(self, role_name): - role_id = uuid.uuid4().hex - role_dict = {'id': role_id, 'name': role_name} - self.identity_api.create_role(role_id, role_dict) - - def test_import(self): - self._create_role('role1') - - nova.import_auth(FIXTURE) - - users = {} - for user in ['user1', 'user2', 'user3', 'user4']: - users[user] = self.identity_api.get_user_by_name( - user, DEFAULT_DOMAIN_ID) - - tenants = {} - for tenant in ['proj1', 'proj2', 'proj4']: - tenants[tenant] = self.identity_api.get_project_by_name( - tenant, DEFAULT_DOMAIN_ID) - - membership_map = { - 'user1': ['proj1'], - 'user2': ['proj1', 'proj2'], - 'user3': ['proj1'], - 'user4': ['proj4'], - } - - for (old_user, old_projects) in membership_map.iteritems(): - user = users[old_user] - membership = self.identity_api.get_projects_for_user(user['id']) - expected = [tenants[t]['id'] for t in old_projects] - self.assertEqual(set(expected), set(membership)) - for tenant_id in membership: - password = None - for _user in FIXTURE['users']: - if _user['id'] == old_user: - password = _user['password'] - self.identity_api.authenticate(user['id'], tenant_id, password) - - for ec2_cred in FIXTURE['ec2_credentials']: - user_id = users[ec2_cred['user_id']]['id'] - for tenant_id in self.identity_api.get_projects_for_user(user_id): - access = '%s:%s' % (tenant_id, ec2_cred['access_key']) - cred = self.ec2_api.get_credential(access) - actual = cred['secret'] - expected = ec2_cred['secret_key'] - self.assertEqual(expected, actual) - - roles = self.identity_api.list_roles() - role_names = set([role['name'] for role in roles]) - self.assertEqual(role_names, set(['role2', 'role1', 'role3', - CONF.member_role_name])) - - assignment_map = { - 'user1': {'proj1': ['role1', 'role2']}, - 'user2': {'proj1': ['role1'], 'proj2': ['role1', 'role2']}, - 'user3': {'proj1': ['role3']}, - 'user4': {'proj4': ['role1']}, - } - - for (old_user, old_project_map) in assignment_map.iteritems(): - tenant_names = ['proj1', 'proj2', 'proj4'] - for tenant_name in tenant_names: - user = users[old_user] - tenant = tenants[tenant_name] - roles = self.identity_api.get_roles_for_user_and_project( - user['id'], tenant['id']) - actual = [self.identity_api.get_role(role_id)['name'] - for role_id in roles] - if CONF.member_role_name in actual: - actual.remove(CONF.member_role_name) - expected = old_project_map.get(tenant_name, []) - self.assertEqual(set(actual), set(expected)) -- cgit