summaryrefslogtreecommitdiffstats
path: root/keystone-moon/keystone/token
diff options
context:
space:
mode:
Diffstat (limited to 'keystone-moon/keystone/token')
-rw-r--r--keystone-moon/keystone/token/persistence/backends/kvs.py2
-rw-r--r--keystone-moon/keystone/token/persistence/backends/sql.py2
-rw-r--r--keystone-moon/keystone/token/persistence/core.py5
-rw-r--r--keystone-moon/keystone/token/providers/fernet/token_formatters.py36
4 files changed, 33 insertions, 12 deletions
diff --git a/keystone-moon/keystone/token/persistence/backends/kvs.py b/keystone-moon/keystone/token/persistence/backends/kvs.py
index 1bd08a31..51931586 100644
--- a/keystone-moon/keystone/token/persistence/backends/kvs.py
+++ b/keystone-moon/keystone/token/persistence/backends/kvs.py
@@ -33,7 +33,7 @@ CONF = cfg.CONF
LOG = log.getLogger(__name__)
-class Token(token.persistence.Driver):
+class Token(token.persistence.TokenDriverV8):
"""KeyValueStore backend for tokens.
This is the base implementation for any/all key-value-stores (e.g.
diff --git a/keystone-moon/keystone/token/persistence/backends/sql.py b/keystone-moon/keystone/token/persistence/backends/sql.py
index 08c3a216..6fc1d223 100644
--- a/keystone-moon/keystone/token/persistence/backends/sql.py
+++ b/keystone-moon/keystone/token/persistence/backends/sql.py
@@ -83,7 +83,7 @@ def _expiry_range_all(session, upper_bound_func):
yield upper_bound_func()
-class Token(token.persistence.Driver):
+class Token(token.persistence.TokenDriverV8):
# Public interface
def get_token(self, token_id):
if token_id is None:
diff --git a/keystone-moon/keystone/token/persistence/core.py b/keystone-moon/keystone/token/persistence/core.py
index 15a58085..e68970ac 100644
--- a/keystone-moon/keystone/token/persistence/core.py
+++ b/keystone-moon/keystone/token/persistence/core.py
@@ -230,7 +230,7 @@ class Manager(object):
@six.add_metaclass(abc.ABCMeta)
-class Driver(object):
+class TokenDriverV8(object):
"""Interface description for a Token driver."""
@abc.abstractmethod
@@ -357,3 +357,6 @@ class Driver(object):
"""Archive or delete tokens that have expired.
"""
raise exception.NotImplemented() # pragma: no cover
+
+
+Driver = manager.create_legacy_driver(TokenDriverV8)
diff --git a/keystone-moon/keystone/token/providers/fernet/token_formatters.py b/keystone-moon/keystone/token/providers/fernet/token_formatters.py
index d1dbb08c..f0b6271d 100644
--- a/keystone-moon/keystone/token/providers/fernet/token_formatters.py
+++ b/keystone-moon/keystone/token/providers/fernet/token_formatters.py
@@ -21,7 +21,7 @@ from oslo_config import cfg
from oslo_log import log
from oslo_utils import timeutils
import six
-from six.moves import map, urllib
+from six.moves import map
from keystone.auth import plugins as auth_plugins
from keystone.common import utils as ks_utils
@@ -67,11 +67,14 @@ class TokenFormatter(object):
def pack(self, payload):
"""Pack a payload for transport as a token."""
# base64 padding (if any) is not URL-safe
- return urllib.parse.quote(self.crypto.encrypt(payload))
+ return self.crypto.encrypt(payload).rstrip('=')
def unpack(self, token):
"""Unpack a token, and validate the payload."""
- token = urllib.parse.unquote(six.binary_type(token))
+ token = six.binary_type(token)
+
+ # Restore padding on token before decoding it
+ token = TokenFormatter.restore_padding(token)
try:
return self.crypto.decrypt(token)
@@ -80,16 +83,31 @@ class TokenFormatter(object):
_('This is not a recognized Fernet token'))
@classmethod
+ def restore_padding(cls, token):
+ """Restore padding based on token size.
+
+ :param token: token to restore padding on
+ :returns: token with correct padding
+
+ """
+ # Re-inflate the padding
+ mod_returned = len(token) % 4
+ if mod_returned:
+ missing_padding = 4 - mod_returned
+ token += b'=' * missing_padding
+ return token
+
+ @classmethod
def creation_time(cls, fernet_token):
"""Returns the creation time of a valid Fernet token."""
# tokens may be transmitted as Unicode, but they're just ASCII
# (pypi/cryptography will refuse to operate on Unicode input)
fernet_token = six.binary_type(fernet_token)
- # the base64 padding on fernet tokens is made URL-safe
- fernet_token = urllib.parse.unquote(fernet_token)
+ # Restore padding on token before decoding it
+ fernet_token = TokenFormatter.restore_padding(fernet_token)
- # fernet tokens are base64 encoded and the padding made URL-safe
+ # fernet tokens are base64 encoded, so we need to unpack them first
token_bytes = base64.urlsafe_b64decode(fernet_token)
# slice into the byte array to get just the timestamp
@@ -571,9 +589,9 @@ class FederatedUnscopedPayload(BasePayload):
"""Validate a federated payload.
:param token_string: a string representing the token
- :return: a tuple containing the user_id, auth methods, audit_ids, and
- a dictionary containing federated information such as the the
- group IDs, the identity provider ID, the protocol ID, and the
+ :return: a tuple containing the user_id, auth methods, audit_ids, and a
+ dictionary containing federated information such as the group
+ IDs, the identity provider ID, the protocol ID, and the
federated domain ID
"""