Additional test coverage for password changes

Keystone has four API calls which may result in a user's password
changing.

1. Administrative password reset on v2:

    POST /v2.0/users/{user_id}/OS-KSADM/password

2. Self-service password change on v2:

    PATCH /v2.0/OS-KSCRUD/users/{user_id}

3. Administrative password reset on v3:

    POST /v3/users/{user_id}

4. Self-service password change on v3:

    POST /v3/users/{user_id}/password

This patch adds additional test coverage to *consistently* ensure that:

- Old passwords no longer work
- Old tokens no longer work
- The new password works

Change-Id: I2a296b7ed407c75018fff3b60bd13aaa4fa9a849
Closes-Bug: 1407105
(cherry picked from commit a22aa08bf2)
This commit is contained in:
Dolph Mathews 2015-01-05 22:42:30 +00:00 committed by Alan Pevec
parent 09cbadde67
commit 0967058007
3 changed files with 101 additions and 18 deletions

View File

@ -383,25 +383,64 @@ class ClientDrivenTestCase(tests.TestCase):
password=uuid.uuid4().hex)
def test_change_password_invalidates_token(self):
client = self.get_client(admin=True)
admin_client = self.get_client(admin=True)
username = uuid.uuid4().hex
passwd = uuid.uuid4().hex
user = client.users.create(name=username, password=passwd,
email=uuid.uuid4().hex)
password = uuid.uuid4().hex
user = admin_client.users.create(name=username, password=password,
email=uuid.uuid4().hex)
token_id = client.tokens.authenticate(username=username,
password=passwd).id
# auth as user should work before a password change
client = self._client(username=username, password=password)
# authenticate with a token should work before a password change
client.tokens.authenticate(token=token_id)
# auth as user with a token should work before a password change
self._client(token=client.auth_token)
client.users.update_password(user=user.id, password=uuid.uuid4().hex)
# administrative password reset
admin_client.users.update_password(
user=user.id,
password=uuid.uuid4().hex)
# authenticate with a token should not work after a password change
# auth as user with original password should not work after change
self.assertRaises(client_exceptions.Unauthorized,
client.tokens.authenticate,
token=token_id)
self._client,
username=username,
password=password)
# authenticate with an old token should not work after change
self.assertRaises(client_exceptions.Unauthorized,
self._client,
token=client.auth_token)
def test_user_change_own_password_invalidates_token(self):
from keystoneclient import exceptions as client_exceptions
# bootstrap a user as admin
client = self.get_client(admin=True)
username = uuid.uuid4().hex
password = uuid.uuid4().hex
client.users.create(name=username, password=password,
email=uuid.uuid4().hex)
# auth as user should work before a password change
client = self._client(username=username, password=password)
# auth as user with a token should work before a password change
self._client(token=client.auth_token)
# change the user's own password
client.users.update_own_password(password, uuid.uuid4().hex)
# auth as user with original password should not work after change
self.assertRaises(client_exceptions.Unauthorized,
self._client,
username=username,
password=password)
# auth as user with an old token should not work after change
self.assertRaises(client_exceptions.Unauthorized,
self._client,
token=client.auth_token)
def test_disable_tenant_invalidates_token(self):
admin_client = self.get_client(admin=True)

View File

@ -326,12 +326,15 @@ class RestfulTestCase(tests.SQLDriverOverrides, rest.RestfulTestCase):
def get_requested_token(self, auth):
"""Request the specific token we want."""
r = self.admin_request(
method='POST',
path='/v3/auth/tokens',
body=auth)
r = self.v3_authenticate_token(auth)
return r.headers.get('X-Subject-Token')
def v3_authenticate_token(self, auth, expected_status=201):
return self.admin_request(method='POST',
path='/v3/auth/tokens',
body=auth,
expected_status=expected_status)
def v3_request(self, path, **kwargs):
# Check if the caller has passed in auth details for
# use in requesting the token

View File

@ -593,6 +593,41 @@ class IdentityTestCase(test_v3.RestfulTestCase):
body={'user': user})
self.assertValidUserResponse(r, user)
def test_admin_password_reset(self):
# bootstrap a user as admin
user_ref = self.new_user_ref(domain_id=self.domain['id'])
password = user_ref['password']
user_ref = self.identity_api.create_user(user_ref['id'], user_ref)
# auth as user should work before a password change
old_password_auth = self.build_authentication_request(
user_id=user_ref['id'],
password=password)
r = self.v3_authenticate_token(old_password_auth, expected_status=201)
old_token = r.headers.get('X-Subject-Token')
# auth as user with a token should work before a password change
old_token_auth = self.build_authentication_request(token=old_token)
self.v3_authenticate_token(old_token_auth, expected_status=201)
# administrative password reset
new_password = uuid.uuid4().hex
self.patch('/users/%s' % user_ref['id'],
body={'user': {'password': new_password}},
expected_status=200)
# auth as user with original password should not work after change
self.v3_authenticate_token(old_password_auth, expected_status=401)
# auth as user with an old token should not work after change
self.v3_authenticate_token(old_token_auth, expected_status=404)
# new password should work
new_password_auth = self.build_authentication_request(
user_id=user_ref['id'],
password=new_password)
self.v3_authenticate_token(new_password_auth, expected_status=201)
def test_update_user_domain_id(self):
"""Call ``PATCH /users/{user_id}`` with domain_id."""
user = self.new_user_ref(domain_id=self.domain['id'])
@ -1917,8 +1952,11 @@ class UserSelfServiceChangingPasswordsTestCase(test_v3.RestfulTestCase):
def test_changing_password(self):
# original password works
self.get_request_token(self.user_ref['password'],
expected_status=201)
token_id = self.get_request_token(self.user_ref['password'],
expected_status=201)
# original token works
old_token_auth = self.build_authentication_request(token=token_id)
self.v3_authenticate_token(old_token_auth, expected_status=201)
# change password
new_password = uuid.uuid4().hex
@ -1929,6 +1967,9 @@ class UserSelfServiceChangingPasswordsTestCase(test_v3.RestfulTestCase):
# old password fails
self.get_request_token(self.user_ref['password'], expected_status=401)
# old token fails
self.v3_authenticate_token(old_token_auth, expected_status=404)
# new password works
self.get_request_token(new_password, expected_status=201)