summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDolph Mathews <dolph.mathews@gmail.com>2015-01-05 22:42:30 +0000
committerAlan Pevec <alan.pevec@redhat.com>2015-03-10 08:38:19 +0100
commit096705800736bb6d2be39f1cb22ad69e18d4252a (patch)
treee2e7c81f58cc2872804d7c15998c1c335a3e8acc
parent09cbadde67f64836f506c2235e683f8e44788888 (diff)
downloadkeystone-096705800736bb6d2be39f1cb22ad69e18d4252a.tar.gz
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 a22aa08bf2176ac2da75258223f58d70303259e4)
-rw-r--r--keystone/tests/test_keystoneclient.py63
-rw-r--r--keystone/tests/test_v3.py11
-rw-r--r--keystone/tests/test_v3_identity.py45
3 files changed, 101 insertions, 18 deletions
diff --git a/keystone/tests/test_keystoneclient.py b/keystone/tests/test_keystoneclient.py
index 1769a747d..62e1d9d1a 100644
--- a/keystone/tests/test_keystoneclient.py
+++ b/keystone/tests/test_keystoneclient.py
@@ -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)
diff --git a/keystone/tests/test_v3.py b/keystone/tests/test_v3.py
index 5d85cef17..027163e81 100644
--- a/keystone/tests/test_v3.py
+++ b/keystone/tests/test_v3.py
@@ -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
diff --git a/keystone/tests/test_v3_identity.py b/keystone/tests/test_v3_identity.py
index 000c50c16..ea222f305 100644
--- a/keystone/tests/test_v3_identity.py
+++ b/keystone/tests/test_v3_identity.py
@@ -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)