summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--keystone/common/utils.py2
-rw-r--r--keystone/identity/controllers.py22
-rw-r--r--tests/test_content_types.py36
-rw-r--r--tests/test_keystoneclient.py13
-rw-r--r--tests/test_v3_auth.py60
5 files changed, 98 insertions, 35 deletions
diff --git a/keystone/common/utils.py b/keystone/common/utils.py
index 687d4cd2..fc62de97 100644
--- a/keystone/common/utils.py
+++ b/keystone/common/utils.py
@@ -219,7 +219,7 @@ def setup_remote_pydev_debug():
if CONF.pydev_debug_host and CONF.pydev_debug_port:
try:
try:
- from pydevd import pydevd
+ from pydev import pydevd
except ImportError:
import pydevd
diff --git a/keystone/identity/controllers.py b/keystone/identity/controllers.py
index 3e60272d..1afdfd26 100644
--- a/keystone/identity/controllers.py
+++ b/keystone/identity/controllers.py
@@ -242,10 +242,15 @@ class User(controller.V2Controller):
def update_user_project(self, context, user_id, user):
"""Update the default tenant."""
self.assert_admin(context)
- # ensure that we're a member of that tenant
- default_tenant_id = user.get('tenantId')
- self.identity_api.add_user_to_project(context,
- default_tenant_id, user_id)
+
+ try:
+ # ensure that we're a member of that tenant
+ self.identity_api.add_user_to_project(
+ context, user.get('tenantId'), user_id)
+ except exception.Conflict:
+ # we're already a member of that tenant
+ pass
+
return self.update_user(context, user_id, user)
@@ -308,7 +313,6 @@ class Role(controller.V2Controller):
self.identity_api.add_role_to_user_and_project(
context, user_id, tenant_id, role_id)
- self._delete_tokens_for_user(context, user_id)
role_ref = self.identity_api.get_role(context, role_id)
return {'role': role_ref}
@@ -766,14 +770,6 @@ class RoleV3(controller.V3Controller):
self.identity_api.create_grant(
context, role_id, user_id, group_id, domain_id, project_id)
- # So that existing tokens don't stop the use of this grant
- # delete any tokens for this user or, in the case of a group,
- # tokens from all the uses who are members of this group.
- if user_id:
- self._delete_tokens_for_user(context, user_id)
- else:
- self._delete_tokens_for_group(context, group_id)
-
@controller.protected
def list_grants(self, context, user_id=None, group_id=None,
domain_id=None, project_id=None):
diff --git a/tests/test_content_types.py b/tests/test_content_types.py
index e5bdc56a..d4cc1d81 100644
--- a/tests/test_content_types.py
+++ b/tests/test_content_types.py
@@ -214,23 +214,35 @@ class RestfulTestCase(test.TestCase):
def admin_request(self, **kwargs):
return self._request(app=self.admin_app, **kwargs)
+ def _get_token(self, body):
+ """Convenience method so that we can test authenticated requests."""
+ r = self.public_request(method='POST', path='/v2.0/tokens', body=body)
+ return self._get_token_id(r)
+
+ def get_unscoped_token(self):
+ """Convenience method so that we can test authenticated requests."""
+ return self._get_token({
+ 'auth': {
+ 'passwordCredentials': {
+ 'username': self.user_foo['name'],
+ 'password': self.user_foo['password'],
+ },
+ },
+ })
+
def get_scoped_token(self, tenant_id=None):
"""Convenience method so that we can test authenticated requests."""
if not tenant_id:
tenant_id = self.tenant_bar['id']
- r = self.public_request(
- method='POST',
- path='/v2.0/tokens',
- body={
- 'auth': {
- 'passwordCredentials': {
- 'username': self.user_foo['name'],
- 'password': self.user_foo['password'],
- },
- 'tenantId': tenant_id,
+ return self._get_token({
+ 'auth': {
+ 'passwordCredentials': {
+ 'username': self.user_foo['name'],
+ 'password': self.user_foo['password'],
},
- })
- return self._get_token_id(r)
+ 'tenantId': tenant_id,
+ },
+ })
def _get_token_id(self, r):
"""Helper method to return a token ID from a response.
diff --git a/tests/test_keystoneclient.py b/tests/test_keystoneclient.py
index 49e3bfc9..bd538700 100644
--- a/tests/test_keystoneclient.py
+++ b/tests/test_keystoneclient.py
@@ -482,6 +482,19 @@ class KeystoneClientTests(object):
tenant_id='bar')
self.assertEquals(user2.name, test_username)
+ def test_update_default_tenant_to_existing_value(self):
+ client = self.get_client(admin=True)
+
+ user = client.users.create(
+ name=uuid.uuid4().hex,
+ password=uuid.uuid4().hex,
+ email=uuid.uuid4().hex,
+ tenant_id=self.tenant_bar['id'])
+
+ # attempting to update the tenant with the existing value should work
+ user = client.users.update_tenant(
+ user=user, tenant=self.tenant_bar['id'])
+
def test_user_create_no_name(self):
from keystoneclient import exceptions as client_exceptions
client = self.get_client(admin=True)
diff --git a/tests/test_v3_auth.py b/tests/test_v3_auth.py
index 1ee3719d..dd39f96a 100644
--- a/tests/test_v3_auth.py
+++ b/tests/test_v3_auth.py
@@ -490,6 +490,48 @@ class TestTokenRevoking(test_v3.RestfulTestCase):
group_id=self.group1['id'],
project_id=self.projectA['id'])
+ def test_unscoped_token_remains_valid_after_role_assignment(self):
+ r = self.post(
+ '/auth/tokens',
+ body=self.build_authentication_request(
+ user_id=self.user1['id'],
+ password=self.user1['password']))
+ unscoped_token = r.headers.get('X-Subject-Token')
+
+ r = self.post(
+ '/auth/tokens',
+ body=self.build_authentication_request(
+ token=unscoped_token,
+ project_id=self.projectA['id']))
+ scoped_token = r.headers.get('X-Subject-Token')
+
+ # confirm both tokens are valid
+ self.head('/auth/tokens',
+ headers={'X-Subject-Token': unscoped_token},
+ expected_status=204)
+ self.head('/auth/tokens',
+ headers={'X-Subject-Token': scoped_token},
+ expected_status=204)
+
+ # create a new role
+ role = self.new_role_ref()
+ self.identity_api.create_role(role['id'], role)
+
+ # assign a new role
+ self.put(
+ '/projects/%(project_id)s/users/%(user_id)s/roles/%(role_id)s' % {
+ 'project_id': self.projectA['id'],
+ 'user_id': self.user1['id'],
+ 'role_id': role['id']})
+
+ # both tokens should remain valid
+ self.head('/auth/tokens',
+ headers={'X-Subject-Token': unscoped_token},
+ expected_status=204)
+ self.head('/auth/tokens',
+ headers={'X-Subject-Token': scoped_token},
+ expected_status=204)
+
def test_deleting_user_grant_revokes_token(self):
"""Test deleting a user grant revokes token.
@@ -521,13 +563,13 @@ class TestTokenRevoking(test_v3.RestfulTestCase):
headers={'X-Subject-Token': token},
expected_status=401)
- def test_creating_user_grant_revokes_token(self):
- """Test creating a user grant revokes token.
+ def test_domain_user_role_assignment_maintains_token(self):
+ """Test user-domain role assignment maintains existing token.
Test Plan:
- Get a token for user1, scoped to ProjectA
- Create a grant for user1 on DomainB
- - Check token is no longer valid
+ - Check token is still valid
"""
auth_data = self.build_authentication_request(
@@ -540,7 +582,7 @@ class TestTokenRevoking(test_v3.RestfulTestCase):
self.head('/auth/tokens',
headers={'X-Subject-Token': token},
expected_status=204)
- # Delete the grant, which should invalidate the token
+ # Assign a role, which should not affect the token
grant_url = (
'/domains/%(domain_id)s/users/%(user_id)s/'
'roles/%(role_id)s' % {
@@ -550,7 +592,7 @@ class TestTokenRevoking(test_v3.RestfulTestCase):
self.put(grant_url)
self.head('/auth/tokens',
headers={'X-Subject-Token': token},
- expected_status=401)
+ expected_status=204)
def test_deleting_group_grant_revokes_tokens(self):
"""Test deleting a group grant revokes tokens.
@@ -613,13 +655,13 @@ class TestTokenRevoking(test_v3.RestfulTestCase):
headers={'X-Subject-Token': token3},
expected_status=204)
- def test_creating_group_grant_revokes_token(self):
- """Test creating a group grant revokes token.
+ def test_domain_group_role_assignment_maintains_token(self):
+ """Test domain-group role assignment maintains existing token.
Test Plan:
- Get a token for user1, scoped to ProjectA
- Create a grant for group1 on DomainB
- - Check token is no longer valid
+ - Check token is still longer valid
"""
auth_data = self.build_authentication_request(
@@ -642,7 +684,7 @@ class TestTokenRevoking(test_v3.RestfulTestCase):
self.put(grant_url)
self.head('/auth/tokens',
headers={'X-Subject-Token': token},
- expected_status=401)
+ expected_status=204)
def test_group_membership_changes_revokes_token(self):
"""Test add/removal to/from group revokes token.