1# Copyright (C) 2020 The Android Open Source Project 2# 3# Licensed under the Apache License, Version 2.0 (the "License"); 4# you may not use this file except in compliance with the License. 5# You may obtain a copy of the License at 6# 7# http://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, 11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12# See the License for the specific language governing permissions and 13# limitations under the License. 14# 15# Licensed under the Apache License, Version 2.0 (the "License"); 16# you may not use this file except in compliance with the License. 17# You may obtain a copy of the License at 18# 19# http://www.apache.org/licenses/LICENSE-2.0 20# 21# Unless required by applicable law or agreed to in writing, software 22# distributed under the License is distributed on an "AS IS" BASIS, 23# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 24# See the License for the specific language governing permissions and 25# limitations under the License. 26""" 27Utility functions for atest. 28""" 29from __future__ import print_function 30 31import os 32import logging 33try: 34 import httplib2 35except ModuleNotFoundError as e: 36 logging.debug('Import error due to %s', e) 37import constants 38 39try: 40 # pylint: disable=import-error 41 from oauth2client import client as oauth2_client 42 from oauth2client.contrib import multistore_file 43 from oauth2client import tools as oauth2_tools 44except ModuleNotFoundError as e: 45 logging.debug('Import error due to %s', e) 46 47 48class RunFlowFlags(): 49 """Flags for oauth2client.tools.run_flow.""" 50 def __init__(self, browser_auth): 51 self.auth_host_port = [8080, 8090] 52 self.auth_host_name = "localhost" 53 self.logging_level = "ERROR" 54 self.noauth_local_webserver = not browser_auth 55 56 57class GCPHelper(): 58 """GCP bucket helper class.""" 59 def __init__(self, client_id=None, client_secret=None, 60 user_agent=None, scope=constants.SCOPE_BUILD_API_SCOPE): 61 """Init stuff for GCPHelper class. 62 Args: 63 client_id: String, client id from the cloud project. 64 client_secret: String, client secret for the client_id. 65 user_agent: The user agent for the credential. 66 scope: String, scopes separated by space. 67 """ 68 self.client_id = client_id 69 self.client_secret = client_secret 70 self.user_agent = user_agent 71 self.scope = scope 72 73 def get_refreshed_credential_from_file(self, creds_file_path): 74 """Get refreshed credential from file. 75 Args: 76 creds_file_path: Credential file path. 77 Returns: 78 An oauth2client.OAuth2Credentials instance. 79 """ 80 credential = self.get_credential_from_file(creds_file_path) 81 if credential: 82 try: 83 credential.refresh(httplib2.Http()) 84 except oauth2_client.AccessTokenRefreshError as e: 85 logging.debug('Token refresh error: %s', e) 86 if not credential.invalid: 87 return credential 88 logging.debug('Cannot get credential.') 89 return None 90 91 def get_credential_from_file(self, creds_file_path): 92 """Get credential from file. 93 Args: 94 creds_file_path: Credential file path. 95 Returns: 96 An oauth2client.OAuth2Credentials instance. 97 """ 98 storage = multistore_file.get_credential_storage( 99 filename=os.path.abspath(creds_file_path), 100 client_id=self.client_id, 101 user_agent=self.user_agent, 102 scope=self.scope) 103 return storage.get() 104 105 def get_credential_with_auth_flow(self, creds_file_path): 106 """Get Credential object from file. 107 Get credential object from file. Run oauth flow if haven't authorized 108 before. 109 110 Args: 111 creds_file_path: Credential file path. 112 Returns: 113 An oauth2client.OAuth2Credentials instance. 114 """ 115 credentials = self.get_refreshed_credential_from_file(creds_file_path) 116 if not credentials: 117 storage = multistore_file.get_credential_storage( 118 filename=os.path.abspath(creds_file_path), 119 client_id=self.client_id, 120 user_agent=self.user_agent, 121 scope=self.scope) 122 return self._run_auth_flow(storage) 123 return credentials 124 125 def _run_auth_flow(self, storage): 126 """Get user oauth2 credentials. 127 128 Args: 129 storage: GCP storage object. 130 Returns: 131 An oauth2client.OAuth2Credentials instance. 132 """ 133 flags = RunFlowFlags(browser_auth=False) 134 flow = oauth2_client.OAuth2WebServerFlow( 135 client_id=self.client_id, 136 client_secret=self.client_secret, 137 scope=self.scope, 138 user_agent=self.user_agent) 139 credentials = oauth2_tools.run_flow( 140 flow=flow, storage=storage, flags=flags) 141 return credentials 142