Merge "Fix PostgreSQL specifc issue with credentials encoding"

This commit is contained in:
Zuul 2019-09-20 01:50:15 +00:00 committed by Gerrit Code Review
commit 0ac5a43ad1
3 changed files with 39 additions and 1 deletions

View File

@ -13,6 +13,8 @@
# under the License.
from oslo_db import api as oslo_db_api
import six
from sqlalchemy.ext.hybrid import hybrid_property
from keystone.common import driver_hints
from keystone.common import sql
@ -29,11 +31,24 @@ class CredentialModel(sql.ModelBase, sql.ModelDictMixinWithExtras):
user_id = sql.Column(sql.String(64),
nullable=False)
project_id = sql.Column(sql.String(64))
encrypted_blob = sql.Column(sql.Text(), nullable=True)
_encrypted_blob = sql.Column('encrypted_blob', sql.Text(), nullable=True)
type = sql.Column(sql.String(255), nullable=False)
key_hash = sql.Column(sql.String(64), nullable=True)
extra = sql.Column(sql.JsonBlob())
@hybrid_property
def encrypted_blob(self):
return self._encrypted_blob
@encrypted_blob.setter
def encrypted_blob(self, encrypted_blob):
# Make sure to hand over the encrypted credential as a string value
# to the backend driver to avoid the sql drivers (esp. psycopg2)
# treating this as binary data and e.g. hex-escape it.
if six.PY3 and isinstance(encrypted_blob, six.binary_type):
encrypted_blob = encrypted_blob.decode('utf-8')
self._encrypted_blob = encrypted_blob
class Credential(base.CredentialDriverBase):

View File

@ -21,6 +21,8 @@ from keystone.tests.unit import default_fixtures
from keystone.tests.unit import ksfixtures
from keystone.tests.unit.ksfixtures import database
from keystone.credential.backends import sql as credential_sql
PROVIDERS = provider_api.ProviderAPIs
@ -90,3 +92,15 @@ class SqlCredential(SqlTests):
def test_backend_credential_sql_no_hints(self):
credentials = PROVIDERS.credential_api.list_credentials()
self._validate_credential_list(credentials, self.user_credentials)
def test_backend_credential_sql_encrypted_string(self):
cred_dict = {
'id': uuid.uuid4().hex,
'type': uuid.uuid4().hex,
'hash': uuid.uuid4().hex,
'encrypted_blob': b'randomdata'
}
ref = credential_sql.CredentialModel.from_dict(cred_dict)
# Make sure CredentialModel is handing over a text string
# to the database. To avoid encoding issues
self.assertIsInstance(ref.encrypted_blob, str)

View File

@ -0,0 +1,9 @@
---
fixes:
- |
[`bug 1833739 <https://bugs.launchpad.net/keystone/+bug/1833739>`_]
Fix PostgreSQL specifc issue with storing encrypted credentials. In
Python 3 the psycopg2 module treats bytes strings as binary data. This
causes issues when storing encrypted credentials in the Database.
To fix this isseu the credentials sql backend is updated to encode the
credential into a text string before handing it over to the database.