def test_user_management_normalized_keys(self): """Illustrate the inconsistent handling of hyphens in keys. To quote Morgan in bug 1526244: the reason this is converted from "domain-id" to "domain_id" is because of how we process/normalize data. The way we have to handle specific data types for known columns requires avoiding "-" in the actual python code since "-" is not valid for attributes in python w/o significant use of "getattr" etc. In short, historically we handle some things in conversions. The use of "extras" has long been a poor design choice that leads to odd/strange inconsistent behaviors because of other choices made in handling data from within the body. (In many cases we convert from "-" to "_" throughout openstack) Source: https://bugs.launchpad.net/keystone/+bug/1526244/comments/9 """ # Create two domains to work with. domain1 = unit.new_domain_ref() self.resource_api.create_domain(domain1["id"], domain1) domain2 = unit.new_domain_ref() self.resource_api.create_domain(domain2["id"], domain2) # We can successfully create a normal user without any surprises. user = unit.new_user_ref(domain_id=domain1["id"]) r = self.post("/users", body={"user": user}) self.assertValidUserResponse(r, user) user["id"] = r.json["user"]["id"] # Query strings are not normalized: so we get all users back (like # self.user), not just the ones in the specified domain. r = self.get("/users?domain-id=%s" % domain1["id"]) self.assertValidUserListResponse(r, ref=self.user) self.assertNotEqual(domain1["id"], self.user["domain_id"]) # When creating a new user, if we move the 'domain_id' into the # 'domain-id' attribute, the server will normalize the request # attribute, and effectively "move it back" for us. user = unit.new_user_ref(domain_id=domain1["id"]) user["domain-id"] = user.pop("domain_id") r = self.post("/users", body={"user": user}) self.assertNotIn("domain-id", r.json["user"]) self.assertEqual(domain1["id"], r.json["user"]["domain_id"]) # (move this attribute back so we can use assertValidUserResponse) user["domain_id"] = user.pop("domain-id") self.assertValidUserResponse(r, user) user["id"] = r.json["user"]["id"] # If we try updating the user's 'domain_id' by specifying a # 'domain-id', then it'll be stored into extras rather than normalized, # and the user's actual 'domain_id' is not affected. r = self.patch("/users/%s" % user["id"], body={"user": {"domain-id": domain2["id"]}}) self.assertEqual(domain2["id"], r.json["user"]["domain-id"]) self.assertEqual(user["domain_id"], r.json["user"]["domain_id"]) self.assertNotEqual(domain2["id"], user["domain_id"]) self.assertValidUserResponse(r, user)
def test_validate_v3_token_trust(self): # Check the trust fields in the token result when use validate_v3_token # when the token has trust info. domain_ref = unit.new_domain_ref() domain_ref = PROVIDERS.resource_api.create_domain( domain_ref['id'], domain_ref ) user_ref = unit.new_user_ref(domain_ref['id']) user_ref = PROVIDERS.identity_api.create_user(user_ref) trustor_user_ref = unit.new_user_ref(domain_ref['id']) trustor_user_ref = PROVIDERS.identity_api.create_user(trustor_user_ref) project_ref = unit.new_project_ref(domain_id=domain_ref['id']) project_ref = PROVIDERS.resource_api.create_project( project_ref['id'], project_ref ) role_ref = unit.new_role_ref() role_ref = PROVIDERS.role_api.create_role(role_ref['id'], role_ref) PROVIDERS.assignment_api.create_grant( role_ref['id'], user_id=user_ref['id'], project_id=project_ref['id']) PROVIDERS.assignment_api.create_grant( role_ref['id'], user_id=trustor_user_ref['id'], project_id=project_ref['id']) trustor_user_id = trustor_user_ref['id'] trustee_user_id = user_ref['id'] trust_ref = unit.new_trust_ref( trustor_user_id, trustee_user_id, project_id=project_ref['id'], role_ids=[role_ref['id'], ]) trust_ref = PROVIDERS.trust_api.create_trust( trust_ref['id'], trust_ref, trust_ref['roles'] ) method_names = ['password'] token_id, token_data_ = PROVIDERS.token_provider_api.issue_token( user_ref['id'], method_names, project_id=project_ref['id'], trust=trust_ref) token_data = PROVIDERS.token_provider_api.validate_token(token_id) token = token_data['token'] exp_trust_info = { 'id': trust_ref['id'], 'impersonation': False, 'trustee_user': {'id': user_ref['id'], }, 'trustor_user': {'id': trustor_user_ref['id'], }, } self.assertEqual(exp_trust_info, token['OS-TRUST:trust'])
def test_delete_trust(self): trustor = unit.new_user_ref(domain_id=self.domain_id) trustor = self.identity_api.create_user(trustor) trustee = unit.new_user_ref(domain_id=self.domain_id) trustee = self.identity_api.create_user(trustee) role_ref = unit.new_role_ref() trust_ref = unit.new_trust_ref(trustor["id"], trustee["id"]) self.trust_api.create_trust(trust_ref["id"], trust_ref, [role_ref]) self.trust_api.delete_trust(trust_ref["id"]) self._assert_last_note(trust_ref["id"], DELETED_OPERATION, "OS-TRUST:trust") self._assert_last_audit(trust_ref["id"], DELETED_OPERATION, "OS-TRUST:trust", cadftaxonomy.SECURITY_TRUST)
def test_create_nonlocal_user_unique_constraint(self): user = unit.new_user_ref(domain_id=CONF.identity.default_domain_id) user_created = PROVIDERS.shadow_users_api.create_nonlocal_user(user) self.assertNotIn('password', user_created) self.assertEqual(user_created['id'], user['id']) self.assertEqual(user_created['domain_id'], user['domain_id']) self.assertEqual(user_created['name'], user['name']) new_user = unit.new_user_ref(domain_id=CONF.identity.default_domain_id) new_user['name'] = user['name'] self.assertRaises(exception.Conflict, PROVIDERS.shadow_users_api.create_nonlocal_user, new_user)
def test_delete_group_without_role_does_not_revoke_users(self): revocation_backend = sql.Revoke() domain = unit.new_domain_ref() PROVIDERS.resource_api.create_domain(domain['id'], domain) # Create two groups. Group1 will be used to test deleting a group, # without role assignments and users in the group, doesn't create # revoked events. Group2 will show that deleting a group with role # assignment and users in the group does create revoked events group1 = unit.new_group_ref(domain_id=domain['id']) group1 = PROVIDERS.identity_api.create_group(group1) group2 = unit.new_group_ref(domain_id=domain['id']) group2 = PROVIDERS.identity_api.create_group(group2) role = unit.new_role_ref() PROVIDERS.role_api.create_role(role['id'], role) user1 = unit.new_user_ref(domain_id=domain['id']) user1 = PROVIDERS.identity_api.create_user(user1) user2 = unit.new_user_ref(domain_id=domain['id']) user2 = PROVIDERS.identity_api.create_user(user2) # Add two users to the group, verify they are added, delete group, and # check that the revocaiton events have not been created PROVIDERS.identity_api.add_user_to_group( user_id=user1['id'], group_id=group1['id'] ) PROVIDERS.identity_api.add_user_to_group( user_id=user2['id'], group_id=group1['id'] ) self.assertEqual( 2, len(PROVIDERS.identity_api.list_users_in_group(group1['id']))) PROVIDERS.identity_api.delete_group(group1['id']) self.assertEqual(0, len(revocation_backend.list_events())) # Assign a role to the group, add two users to the group, verify that # the role has been assigned to the group, verify the users have been # added to the group, delete the group, check that the revocation # events have been created PROVIDERS.assignment_api.create_grant( group_id=group2['id'], domain_id=domain['id'], role_id=role['id'] ) grants = PROVIDERS.assignment_api.list_role_assignments( role_id=role['id'] ) self.assertThat(grants, matchers.HasLength(1)) PROVIDERS.identity_api.add_user_to_group( user_id=user1['id'], group_id=group2['id'] ) PROVIDERS.identity_api.add_user_to_group( user_id=user2['id'], group_id=group2['id'] ) self.assertEqual( 2, len(PROVIDERS.identity_api.list_users_in_group(group2['id']))) PROVIDERS.identity_api.delete_group(group2['id']) self.assertEqual(2, len(revocation_backend.list_events()))
def test_create_user_without_domain(self): """Call ``POST /users`` without specifying domain. According to the identity-api specification, if you do not explicitly specific the domain_id in the entity, it should take the domain scope of the token as the domain_id. """ # Create a user with a role on the domain so we can get a # domain scoped token domain = unit.new_domain_ref() self.resource_api.create_domain(domain['id'], domain) user = unit.create_user(self.identity_api, domain_id=domain['id']) self.assignment_api.create_grant( role_id=self.role_id, user_id=user['id'], domain_id=domain['id']) ref = unit.new_user_ref(domain_id=domain['id']) ref_nd = ref.copy() ref_nd.pop('domain_id') auth = self.build_authentication_request( user_id=user['id'], password=user['password'], domain_id=domain['id']) r = self.post('/users', body={'user': ref_nd}, auth=auth) self.assertValidUserResponse(r, ref) # Now try the same thing without a domain token - which should fail ref = unit.new_user_ref(domain_id=domain['id']) ref_nd = ref.copy() ref_nd.pop('domain_id') auth = self.build_authentication_request( user_id=self.user['id'], password=self.user['password'], project_id=self.project['id']) # TODO(henry-nash): Due to bug #1283539 we currently automatically # use the default domain_id if a domain scoped token is not being # used. For now we just check that a deprecation warning has been # issued. Change the code below to expect a failure once this bug is # fixed. with mock.patch( 'oslo_log.versionutils.report_deprecated_feature') as mock_dep: r = self.post('/users', body={'user': ref_nd}, auth=auth) self.assertTrue(mock_dep.called) ref['domain_id'] = CONF.identity.default_domain_id return self.assertValidUserResponse(r, ref)
def test_user_can_delete_users(self): user = PROVIDERS.identity_api.create_user( unit.new_user_ref(domain_id=CONF.identity.default_domain_id) ) with self.test_client() as c: c.delete('/v3/users/%s' % user['id'], headers=self.headers)
def test_setting_default_project_id_to_domain_failed(self): """Call ``POST and PATCH /users`` default_project_id=domain_id. Make sure we validate the default_project_id if it is specified. It cannot be set to a domain_id, even for a project acting as domain right now. That's because we haven't sort out the issuing project-scoped token for project acting as domain bit yet. Once we got that sorted out, we can relax this constraint. """ # creating a new user with default_project_id set to a # domain_id should result in HTTP 400 ref = unit.new_user_ref(domain_id=self.domain_id, project_id=self.domain_id) self.post('/users', body={'user': ref}, token=CONF.admin_token, expected_status=http_client.BAD_REQUEST) # updating user's default_project_id to a domain_id should result # in HTTP 400 user = {'default_project_id': self.domain_id} self.patch('/users/%(user_id)s' % { 'user_id': self.user['id']}, body={'user': user}, token=CONF.admin_token, expected_status=http_client.BAD_REQUEST)
def test_list_domains_for_user(self): domain = unit.new_domain_ref() PROVIDERS.resource_api.create_domain(domain['id'], domain) user = unit.new_user_ref(domain_id=domain['id']) test_domain1 = unit.new_domain_ref() PROVIDERS.resource_api.create_domain(test_domain1['id'], test_domain1) test_domain2 = unit.new_domain_ref() PROVIDERS.resource_api.create_domain(test_domain2['id'], test_domain2) user = PROVIDERS.identity_api.create_user(user) user_domains = PROVIDERS.assignment_api.list_domains_for_user( user['id'] ) self.assertEqual(0, len(user_domains)) PROVIDERS.assignment_api.create_grant( user_id=user['id'], domain_id=test_domain1['id'], role_id=self.role_member['id'] ) PROVIDERS.assignment_api.create_grant( user_id=user['id'], domain_id=test_domain2['id'], role_id=self.role_member['id'] ) user_domains = PROVIDERS.assignment_api.list_domains_for_user( user['id'] ) self.assertThat(user_domains, matchers.HasLength(2))
def setUp(self): super(SystemMemberTests, self).setUp() self.loadapp() self.useFixture(ksfixtures.Policy(self.config_fixture)) self.config_fixture.config(group='oslo_policy', enforce_scope=True) system_member = unit.new_user_ref( domain_id=CONF.identity.default_domain_id ) self.user_id = PROVIDERS.identity_api.create_user( system_member )['id'] PROVIDERS.assignment_api.create_system_grant_for_user( self.user_id, self.bootstrapper.member_role_id ) auth = self.build_authentication_request( user_id=self.user_id, password=system_member['password'], system=True ) # Grab a token using the persona we're testing and prepare headers # for requests we'll be making in the tests. with self.test_client() as c: r = c.post('/v3/auth/tokens', json=auth) self.token_id = r.headers['X-Subject-Token'] self.headers = {'X-Auth-Token': self.token_id}
def test_validate_v3_token_simple(self): # Check the fields in the token result when use validate_v3_token # with a simple token. domain_ref = unit.new_domain_ref() domain_ref = PROVIDERS.resource_api.create_domain( domain_ref['id'], domain_ref ) user_ref = unit.new_user_ref(domain_ref['id']) user_ref = PROVIDERS.identity_api.create_user(user_ref) method_names = ['password'] token = PROVIDERS.token_provider_api.issue_token( user_ref['id'], method_names) token = PROVIDERS.token_provider_api.validate_token(token.id) self.assertIsInstance(token.audit_ids, list) self.assertIsInstance(token.expires_at, str) self.assertIsInstance(token.issued_at, str) self.assertEqual(method_names, token.methods) self.assertEqual(user_ref['id'], token.user_id) self.assertEqual(user_ref['name'], token.user['name']) self.assertDictEqual(domain_ref, token.user_domain) self.assertEqual( user_ref['password_expires_at'], token.user['password_expires_at'] )
def test_validate_v3_token_simple(self): # Check the fields in the token result when use validate_v3_token # with a simple token. domain_ref = unit.new_domain_ref() domain_ref = self.resource_api.create_domain(domain_ref["id"], domain_ref) user_ref = unit.new_user_ref(domain_ref["id"]) user_ref = self.identity_api.create_user(user_ref) method_names = ["password"] token_id, token_data_ = self.token_provider_api.issue_v3_token(user_ref["id"], method_names) token_data = self.token_provider_api.validate_v3_token(token_id) token = token_data["token"] self.assertIsInstance(token["audit_ids"], list) self.assertIsInstance(token["expires_at"], str) self.assertIsInstance(token["issued_at"], str) self.assertEqual(method_names, token["methods"]) exp_user_info = { "id": user_ref["id"], "name": user_ref["name"], "domain": {"id": domain_ref["id"], "name": domain_ref["name"]}, } self.assertEqual(exp_user_info, token["user"])
def setUp(self): super(DomainUserTests, self).setUp() self.loadapp() self.useFixture(ksfixtures.Policy(self.config_fixture)) self.config_fixture.config(group='oslo_policy', enforce_scope=True) domain = PROVIDERS.resource_api.create_domain( uuid.uuid4().hex, unit.new_domain_ref() ) self.domain_id = domain['id'] domain_admin = unit.new_user_ref(domain_id=self.domain_id) self.user_id = PROVIDERS.identity_api.create_user(domain_admin)['id'] PROVIDERS.assignment_api.create_grant( self.bootstrapper.admin_role_id, user_id=self.user_id, domain_id=self.domain_id ) auth = self.build_authentication_request( user_id=self.user_id, password=domain_admin['password'], domain_id=self.domain_id ) # Grab a token using the persona we're testing and prepare headers # for requests we'll be making in the tests. with self.test_client() as c: r = c.post('/v3/auth/tokens', json=auth) self.token_id = r.headers['X-Subject-Token'] self.headers = {'X-Auth-Token': self.token_id}
def test_get_user_does_not_include_extra_attributes(self): """Call ``GET /users/{user_id}`` extra attributes are not included.""" user = unit.new_user_ref(domain_id=self.domain_id, project_id=self.project_id) user = self.identity_api.create_user(user) self.assertNotIn('created_at', user) self.assertNotIn('last_active_at', user)
def test_create_user(self): """Call ``POST /users``.""" ref = unit.new_user_ref(domain_id=self.domain_id) r = self.post( '/users', body={'user': ref}) return self.assertValidUserResponse(r, ref)
def test_get_user_with_default_project(self): """Call ``GET /users/{user_id}`` making sure of default_project_id.""" user = unit.new_user_ref(domain_id=self.domain_id, project_id=self.project_id) user = self.identity_api.create_user(user) r = self.get('/users/%(user_id)s' % {'user_id': user['id']}) self.assertValidUserResponse(r, user)
def test_list_users_no_default_project(self): """Call ``GET /users`` making sure no default_project_id.""" user = unit.new_user_ref(self.domain_id) user = self.identity_api.create_user(user) resource_url = "/users" r = self.get(resource_url) self.assertValidUserListResponse(r, ref=user, resource_url=resource_url)
def test_assignment_created_with_user_exists(self): # test assignment can be created if user already exists. bootstrap = cli.BootStrap() bootstrap.resource_manager.create_domain(self.default_domain["id"], self.default_domain) user_ref = unit.new_user_ref(self.default_domain["id"], name=self.username, password=self.password) bootstrap.identity_manager.create_user(user_ref) self._do_test_bootstrap(bootstrap)
def test_validate_v3_receipt_simple(self): # Check the fields in the receipt result when use validate_v3_receipt # with a simple receipt. domain_ref = unit.new_domain_ref() domain_ref = PROVIDERS.resource_api.create_domain( domain_ref['id'], domain_ref ) rule_list = [ ['password', 'totp'], ['password', 'totp', 'token'], ] user_ref = unit.new_user_ref(domain_ref['id']) user_ref = PROVIDERS.identity_api.create_user(user_ref) user_ref['options'][ro.MFA_RULES_OPT.option_name] = rule_list user_ref['options'][ro.MFA_ENABLED_OPT.option_name] = True PROVIDERS.identity_api.update_user(user_ref['id'], user_ref) method_names = ['password'] receipt = PROVIDERS.receipt_provider_api.\ issue_receipt(user_ref['id'], method_names) receipt = PROVIDERS.receipt_provider_api.validate_receipt( receipt.id) self.assertIsInstance(receipt.expires_at, str) self.assertIsInstance(receipt.issued_at, str) self.assertEqual(set(method_names), set(receipt.methods)) self.assertEqual( set(frozenset(r) for r in rule_list), set(frozenset(r) for r in receipt.required_methods)) self.assertEqual(user_ref['id'], receipt.user_id)
def test_update_user_returns_extra(self): """Test for backwards-compatibility with an essex/folsom bug. Non-indexed attributes were returned in an 'extra' attribute, instead of on the entity itself; for consistency and backwards compatibility, those attributes should be included twice. This behavior is specific to the SQL driver. """ arbitrary_key = uuid.uuid4().hex arbitrary_value = uuid.uuid4().hex user = unit.new_user_ref(domain_id=CONF.identity.default_domain_id) user[arbitrary_key] = arbitrary_value del user["id"] ref = self.identity_api.create_user(user) self.assertEqual(arbitrary_value, ref[arbitrary_key]) self.assertIsNone(ref.get('password')) self.assertIsNone(ref.get('extra')) user['name'] = uuid.uuid4().hex user['password'] = uuid.uuid4().hex ref = self.identity_api.update_user(ref['id'], user) self.assertIsNone(ref.get('password')) self.assertIsNone(ref['extra'].get('password')) self.assertEqual(arbitrary_value, ref[arbitrary_key]) self.assertEqual(arbitrary_value, ref['extra'][arbitrary_key])
def test_list_domains_for_user_with_grants(self): # Create two groups each with a role on a different domain, and # make user1 a member of both groups. Both these new domains # should now be included, along with any direct user grants. domain = unit.new_domain_ref() self.resource_api.create_domain(domain['id'], domain) user = unit.new_user_ref(domain_id=domain['id']) user = self.identity_api.create_user(user) group1 = unit.new_group_ref(domain_id=domain['id']) group1 = self.identity_api.create_group(group1) group2 = unit.new_group_ref(domain_id=domain['id']) group2 = self.identity_api.create_group(group2) test_domain1 = unit.new_domain_ref() self.resource_api.create_domain(test_domain1['id'], test_domain1) test_domain2 = unit.new_domain_ref() self.resource_api.create_domain(test_domain2['id'], test_domain2) test_domain3 = unit.new_domain_ref() self.resource_api.create_domain(test_domain3['id'], test_domain3) self.identity_api.add_user_to_group(user['id'], group1['id']) self.identity_api.add_user_to_group(user['id'], group2['id']) # Create 3 grants, one user grant, the other two as group grants self.assignment_api.create_grant(user_id=user['id'], domain_id=test_domain1['id'], role_id=self.role_member['id']) self.assignment_api.create_grant(group_id=group1['id'], domain_id=test_domain2['id'], role_id=self.role_admin['id']) self.assignment_api.create_grant(group_id=group2['id'], domain_id=test_domain3['id'], role_id=self.role_admin['id']) user_domains = self.assignment_api.list_domains_for_user(user['id']) self.assertThat(user_domains, matchers.HasLength(3))
def test_create_nonlocal_user_does_not_create_local_user(self): user = unit.new_user_ref(domain_id=CONF.identity.default_domain_id) new_nonlocal_user = PROVIDERS.shadow_users_api.create_nonlocal_user( user ) user_ref = self._get_user_ref(new_nonlocal_user['id']) self.assertIsNone(user_ref.local_user)
def test_validate_v3_token_simple(self): # Check the fields in the token result when use validate_v3_token # with a simple token. domain_ref = unit.new_domain_ref() domain_ref = self.resource_api.create_domain(domain_ref['id'], domain_ref) user_ref = unit.new_user_ref(domain_ref['id']) user_ref = self.identity_api.create_user(user_ref) method_names = ['password'] token_id, token_data_ = self.token_provider_api.issue_v3_token( user_ref['id'], method_names) token_data = self.token_provider_api.validate_v3_token(token_id) token = token_data['token'] self.assertIsInstance(token['audit_ids'], list) self.assertIsInstance(token['expires_at'], str) self.assertEqual({}, token['extras']) self.assertIsInstance(token['issued_at'], str) self.assertEqual(method_names, token['methods']) exp_user_info = { 'id': user_ref['id'], 'name': user_ref['name'], 'domain': { 'id': domain_ref['id'], 'name': domain_ref['name'], }, } self.assertEqual(exp_user_info, token['user'])
def test_trust_duplicate_conflict_gives_name(self): trustor = unit.new_user_ref(domain_id=self.domain_id) trustor = self.identity_api.create_user(trustor) trustee = unit.new_user_ref(domain_id=self.domain_id) trustee = self.identity_api.create_user(trustee) role_ref = unit.new_role_ref() self.role_api.create_role(role_ref['id'], role_ref) trust_ref = unit.new_trust_ref(trustor['id'], trustee['id']) self.trust_api.create_trust(trust_ref['id'], trust_ref, [role_ref]) try: self.trust_api.create_trust(trust_ref['id'], trust_ref, [role_ref]) except exception.Conflict as e: self.assertIn("Duplicate entry found with ID %s" % trust_ref['id'], repr(e)) else: self.fail("Create duplicate trust did not raise a conflict")
def test_get_user(self): user = unit.new_user_ref(domain_id=CONF.identity.default_domain_id) user.pop('email') user.pop('password') user_created = PROVIDERS.shadow_users_api.create_nonlocal_user(user) self.assertEqual(user_created['id'], user['id']) user_found = PROVIDERS.shadow_users_api.get_user(user_created['id']) self.assertItemsEqual(user_created, user_found)
def test_get_user_does_not_include_extra_attributes(self): """Call ``GET /users/{user_id}`` extra attributes are not included.""" user = unit.new_user_ref(domain_id=self.domain_id, project_id=self.project_id) user = self.identity_api.create_user(user) self.assertNotIn("created_at", user) self.assertNotIn("last_active_at", user) r = self.get("/users/%(user_id)s" % {"user_id": user["id"]}) self.assertValidUserResponse(r, user)
def test_user_can_get_other_users(self): user = PROVIDERS.identity_api.create_user( unit.new_user_ref(domain_id=CONF.identity.default_domain_id) ) with self.test_client() as c: r = c.get('/v3/users/%s' % user['id'], headers=self.headers) self.assertEqual(user['id'], r.json['user']['id'])
def setUp(self): super(TestCredentialTrustScoped, self).setUp() self.trustee_user = unit.new_user_ref(domain_id=self.domain_id) password = self.trustee_user['password'] self.trustee_user = self.identity_api.create_user(self.trustee_user) self.trustee_user['password'] = password self.trustee_user_id = self.trustee_user['id']
def test_delete_project_with_user_association(self): user = unit.new_user_ref(domain_id=CONF.identity.default_domain_id) user = self.identity_api.create_user(user) self.assignment_api.add_user_to_project(self.tenant_bar['id'], user['id']) self.resource_api.delete_project(self.tenant_bar['id']) tenants = self.assignment_api.list_projects_for_user(user['id']) self.assertEqual([], tenants)
def test_update_user(self): """Call ``PATCH /users/{user_id}``.""" user = unit.new_user_ref(domain_id=self.domain_id) del user['id'] r = self.patch('/users/%(user_id)s' % { 'user_id': self.user['id']}, body={'user': user}) self.assertValidUserResponse(r, user)
def test_user_can_add_users_to_group(self): domain = PROVIDERS.resource_api.create_domain(uuid.uuid4().hex, unit.new_domain_ref()) group = PROVIDERS.identity_api.create_group( unit.new_group_ref(domain_id=domain['id'])) user = PROVIDERS.identity_api.create_user( unit.new_user_ref(domain_id=domain['id'])) with self.test_client() as c: c.put('/v3/groups/%s/users/%s' % (group['id'], user['id']), headers=self.headers)
def test_sql_user_to_dict_null_default_project_id(self): user = unit.new_user_ref(domain_id=CONF.identity.default_domain_id) user = self.identity_api.create_user(user) with sql.session_for_read() as session: query = session.query(identity_sql.User) query = query.filter_by(id=user['id']) raw_user_ref = query.one() self.assertIsNone(raw_user_ref.default_project_id) user_ref = raw_user_ref.to_dict() self.assertNotIn('default_project_id', user_ref) session.close()
def test_nonlocal_user_unique_user_id_constraint(self): user_ref = unit.new_user_ref(domain_id=CONF.identity.default_domain_id) user = PROVIDERS.shadow_users_api.create_nonlocal_user(user_ref) # attempt to create a nonlocal_user with the same user_id nonlocal_user = { 'domain_id': CONF.identity.default_domain_id, 'name': uuid.uuid4().hex, 'user_id': user['id'] } self.assertRaises(sql.DBDuplicateEntry, self._add_nonlocal_user, nonlocal_user)
def test_delete_project_with_user_association(self): user = unit.new_user_ref(domain_id=CONF.identity.default_domain_id) user = PROVIDERS.identity_api.create_user(user) role_member = unit.new_role_ref() PROVIDERS.role_api.create_role(role_member['id'], role_member) PROVIDERS.assignment_api.add_role_to_user_and_project( user['id'], self.tenant_bar['id'], role_member['id'] ) PROVIDERS.resource_api.delete_project(self.tenant_bar['id']) tenants = PROVIDERS.assignment_api.list_projects_for_user(user['id']) self.assertEqual([], tenants)
def test_user_can_create_grant_for_user_on_domain(self): user = PROVIDERS.identity_api.create_user( unit.new_user_ref(domain_id=CONF.identity.default_domain_id)) domain = PROVIDERS.resource_api.create_domain(uuid.uuid4().hex, unit.new_domain_ref()) with self.test_client() as c: c.put('/v3/domains/%s/users/%s/roles/%s' % (domain['id'], user['id'], self.bootstrapper.reader_role_id), headers=self.headers)
def new_user_ref(self, **kwargs): """Construct a bare bones user ref. Omits all optional components. """ ref = unit.new_user_ref(**kwargs) # description is already omitted del ref['email'] del ref['enabled'] del ref['password'] return ref
def test_create_user_password_not_logged(self): # When a user is created, the password isn't logged at any level. log_fix = self.useFixture(fixtures.FakeLogger(level=logging.DEBUG)) ref = unit.new_user_ref(domain_id=self.domain_id) self.post( '/users', body={'user': ref}) self.assertNotIn(ref['password'], log_fix.output)
def setUp(self): super(TestCredentialTrustScoped, self).setUp() self.trustee_user = unit.new_user_ref(domain_id=self.domain_id) password = self.trustee_user['password'] self.trustee_user = self.identity_api.create_user(self.trustee_user) self.trustee_user['password'] = password self.trustee_user_id = self.trustee_user['id'] self.useFixture( ksfixtures.KeyRepository(self.config_fixture, 'credential', credential_fernet.MAX_ACTIVE_KEYS))
def test_user_can_add_user_in_own_domain_to_group_in_own_domain(self): group = PROVIDERS.identity_api.create_group( unit.new_group_ref(domain_id=self.domain_id)) user = PROVIDERS.identity_api.create_user( unit.new_user_ref(domain_id=self.domain_id)) with self.test_client() as c: c.put('/v3/groups/%(group)s/users/%(user)s' % { 'group': group['id'], 'user': user['id'] }, headers=self.headers)
def test_user_cannot_update_users_within_domain(self): user = PROVIDERS.identity_api.create_user( unit.new_user_ref(domain_id=self.domain_id) ) update = {'user': {'email': uuid.uuid4().hex}} with self.test_client() as c: c.patch( '/v3/users/%s' % user['id'], json=update, headers=self.headers, expected_status_code=http_client.FORBIDDEN )
def test_user_duplicate_conflict_gives_name(self): user = unit.new_user_ref(domain_id=CONF.identity.default_domain_id) user = self.identity_api.create_user(user) user['id'] = uuid.uuid4().hex try: self.identity_api.create_user(user) except exception.Conflict as e: self.assertIn("Duplicate entry found with name %s" % user['name'], repr(e)) else: self.fail("Create duplicate user did not raise a conflict")
def test_tls_bad_certdir(self): self.config_fixture.config( group='ldap', use_tls=True, tls_cacertfile=None, tls_req_cert='demand', tls_cacertdir='/etc/keystone/ssl/mythicalcertdir') self.identity_api = identity.backends.ldap.Identity() user = unit.new_user_ref('default') self.assertRaises(IOError, self.identity_api.create_user, user)
def test_sql_user_to_dict_null_default_project_id(self): user = unit.new_user_ref(domain_id=DEFAULT_DOMAIN_ID) user = self.identity_api.create_user(user) session = sql.get_session() query = session.query(identity_sql.User) query = query.filter_by(id=user['id']) raw_user_ref = query.one() self.assertIsNone(raw_user_ref.default_project_id) user_ref = raw_user_ref.to_dict() self.assertNotIn('default_project_id', user_ref) session.close()
def test_user_can_list_users_in_own_domain_for_group_in_own_domain(self): user = PROVIDERS.identity_api.create_user( unit.new_user_ref(domain_id=self.domain_id)) group = PROVIDERS.identity_api.create_group( unit.new_group_ref(domain_id=self.domain_id)) PROVIDERS.identity_api.add_user_to_group(user['id'], group['id']) with self.test_client() as c: r = c.get('/v3/groups/%s/users' % group['id'], headers=self.headers) self.assertEqual(1, len(r.json['users'])) self.assertEqual(user['id'], r.json['users'][0]['id'])
def test_get_user_includes_required_attributes(self): """Call ``GET /users/{user_id}`` required attributes are included.""" user = unit.new_user_ref(domain_id=self.domain_id, project_id=self.project_id) user = self.identity_api.create_user(user) self.assertIn('id', user) self.assertIn('name', user) self.assertIn('enabled', user) self.assertIn('password_expires_at', user) r = self.get('/users/%(user_id)s' % {'user_id': user['id']}) self.assertValidUserResponse(r, user)
def test_credential_duplicate_conflict_gives_name(self): user = unit.new_user_ref(domain_id=CONF.identity.default_domain_id) credential = unit.new_credential_ref(user_id=user['id']) self.credential_api.create_credential(credential['id'], credential) try: self.credential_api.create_credential(credential['id'], credential) except exception.Conflict as e: self.assertIn( "Duplicate entry found with ID %s" % credential['id'], repr(e)) else: self.fail("Create duplicate credential did not raise a conflict")
def test_user_cannot_get_user_in_other_domain(self): domain = PROVIDERS.resource_api.create_domain(uuid.uuid4().hex, unit.new_domain_ref()) user = PROVIDERS.identity_api.create_user( unit.new_user_ref(domain_id=domain['id'])) with self.test_client() as c: c.get('/v3/users/%s' % user['id'], headers=self.headers, expected_status_code=http.client.FORBIDDEN)
def test_user_cannot_list_system_role_assignments(self): user = PROVIDERS.identity_api.create_user( unit.new_user_ref(CONF.identity.default_domain_id)) PROVIDERS.assignment_api.create_system_grant_for_user( user['id'], self.bootstrapper.member_role_id) with self.test_client() as c: c.get('/v3/system/users/%s/roles' % user['id'], headers=self.headers, expected_status_code=http.client.FORBIDDEN)
def test_user_can_revoke_system_assignments(self): user = PROVIDERS.identity_api.create_user( unit.new_user_ref(CONF.identity.default_domain_id)) PROVIDERS.assignment_api.create_system_grant_for_user( user['id'], self.bootstrapper.member_role_id) with self.test_client() as c: c.delete('/v3/system/users/%s/roles/%s' % (user['id'], self.bootstrapper.member_role_id), headers=self.headers)
def test_update_user_domain_id(self): """Call ``PATCH /users/{user_id}`` with domain_id. A user's `domain_id` is immutable. Ensure that any attempts to update the `domain_id` of a user fails. """ user = unit.new_user_ref(domain_id=self.domain['id']) user = self.identity_api.create_user(user) user['domain_id'] = CONF.identity.default_domain_id self.patch('/users/%(user_id)s' % {'user_id': user['id']}, body={'user': user}, expected_status=exception.ValidationError.code)
def test_user_can_list_users_within_domain(self): user = PROVIDERS.identity_api.create_user( unit.new_user_ref(domain_id=self.domain_id)) with self.test_client() as c: r = c.get('/v3/users', headers=self.headers) self.assertEqual(2, len(r.json['users'])) user_ids = [] for user in r.json['users']: user_ids.append(user['id']) self.assertIn(self.user_id, user_ids) self.assertIn(user['id'], user_ids)
def test_update_user_with_null_password(self): user_dict = unit.new_user_ref( domain_id=CONF.identity.default_domain_id) self.assertTrue(user_dict['password']) new_user_dict = self.identity_api.create_user(user_dict) new_user_dict["password"] = None new_user_dict = self.identity_api.update_user(new_user_dict['id'], new_user_dict) with sql.session_for_read() as session: new_user_ref = self.identity_api._get_user(session, new_user_dict['id']) self.assertFalse(new_user_ref.local_user.passwords)
def test_user_cannot_list_users_in_own_domain_group_in_other_domain(self): domain = PROVIDERS.resource_api.create_domain(uuid.uuid4().hex, unit.new_domain_ref()) user = PROVIDERS.identity_api.create_user( unit.new_user_ref(domain_id=self.domain_id)) group = PROVIDERS.identity_api.create_group( unit.new_group_ref(domain_id=domain['id'])) PROVIDERS.identity_api.add_user_to_group(user['id'], group['id']) with self.test_client() as c: c.get('/v3/groups/%s/users' % group['id'], headers=self.headers, expected_status_code=http.client.FORBIDDEN)
def test_delete_user_with_project_association(self): user = unit.new_user_ref(domain_id=CONF.identity.default_domain_id) user = PROVIDERS.identity_api.create_user(user) role_member = unit.new_role_ref() PROVIDERS.role_api.create_role(role_member['id'], role_member) PROVIDERS.assignment_api.add_role_to_user_and_project( user['id'], self.tenant_bar['id'], role_member['id'] ) PROVIDERS.identity_api.delete_user(user['id']) self.assertRaises(exception.UserNotFound, PROVIDERS.assignment_api.list_projects_for_user, user['id'])
def _load_sample_data(self): self.project_id = uuid.uuid4().hex self.project_name = uuid.uuid4().hex self.protocol_id = 'x509' # 1) Create a domain for the user. self.domain = unit.new_domain_ref() self.domain_id = self.domain['id'] self.domain_name = self.domain['name'] self.resource_api.create_domain(self.domain_id, self.domain) # 2) Create a project for the user. self.project = { 'description': uuid.uuid4().hex, 'domain_id': self.domain_id, 'enabled': True, 'id': self.project_id, 'name': self.project_name, } self.resource_api.create_project(self.project_id, self.project) # 3) Create a user in new domain. self.user = unit.new_user_ref(domain_id=self.domain_id, project_id=self.project_id) self.user = self.identity_api.create_user(self.user) # Add IDP self.idp = self._idp_ref(id=self.idp_id) self.federation_api.create_idp(self.idp['id'], self.idp) # Add a role self.role = unit.new_role_ref() self.role_id = self.role['id'] self.role_name = self.role['name'] self.role_api.create_role(self.role_id, self.role) # Add a group self.group = unit.new_group_ref(domain_id=self.domain_id) self.group = self.identity_api.create_group(self.group) # Assign a role to the user on a project self.assignment_api.add_role_to_user_and_project( user_id=self.user['id'], tenant_id=self.project_id, role_id=self.role_id) # Assign a role to the group on a project self.assignment_api.create_grant(role_id=self.role_id, group_id=self.group['id'], project_id=self.project_id)
def test_update_user_domain_id(self): """Call ``PATCH /users/{user_id}`` with domain_id.""" user = unit.new_user_ref(domain_id=self.domain['id']) user = self.identity_api.create_user(user) user['domain_id'] = CONF.identity.default_domain_id r = self.patch('/users/%(user_id)s' % {'user_id': user['id']}, body={'user': user}, expected_status=exception.ValidationError.code) self.config_fixture.config(domain_id_immutable=False) user['domain_id'] = self.domain['id'] r = self.patch('/users/%(user_id)s' % {'user_id': user['id']}, body={'user': user}) self.assertValidUserResponse(r, user)
def test_user_cannot_list_users_in_other_domain(self): domain = PROVIDERS.resource_api.create_domain(uuid.uuid4().hex, unit.new_domain_ref()) user = PROVIDERS.identity_api.create_user( unit.new_user_ref(domain_id=domain['id'])) with self.test_client() as c: r = c.get('/v3/users', headers=self.headers) user_ids = [] for u in r.json['users']: user_ids.append(u['id']) self.assertNotIn(user['id'], user_ids)
def test_user_can_create_credentials_for_other_users(self): user = PROVIDERS.identity_api.create_user( unit.new_user_ref(domain_id=CONF.identity.default_domain_id)) with self.test_client() as c: create = { 'credential': { 'blob': uuid.uuid4().hex, 'type': uuid.uuid4().hex, 'user_id': user['id'] } } c.post('/v3/credentials', json=create, headers=self.headers)
def test_create_user_case_sensitivity(self): # user name case sensitivity is down to the fact that it is marked as # an SQL UNIQUE column, which may not be valid for other backends, like # LDAP. # create a ref with a lowercase name ref = unit.new_user_ref(name=uuid.uuid4().hex.lower(), domain_id=CONF.identity.default_domain_id) ref = self.identity_api.create_user(ref) # assign a new ID with the same name, but this time in uppercase ref['name'] = ref['name'].upper() self.identity_api.create_user(ref)
def test_user_can_list_user_system_role_assignments(self): user = PROVIDERS.identity_api.create_user( unit.new_user_ref(CONF.identity.default_domain_id)) PROVIDERS.assignment_api.create_system_grant_for_user( user['id'], self.bootstrapper.member_role_id) with self.test_client() as c: r = c.get('/v3/system/users/%s/roles' % user['id'], headers=self.headers) self.assertEqual(1, len(r.json['roles'])) self.assertEqual(self.bootstrapper.member_role_id, r.json['roles'][0]['id'])