Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion gcloud/bigquery/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
11 changes: 3 additions & 8 deletions gcloud/bigquery/connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -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."""

Expand All @@ -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."""
9 changes: 8 additions & 1 deletion gcloud/connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand Down
4 changes: 3 additions & 1 deletion gcloud/datastore/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
10 changes: 4 additions & 6 deletions gcloud/datastore/connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand All @@ -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,
Expand Down
5 changes: 4 additions & 1 deletion gcloud/pubsub/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
19 changes: 11 additions & 8 deletions gcloud/pubsub/connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -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."""
Expand All @@ -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."""
5 changes: 4 additions & 1 deletion gcloud/resource_manager/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
16 changes: 11 additions & 5 deletions gcloud/resource_manager/connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -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."""
Expand All @@ -36,12 +40,14 @@ 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 '
'AppAssertionCredentials. Only user credentials can be '
'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)
4 changes: 3 additions & 1 deletion gcloud/storage/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
21 changes: 12 additions & 9 deletions gcloud/storage/connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -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."""
Expand All @@ -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."""
69 changes: 38 additions & 31 deletions gcloud/test_connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand All @@ -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
Expand All @@ -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):
Expand All @@ -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):
Expand All @@ -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()
Expand Down Expand Up @@ -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()
Expand All @@ -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()
Expand Down Expand Up @@ -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