diff --git a/keystone/contrib/oauth1/backends/sql.py b/keystone/contrib/oauth1/backends/sql.py index 3e6a98698e..bc2b3d0020 100644 --- a/keystone/contrib/oauth1/backends/sql.py +++ b/keystone/contrib/oauth1/backends/sql.py @@ -204,7 +204,8 @@ class OAuth1(object): token_ref = self._get_request_token(session, request_token_id) token_dict = token_ref.to_dict() token_dict['authorizing_user_id'] = user_id - token_dict['verifier'] = str(random.randint(1000, 9999)) + token_dict['verifier'] = ''.join(random.sample(core.VERIFIER_CHARS, + 8)) token_dict['role_ids'] = jsonutils.dumps(role_ids) new_token = RequestToken.from_dict(token_dict) diff --git a/keystone/contrib/oauth1/core.py b/keystone/contrib/oauth1/core.py index 41d681004f..c0a9764817 100644 --- a/keystone/contrib/oauth1/core.py +++ b/keystone/contrib/oauth1/core.py @@ -17,6 +17,7 @@ from __future__ import absolute_import import abc +import string import oauthlib.common from oauthlib import oauth1 @@ -39,6 +40,11 @@ AuthorizationEndpoint = oauth1.AuthorizationEndpoint SIG_HMAC = oauth1.SIGNATURE_HMAC RequestTokenEndpoint = oauth1.RequestTokenEndpoint oRequest = oauthlib.common.Request +# The characters used to generate verifiers are limited to alphanumerical +# values for ease of manual entry. Commonly confused characters are omitted. +VERIFIER_CHARS = string.ascii_letters + string.digits +CONFUSED_CHARS = 'jiIl1oO0' +VERIFIER_CHARS = ''.join(c for c in VERIFIER_CHARS if c not in CONFUSED_CHARS) class Token(object): diff --git a/keystone/contrib/oauth1/validator.py b/keystone/contrib/oauth1/validator.py index 78dc906489..c598516037 100644 --- a/keystone/contrib/oauth1/validator.py +++ b/keystone/contrib/oauth1/validator.py @@ -58,10 +58,8 @@ class OAuthValidator(oauth1.RequestValidator): return set(nonce) <= self.safe_characters def check_verifier(self, verifier): - try: - return 1000 <= int(verifier) <= 9999 - except ValueError: - return False + return (all(i in oauth1.VERIFIER_CHARS for i in verifier) and + len(verifier) == 8) def get_client_secret(self, client_key, request): client = self.oauth_api.get_consumer_with_secret(client_key) diff --git a/keystone/tests/test_v3_oauth1.py b/keystone/tests/test_v3_oauth1.py index 23d129647b..525b4b0e90 100644 --- a/keystone/tests/test_v3_oauth1.py +++ b/keystone/tests/test_v3_oauth1.py @@ -20,6 +20,7 @@ from six.moves import urllib from keystone import config from keystone.contrib import oauth1 from keystone.contrib.oauth1 import controllers +from keystone.contrib.oauth1 import core from keystone import exception from keystone.tests import test_v3 @@ -256,6 +257,8 @@ class OAuthFlowTests(OAuth1Tests): body = {'roles': [{'id': self.role_id}]} resp = self.put(url, body=body, expected_status=200) self.verifier = resp.result['token']['oauth_verifier'] + self.assertTrue(all(i in core.VERIFIER_CHARS for i in self.verifier)) + self.assertEqual(8, len(self.verifier)) self.request_token.set_verifier(self.verifier) url, headers = self._create_access_token(self.consumer,