diff --git a/gcloud/bigquery/__init__.py b/gcloud/bigquery/__init__.py index 30207de37489..cca30b80e91f 100644 --- a/gcloud/bigquery/__init__.py +++ b/gcloud/bigquery/__init__.py @@ -22,7 +22,10 @@ """ from gcloud.bigquery.client import Client -from gcloud.bigquery.connection import SCOPE +from gcloud.bigquery.connection import Connection from gcloud.bigquery.dataset import Dataset from gcloud.bigquery.table import SchemaField from gcloud.bigquery.table import Table + + +SCOPE = Connection.SCOPE diff --git a/gcloud/bigquery/connection.py b/gcloud/bigquery/connection.py index b88c711cf848..e0ffe70f2139 100644 --- a/gcloud/bigquery/connection.py +++ b/gcloud/bigquery/connection.py @@ -17,11 +17,6 @@ from gcloud import connection as base_connection -SCOPE = ('https://www.googleapis.com/auth/bigquery', - 'https://www.googleapis.com/auth/cloud-platform') -"""The scopes required for authenticating as a Cloud BigQuery consumer.""" - - class Connection(base_connection.JSONConnection): """A connection to Google Cloud Pubsub via the JSON REST API.""" @@ -34,6 +29,6 @@ class Connection(base_connection.JSONConnection): API_URL_TEMPLATE = '{api_base_url}/bigquery/{api_version}{path}' """A template for the URL of a particular API call.""" - def __init__(self, credentials=None, http=None): - credentials = self._create_scoped_credentials(credentials, SCOPE) - super(Connection, self).__init__(credentials=credentials, http=http) + SCOPE = ('https://www.googleapis.com/auth/bigquery', + 'https://www.googleapis.com/auth/cloud-platform') + """The scopes required for authenticating as a Cloud BigQuery consumer.""" diff --git a/gcloud/connection.py b/gcloud/connection.py index b63c35660a43..80dcb92fadea 100644 --- a/gcloud/connection.py +++ b/gcloud/connection.py @@ -69,9 +69,16 @@ class Connection(object): USER_AGENT = "gcloud-python/{0}".format(get_distribution('gcloud').version) """The user agent for gcloud-python requests.""" + SCOPE = None + """The scopes required for authenticating with a service. + + Needs to be set by subclasses. + """ + def __init__(self, credentials=None, http=None): self._http = http - self._credentials = credentials + self._credentials = self._create_scoped_credentials( + credentials, self.SCOPE) @property def credentials(self): diff --git a/gcloud/datastore/__init__.py b/gcloud/datastore/__init__.py index c9cb11020b07..313fb6902ec3 100644 --- a/gcloud/datastore/__init__.py +++ b/gcloud/datastore/__init__.py @@ -51,10 +51,12 @@ """ from gcloud.datastore.batch import Batch -from gcloud.datastore.connection import SCOPE from gcloud.datastore.connection import Connection from gcloud.datastore.client import Client from gcloud.datastore.entity import Entity from gcloud.datastore.key import Key from gcloud.datastore.query import Query from gcloud.datastore.transaction import Transaction + + +SCOPE = Connection.SCOPE diff --git a/gcloud/datastore/connection.py b/gcloud/datastore/connection.py index e3108a017764..95f78f4ca168 100644 --- a/gcloud/datastore/connection.py +++ b/gcloud/datastore/connection.py @@ -22,11 +22,6 @@ from gcloud.datastore import _datastore_v1_pb2 as datastore_pb -SCOPE = ('https://www.googleapis.com/auth/datastore', - 'https://www.googleapis.com/auth/userinfo.email') -"""The scopes required for authenticating as a Cloud Datastore consumer.""" - - class Connection(connection.Connection): """A connection to the Google Cloud Datastore via the Protobuf API. @@ -51,8 +46,11 @@ class Connection(connection.Connection): '/datasets/{dataset_id}/{method}') """A template for the URL of a particular API call.""" + SCOPE = ('https://www.googleapis.com/auth/datastore', + 'https://www.googleapis.com/auth/userinfo.email') + """The scopes required for authenticating as a Cloud Datastore consumer.""" + def __init__(self, credentials=None, http=None, api_base_url=None): - credentials = self._create_scoped_credentials(credentials, SCOPE) super(Connection, self).__init__(credentials=credentials, http=http) if api_base_url is None: api_base_url = os.getenv(GCD_HOST, diff --git a/gcloud/pubsub/__init__.py b/gcloud/pubsub/__init__.py index c39eb343ee6c..b9439548a705 100644 --- a/gcloud/pubsub/__init__.py +++ b/gcloud/pubsub/__init__.py @@ -24,6 +24,9 @@ """ from gcloud.pubsub.client import Client -from gcloud.pubsub.connection import SCOPE +from gcloud.pubsub.connection import Connection from gcloud.pubsub.subscription import Subscription from gcloud.pubsub.topic import Topic + + +SCOPE = Connection.SCOPE diff --git a/gcloud/pubsub/connection.py b/gcloud/pubsub/connection.py index 1411d603270e..367b524b62e9 100644 --- a/gcloud/pubsub/connection.py +++ b/gcloud/pubsub/connection.py @@ -17,13 +17,16 @@ from gcloud import connection as base_connection -SCOPE = ('https://www.googleapis.com/auth/pubsub', - 'https://www.googleapis.com/auth/cloud-platform') -"""The scopes required for authenticating as a Cloud Pub/Sub consumer.""" +class Connection(base_connection.JSONConnection): + """A connection to Google Cloud Pubsub via the JSON REST API. + :type credentials: :class:`oauth2client.client.OAuth2Credentials` + :param credentials: (Optional) The OAuth2 Credentials to use for this + connection. -class Connection(base_connection.JSONConnection): - """A connection to Google Cloud Pubsub via the JSON REST API.""" + :type http: :class:`httplib2.Http` or class that defines ``request()``. + :param http: (Optional) HTTP object to make requests. + """ API_BASE_URL = 'https://pubsub.googleapis.com' """The base of the API call URL.""" @@ -34,6 +37,6 @@ class Connection(base_connection.JSONConnection): API_URL_TEMPLATE = '{api_base_url}/{api_version}{path}' """A template for the URL of a particular API call.""" - def __init__(self, credentials=None, http=None): - credentials = self._create_scoped_credentials(credentials, SCOPE) - super(Connection, self).__init__(credentials=credentials, http=http) + SCOPE = ('https://www.googleapis.com/auth/pubsub', + 'https://www.googleapis.com/auth/cloud-platform') + """The scopes required for authenticating as a Cloud Pub/Sub consumer.""" diff --git a/gcloud/resource_manager/__init__.py b/gcloud/resource_manager/__init__.py index c86c983b7a25..25089c3854c4 100644 --- a/gcloud/resource_manager/__init__.py +++ b/gcloud/resource_manager/__init__.py @@ -15,5 +15,8 @@ """Google Cloud Resource Manager API wrapper.""" from gcloud.resource_manager.client import Client -from gcloud.resource_manager.connection import SCOPE +from gcloud.resource_manager.connection import Connection from gcloud.resource_manager.project import Project + + +SCOPE = Connection.SCOPE diff --git a/gcloud/resource_manager/connection.py b/gcloud/resource_manager/connection.py index 5f60b2768cba..1e8305fc3641 100644 --- a/gcloud/resource_manager/connection.py +++ b/gcloud/resource_manager/connection.py @@ -20,12 +20,16 @@ from gcloud import connection as base_connection -SCOPE = ('https://www.googleapis.com/auth/cloud-platform',) -"""The scopes required for authenticating as a Resouce Manager consumer.""" +class Connection(base_connection.JSONConnection): + """A connection to Google Cloud Resource Manager via the JSON REST API. + :type credentials: :class:`oauth2client.client.OAuth2Credentials` + :param credentials: (Optional) The OAuth2 Credentials to use for this + connection. -class Connection(base_connection.JSONConnection): - """A connection to Google Cloud Resource Manager via the JSON REST API.""" + :type http: :class:`httplib2.Http` or class that defines ``request()``. + :param http: (Optional) HTTP object to make requests. + """ API_BASE_URL = 'https://cloudresourcemanager.googleapis.com' """The base of the API call URL.""" @@ -36,6 +40,9 @@ class Connection(base_connection.JSONConnection): API_URL_TEMPLATE = '{api_base_url}/{api_version}{path}' """A template for the URL of a particular API call.""" + SCOPE = ('https://www.googleapis.com/auth/cloud-platform',) + """The scopes required for authenticating as a Resouce Manager consumer.""" + def __init__(self, credentials=None, http=None): if isinstance(credentials, AssertionCredentials): message = ('credentials (%r) inherits from ' @@ -43,5 +50,4 @@ def __init__(self, credentials=None, http=None): 'used with the Resource Manager API. ' % (credentials,)) raise TypeError(message) - credentials = self._create_scoped_credentials(credentials, SCOPE) super(Connection, self).__init__(credentials=credentials, http=http) diff --git a/gcloud/storage/__init__.py b/gcloud/storage/__init__.py index 1910329d25ec..8847798d25e3 100644 --- a/gcloud/storage/__init__.py +++ b/gcloud/storage/__init__.py @@ -43,5 +43,7 @@ from gcloud.storage.blob import Blob from gcloud.storage.bucket import Bucket from gcloud.storage.client import Client -from gcloud.storage.connection import SCOPE from gcloud.storage.connection import Connection + + +SCOPE = Connection.SCOPE diff --git a/gcloud/storage/connection.py b/gcloud/storage/connection.py index 2740a47063db..7aec23b3844d 100644 --- a/gcloud/storage/connection.py +++ b/gcloud/storage/connection.py @@ -17,14 +17,16 @@ from gcloud import connection as base_connection -SCOPE = ('https://www.googleapis.com/auth/devstorage.full_control', - 'https://www.googleapis.com/auth/devstorage.read_only', - 'https://www.googleapis.com/auth/devstorage.read_write') -"""The scopes required for authenticating as a Cloud Storage consumer.""" +class Connection(base_connection.JSONConnection): + """A connection to Google Cloud Storage via the JSON REST API. + :type credentials: :class:`oauth2client.client.OAuth2Credentials` + :param credentials: (Optional) The OAuth2 Credentials to use for this + connection. -class Connection(base_connection.JSONConnection): - """A connection to Google Cloud Storage via the JSON REST API.""" + :type http: :class:`httplib2.Http` or class that defines ``request()``. + :param http: (Optional) HTTP object to make requests. + """ API_BASE_URL = base_connection.API_BASE_URL """The base of the API call URL.""" @@ -35,6 +37,7 @@ class Connection(base_connection.JSONConnection): API_URL_TEMPLATE = '{api_base_url}/storage/{api_version}{path}' """A template for the URL of a particular API call.""" - def __init__(self, credentials=None, http=None): - credentials = self._create_scoped_credentials(credentials, SCOPE) - super(Connection, self).__init__(credentials=credentials, http=http) + SCOPE = ('https://www.googleapis.com/auth/devstorage.full_control', + 'https://www.googleapis.com/auth/devstorage.read_only', + 'https://www.googleapis.com/auth/devstorage.read_write') + """The scopes required for authenticating as a Cloud Storage consumer.""" diff --git a/gcloud/test_connection.py b/gcloud/test_connection.py index 159f404b6746..d5cbcaa768bc 100644 --- a/gcloud/test_connection.py +++ b/gcloud/test_connection.py @@ -29,9 +29,9 @@ def test_ctor_defaults(self): self.assertEqual(conn.credentials, None) def test_ctor_explicit(self): - creds = object() - conn = self._makeOne(creds) - self.assertTrue(conn.credentials is creds) + credentials = _Credentials() + conn = self._makeOne(credentials) + self.assertTrue(conn.credentials is credentials) self.assertEqual(conn._http, None) def test_ctor_explicit_http(self): @@ -54,15 +54,10 @@ def test_http_w_creds(self): import httplib2 authorized = object() - - class Creds(object): - def authorize(self, http): - self._called_with = http - return authorized - creds = Creds() - conn = self._makeOne(creds) + credentials = _Credentials(authorized) + conn = self._makeOne(credentials) self.assertTrue(conn.http is authorized) - self.assertTrue(isinstance(creds._called_with, httplib2.Http)) + self.assertTrue(isinstance(credentials._called_with, httplib2.Http)) def test_user_agent_format(self): from pkg_resources import get_distribution @@ -76,18 +71,18 @@ def _from_service_account_json_helper(self, **kwargs): from gcloud import connection KLASS = self._getTargetClass() - CREDS = object() + CREDENTIALS = _Credentials() _CALLED = [] def mock_creds(arg1): _CALLED.append((arg1,)) - return CREDS + return CREDENTIALS FOO = object() with _Monkey(connection, get_for_service_account_json=mock_creds): conn = KLASS.from_service_account_json(FOO, **kwargs) - self.assertTrue(conn.credentials is CREDS) + self.assertTrue(conn.credentials is CREDENTIALS) self.assertEqual(_CALLED, [(FOO,)]) def test_from_service_account_json(self): @@ -102,19 +97,19 @@ def _from_service_account_p12_helper(self, **kwargs): from gcloud import connection KLASS = self._getTargetClass() - CREDS = object() + CREDENTIALS = _Credentials() _CALLED = [] def mock_creds(arg1, arg2): _CALLED.append((arg1, arg2)) - return CREDS + return CREDENTIALS FOO = object() BAR = object() with _Monkey(connection, get_for_service_account_p12=mock_creds): conn = KLASS.from_service_account_p12(FOO, BAR, **kwargs) - self.assertTrue(conn.credentials is CREDS) + self.assertTrue(conn.credentials is CREDENTIALS) self.assertEqual(_CALLED, [(FOO, BAR)]) def test_from_service_account_p12(self): @@ -129,15 +124,15 @@ def _from_environment_helper(self, **kwargs): from gcloud import connection KLASS = self._getTargetClass() - CREDS = object() + CREDENTIALS = _Credentials() def mock_creds(): - return CREDS + return CREDENTIALS with _Monkey(connection, get_credentials=mock_creds): conn = KLASS.from_environment(**kwargs) - self.assertTrue(conn.credentials is CREDS) + self.assertTrue(conn.credentials is CREDENTIALS) def test_from_environment(self): self._from_environment_helper() @@ -174,9 +169,9 @@ def test_ctor_defaults(self): self.assertEqual(conn.credentials, None) def test_ctor_explicit(self): - creds = object() - conn = self._makeOne(creds) - self.assertTrue(conn.credentials is creds) + credentials = _Credentials() + conn = self._makeOne(credentials) + self.assertTrue(conn.credentials is credentials) def test_http_w_existing(self): conn = self._makeOne() @@ -190,16 +185,12 @@ def test_http_wo_creds(self): def test_http_w_creds(self): import httplib2 - authorized = object() - class Creds(object): - def authorize(self, http): - self._called_with = http - return authorized - creds = Creds() - conn = self._makeOne(creds) + authorized = object() + credentials = _Credentials(authorized) + conn = self._makeOne(credentials) self.assertTrue(conn.http is authorized) - self.assertTrue(isinstance(creds._called_with, httplib2.Http)) + self.assertTrue(isinstance(credentials._called_with, httplib2.Http)) def test_build_api_url_no_extra_query_params(self): conn = self._makeMockOne() @@ -447,3 +438,19 @@ def __init__(self, headers, content): def request(self, **kw): self._called_with = kw return self._response, self._content + + +class _Credentials(object): + + _scopes = None + + def __init__(self, authorized=None): + self._authorized = authorized + + def authorize(self, http): + self._called_with = http + return self._authorized + + @staticmethod + def create_scoped_required(): + return False