[openstack-keystone/f17] Updated patches from f17-patches

Alan Pevec apevec at fedoraproject.org
Mon Jun 11 19:39:01 UTC 2012


commit 4aa71204398eea908b5c4f29a61ab7ef7f0febf3
Author: Alan Pevec <apevec at redhat.com>
Date:   Mon Jun 11 21:30:00 2012 +0200

    Updated patches from f17-patches

 0002-Fix-test-env-for-the-stable-branch.patch      |   65 ++++++++
 ...s-url-conversion-in-export_legacy_catalog.patch |   49 ++++++
 ...date-user-tokens-when-password-is-changed.patch |  157 ++++++++++++++++++++
 ...idate-user-tokens-when-a-user-is-disabled.patch |  148 ++++++++++++++++++
 ...ver-token-expiry-time-when-token-chaining.patch |   60 ++++++++
 openstack-keystone.spec                            |   18 ++-
 6 files changed, 496 insertions(+), 1 deletions(-)
---
diff --git a/0002-Fix-test-env-for-the-stable-branch.patch b/0002-Fix-test-env-for-the-stable-branch.patch
new file mode 100644
index 0000000..d26872e
--- /dev/null
+++ b/0002-Fix-test-env-for-the-stable-branch.patch
@@ -0,0 +1,65 @@
+From 7715d6cd72477af83d95563b69a5f0273bdb719b Mon Sep 17 00:00:00 2001
+From: Alan Pevec <apevec at redhat.com>
+Date: Mon, 11 Jun 2012 20:19:50 +0200
+Subject: [PATCH] Fix test env for the stable branch
+
+Need both changes in one commit to pass the gate!
+
+* Nail pep8 dependencies to 1.0.1.
+
+Nails the pep8 deps for tox and test-requires to 1.0.1.
+Fixes an issues causing pep8 failures due to a new pep8 release.
+
+(cherry picked from Nova stable)
+
+* Switch to 1000 rounds during unit tests
+
+Fixes bug 992918
+
+passlib 1.6 introduced a minimum number of rounds for sha512_crypt. As
+a result, increase the rounds used during testing to the minimum
+
+Change-Id: Ic0c635e92b4f13180a047904a6efa490ab599012
+---
+ tests/test_overrides.conf |    2 +-
+ tools/test-requires       |    2 +-
+ tox.ini                   |    2 +-
+ 3 files changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/tests/test_overrides.conf b/tests/test_overrides.conf
+index 20bc30e..4a05b95 100644
+--- a/tests/test_overrides.conf
++++ b/tests/test_overrides.conf
+@@ -1,5 +1,5 @@
+ [DEFAULT]
+-crypt_strength = 10
++crypt_strength = 1000
+ 
+ [identity]
+ driver = keystone.identity.backends.kvs.Identity
+diff --git a/tools/test-requires b/tools/test-requires
+index f2e3c22..43f3d7b 100644
+--- a/tools/test-requires
++++ b/tools/test-requires
+@@ -11,7 +11,7 @@ nose # for test discovery and console feedback
+ nosexcover
+ openstack.nose_plugin
+ pylint # static code analysis
+-pep8==0.6.1 # checks for PEP8 code style compliance
++pep8==1.0.1 # checks for PEP8 code style compliance
+ Sphinx>=1.1.2 # required to build documentation
+ unittest2 # backport of unittest lib in python 2.7
+ webtest # test wsgi apps without starting an http server
+diff --git a/tox.ini b/tox.ini
+index 1536bf1..a1137b6 100644
+--- a/tox.ini
++++ b/tox.ini
+@@ -8,7 +8,7 @@ deps = -r{toxinidir}/tools/pip-requires
+ commands = bash run_tests.sh -N --no-pep8
+ 
+ [testenv:pep8]
+-deps = pep8
++deps = pep8==1.0.1
+ commands = pep8 --exclude=vcsversion.py,*.pyc --repeat --show-source bin keystone setup.py
+ 
+ [testenv:hudson]
diff --git a/0003-Corrects-url-conversion-in-export_legacy_catalog.patch b/0003-Corrects-url-conversion-in-export_legacy_catalog.patch
new file mode 100644
index 0000000..a6077d2
--- /dev/null
+++ b/0003-Corrects-url-conversion-in-export_legacy_catalog.patch
@@ -0,0 +1,49 @@
+From 426549934e323a9bc435b9ec58163e88f5e74a32 Mon Sep 17 00:00:00 2001
+From: Sam Morrison <sorrison at gmail.com>
+Date: Mon, 7 May 2012 09:09:57 +1000
+Subject: [PATCH] Corrects url conversion in export_legacy_catalog
+
+Fixes bug 994936
+
+Change-Id: Ia63fdae7d0bcd7f8b0b587da588404765e22fb8f
+---
+ AUTHORS                       |    1 +
+ keystone/common/sql/legacy.py |    2 +-
+ tests/test_import_legacy.py   |    2 +-
+ 3 files changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/AUTHORS b/AUTHORS
+index b8d2014..a33f07e 100644
+--- a/AUTHORS
++++ b/AUTHORS
+@@ -86,6 +86,7 @@ Russell Bryant <rbryant at redhat.com>
+ saikrishna1511 at gmail.com <psaikrishna at ubudesk1004.(none)>
+ Sai Krishna <saikrishna1511 at gmail.com>
+ Salvatore Orlando <salvatore.orlando at eu.citrix.com>
++Sam Morrison <sorrison at gmail.com>
+ Sandy Walsh <sandy at sandywalsh.com>
+ Shevek <shevek at nebula.com>
+ sirish bitra <sirish.bitra at gmail.com>
+diff --git a/keystone/common/sql/legacy.py b/keystone/common/sql/legacy.py
+index ca19ccb..55e27b3 100644
+--- a/keystone/common/sql/legacy.py
++++ b/keystone/common/sql/legacy.py
+@@ -77,7 +77,7 @@ class LegacyMigration(object):
+                  'region': row['region']}
+ 
+             for x in ['internal_url', 'public_url', 'admin_url', 'enabled']:
+-                d['key'] = x.replace('_u', 'U')
++                d['key'] = x.replace('_url', 'URL')
+                 d['value'] = _translate_replacements(row[x])
+                 o.append(template % d)
+ 
+diff --git a/tests/test_import_legacy.py b/tests/test_import_legacy.py
+index aa3c517..6ae829c 100644
+--- a/tests/test_import_legacy.py
++++ b/tests/test_import_legacy.py
+@@ -108,4 +108,4 @@ class ImportLegacy(test.TestCase):
+         catalog = catalog_templated.parse_templates(catalog_lines)
+         self.assert_('RegionOne' in catalog)
+         self.assert_('compute' in catalog['RegionOne'])
+-        self.assert_('adminUrl' in catalog['RegionOne']['compute'])
++        self.assert_('adminURL' in catalog['RegionOne']['compute'])
diff --git a/0004-Invalidate-user-tokens-when-password-is-changed.patch b/0004-Invalidate-user-tokens-when-password-is-changed.patch
new file mode 100644
index 0000000..546cf5a
--- /dev/null
+++ b/0004-Invalidate-user-tokens-when-password-is-changed.patch
@@ -0,0 +1,157 @@
+From 645797b6b47bd9be7ac6e86fec01901fa557f7d8 Mon Sep 17 00:00:00 2001
+From: Derek Higgins <derekh at redhat.com>
+Date: Wed, 9 May 2012 15:55:46 +0100
+Subject: [PATCH] Invalidate user tokens when password is changed
+
+Fixes bug 996595
+
+This commit will cause all valid tokens to be deleted for a user
+who's password is changed (implemented for the sql and kvs backends)
+
+Change-Id: I6ad7da8957b7041983a3fc91d9ba9368667d06ac
+---
+ keystone/identity/core.py      |   14 +++++++++++++-
+ keystone/token/backends/kvs.py |   15 +++++++++++++++
+ keystone/token/backends/sql.py |   14 ++++++++++++++
+ keystone/token/core.py         |   10 ++++++++++
+ tests/test_keystoneclient.py   |   23 +++++++++++++++++++++++
+ 5 files changed, 75 insertions(+), 1 deletions(-)
+
+diff --git a/keystone/identity/core.py b/keystone/identity/core.py
+index ee22526..5efd142 100644
+--- a/keystone/identity/core.py
++++ b/keystone/identity/core.py
+@@ -24,12 +24,15 @@ from keystone import config
+ from keystone import exception
+ from keystone import policy
+ from keystone import token
++from keystone.common import logging
+ from keystone.common import manager
+ from keystone.common import wsgi
+ 
+ 
+ CONF = config.CONF
+ 
++LOG = logging.getLogger(__name__)
++
+ 
+ class Manager(manager.Manager):
+     """Default pivot point for the Identity backend.
+@@ -418,7 +421,16 @@ class UserController(wsgi.Application):
+         return self.update_user(context, user_id, user)
+ 
+     def set_user_password(self, context, user_id, user):
+-        return self.update_user(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
+ 
+     def update_user_tenant(self, context, user_id, user):
+         """Update the default tenant."""
+diff --git a/keystone/token/backends/kvs.py b/keystone/token/backends/kvs.py
+index 71b86f8..b033dd3 100644
+--- a/keystone/token/backends/kvs.py
++++ b/keystone/token/backends/kvs.py
+@@ -44,3 +44,18 @@ class Token(kvs.Base, token.Driver):
+             return self.db.delete('token-%s' % token_id)
+         except KeyError:
+             raise exception.TokenNotFound(token_id=token_id)
++
++    def list_tokens(self, user_id):
++        tokens = []
++        now = datetime.datetime.utcnow()
++        for token, user_ref in self.db.items():
++            if not token.startswith('token-'):
++                continue
++            if 'user' not in user_ref:
++                continue
++            if user_ref['user'].get('id') != user_id:
++                continue
++            if user_ref.get('expires') and user_ref.get('expires') < now:
++                continue
++            tokens.append(token.split('-', 1)[1])
++        return tokens
+diff --git a/keystone/token/backends/sql.py b/keystone/token/backends/sql.py
+index 7a9a551..543f962 100644
+--- a/keystone/token/backends/sql.py
++++ b/keystone/token/backends/sql.py
+@@ -81,3 +81,17 @@ class Token(sql.Base, token.Driver):
+         with session.begin():
+             session.delete(token_ref)
+             session.flush()
++
++    def list_tokens(self, user_id):
++        session = self.get_session()
++        tokens = []
++        now = datetime.datetime.utcnow()
++        for token_ref in session.query(TokenModel)\
++                                      .filter(TokenModel.expires > now):
++            token_ref_dict = token_ref.to_dict()
++            if 'user' not in token_ref_dict:
++                continue
++            if token_ref_dict['user'].get('id') != user_id:
++                continue
++            tokens.append(token_ref['id'])
++        return tokens
+diff --git a/keystone/token/core.py b/keystone/token/core.py
+index 0a28e38..0d1101d 100644
+--- a/keystone/token/core.py
++++ b/keystone/token/core.py
+@@ -87,6 +87,16 @@ class Driver(object):
+         """
+         raise exception.NotImplemented()
+ 
++    def list_tokens(self, user_id):
++        """Returns a list of current token_id's for a user
++
++        :param user_id: identity of the user
++        :type user_id: string
++        :returns: list of token_id's
++
++        """
++        raise exception.NotImplemented()
++
+     def _get_default_expire_time(self):
+         """Determine when a token should expire based on the config.
+ 
+diff --git a/tests/test_keystoneclient.py b/tests/test_keystoneclient.py
+index 810d233..8d4f002 100644
+--- a/tests/test_keystoneclient.py
++++ b/tests/test_keystoneclient.py
+@@ -286,6 +286,29 @@ class KeystoneClientTests(object):
+                           username='blah',
+                           password='blah')
+ 
++    def test_change_password_invalidates_token(self):
++        from keystoneclient import exceptions as client_exceptions
++
++        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)
++
++        token_id = client.tokens.authenticate(username=username,
++                                              password=passwd).id
++
++        # authenticate with a token should work before a password change
++        client.tokens.authenticate(token=token_id)
++
++        client.users.update_password(user=user.id, password=uuid.uuid4().hex)
++
++        # authenticate with a token should not work after a password change
++        self.assertRaises(client_exceptions.Unauthorized,
++                          client.tokens.authenticate,
++                          token=token_id)
++
+     def test_user_create_update_delete(self):
+         from keystoneclient import exceptions as client_exceptions
+ 
diff --git a/0005-Invalidate-user-tokens-when-a-user-is-disabled.patch b/0005-Invalidate-user-tokens-when-a-user-is-disabled.patch
new file mode 100644
index 0000000..da6d879
--- /dev/null
+++ b/0005-Invalidate-user-tokens-when-a-user-is-disabled.patch
@@ -0,0 +1,148 @@
+From 516ed98324954d925b81d0ea0f21194dd7a85262 Mon Sep 17 00:00:00 2001
+From: Derek Higgins <derekh at redhat.com>
+Date: Fri, 11 May 2012 13:42:43 +0100
+Subject: [PATCH] Invalidate user tokens when a user is disabled
+
+Fixes Bug 997194
+
+Delete valid tokens for a user when they have been disabled
+
+Moved logic to delete tokens into update_user, as this can be called
+directly form the REST API.
+
+Also checks if a user is enabled when creating a token from another
+token, this helps in cases there the backend didn't support listing of
+tokens (and as a result weren't deleted)
+
+Change-Id: Ib5ed73a7873bfa66ef31bf6d0f0322f50e677688
+---
+ keystone/identity/core.py    |   22 ++++++++++++----------
+ keystone/service.py          |   14 +++++++++++++-
+ tests/test_keystoneclient.py |   21 +++++++++++++++++++--
+ 3 files changed, 44 insertions(+), 13 deletions(-)
+
+diff --git a/keystone/identity/core.py b/keystone/identity/core.py
+index 5efd142..83b1798 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 1cb455d..2b024f4 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 8d4f002..1e0be60 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')
diff --git a/0006-Carrying-over-token-expiry-time-when-token-chaining.patch b/0006-Carrying-over-token-expiry-time-when-token-chaining.patch
new file mode 100644
index 0000000..df890ea
--- /dev/null
+++ b/0006-Carrying-over-token-expiry-time-when-token-chaining.patch
@@ -0,0 +1,60 @@
+From fb7bc0e9c86a5c1b9d68232eeffca54b39f7a9d4 Mon Sep 17 00:00:00 2001
+From: Derek Higgins <derekh at redhat.com>
+Date: Tue, 5 Jun 2012 09:33:53 +0100
+Subject: [PATCH] Carrying over token expiry time when token chaining
+
+Fixes bug #998185
+
+This commit causes the token expiry time to be maintained when
+one token is being created from another
+
+Change-Id: I7b61692a60d9227423b93c267864a5abe939ca33
+---
+ keystone/service.py          |    3 ++-
+ tests/test_keystoneclient.py |   12 ++++++++++++
+ 2 files changed, 14 insertions(+), 1 deletions(-)
+
+diff --git a/keystone/service.py b/keystone/service.py
+index 2b024f4..ebdea50 100644
+--- a/keystone/service.py
++++ b/keystone/service.py
+@@ -351,7 +351,8 @@ class TokenController(wsgi.Application):
+                     context, token_id, dict(id=token_id,
+                                             user=user_ref,
+                                             tenant=tenant_ref,
+-                                            metadata=metadata_ref))
++                                            metadata=metadata_ref,
++                                            expires=old_token_ref['expires']))
+ 
+         # TODO(termie): optimize this call at some point and put it into the
+         #               the return for metadata
+diff --git a/tests/test_keystoneclient.py b/tests/test_keystoneclient.py
+index 1e0be60..5705024 100644
+--- a/tests/test_keystoneclient.py
++++ b/tests/test_keystoneclient.py
+@@ -14,6 +14,7 @@
+ # License for the specific language governing permissions and limitations
+ # under the License.
+ 
++import time
+ import uuid
+ 
+ import nose.exc
+@@ -326,6 +327,17 @@ class KeystoneClientTests(object):
+                           self.get_client,
+                           self.user_foo)
+ 
++    def test_token_expiry_maintained(self):
++        foo_client = self.get_client(self.user_foo)
++        orig_token = foo_client.service_catalog.catalog['token']
++
++        time.sleep(1.01)
++        reauthenticated_token = foo_client.tokens.authenticate(
++                                    token=foo_client.auth_token)
++
++        self.assertEquals(orig_token['expires'],
++                          reauthenticated_token.expires)
++
+     def test_user_create_update_delete(self):
+         from keystoneclient import exceptions as client_exceptions
+ 
diff --git a/openstack-keystone.spec b/openstack-keystone.spec
index c148006..c1bd42b 100644
--- a/openstack-keystone.spec
+++ b/openstack-keystone.spec
@@ -11,7 +11,7 @@
 
 Name:           openstack-keystone
 Version:        2012.1
-Release:        3%{?dist}
+Release:        4%{?dist}
 #Release:       0.1.%{release_letter}%{milestone}%{?dist}
 Summary:        OpenStack Identity Service
 
@@ -28,6 +28,11 @@ Source5:        openstack-keystone-sample-data
 # patches_base=2012.1
 #
 Patch0001: 0001-Make-import_nova_auth-only-create-roles-which-don-t-.patch
+Patch0002: 0002-Fix-test-env-for-the-stable-branch.patch
+Patch0003: 0003-Corrects-url-conversion-in-export_legacy_catalog.patch
+Patch0004: 0004-Invalidate-user-tokens-when-password-is-changed.patch
+Patch0005: 0005-Invalidate-user-tokens-when-a-user-is-disabled.patch
+Patch0006: 0006-Carrying-over-token-expiry-time-when-token-chaining.patch
 
 BuildArch:      noarch
 BuildRequires:  python2-devel
@@ -97,6 +102,11 @@ This package contains the Keystone Authentication Middleware.
 %setup -q -n keystone-%{version}
 
 %patch0001 -p1
+%patch0002 -p1
+%patch0003 -p1
+%patch0004 -p1
+%patch0005 -p1
+%patch0006 -p1
 
 find . \( -name .gitignore -o -name .placeholder \) -delete
 find keystone -name \*.py -exec sed -i '/\/usr\/bin\/env python/d' {} \;
@@ -206,6 +216,12 @@ fi
 %{python_sitelib}/keystone/middleware/auth_token.py*
 
 %changelog
+* Mon Jun 11 2012 Alan Pevec <apevec at redhat.com> 2012.1-4
+- Corrects url conversion in export_legacy_catalog (lp#994936)
+- Invalidate user tokens when password is changed (lp#996595)
+- Invalidate user tokens when a user is disabled (lp#997194)
+- Carrying over token expiry time when token chaining (lp#998185)
+
 * Thu May 24 2012 Alan Pevec <apevec at redhat.com> 2012.1-3
 - python-keystone-auth-token subpackage (rhbz#824034)
 - use reserved user id for keystone (rhbz#752842)


More information about the scm-commits mailing list