Beispiel #1
0
    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()
Beispiel #2
0
    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())