def _get_access_token(self): log.info('Requesting new access token') headers = CaseInsensitiveDict() headers['Content-Type'] = 'application/x-www-form-urlencoded; charset=utf-8' body = urlencode({'client_id': OAUTH_CLIENT_ID, 'client_secret': OAUTH_CLIENT_SECRET, 'refresh_token': self.password, 'grant_type': 'refresh_token' }) conn = HTTPConnection('accounts.google.com', 443, proxy=self.proxy, ssl_context=self.ssl_context) try: conn.send_request('POST', '/o/oauth2/token', headers=headers, body=body.encode('utf-8')) resp = conn.read_response() if resp.status > 299 or resp.status < 200: raise HTTPError(resp.status, resp.reason, resp.headers) content_type = resp.headers.get('Content-Type', None) if content_type: hit = re.match(r'application/json(?:; charset="(.+)")?$', resp.headers['Content-Type'], re.IGNORECASE) else: hit = None if not hit: log.error('Unexpected server reply when refreshing access token:\n%s', self._dump_response(resp)) raise RuntimeError('Unable to parse server response') charset = hit.group(1) or 'utf-8' body = conn.readall().decode(charset) resp_json = json.loads(body) if not isinstance(resp_json, dict): log.error('Invalid json server response. Expected dict, got:\n%s', body) raise RuntimeError('Unable to parse server response') if 'error' in resp_json: raise AuthenticationError(resp_json['error']) if 'access_token' not in resp_json: log.error('Unable to find access token in server response:\n%s', body) raise RuntimeError('Unable to parse server response') self.access_token[self.password] = resp_json['access_token'] finally: conn.disconnect()
def __call__(self, url: str, method: str = 'GET', body=None, headers=None, timeout=None): # https://github.com/googleapis/google-auth-library-python/issues/318 if not isinstance(body, bytes): body = str(body).encode('ascii') if timeout is not None: raise ValueError('*timeout* argument is not supported') hit = re.match(r'^(https?)://([^:/]+)(?::(\d+))?(.*)$', url) if not hit: raise ValueError('Unsupported URL: ' + url) if hit.group(1) == 'https': ssl_context = self.ssl_context proxy = self.ssl_proxy else: ssl_context = None proxy = self.proxy hostname = hit.group(2) if hit.group(3): port = int(hit.group(3)) elif ssl_context: port = 443 else: port = 80 path = hit.group(4) try: conn = self.conn_pool[(hostname, port)] except KeyError: conn = HTTPConnection(hostname, port, proxy=proxy, ssl_context=ssl_context) self.conn_pool[(hostname, port)] = conn try: conn.send_request(method, path, headers=headers, body=body) resp = conn.read_response() except (dugong.ConnectionClosed, dugong.InvalidResponse, dugong.UnsupportedResponse, dugong.ConnectionTimedOut, dugong.HostnameNotResolvable, dugong.DNSUnavailable, ssl.SSLError) as exc: raise g_auth.exceptions.TransportError(exc) return Namespace(status=resp.status, headers=resp.headers, data=conn.readall())