From d8efecb588fad1d3bf9af13b9994d1def4792213 Mon Sep 17 00:00:00 2001 From: Craig Citro Date: Tue, 24 Jun 2014 23:48:11 -0700 Subject: [PATCH] Allow kwargs in `OAuth2DecoratorFromClientSecrets`. This just extends `OAuth2Decorator`'s support for mapping additional kwargs to the subclass `OAuth2DecoratorFromClientSecrets`, and adds a test. --- oauth2client/appengine.py | 16 ++++++++++------ tests/test_appengine.py | 22 +++++++++++++++------- 2 files changed, 25 insertions(+), 13 deletions(-) diff --git a/oauth2client/appengine.py b/oauth2client/appengine.py index e90a4c6..7c7feab 100644 --- a/oauth2client/appengine.py +++ b/oauth2client/appengine.py @@ -665,8 +665,9 @@ class OAuth2Decorator(object): provided to this constructor. A string indicating the name of the field on the _credentials_class where a Credentials object will be stored. Defaults to 'credentials'. - **kwargs: dict, Keyword arguments are be passed along as kwargs to the - OAuth2WebServerFlow constructor. + **kwargs: dict, Keyword arguments are passed along as kwargs to + the OAuth2WebServerFlow constructor. + """ self._tls = threading.local() self.flow = None @@ -923,7 +924,7 @@ class OAuth2DecoratorFromClientSecrets(OAuth2Decorator): """ @util.positional(3) - def __init__(self, filename, scope, message=None, cache=None): + def __init__(self, filename, scope, message=None, cache=None, **kwargs): """Constructor Args: @@ -936,17 +937,20 @@ class OAuth2DecoratorFromClientSecrets(OAuth2Decorator): decorator. cache: An optional cache service client that implements get() and set() methods. See clientsecrets.loadfile() for details. + **kwargs: dict, Keyword arguments are passed along as kwargs to + the OAuth2WebServerFlow constructor. """ client_type, client_info = clientsecrets.loadfile(filename, cache=cache) if client_type not in [ clientsecrets.TYPE_WEB, clientsecrets.TYPE_INSTALLED]: raise InvalidClientSecretsError( - 'OAuth2Decorator doesn\'t support this OAuth 2.0 flow.') - constructor_kwargs = { + "OAuth2Decorator doesn't support this OAuth 2.0 flow.") + constructor_kwargs = dict(kwargs) + constructor_kwargs.update({ 'auth_uri': client_info['auth_uri'], 'token_uri': client_info['token_uri'], 'message': message, - } + }) revoke_uri = client_info.get('revoke_uri') if revoke_uri is not None: constructor_kwargs['revoke_uri'] = revoke_uri diff --git a/tests/test_appengine.py b/tests/test_appengine.py index 2bea272..0cb37b8 100644 --- a/tests/test_appengine.py +++ b/tests/test_appengine.py @@ -62,8 +62,8 @@ from oauth2client.appengine import CredentialsNDBModel from oauth2client.appengine import FlowNDBProperty from oauth2client.appengine import FlowProperty from oauth2client.appengine import OAuth2Decorator +from oauth2client.appengine import OAuth2DecoratorFromClientSecrets from oauth2client.appengine import StorageByKeyName -from oauth2client.appengine import oauth2decorator_from_clientsecrets from oauth2client.client import AccessTokenRefreshError from oauth2client.client import Credentials from oauth2client.client import FlowExchangeError @@ -748,7 +748,7 @@ class DecoratorTests(unittest.TestCase): self.test_required() def test_decorator_from_client_secrets(self): - decorator = oauth2decorator_from_clientsecrets( + decorator = OAuth2DecoratorFromClientSecrets( datafile('client_secrets.json'), scope=['foo_scope', 'bar_scope']) self._finish_setup(decorator, user_mock=UserMock) @@ -765,16 +765,24 @@ class DecoratorTests(unittest.TestCase): self.assertEqual(self.decorator._revoke_uri, self.decorator.credentials.revoke_uri) + def test_decorator_from_client_secrets_kwargs(self): + decorator = OAuth2DecoratorFromClientSecrets( + datafile('client_secrets.json'), + scope=['foo_scope', 'bar_scope'], + approval_prompt='force') + self.assertTrue('approval_prompt' in decorator._kwargs) + + def test_decorator_from_cached_client_secrets(self): cache_mock = CacheMock() load_and_cache('client_secrets.json', 'secret', cache_mock) - decorator = oauth2decorator_from_clientsecrets( + decorator = OAuth2DecoratorFromClientSecrets( # filename, scope, message=None, cache=None 'secret', '', cache=cache_mock) self.assertFalse(decorator._in_error) def test_decorator_from_client_secrets_not_logged_in_required(self): - decorator = oauth2decorator_from_clientsecrets( + decorator = OAuth2DecoratorFromClientSecrets( datafile('client_secrets.json'), scope=['foo_scope', 'bar_scope'], message='NotLoggedInMessage') self.decorator = decorator @@ -789,7 +797,7 @@ class DecoratorTests(unittest.TestCase): self.assertTrue('Login' in str(response)) def test_decorator_from_client_secrets_not_logged_in_aware(self): - decorator = oauth2decorator_from_clientsecrets( + decorator = OAuth2DecoratorFromClientSecrets( datafile('client_secrets.json'), scope=['foo_scope', 'bar_scope'], message='NotLoggedInMessage') self.decorator = decorator @@ -804,7 +812,7 @@ class DecoratorTests(unittest.TestCase): def test_decorator_from_unfilled_client_secrets_required(self): MESSAGE = 'File is missing' try: - decorator = oauth2decorator_from_clientsecrets( + decorator = OAuth2DecoratorFromClientSecrets( datafile('unfilled_client_secrets.json'), scope=['foo_scope', 'bar_scope'], message=MESSAGE) except InvalidClientSecretsError: @@ -813,7 +821,7 @@ class DecoratorTests(unittest.TestCase): def test_decorator_from_unfilled_client_secrets_aware(self): MESSAGE = 'File is missing' try: - decorator = oauth2decorator_from_clientsecrets( + decorator = OAuth2DecoratorFromClientSecrets( datafile('unfilled_client_secrets.json'), scope=['foo_scope', 'bar_scope'], message=MESSAGE) except InvalidClientSecretsError: