Index: third_party/gsutil/third_party/gcs-oauth2-boto-plugin/gcs_oauth2_boto_plugin/oauth2_helper.py |
diff --git a/third_party/gsutil/third_party/gcs-oauth2-boto-plugin/gcs_oauth2_boto_plugin/oauth2_helper.py b/third_party/gsutil/third_party/gcs-oauth2-boto-plugin/gcs_oauth2_boto_plugin/oauth2_helper.py |
new file mode 100644 |
index 0000000000000000000000000000000000000000..84ba62cd4438bf8d451e992aa8a7844b5598b1ca |
--- /dev/null |
+++ b/third_party/gsutil/third_party/gcs-oauth2-boto-plugin/gcs_oauth2_boto_plugin/oauth2_helper.py |
@@ -0,0 +1,198 @@ |
+# Copyright 2014 Google Inc. All Rights Reserved. |
+# |
+# Licensed under the Apache License, Version 2.0 (the "License"); |
+# you may not use this file except in compliance with the License. |
+# You may obtain a copy of the License at |
+# |
+# http://www.apache.org/licenses/LICENSE-2.0 |
+# |
+# Unless required by applicable law or agreed to in writing, software |
+# distributed under the License is distributed on an "AS IS" BASIS, |
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
+# See the License for the specific language governing permissions and |
+# limitations under the License. |
+ |
+"""Helper routines to facilitate use of oauth2_client.""" |
+ |
+from __future__ import absolute_import |
+ |
+import json |
+import os |
+import sys |
+import time |
+import webbrowser |
+ |
+from oauth2client.client import OAuth2WebServerFlow |
+ |
+from gcs_oauth2_boto_plugin import oauth2_client |
+ |
+CLIENT_ID = None |
+CLIENT_SECRET = None |
+ |
+GOOGLE_OAUTH2_PROVIDER_AUTHORIZATION_URI = ( |
+ 'https://accounts.google.com/o/oauth2/auth') |
+GOOGLE_OAUTH2_PROVIDER_TOKEN_URI = ( |
+ 'https://accounts.google.com/o/oauth2/token') |
+GOOGLE_OAUTH2_DEFAULT_FILE_PASSWORD = 'notasecret' |
+ |
+OOB_REDIRECT_URI = 'urn:ietf:wg:oauth:2.0:oob' |
+ |
+ |
+def OAuth2ClientFromBotoConfig( |
+ config, cred_type=oauth2_client.CredTypes.OAUTH2_USER_ACCOUNT): |
+ token_cache = None |
+ token_cache_type = config.get('OAuth2', 'token_cache', 'file_system') |
+ if token_cache_type == 'file_system': |
+ if config.has_option('OAuth2', 'token_cache_path_pattern'): |
+ token_cache = oauth2_client.FileSystemTokenCache( |
+ path_pattern=config.get('OAuth2', 'token_cache_path_pattern')) |
+ else: |
+ token_cache = oauth2_client.FileSystemTokenCache() |
+ elif token_cache_type == 'in_memory': |
+ token_cache = oauth2_client.InMemoryTokenCache() |
+ else: |
+ raise Exception( |
+ "Invalid value for config option OAuth2/token_cache: %s" % |
+ token_cache_type) |
+ |
+ proxy_host = None |
+ proxy_port = None |
+ proxy_user = None |
+ proxy_pass = None |
+ if (config.has_option('Boto', 'proxy') |
+ and config.has_option('Boto', 'proxy_port')): |
+ proxy_host = config.get('Boto', 'proxy') |
+ proxy_port = int(config.get('Boto', 'proxy_port')) |
+ proxy_user = config.get('Boto', 'proxy_user', None) |
+ proxy_pass = config.get('Boto', 'proxy_pass', None) |
+ |
+ provider_authorization_uri = config.get( |
+ 'OAuth2', 'provider_authorization_uri', |
+ GOOGLE_OAUTH2_PROVIDER_AUTHORIZATION_URI) |
+ provider_token_uri = config.get( |
+ 'OAuth2', 'provider_token_uri', GOOGLE_OAUTH2_PROVIDER_TOKEN_URI) |
+ |
+ if cred_type == oauth2_client.CredTypes.OAUTH2_SERVICE_ACCOUNT: |
+ service_client_id = config.get('Credentials', 'gs_service_client_id', '') |
+ private_key_filename = config.get('Credentials', 'gs_service_key_file', '') |
+ with open(private_key_filename, 'rb') as private_key_file: |
+ private_key = private_key_file.read() |
+ |
+ json_key = None |
+ try: |
+ json_key = json.loads(private_key) |
+ except ValueError: |
+ pass |
+ if json_key: |
+ for json_entry in ('client_id', 'client_email', 'private_key_id', |
+ 'private_key'): |
+ if json_entry not in json_key: |
+ raise Exception('The JSON private key file at %s ' |
+ 'did not contain the required entry: %s' % |
+ (private_key_filename, json_entry)) |
+ |
+ return oauth2_client.OAuth2JsonServiceAccountClient( |
+ json_key['client_id'], json_key['client_email'], |
+ json_key['private_key_id'], json_key['private_key'], |
+ access_token_cache=token_cache, auth_uri=provider_authorization_uri, |
+ token_uri=provider_token_uri, |
+ disable_ssl_certificate_validation=not(config.getbool( |
+ 'Boto', 'https_validate_certificates', True)), |
+ proxy_host=proxy_host, proxy_port=proxy_port, |
+ proxy_user=proxy_user, proxy_pass=proxy_pass) |
+ else: |
+ key_file_pass = config.get('Credentials', 'gs_service_key_file_password', |
+ GOOGLE_OAUTH2_DEFAULT_FILE_PASSWORD) |
+ |
+ return oauth2_client.OAuth2ServiceAccountClient( |
+ service_client_id, private_key, key_file_pass, |
+ access_token_cache=token_cache, auth_uri=provider_authorization_uri, |
+ token_uri=provider_token_uri, |
+ disable_ssl_certificate_validation=not(config.getbool( |
+ 'Boto', 'https_validate_certificates', True)), |
+ proxy_host=proxy_host, proxy_port=proxy_port, |
+ proxy_user=proxy_user, proxy_pass=proxy_pass) |
+ |
+ elif cred_type == oauth2_client.CredTypes.OAUTH2_USER_ACCOUNT: |
+ client_id = config.get('OAuth2', 'client_id', |
+ os.environ.get('OAUTH2_CLIENT_ID', CLIENT_ID)) |
+ if not client_id: |
+ raise Exception( |
+ 'client_id for your application obtained from ' |
+ 'https://console.developers.google.com must be set in a boto config ' |
+ 'or with OAUTH2_CLIENT_ID environment variable or with ' |
+ 'gcs_oauth2_boto_plugin.SetFallbackClientIdAndSecret function.') |
+ |
+ client_secret = config.get('OAuth2', 'client_secret', |
+ os.environ.get('OAUTH2_CLIENT_SECRET', |
+ CLIENT_SECRET)) |
+ ca_certs_file=config.get_value('Boto', 'ca_certificates_file') |
+ if ca_certs_file == 'system': |
+ ca_certs_file = None |
+ |
+ if not client_secret: |
+ raise Exception( |
+ 'client_secret for your application obtained from ' |
+ 'https://console.developers.google.com must be set in a boto config ' |
+ 'or with OAUTH2_CLIENT_SECRET environment variable or with ' |
+ 'gcs_oauth2_boto_plugin.SetFallbackClientIdAndSecret function.') |
+ return oauth2_client.OAuth2UserAccountClient( |
+ provider_token_uri, client_id, client_secret, |
+ config.get('Credentials', 'gs_oauth2_refresh_token'), |
+ auth_uri=provider_authorization_uri, access_token_cache=token_cache, |
+ disable_ssl_certificate_validation=not(config.getbool( |
+ 'Boto', 'https_validate_certificates', True)), |
+ proxy_host=proxy_host, proxy_port=proxy_port, |
+ proxy_user=proxy_user, proxy_pass=proxy_pass, |
+ ca_certs_file=ca_certs_file) |
+ else: |
+ raise Exception('You have attempted to create an OAuth2 client without ' |
+ 'setting up OAuth2 credentials.') |
+ |
+ |
+def OAuth2ApprovalFlow(client, scopes, launch_browser=False): |
+ flow = OAuth2WebServerFlow( |
+ client.client_id, client.client_secret, scopes, auth_uri=client.auth_uri, |
+ token_uri=client.token_uri, redirect_uri=OOB_REDIRECT_URI) |
+ approval_url = flow.step1_get_authorize_url() |
+ |
+ if launch_browser: |
+ sys.stdout.write( |
+ 'Attempting to launch a browser with the OAuth2 approval dialog at ' |
+ 'URL: %s\n\n' |
+ '[Note: due to a Python bug, you may see a spurious error message ' |
+ '"object is not\ncallable [...] in [...] Popen.__del__" which can be ' |
+ 'ignored.]\n\n' % approval_url) |
+ else: |
+ sys.stdout.write( |
+ 'Please navigate your browser to the following URL:\n%s\n' % |
+ approval_url) |
+ |
+ sys.stdout.write( |
+ 'In your browser you should see a page that requests you to authorize ' |
+ 'access to Google Cloud Platform APIs and Services on your behalf. ' |
+ 'After you approve, an authorization code will be displayed.\n\n') |
+ if (launch_browser and |
+ not webbrowser.open(approval_url, new=1, autoraise=True)): |
+ sys.stdout.write( |
+ 'Launching browser appears to have failed; please navigate a browser ' |
+ 'to the following URL:\n%s\n' % approval_url) |
+ # Short delay; webbrowser.open on linux insists on printing out a message |
+ # which we don't want to run into the prompt for the auth code. |
+ time.sleep(2) |
+ code = raw_input('Enter the authorization code: ') |
+ credentials = flow.step2_exchange(code, http=client.CreateHttpRequest()) |
+ return credentials.refresh_token |
+ |
+ |
+def SetFallbackClientIdAndSecret(client_id, client_secret): |
+ global CLIENT_ID |
+ global CLIENT_SECRET |
+ |
+ CLIENT_ID = client_id |
+ CLIENT_SECRET = client_secret |
+ |
+ |
+def SetLock(lock): |
+ oauth2_client.token_exchange_lock = lock |
+ |