Exemplo n.º 1
0
  def response(self, resp, content):
    """Convert the response wire format into a Python object.

    Args:
      resp: httplib2.Response, the HTTP response headers and status
      content: string, the body of the HTTP response

    Returns:
      The body de-serialized as a Python object.

    Raises:
      apiclient.errors.HttpError if a non 2xx response is received.
    """
    # Error handling is TBD, for example, do we retry
    # for some operation/error combinations?
    if resp.status < 300:
      if resp.status == 204:
        # A 204: No Content response should be treated differently
        # to all the other success states
        return simplejson.loads('{}')
      body = simplejson.loads(content)
      if isinstance(body, dict) and 'data' in body:
        body = body['data']
      return body
    else:
      logging.debug('Content from bad request was: %s' % content)
      raise HttpError(resp, content)
Exemplo n.º 2
0
 def __call__(self, http, postproc, uri, method='GET', body=None,
              headers=None, methodId=None):
   """Implements the callable interface that discovery.build() expects
   of requestBuilder, which is to build an object compatible with
   HttpRequest.execute(). See that method for the description of the
   parameters and the expected response.
   """
   if methodId in self.responses:
     response = self.responses[methodId]
     resp, content = response[:2]
     if len(response) > 2:
       # Test the body against the supplied expected_body.
       expected_body = response[2]
       if bool(expected_body) != bool(body):
         # Not expecting a body and provided one
         # or expecting a body and not provided one.
         raise UnexpectedBodyError(expected_body, body)
       if isinstance(expected_body, str):
         expected_body = simplejson.loads(expected_body)
       body = simplejson.loads(body)
       if body != expected_body:
         raise UnexpectedBodyError(expected_body, body)
     return HttpRequestMock(resp, content, postproc)
   elif self.check_unexpected:
     raise UnexpectedMethodError(methodId)
   else:
     model = JsonModel(False)
     return HttpRequestMock(None, '{}', model.response)
Exemplo n.º 3
0
    def response(self, resp, content):
        """Convert the response wire format into a Python object.

    Args:
      resp: httplib2.Response, the HTTP response headers and status
      content: string, the body of the HTTP response

    Returns:
      The body de-serialized as a Python object.

    Raises:
      apiclient.errors.HttpError if a non 2xx response is received.
    """
        # Error handling is TBD, for example, do we retry
        # for some operation/error combinations?
        if resp.status < 300:
            if resp.status == 204:
                # A 204: No Content response should be treated differently
                # to all the other success states
                return simplejson.loads('{}')
            body = simplejson.loads(content)
            if isinstance(body, dict) and 'data' in body:
                body = body['data']
            return body
        else:
            logging.debug('Content from bad request was: %s' % content)
            raise HttpError(resp, content)
Exemplo n.º 4
0
 def __call__(self,
              http,
              postproc,
              uri,
              method='GET',
              body=None,
              headers=None,
              methodId=None,
              resumable=None):
     """Implements the callable interface that discovery.build() expects
 of requestBuilder, which is to build an object compatible with
 HttpRequest.execute(). See that method for the description of the
 parameters and the expected response.
 """
     if methodId in self.responses:
         response = self.responses[methodId]
         resp, content = response[:2]
         if len(response) > 2:
             # Test the body against the supplied expected_body.
             expected_body = response[2]
             if bool(expected_body) != bool(body):
                 # Not expecting a body and provided one
                 # or expecting a body and not provided one.
                 raise UnexpectedBodyError(expected_body, body)
             if isinstance(expected_body, str):
                 expected_body = simplejson.loads(expected_body)
             body = simplejson.loads(body)
             if body != expected_body:
                 raise UnexpectedBodyError(expected_body, body)
         return HttpRequestMock(resp, content, postproc)
     elif self.check_unexpected:
         raise UnexpectedMethodError(methodId)
     else:
         model = JsonModel(False)
         return HttpRequestMock(None, '{}', model.response)
def build_from_document(
    service,
    base,
    future=None,
    http=None,
    developerKey=None,
    model=None,
    requestBuilder=HttpRequest):
  """Create a Resource for interacting with an API.

  Same as `build()`, but constructs the Resource object
  from a discovery document that is it given, as opposed to
  retrieving one over HTTP.

  Args:
    service: string, discovery document
    base: string, base URI for all HTTP requests, usually the discovery URI
    future: string, discovery document with future capabilities
    auth_discovery: dict, information about the authentication the API supports
    http: httplib2.Http, An instance of httplib2.Http or something that acts
      like it that HTTP requests will be made through.
    developerKey: string, Key for controlling API usage, generated
      from the API Console.
    model: Model class instance that serializes and
      de-serializes requests and responses.
    requestBuilder: Takes an http request and packages it up to be executed.

  Returns:
    A Resource object with methods for interacting with
    the service.
  """

  service = simplejson.loads(service)
  base = urlparse.urljoin(base, service['basePath'])
  if future:
    future = simplejson.loads(future)
    auth_discovery = future.get('auth', {})
  else:
    future = {}
    auth_discovery = {}
  schema = service.get('schemas', {})

  if model is None:
    features = service.get('features', [])
    model = JsonModel('dataWrapper' in features)
  resource = createResource(http, base, model, requestBuilder, developerKey,
                       service, future, schema)

  def auth_method():
    """Discovery information about the authentication the API uses."""
    return auth_discovery

  setattr(resource, 'auth_discovery', auth_method)

  return resource
Exemplo n.º 6
0
def build_from_document(service,
                        base,
                        future=None,
                        http=None,
                        developerKey=None,
                        model=None,
                        requestBuilder=HttpRequest):
    """Create a Resource for interacting with an API.

  Same as `build()`, but constructs the Resource object
  from a discovery document that is it given, as opposed to
  retrieving one over HTTP.

  Args:
    service: string, discovery document
    base: string, base URI for all HTTP requests, usually the discovery URI
    future: string, discovery document with future capabilities
    auth_discovery: dict, information about the authentication the API supports
    http: httplib2.Http, An instance of httplib2.Http or something that acts
      like it that HTTP requests will be made through.
    developerKey: string, Key for controlling API usage, generated
      from the API Console.
    model: Model class instance that serializes and
      de-serializes requests and responses.
    requestBuilder: Takes an http request and packages it up to be executed.

  Returns:
    A Resource object with methods for interacting with
    the service.
  """

    service = simplejson.loads(service)
    base = urlparse.urljoin(base, service['basePath'])
    if future:
        future = simplejson.loads(future)
        auth_discovery = future.get('auth', {})
    else:
        future = {}
        auth_discovery = {}
    schema = service.get('schemas', {})

    if model is None:
        features = service.get('features', [])
        model = JsonModel('dataWrapper' in features)
    resource = createResource(http, base, model, requestBuilder, developerKey,
                              service, future, schema)

    def auth_method():
        """Discovery information about the authentication the API uses."""
        return auth_discovery

    setattr(resource, 'auth_discovery', auth_method)

    return resource
Exemplo n.º 7
0
    def _do_refresh_request(self, http_request):
        """Refresh the access_token using the refresh_token.

    Args:
      http_request: callable, a callable that matches the method signature of
        httplib2.Http.request, used to make the refresh request.

    Raises:
      AccessTokenRefreshError: When the refresh fails.
    """
        body = self._generate_refresh_request_body()
        headers = self._generate_refresh_request_headers()

        logger.info('Refreshing access_token')
        resp, content = http_request(self.token_uri,
                                     method='POST',
                                     body=body,
                                     headers=headers)
        logging.getLogger().setLevel(logging.DEBUG)
        logging.debug(resp)
        logging.debug(content)
        if resp.status == 200:
            # TODO(jcgregorio) Raise an error if loads fails?
            d = simplejson.loads(content)
            self.access_token = d['access_token']
            self.refresh_token = d.get('refresh_token', self.refresh_token)
            if 'expires_in' in d:
                self.token_expiry = datetime.timedelta(
                    seconds=int(d['expires_in'])) + datetime.datetime.utcnow()
            else:
                self.token_expiry = None
            if self.store:
                self.store.locked_put(self)
        else:
            # An {'error':...} response body means the token is expired or revoked,
            # so we flag the credentials as such.
            logger.info('Failed to retrieve access token: %s' % content)
            error_msg = 'Invalid response %s.' % resp['status']
            try:
                d = simplejson.loads(content)
                if 'error' in d:
                    error_msg = d['error']
                    self.invalid = True
                    if self.store:
                        self.store.locked_put(self)
            except:
                pass
            raise AccessTokenRefreshError(error_msg)
Exemplo n.º 8
0
def _parse_exchange_token_response(content):
  """Parses response of an exchange token request.

  Most providers return JSON but some (e.g. Facebook) return a
  url-encoded string.

  Args:
    content: The body of a response

  Returns:
    Content as a dictionary object. Note that the dict could be empty,
    i.e. {}. That basically indicates a failure.
  """
  resp = {}
  try:
    resp = simplejson.loads(content)
  except StandardError:
    # different JSON libs raise different exceptions,
    # so we just do a catch-all here
    resp = dict(parse_qsl(content))

  # some providers respond with 'expires', others with 'expires_in'
  if resp and 'expires' in resp:
    resp['expires_in'] = resp.pop('expires')

  return resp
Exemplo n.º 9
0
    def from_json(cls, s):
        """Instantiate a Credentials object from a JSON description of it. The JSON
    should have been produced by calling .to_json() on the object.

    Args:
      data: dict, A deserialized JSON object.

    Returns:
      An instance of a Credentials subclass.
    """
        data = simplejson.loads(s)
        if 'token_expiry' in data and not isinstance(data['token_expiry'],
                                                     datetime.datetime):
            try:
                data['token_expiry'] = datetime.datetime.strptime(
                    data['token_expiry'], EXPIRY_FORMAT)
            except:
                data['token_expiry'] = None
        retval = OAuth2Credentials(data['access_token'], data['client_id'],
                                   data['client_secret'],
                                   data['refresh_token'], data['token_expiry'],
                                   data['token_uri'], data['user_agent'],
                                   data.get('id_token', None))
        retval.invalid = data['invalid']
        return retval
Exemplo n.º 10
0
  def from_json(cls, s):
    """Instantiate a Credentials object from a JSON description of it. The JSON
    should have been produced by calling .to_json() on the object.

    Args:
      data: dict, A deserialized JSON object.

    Returns:
      An instance of a Credentials subclass.
    """
    data = simplejson.loads(s)
    if 'token_expiry' in data and not isinstance(data['token_expiry'],
        datetime.datetime):
      try:
        data['token_expiry'] = datetime.datetime.strptime(
            data['token_expiry'], EXPIRY_FORMAT)
      except:
        data['token_expiry'] = None
    retval = OAuth2Credentials(
        data['access_token'],
        data['client_id'],
        data['client_secret'],
        data['refresh_token'],
        data['token_expiry'],
        data['token_uri'],
        data['user_agent'],
        data.get('id_token', None))
    retval.invalid = data['invalid']
    return retval
Exemplo n.º 11
0
    def verify_id_token(id_token,
                        audience,
                        http=None,
                        cert_uri=ID_TOKEN_VERIFICATON_CERTS):
        """Verifies a signed JWT id_token.

    Args:
      id_token: string, A Signed JWT.
      audience: string, The audience 'aud' that the token should be for.
      http: httplib2.Http, instance to use to make the HTTP request. Callers
        should supply an instance that has caching enabled.
      cert_uri: string, URI of the certificates in JSON format to
        verify the JWT against.

    Returns:
      The deserialized JSON in the JWT.

    Raises:
      oauth2client.crypt.AppIdentityError if the JWT fails to verify.
    """
        if http is None:
            http = _cached_http

        resp, content = http.request(cert_uri)

        if resp.status == 200:
            certs = simplejson.loads(content)
            return verify_signed_jwt_with_certs(id_token, certs, audience)
        else:
            raise VerifyJwtTokenError('Status code: %d' % resp.status)
Exemplo n.º 12
0
def build(serviceName, version,
    http=None,
    discoveryServiceUrl=DISCOVERY_URI,
    developerKey=None,
    model=JsonModel(),
    requestBuilder=HttpRequest):
  params = {
      'api': serviceName,
      'apiVersion': version
      }

  if http is None:
    http = httplib2.Http()
  requested_url = uritemplate.expand(discoveryServiceUrl, params)
  logging.info('URL being requested: %s' % requested_url)
  resp, content = http.request(requested_url)
  service = simplejson.loads(content)

  fn = os.path.join(os.path.dirname(__file__), "contrib",
      serviceName, "future.json")
  try:
    f = file(fn, "r")
    d = simplejson.load(f)
    f.close()
    future = d['resources']
    auth_discovery = d['auth']
  except IOError:
    future = {}
    auth_discovery = {}

  base = urlparse.urljoin(discoveryServiceUrl, service['restBasePath'])
  resources = service['resources']

  class Service(object):
    """Top level interface for a service"""

    def __init__(self, http=http):
      self._http = http
      self._baseUrl = base
      self._model = model
      self._developerKey = developerKey
      self._requestBuilder = requestBuilder

    def auth_discovery(self):
      return auth_discovery

  def createMethod(theclass, methodName, methodDesc, futureDesc):

    def method(self):
      return createResource(self._http, self._baseUrl, self._model,
                            self._requestBuilder, methodName,
                            self._developerKey, methodDesc, futureDesc)

    setattr(method, '__doc__', 'A description of how to use this function')
    setattr(method, '__is_resource__', True)
    setattr(theclass, methodName, method)

  for methodName, methodDesc in resources.iteritems():
    createMethod(Service, methodName, methodDesc, future.get(methodName, {}))
  return Service()
Exemplo n.º 13
0
  def new_from_json(cls, s):
    """Utility class method to instantiate a Credentials subclass from a JSON
    representation produced by to_json().

    Args:
      s: string, JSON from to_json().

    Returns:
      An instance of the subclass of Credentials that was serialized with
      to_json().
    """
    data = simplejson.loads(s)
    # Find and call the right classmethod from_json() to restore the object.
    module = data['_module']
    try:
      m = __import__(module)
    except ImportError:
      # In case there's an object from the old package structure, update it
      module = module.replace('.apiclient', '')
      m = __import__(module)

    m = __import__(module, fromlist=module.split('.')[:-1])
    kls = getattr(m, data['_class'])
    from_json = getattr(kls, 'from_json')
    return from_json(s)
Exemplo n.º 14
0
  def _do_revoke(self, http_request, token):
    """Revokes the credentials and deletes the store if available.

    Args:
      http_request: callable, a callable that matches the method signature of
        httplib2.Http.request, used to make the refresh request.
      token: A string used as the token to be revoked. Can be either an
        access_token or refresh_token.

    Raises:
      TokenRevokeError: If the revoke request does not return with a 200 OK.
    """
    logger.info('Revoking token')
    query_params = {'token': token}
    token_revoke_uri = _update_query_params(self.revoke_uri, query_params)
    resp, content = http_request(token_revoke_uri)
    if resp.status == 200:
      self.invalid = True
    else:
      error_msg = 'Invalid response %s.' % resp.status
      try:
        d = simplejson.loads(content)
        if 'error' in d:
          error_msg = d['error']
      except StandardError:
        pass
      raise TokenRevokeError(error_msg)

    if self.store:
      self.store.delete()
Exemplo n.º 15
0
  def verify_id_token(id_token, audience, http=None,
      cert_uri=ID_TOKEN_VERIFICATON_CERTS):
    """Verifies a signed JWT id_token.

    Args:
      id_token: string, A Signed JWT.
      audience: string, The audience 'aud' that the token should be for.
      http: httplib2.Http, instance to use to make the HTTP request. Callers
        should supply an instance that has caching enabled.
      cert_uri: string, URI of the certificates in JSON format to
        verify the JWT against.

    Returns:
      The deserialized JSON in the JWT.

    Raises:
      oauth2client.crypt.AppIdentityError if the JWT fails to verify.
    """
    if http is None:
      http = _cached_http

    resp, content = http.request(cert_uri)

    if resp.status == 200:
      certs = simplejson.loads(content)
      return verify_signed_jwt_with_certs(id_token, certs, audience)
    else:
      raise VerifyJwtTokenError('Status code: %d' % resp.status)
Exemplo n.º 16
0
def build(serviceName,
          version,
          http=None,
          discoveryServiceUrl=DISCOVERY_URI,
          developerKey=None,
          model=None,
          requestBuilder=HttpRequest):
    """Construct a Resource for interacting with an API.

  Construct a Resource object for interacting with
  an API. The serviceName and version are the
  names from the Discovery service.

  Args:
    serviceName: string, name of the service
    version: string, the version of the service
    discoveryServiceUrl: string, a URI Template that points to
      the location of the discovery service. It should have two
      parameters {api} and {apiVersion} that when filled in
      produce an absolute URI to the discovery document for
      that service.
    developerKey: string, key obtained
      from https://code.google.com/apis/console
    model: apiclient.Model, converts to and from the wire format
    requestBuilder: apiclient.http.HttpRequest, encapsulator for
      an HTTP request

  Returns:
    A Resource object with methods for interacting with
    the service.
  """
    params = {'api': serviceName, 'apiVersion': version}

    if http is None:
        http = httplib2.Http()

    requested_url = uritemplate.expand(discoveryServiceUrl, params)

    # REMOTE_ADDR is defined by the CGI spec [RFC3875] as the environment variable
    # that contains the network address of the client sending the request. If it
    # exists then add that to the request for the discovery document to avoid
    # exceeding the quota on discovery requests.
    if 'REMOTE_ADDR' in os.environ:
        requested_url = _add_query_parameter(requested_url, 'userIp',
                                             os.environ['REMOTE_ADDR'])
    logging.info('URL being requested: %s' % requested_url)

    resp, content = http.request(requested_url)

    if resp.status == 404:
        raise UnknownApiNameOrVersion("name: %s  version: %s" %
                                      (serviceName, version))
    if resp.status >= 400:
        raise HttpError(resp, content, requested_url)

    try:
        service = simplejson.loads(content)
    except ValueError, e:
        logging.error('Failed to parse as JSON: ' + content)
        raise InvalidJsonError()
Exemplo n.º 17
0
    def new_from_json(cls, s):
        """Utility class method to instantiate a Credentials subclass from a JSON
    representation produced by to_json().

    Args:
      s: string, JSON from to_json().

    Returns:
      An instance of the subclass of Credentials that was serialized with
      to_json().
    """
        data = simplejson.loads(s)
        # Find and call the right classmethod from_json() to restore the object.
        module = data['_module']
        try:
            m = __import__(module)
        except ImportError:
            # In case there's an object from the old package structure, update it
            module = module.replace('.apiclient', '')
            m = __import__(module)

        m = __import__(module, fromlist=module.split('.')[:-1])
        kls = getattr(m, data['_class'])
        from_json = getattr(kls, 'from_json')
        return from_json(s)
def build(serviceName, version,
          http=None,
          discoveryServiceUrl=DISCOVERY_URI,
          developerKey=None,
          model=None,
          requestBuilder=HttpRequest):
  """Construct a Resource for interacting with an API.

  Construct a Resource object for interacting with
  an API. The serviceName and version are the
  names from the Discovery service.

  Args:
    serviceName: string, name of the service
    version: string, the version of the service
    discoveryServiceUrl: string, a URI Template that points to
      the location of the discovery service. It should have two
      parameters {api} and {apiVersion} that when filled in
      produce an absolute URI to the discovery document for
      that service.
    developerKey: string, key obtained
      from https://code.google.com/apis/console
    model: apiclient.Model, converts to and from the wire format
    requestBuilder: apiclient.http.HttpRequest, encapsulator for
      an HTTP request

  Returns:
    A Resource object with methods for interacting with
    the service.
  """
  params = {
      'api': serviceName,
      'apiVersion': version
      }

  if http is None:
    http = httplib2.Http()

  requested_url = uritemplate.expand(discoveryServiceUrl, params)

  # REMOTE_ADDR is defined by the CGI spec [RFC3875] as the environment variable
  # that contains the network address of the client sending the request. If it
  # exists then add that to the request for the discovery document to avoid
  # exceeding the quota on discovery requests.
  if 'REMOTE_ADDR' in os.environ:
    requested_url = _add_query_parameter(requested_url, 'userIp',
                                         os.environ['REMOTE_ADDR'])
  logging.info('URL being requested: %s' % requested_url)

  resp, content = http.request(requested_url)

  if resp.status >= 400:
    raise HttpError(resp, content, requested_url)

  try:
    service = simplejson.loads(content)
  except ValueError, e:
    logging.error('Failed to parse as JSON: ' + content)
    raise InvalidJsonError()
Exemplo n.º 19
0
 def from_json(cls, json):
   data = simplejson.loads(json)
   retval = AccessTokenCredentials(
       data['scope'],
       data['audience'],
       data['assertion_type'],
       data['token_uri'])
   return retval
Exemplo n.º 20
0
  def _do_refresh_request(self, http_request):
    """Refresh the access_token using the refresh_token.

    Args:
      http_request: callable, a callable that matches the method signature of
        httplib2.Http.request, used to make the refresh request.

    Raises:
      AccessTokenRefreshError: When the refresh fails.
    """
    body = self._generate_refresh_request_body()
    headers = self._generate_refresh_request_headers()

    logger.info('Refreshing access_token')
    resp, content = http_request(
        self.token_uri, method='POST', body=body, headers=headers)
    logging.getLogger().setLevel(logging.DEBUG)
    logging.debug(resp)
    logging.debug(content)
    if resp.status == 200:
      # TODO(jcgregorio) Raise an error if loads fails?
      d = simplejson.loads(content)
      self.access_token = d['access_token']
      self.refresh_token = d.get('refresh_token', self.refresh_token)
      if 'expires_in' in d:
        self.token_expiry = datetime.timedelta(
            seconds=int(d['expires_in'])) + datetime.datetime.utcnow()
      else:
        self.token_expiry = None
      if self.store:
        self.store.locked_put(self)
    else:
      # An {'error':...} response body means the token is expired or revoked,
      # so we flag the credentials as such.
      logger.info('Failed to retrieve access token: %s' % content)
      error_msg = 'Invalid response %s.' % resp['status']
      try:
        d = simplejson.loads(content)
        if 'error' in d:
          error_msg = d['error']
          self.invalid = True
          if self.store:
            self.store.locked_put(self)
      except:
        pass
      raise AccessTokenRefreshError(error_msg)
Exemplo n.º 21
0
 def from_json(cls, s):
     data = simplejson.loads(s)
     retval = SignedJwtAssertionCredentials(
         data['service_account_name'], data['private_key'],
         data['private_key_password'], data['scope'],
         data['user_agent'], data['token_uri'], data['kwargs'])
     retval.invalid = data['invalid']
     return retval
Exemplo n.º 22
0
 def from_json(cls, json):
   data = simplejson.loads(json)
   retval = AccessTokenCredentials(
       data['scope'],
       data['audience'],
       data['assertion_type'],
       data['token_uri'])
   return retval
Exemplo n.º 23
0
 def _get_reason(self):
     """Calculate the reason for the error from the response content."""
     if self.resp.get('content-type', '').startswith('application/json'):
         try:
             data = simplejson.loads(self.content)
             reason = data['error']['message']
         except (ValueError, KeyError):
             reason = self.content
     else:
         reason = self.resp.reason
     return reason
Exemplo n.º 24
0
 def _get_reason(self):
   """Calculate the reason for the error from the response content."""
   reason = self.resp.reason
   try:
     data = simplejson.loads(self.content)
     reason = data['error']['message']
   except (ValueError, KeyError):
     pass
   if reason is None:
     reason = ''
   return reason
Exemplo n.º 25
0
 def _get_reason(self):
   """Calculate the reason for the error from the response content."""
   if self.resp.get('content-type', '').startswith('application/json'):
     try:
       data = simplejson.loads(self.content)
       reason = data['error']['message']
     except (ValueError, KeyError):
       reason = self.content
   else:
     reason = self.resp.reason
   return reason
Exemplo n.º 26
0
    def _do_refresh_request(self, http_request):
        """Refresh the access_token using the refresh_token.

    Args:
      http_request: callable, a callable that matches the method signature of
        httplib2.Http.request, used to make the refresh request.

    Raises:
      AccessTokenRefreshError: When the refresh fails.
    """
        body = self._generate_refresh_request_body()
        headers = self._generate_refresh_request_headers()

        logger.info("Refresing access_token")
        resp, content = http_request(self.token_uri, method="POST", body=body, headers=headers)
        if resp.status == 200:
            # TODO(jcgregorio) Raise an error if loads fails?
            d = simplejson.loads(content)
            self.access_token = d["access_token"]
            self.refresh_token = d.get("refresh_token", self.refresh_token)
            if "expires_in" in d:
                self.token_expiry = datetime.timedelta(seconds=int(d["expires_in"])) + datetime.datetime.utcnow()
            else:
                self.token_expiry = None
            if self.store:
                self.store.locked_put(self)
        else:
            # An {'error':...} response body means the token is expired or revoked,
            # so we flag the credentials as such.
            logger.error("Failed to retrieve access token: %s" % content)
            error_msg = "Invalid response %s." % resp["status"]
            try:
                d = simplejson.loads(content)
                if "error" in d:
                    error_msg = d["error"]
                    self.invalid = True
                    if self.store:
                        self.store.locked_put(self)
            except:
                pass
            raise AccessTokenRefreshError(error_msg)
Exemplo n.º 27
0
  def _write(self):
    """Write the cached data back out.

    The multistore must be locked.
    """
    raw_data = {'file_version': 1}
    raw_creds = []
    raw_data['data'] = raw_creds
    for (cred_key, cred) in self._data.items():
      raw_key = dict(cred_key)
      raw_cred = simplejson.loads(cred.to_json())
      raw_creds.append({'key': raw_key, 'credential': raw_cred})
    self._locked_json_write(raw_data)
Exemplo n.º 28
0
 def from_json(s, http, postproc):
     """Returns an HttpRequest populated with info from a JSON object."""
     d = simplejson.loads(s)
     if d['resumable'] is not None:
         d['resumable'] = MediaUpload.new_from_json(d['resumable'])
     return HttpRequest(http,
                        postproc,
                        uri=d['uri'],
                        method=d['method'],
                        body=d['body'],
                        headers=d['headers'],
                        methodId=d['methodId'],
                        resumable=d['resumable'])
Exemplo n.º 29
0
    def _write(self):
        """Write the cached data back out.

        The multistore must be locked.
        """
        raw_data = {'file_version': 1}
        raw_creds = []
        raw_data['data'] = raw_creds
        for (cred_key, cred) in self._data.items():
            raw_key = dict(cred_key)
            raw_cred = simplejson.loads(cred.to_json())
            raw_creds.append({'key': raw_key, 'credential': raw_cred})
        self._locked_json_write(raw_data)
Exemplo n.º 30
0
 def from_json(cls, s):
   data = simplejson.loads(s)
   retval = SignedJwtAssertionCredentials(
       data['service_account_name'],
       data['private_key'],
       data['private_key_password'],
       data['scope'],
       data['user_agent'],
       data['token_uri'],
       data['kwargs']
       )
   retval.invalid = data['invalid']
   return retval
Exemplo n.º 31
0
    def _write(self):
        """Write the cached data back out.

    The multistore must be locked.
    """
        raw_data = {"file_version": 1}
        raw_creds = []
        raw_data["data"] = raw_creds
        for (cred_key, cred) in self._data.items():
            raw_key = {"clientId": cred_key[0], "userAgent": cred_key[1], "scope": cred_key[2]}
            raw_cred = simplejson.loads(cred.to_json())
            raw_creds.append({"key": raw_key, "credential": raw_cred})
        self._locked_json_write(raw_data)
Exemplo n.º 32
0
 def from_json(cls, s):
     data = simplejson.loads(s)
     retval = SignedJwtAssertionCredentials(
         data["service_account_name"],
         data["private_key"],
         data["private_key_password"],
         data["scope"],
         data["user_agent"],
         data["token_uri"],
         data["kwargs"],
     )
     retval.invalid = data["invalid"]
     return retval
Exemplo n.º 33
0
def build(
    serviceName,
    version,
    http=None,
    discoveryServiceUrl=DISCOVERY_URI,
    developerKey=None,
    model=JsonModel(),
    requestBuilder=HttpRequest,
):
    """Construct a Resource for interacting with an API.

  Construct a Resource object for interacting with
  an API. The serviceName and version are the
  names from the Discovery service.

  Args:
    serviceName: string, name of the service
    version: string, the version of the service
    discoveryServiceUrl: string, a URI Template that points to
      the location of the discovery service. It should have two
      parameters {api} and {apiVersion} that when filled in
      produce an absolute URI to the discovery document for
      that service.
    developerKey: string, key obtained
      from https://code.google.com/apis/console
    model: apiclient.Model, converts to and from the wire format
    requestBuilder: apiclient.http.HttpRequest, encapsulator for
      an HTTP request

  Returns:
    A Resource object with methods for interacting with
    the service.
  """
    params = {"api": serviceName, "apiVersion": version}

    if http is None:
        http = httplib2.Http()
    requested_url = uritemplate.expand(discoveryServiceUrl, params)
    logging.info("URL being requested: %s" % requested_url)
    resp, content = http.request(requested_url)
    service = simplejson.loads(content)

    fn = os.path.join(os.path.dirname(__file__), "contrib", serviceName, "future.json")
    try:
        f = file(fn, "r")
        future = f.read()
        f.close()
    except IOError:
        future = None

    return build_from_document(content, discoveryServiceUrl, future, http, developerKey, model, requestBuilder)
Exemplo n.º 34
0
 def from_json(s, http, postproc):
   """Returns an HttpRequest populated with info from a JSON object."""
   d = simplejson.loads(s)
   if d['resumable'] is not None:
     d['resumable'] = MediaUpload.new_from_json(d['resumable'])
   return HttpRequest(
       http,
       postproc,
       uri=d['uri'],
       method=d['method'],
       body=d['body'],
       headers=d['headers'],
       methodId=d['methodId'],
       resumable=d['resumable'])
Exemplo n.º 35
0
 def from_json(cls, s):
   data = simplejson.loads(s)
   retval = SignedJwtAssertionCredentials(
       data['service_account_name'],
       base64.b64decode(data['private_key']),
       data['scope'],
       private_key_password=data['private_key_password'],
       user_agent=data['user_agent'],
       token_uri=data['token_uri'],
       **data['kwargs']
       )
   retval.invalid = data['invalid']
   retval.access_token = data['access_token']
   return retval
Exemplo n.º 36
0
def build(serviceName, version,
          http=None,
          discoveryServiceUrl=DISCOVERY_URI,
          developerKey=None,
          model=None,
          requestBuilder=HttpRequest):
  """Construct a Resource for interacting with an API.

  Construct a Resource object for interacting with
  an API. The serviceName and version are the
  names from the Discovery service.

  Args:
    serviceName: string, name of the service
    version: string, the version of the service
    discoveryServiceUrl: string, a URI Template that points to
      the location of the discovery service. It should have two
      parameters {api} and {apiVersion} that when filled in
      produce an absolute URI to the discovery document for
      that service.
    developerKey: string, key obtained
      from https://code.google.com/apis/console
    model: apiclient.Model, converts to and from the wire format
    requestBuilder: apiclient.http.HttpRequest, encapsulator for
      an HTTP request

  Returns:
    A Resource object with methods for interacting with
    the service.
  """
  params = {
      'api': serviceName,
      'apiVersion': version
      }

  if http is None:
    http = httplib2.Http()
  requested_url = uritemplate.expand(discoveryServiceUrl, params)
  logging.info('URL being requested: %s' % requested_url)
  resp, content = http.request(requested_url)
  if resp.status > 400:
    raise HttpError(resp, content, requested_url)
  try:
    service = simplejson.loads(content)
  except ValueError, e:
    logging.error('Failed to parse as JSON: ' + content)
    raise InvalidJsonError()
Exemplo n.º 37
0
def build(serviceName, version,
          http=None,
          discoveryServiceUrl=DISCOVERY_URI,
          developerKey=None,
          model=None,
          requestBuilder=HttpRequest):
  """Construct a Resource for interacting with an API.

  Construct a Resource object for interacting with
  an API. The serviceName and version are the
  names from the Discovery service.

  Args:
    serviceName: string, name of the service
    version: string, the version of the service
    discoveryServiceUrl: string, a URI Template that points to
      the location of the discovery service. It should have two
      parameters {api} and {apiVersion} that when filled in
      produce an absolute URI to the discovery document for
      that service.
    developerKey: string, key obtained
      from https://code.google.com/apis/console
    model: apiclient.Model, converts to and from the wire format
    requestBuilder: apiclient.http.HttpRequest, encapsulator for
      an HTTP request

  Returns:
    A Resource object with methods for interacting with
    the service.
  """
  params = {
      'api': serviceName,
      'apiVersion': version
      }

  if http is None:
    http = httplib2.Http()
  requested_url = uritemplate.expand(discoveryServiceUrl, params)
  logging.info('URL being requested: %s' % requested_url)
  resp, content = http.request(requested_url)
  if resp.status > 400:
    raise HttpError(resp, content, requested_url)
  try:
    service = simplejson.loads(content)
  except ValueError, e:
    logging.error('Failed to parse as JSON: ' + content)
    raise InvalidJsonError()
Exemplo n.º 38
0
    def _write(self):
        """Write the cached data back out.

    The multistore must be locked.
    """
        raw_data = {'file_version': 1}
        raw_creds = []
        raw_data['data'] = raw_creds
        for (cred_key, cred) in self._data.items():
            raw_key = {
                'clientId': cred_key[0],
                'userAgent': cred_key[1],
                'scope': cred_key[2]
            }
            raw_cred = simplejson.loads(cred.to_json())
            raw_creds.append({'key': raw_key, 'credential': raw_cred})
        return self._locked_json_write(raw_data)
Exemplo n.º 39
0
def _extract_id_token(id_token):
    """Extract the JSON payload from a JWT.

  Does the extraction w/o checking the signature.

  Args:
    id_token: string, OAuth 2.0 id_token.

  Returns:
    object, The deserialized JSON payload.
  """
    segments = id_token.split(".")

    if len(segments) != 3:
        raise VerifyJwtTokenError("Wrong number of segments in token: %s" % id_token)

    return simplejson.loads(_urlsafe_b64decode(segments[1]))
  def _write(self):
    """Write the cached data back out.

    The multistore must be locked.
    """
    raw_data = {'file_version': 1}
    raw_creds = []
    raw_data['data'] = raw_creds
    for (cred_key, cred) in self._data.items():
      raw_key = {
          'clientId': cred_key[0],
          'userAgent': cred_key[1],
          'scope': cred_key[2]
          }
      raw_cred = simplejson.loads(cred.to_json())
      raw_creds.append({'key': raw_key, 'credential': raw_cred})
    return self._locked_json_write(raw_data)
Exemplo n.º 41
0
def _extract_id_token(id_token):
    """Extract the JSON payload from a JWT.

  Does the extraction w/o checking the signature.

  Args:
    id_token: string, OAuth 2.0 id_token.

  Returns:
    object, The deserialized JSON payload.
  """
    segments = id_token.split('.')

    if (len(segments) != 3):
        raise VerifyJwtTokenError('Wrong number of segments in token: %s' %
                                  id_token)

    return simplejson.loads(_urlsafe_b64decode(segments[1]))
Exemplo n.º 42
0
Arquivo: client.py Projeto: pedia/svfs
  def new_from_json(cls, s):
    """Utility class method to instantiate a Credentials subclass from a JSON
    representation produced by to_json().

    Args:
      s: string, JSON from to_json().

    Returns:
      An instance of the subclass of Credentials that was serialized with
      to_json().
    """
    data = simplejson.loads(s)
    # Find and call the right classmethod from_json() to restore the object.
    module = data['_module']
    m = __import__(module, fromlist=module.split('.')[:-1])
    kls = getattr(m, data['_class'])
    from_json = getattr(kls, 'from_json')
    return from_json(s)
Exemplo n.º 43
0
    def new_from_json(cls, s):
        """Utility class method to instantiate a MediaUpload subclass from a JSON
    representation produced by to_json().

    Args:
      s: string, JSON from to_json().

    Returns:
      An instance of the subclass of MediaUpload that was serialized with
      to_json().
    """
        data = simplejson.loads(s)
        # Find and call the right classmethod from_json() to restore the object.
        module = data['_module']
        m = __import__(module, fromlist=module.split('.')[:-1])
        kls = getattr(m, data['_class'])
        from_json = getattr(kls, 'from_json')
        return from_json(s)
Exemplo n.º 44
0
    def step2_exchange(self, code, http=None):
        """Exhanges a code for OAuth2Credentials.

    Args:
      code: string or dict, either the code as a string, or a dictionary
        of the query parameters to the redirect_uri, which contains
        the code.
      http: httplib2.Http, optional http instance to use to do the fetch
    """

        if not (isinstance(code, str) or isinstance(code, unicode)):
            code = code['code']

        body = urllib.urlencode({
            'grant_type': 'authorization_code',
            'client_id': self.client_id,
            'client_secret': self.client_secret,
            'code': code,
            'redirect_uri': self.redirect_uri,
            'scope': self.scope,
        })
        headers = {
            'content-type': 'application/x-www-form-urlencoded',
        }

        if self.user_agent is not None:
            headers['user-agent'] = self.user_agent

        if http is None:
            http = httplib2.Http()

        resp, content = http.request(self.token_uri,
                                     method='POST',
                                     body=body,
                                     headers=headers)
        if resp.status == 200:
            # TODO(jcgregorio) Raise an error if simplejson.loads fails?
            d = simplejson.loads(content)
            access_token = d['access_token']
            refresh_token = d.get('refresh_token', None)
            token_expiry = None
            if 'expires_in' in d:
                token_expiry = datetime.datetime.utcnow() + datetime.timedelta(
                    seconds=int(d['expires_in']))

            if 'id_token' in d:
                d['id_token'] = _extract_id_token(d['id_token'])

            logger.info('Successfully retrieved access token: %s' % content)
            return OAuth2Credentials(access_token,
                                     self.client_id,
                                     self.client_secret,
                                     refresh_token,
                                     token_expiry,
                                     self.token_uri,
                                     self.user_agent,
                                     id_token=d.get('id_token', None))
        else:
            logger.error('Failed to retrieve access token: %s' % content)
            error_msg = 'Invalid response %s.' % resp['status']
            try:
                d = simplejson.loads(content)
                if 'error' in d:
                    error_msg = d['error']
            except:
                pass

            raise FlowExchangeError(error_msg)
Exemplo n.º 45
0
 def deserialize(self, content):
     body = simplejson.loads(content)
     if isinstance(body, dict) and 'data' in body:
         body = body['data']
     return body
Exemplo n.º 46
0
 def from_json(cls, json):
     data = simplejson.loads(json)
     return AppAssertionCredentials(data['scope'])
Exemplo n.º 47
0
 def from_json(cls, s):
     data = simplejson.loads(s)
     retval = AccessTokenCredentials(data['access_token'],
                                     data['user_agent'])
     return retval
Exemplo n.º 48
0
def verify_signed_jwt_with_certs(jwt, certs, audience):
    """Verify a JWT against public certs.

  See http://self-issued.info/docs/draft-jones-json-web-token.html.

  Args:
    jwt: string, A JWT.
    certs: dict, Dictionary where values of public keys in PEM format.
    audience: string, The audience, 'aud', that this JWT should contain. If
      None then the JWT's 'aud' parameter is not verified.

  Returns:
    dict, The deserialized JSON payload in the JWT.

  Raises:
    AppIdentityError if any checks are failed.
  """
    segments = jwt.split('.')

    if (len(segments) != 3):
        raise AppIdentityError('Wrong number of segments in token: %s' % jwt)
    signed = '%s.%s' % (segments[0], segments[1])

    signature = _urlsafe_b64decode(segments[2])

    # Parse token.
    json_body = _urlsafe_b64decode(segments[1])
    try:
        parsed = simplejson.loads(json_body)
    except:
        raise AppIdentityError('Can\'t parse token: %s' % json_body)

    # Check signature.
    verified = False
    for (keyname, pem) in certs.items():
        verifier = Verifier.from_string(pem, True)
        if (verifier.verify(signed, signature)):
            verified = True
            break
    if not verified:
        raise AppIdentityError('Invalid token signature: %s' % jwt)

    # Check creation timestamp.
    iat = parsed.get('iat')
    if iat is None:
        raise AppIdentityError('No iat field in token: %s' % json_body)
    earliest = iat - CLOCK_SKEW_SECS

    # Check expiration timestamp.
    now = long(time.time())
    exp = parsed.get('exp')
    if exp is None:
        raise AppIdentityError('No exp field in token: %s' % json_body)
    if exp >= now + MAX_TOKEN_LIFETIME_SECS:
        raise AppIdentityError('exp field too far in future: %s' % json_body)
    latest = exp + CLOCK_SKEW_SECS

    if now < earliest:
        raise AppIdentityError('Token used too early, %d < %d: %s' %
                               (now, earliest, json_body))
    if now > latest:
        raise AppIdentityError('Token used too late, %d > %d: %s' %
                               (now, latest, json_body))

    # Check audience.
    if audience is not None:
        aud = parsed.get('aud')
        if aud is None:
            raise AppIdentityError('No aud field in token: %s' % json_body)
        if aud != audience:
            raise AppIdentityError('Wrong recipient, %s != %s: %s' %
                                   (aud, audience, json_body))

    return parsed
Exemplo n.º 49
0
  def step2_exchange(self, code, http=None):
    """Exhanges a code for OAuth2Credentials.

    Args:
      code: string or dict, either the code as a string, or a dictionary
        of the query parameters to the redirect_uri, which contains
        the code.
      http: httplib2.Http, optional http instance to use to do the fetch
    """

    if not (isinstance(code, str) or isinstance(code, unicode)):
      code = code['code']

    body = urllib.urlencode({
        'grant_type': 'authorization_code',
        'client_id': self.client_id,
        'client_secret': self.client_secret,
        'code': code,
        'redirect_uri': self.redirect_uri,
        'scope': self.scope,
        })
    headers = {
        'content-type': 'application/x-www-form-urlencoded',
    }

    if self.user_agent is not None:
      headers['user-agent'] = self.user_agent

    if http is None:
      http = httplib2.Http()

    resp, content = http.request(self.token_uri, method='POST', body=body,
                                 headers=headers)
    if resp.status == 200:
      # TODO(jcgregorio) Raise an error if simplejson.loads fails?
      d = simplejson.loads(content)
      access_token = d['access_token']
      refresh_token = d.get('refresh_token', None)
      token_expiry = None
      if 'expires_in' in d:
        token_expiry = datetime.datetime.utcnow() + datetime.timedelta(
            seconds=int(d['expires_in']))

      if 'id_token' in d:
        d['id_token'] = _extract_id_token(d['id_token'])

      logger.info('Successfully retrieved access token: %s' % content)
      return OAuth2Credentials(access_token, self.client_id,
                               self.client_secret, refresh_token, token_expiry,
                               self.token_uri, self.user_agent,
                               id_token=d.get('id_token', None))
    else:
      logger.info('Failed to retrieve access token: %s' % content)
      error_msg = 'Invalid response %s.' % resp['status']
      try:
        d = simplejson.loads(content)
        if 'error' in d:
          error_msg = d['error']
      except:
        pass

      raise FlowExchangeError(error_msg)
Exemplo n.º 50
0
    def step2_exchange(self, code, http=None):
        """Exhanges a code for OAuth2Credentials.

    Args:
      code: string or dict, either the code as a string, or a dictionary
        of the query parameters to the redirect_uri, which contains
        the code.
      http: httplib2.Http, optional http instance to use to do the fetch
    """

        if not (isinstance(code, str) or isinstance(code, unicode)):
            code = code["code"]

        body = urllib.urlencode(
            {
                "grant_type": "authorization_code",
                "client_id": self.client_id,
                "client_secret": self.client_secret,
                "code": code,
                "redirect_uri": self.redirect_uri,
                "scope": self.scope,
            }
        )
        headers = {"content-type": "application/x-www-form-urlencoded"}

        if self.user_agent is not None:
            headers["user-agent"] = self.user_agent

        if http is None:
            http = httplib2.Http()

        resp, content = http.request(self.token_uri, method="POST", body=body, headers=headers)
        if resp.status == 200:
            # TODO(jcgregorio) Raise an error if simplejson.loads fails?
            d = simplejson.loads(content)
            access_token = d["access_token"]
            refresh_token = d.get("refresh_token", None)
            token_expiry = None
            if "expires_in" in d:
                token_expiry = datetime.datetime.utcnow() + datetime.timedelta(seconds=int(d["expires_in"]))

            if "id_token" in d:
                d["id_token"] = _extract_id_token(d["id_token"])

            logger.info("Successfully retrieved access token: %s" % content)
            return OAuth2Credentials(
                access_token,
                self.client_id,
                self.client_secret,
                refresh_token,
                token_expiry,
                self.token_uri,
                self.user_agent,
                id_token=d.get("id_token", None),
            )
        else:
            logger.error("Failed to retrieve access token: %s" % content)
            error_msg = "Invalid response %s." % resp["status"]
            try:
                d = simplejson.loads(content)
                if "error" in d:
                    error_msg = d["error"]
            except:
                pass

            raise FlowExchangeError(error_msg)
Exemplo n.º 51
0
 def from_json(cls, s):
   data = simplejson.loads(s)
   retval = AccessTokenCredentials(
       data['access_token'],
       data['user_agent'])
   return retval
Exemplo n.º 52
0
def verify_signed_jwt_with_certs(jwt, certs, audience):
  """Verify a JWT against public certs.

  See http://self-issued.info/docs/draft-jones-json-web-token.html.

  Args:
    jwt: string, A JWT.
    certs: dict, Dictionary where values of public keys in PEM format.
    audience: string, The audience, 'aud', that this JWT should contain. If
      None then the JWT's 'aud' parameter is not verified.

  Returns:
    dict, The deserialized JSON payload in the JWT.

  Raises:
    AppIdentityError if any checks are failed.
  """
  segments = jwt.split('.')

  if (len(segments) != 3):
    raise AppIdentityError(
      'Wrong number of segments in token: {0!s}'.format(jwt))
  signed = '{0!s}.{1!s}'.format(segments[0], segments[1])

  signature = _urlsafe_b64decode(segments[2])

  # Parse token.
  json_body = _urlsafe_b64decode(segments[1])
  try:
    parsed = simplejson.loads(json_body)
  except:
    raise AppIdentityError('Can\'t parse token: {0!s}'.format(json_body))

  # Check signature.
  verified = False
  for (keyname, pem) in certs.items():
    verifier = Verifier.from_string(pem, True)
    if (verifier.verify(signed, signature)):
      verified = True
      break
  if not verified:
    raise AppIdentityError('Invalid token signature: {0!s}'.format(jwt))

  # Check creation timestamp.
  iat = parsed.get('iat')
  if iat is None:
    raise AppIdentityError('No iat field in token: {0!s}'.format(json_body))
  earliest = iat - CLOCK_SKEW_SECS

  # Check expiration timestamp.
  now = long(time.time())
  exp = parsed.get('exp')
  if exp is None:
    raise AppIdentityError('No exp field in token: {0!s}'.format(json_body))
  if exp >= now + MAX_TOKEN_LIFETIME_SECS:
    raise AppIdentityError(
      'exp field too far in future: {0!s}'.format(json_body))
  latest = exp + CLOCK_SKEW_SECS

  if now < earliest:
    raise AppIdentityError('Token used too early, {0:d} < {1:d}: {2!s}'.format(now, earliest, json_body))
  if now > latest:
    raise AppIdentityError('Token used too late, {0:d} > {1:d}: {2!s}'.format(now, latest, json_body))

  # Check audience.
  if audience is not None:
    aud = parsed.get('aud')
    if aud is None:
      raise AppIdentityError('No aud field in token: {0!s}'.format(json_body))
    if aud != audience:
      raise AppIdentityError('Wrong recipient, {0!s} != {1!s}: {2!s}'.format(aud, audience, json_body))

  return parsed
def loads(s):
  obj = simplejson.loads(s)
  return _validate_clientsecrets(obj)
Exemplo n.º 54
0
 def from_json(s):
     d = simplejson.loads(s)
     return MediaFileUpload(d['_filename'], d['_mimetype'], d['_chunksize'],
                            d['_resumable'])