summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJenkins <jenkins@review.openstack.org>2012-06-14 19:56:21 +0000
committerGerrit Code Review <review@openstack.org>2012-06-14 19:56:21 +0000
commit9a841f3ba93d5a0bd1f56cc897415258ed6cf877 (patch)
treefab437b2e0392c4ffa5eb3b1a89de54a58c972df
parent35d5ebd54e02e4b79515e882506f0a518548d273 (diff)
parentd9600434da14976463a0bd03abd8e0309f0db454 (diff)
downloadkeystone-9a841f3ba93d5a0bd1f56cc897415258ed6cf877.tar.gz
Merge "Invalidate user tokens when a user is disabled" into stable/essex
-rw-r--r--keystone/identity/core.py22
-rw-r--r--keystone/service.py14
-rw-r--r--tests/test_keystoneclient.py21
3 files changed, 44 insertions, 13 deletions
diff --git a/keystone/identity/core.py b/keystone/identity/core.py
index 5efd142e1..83b1798e2 100644
--- a/keystone/identity/core.py
+++ b/keystone/identity/core.py
@@ -408,6 +408,17 @@ class UserController(wsgi.Application):
raise exception.UserNotFound(user_id=user_id)
user_ref = self.identity_api.update_user(context, user_id, user)
+
+ # If the password was changed or the user was disabled we clear tokens
+ if user.get('password') or user.get('enabled', True) == False:
+ try:
+ for token_id in self.token_api.list_tokens(context, user_id):
+ self.token_api.delete_token(context, token_id)
+ except exception.NotImplemented:
+ # The users status has been changed but tokens remain valid for
+ # backends that can't list tokens for users
+ LOG.warning('User %s status has changed, but existing tokens '
+ 'remain valid' % user_id)
return {'user': user_ref}
def delete_user(self, context, user_id):
@@ -421,16 +432,7 @@ class UserController(wsgi.Application):
return self.update_user(context, user_id, user)
def set_user_password(self, context, user_id, user):
- user_ref = self.update_user(context, user_id, user)
- try:
- for token_id in self.token_api.list_tokens(context, user_id):
- self.token_api.delete_token(context, token_id)
- except exception.NotImplemented:
- # The password has been changed but tokens remain valid for
- # backends that can't list tokens for users
- LOG.warning('Password changed for %s, but existing tokens remain '
- 'valid' % user_id)
- return user_ref
+ return self.update_user(context, user_id, user)
def update_user_tenant(self, context, user_id, user):
"""Update the default tenant."""
diff --git a/keystone/service.py b/keystone/service.py
index 1cb455ddf..2b024f4ed 100644
--- a/keystone/service.py
+++ b/keystone/service.py
@@ -28,6 +28,9 @@ from keystone.common import utils
from keystone.common import wsgi
+LOG = logging.getLogger(__name__)
+
+
class AdminRouter(wsgi.ComposingRouter):
def __init__(self):
mapper = routes.Mapper()
@@ -275,7 +278,8 @@ class TokenController(wsgi.Application):
# If the user is disabled don't allow them to authenticate
if not user_ref.get('enabled', True):
- raise exception.Forbidden(message='User has been disabled')
+ LOG.warning('User %s is disabled' % user_id)
+ raise exception.Unauthorized()
except AssertionError as e:
raise exception.Unauthorized(e.message)
@@ -314,6 +318,14 @@ class TokenController(wsgi.Application):
user_ref = old_token_ref['user']
+ # If the user is disabled don't allow them to authenticate
+ current_user_ref = self.identity_api.get_user(
+ context=context,
+ user_id=user_ref['id'])
+ if not current_user_ref.get('enabled', True):
+ LOG.warning('User %s is disabled' % user_ref['id'])
+ raise exception.Unauthorized()
+
tenants = self.identity_api.get_tenants_for_user(context,
user_ref['id'])
if tenant_id:
diff --git a/tests/test_keystoneclient.py b/tests/test_keystoneclient.py
index 8d4f002dd..1e0be6053 100644
--- a/tests/test_keystoneclient.py
+++ b/tests/test_keystoneclient.py
@@ -309,6 +309,23 @@ class KeystoneClientTests(object):
client.tokens.authenticate,
token=token_id)
+ def test_disable_user_invalidates_token(self):
+ from keystoneclient import exceptions as client_exceptions
+
+ admin_client = self.get_client(admin=True)
+ foo_client = self.get_client(self.user_foo)
+
+ admin_client.users.update_enabled(user=self.user_foo['id'],
+ enabled=False)
+
+ self.assertRaises(client_exceptions.Unauthorized,
+ foo_client.tokens.authenticate,
+ token=foo_client.auth_token)
+
+ self.assertRaises(client_exceptions.Unauthorized,
+ self.get_client,
+ self.user_foo)
+
def test_user_create_update_delete(self):
from keystoneclient import exceptions as client_exceptions
@@ -332,7 +349,7 @@ class KeystoneClientTests(object):
user = client.users.get(user.id)
self.assertFalse(user.enabled)
- self.assertRaises(client_exceptions.AuthorizationFailure,
+ self.assertRaises(client_exceptions.Unauthorized,
self._client,
username=test_username,
password='password')
@@ -871,7 +888,7 @@ class KcEssex3TestCase(CompatTestCase, KeystoneClientTests):
user = client.users.get(user.id)
self.assertFalse(user.enabled)
- self.assertRaises(client_exceptions.AuthorizationFailure,
+ self.assertRaises(client_exceptions.Unauthorized,
self._client,
username=test_username,
password='password')