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:
parent
09cbadde67
commit
0967058007
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
Loading…
Reference in New Issue