Example #1
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)
Example #2
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 = Schemas(service)

  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
Example #3
0
    def post(self, data_source_id):
        try:
            payload      = json.loads(self.request.POST["payload"])
            current_user = User.get_by_google_id(self.session['current_user'])
            data_source  = DataSource.get_by_id(int(data_source_id))

            if data_source is None:
                raise ValueError("No Data Source exists with id %s" % data_source_id)

            if not data_source.user.key() == current_user.key():
                raise ValueError("Data Source with id %s does not belong to user '%s'" % (data_source_id, current_user.profile_slug))

            if "description" in payload.keys(): data_source.description = payload['description']
            if "licence"     in payload.keys(): data_source.licence     = payload['licence']
            if "slug"        in payload.keys(): data_source.slug        = payload['slug']
            if "tags"        in payload.keys(): data_source.tags        = payload['tags']
            if "tbl_stars"   in payload.keys(): data_source.tbl_stars   = int(payload['tbl_stars'])
            if "title"       in payload.keys(): data_source.title       = payload['title']
            data_source.modified_at = DT.now()
            data_source.put()

            self.response.write('{"response":"success","body":%s}' % json.dumps(data_source.to_dict(), ensure_ascii=False))

        except ValueError as e:
            log_api_error(self, e)
            self.response.write('{"response":"error","body":"%s"}' % e)
            self.response.set_status(404)

        except Exception as e:
            log_api_error(self, e)
            self.response.write('{"response":"error","body":"Unknown problem updating data source"}')
            self.response.set_status(500)
  def verify_id_token(id_token, audience, http=None,
      cert_uri=ID_TOKEN_VERIFICATON_CERTS):
    """Verifies a signed JWT id_token.

    This function requires PyOpenSSL and because of that it does not work on
    App Engine.

    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 crypt.verify_signed_jwt_with_certs(id_token, certs, audience)
    else:
      raise VerifyJwtTokenError('Status code: %d' % resp.status)
Example #5
0
 def deserialize(self, content):
   if type(content) is bytes:
       content = content.decode('utf-8')
   body = simplejson.loads(content)
   if self._data_wrapper and isinstance(body, dict) and 'data' in body:
     body = body['data']
   return body
Example #6
0
  def _refresh(self, http_request):
    """Refreshes the access_token.

    Skip all the storage hoops and just refresh using the API.

    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.
    """
    uri = uritemplate.expand(META, {'scope': self.scope})
    response, content = http_request(uri)
    if response.status == 200:
      try:
        d = simplejson.loads(content)
      except Exception as e:
        raise AccessTokenRefreshError(str(e))
      self.access_token = d['accessToken']
    else:
      if response.status == 404:
        content = content + (' This can occur if a VM was created'
            ' with no service account or scopes.')
      raise AccessTokenRefreshError(content)
Example #7
0
    def post(self, data_source_id, data_view_id):
        try:
            current_user = User.get_by_google_id(self.session['current_user'])
            data_source  = DataSource.get_by_id(int(data_source_id))
            data_view    = DataView.get_by_id(int(data_view_id))
            payload      = json.loads(self.request.POST["payload"])

            if data_source is None:
                raise ValueError("No Data Source exists with id %s" % data_source_id)

            if not data_source.user.key() == current_user.key():
                raise ValueError("Data Source with id %s does not belong to user '%s'" % (data_source_id, current_user.profile_slug))

            if data_view is None:
                raise ValueError("No Data View exists with id %s" % data_source_id)

            if not data_view.data_source.key() == data_source.key():
                raise ValueError("Data View with id %s does not belong to Data Source with id %s" % (data_view_id, data_source_id))

            if "template" in payload.keys(): 
                data_view.template = payload['template']
                data_view.modified_at = DT.now()
                data_view.put()

            self.response.write('{"response":"success","body":%s}' % json.dumps(data_view.to_dict(), ensure_ascii=False))

        except ValueError as e:
            log_api_error(self, e)
            self.response.write('{"response":"error","body":"%s"}' % e)
            self.response.set_status(404)

        except Exception as e:
            log_api_error(self, e)
            self.response.write('{"response":"error","body":"Unknown problem updating data source"}')
            self.response.set_status(500)
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
  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()
Example #10
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()
Example #11
0
    def test_resumable_media_handle_resume_of_upload_of_unknown_size(self):
        http = HttpMockSequence(
            [({"status": "200", "location": "http://upload.example.com"}, ""), ({"status": "400"}, "")]
        )

        self.http = HttpMock(datafile("zoo.json"), {"status": "200"})
        zoo = build("zoo", "v1", http=self.http)

        # Create an upload that doesn't know the full size of the media.
        fd = io.StringIO("data goes here")

        upload = MediaIoBaseUpload(fd=fd, mimetype="image/png", chunksize=500, resumable=True)

        request = zoo.animals().insert(media_body=upload, body=None)

        # Put it in an error state.
        self.assertRaises(HttpError, request.next_chunk, http=http)

        http = HttpMockSequence([({"status": "400", "range": "0-5"}, "echo_request_headers_as_json")])
        try:
            # Should resume the upload by first querying the status of the upload.
            request.next_chunk(http=http)
        except HttpError as e:
            expected = {"Content-Range": "bytes */14", "content-length": "0"}
            self.assertEqual(
                expected,
                simplejson.loads(e.content),
                "Should send an empty body when requesting the current upload status.",
            )
  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 test_auth_header_sent(self):
   http = HttpMockSequence([
     ({'status': '200'}, 'echo_request_headers'),
     ])
   http = self.credentials.authorize(http)
   resp, content = http.request('http://example.com')
   self.assertEqual('Bearer foo', simplejson.loads(content.decode())['Authorization'])
  def test_resumable_media_handle_resume_of_upload_of_unknown_size(self):
    http = HttpMockSequence([
      ({'status': '200',
        'location': 'http://upload.example.com'}, ''),
      ({'status': '400'}, ''),
      ])

    self.http = HttpMock(datafile('zoo.json'), {'status': '200'})
    zoo = build('zoo', 'v1', http=self.http)

    # Create an upload that doesn't know the full size of the media.
    fd = io.StringIO('data goes here')

    upload = MediaIoBaseUpload(
        fd=fd, mimetype='image/png', chunksize=500, resumable=True)

    request = zoo.animals().insert(media_body=upload, body=None)

    # Put it in an error state.
    self.assertRaises(HttpError, request.next_chunk, http=http)

    http = HttpMockSequence([
      ({'status': '400',
        'range': '0-5'}, 'echo_request_headers_as_json'),
      ])
    try:
      # Should resume the upload by first querying the status of the upload.
      request.next_chunk(http=http)
    except HttpError as e:
      expected = {
          'Content-Range': 'bytes */14',
          'content-length': '0'
          }
      self.assertEqual(expected, simplejson.loads(e.content),
        'Should send an empty body when requesting the current upload status.')
Example #15
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"],
            id_token=data.get("id_token", None),
        )
        retval.invalid = data["invalid"]
        return retval
  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 = cls(
        data['access_token'],
        data['client_id'],
        data['client_secret'],
        data['refresh_token'],
        data['token_expiry'],
        data['token_uri'],
        data['user_agent'],
        revoke_uri=data.get('revoke_uri', None),
        id_token=data.get('id_token', None),
        token_response=data.get('token_response', None))
    retval.invalid = data['invalid']
    return retval
Example #17
0
 def test_can_build_from_local_deserialized_document(self):
     with open(datafile("plus.json")) as plusfile:
         discovery = plusfile.read()
     discovery = simplejson.loads(discovery)
     plus = build_from_document(discovery, base="https://www.googleapis.com/")
     self.assertTrue(plus is not None)
     self.assertTrue(hasattr(plus, "activities"))
  def test_logging(self):
    class MockLogging(object):
      def __init__(self):
        self.info_record = []
        self.debug_record = []
      def info(self, message, *args):
        self.info_record.append(message % args)

      def debug(self, message, *args):
        self.debug_record.append(message % args)

    class MockResponse(dict):
      def __init__(self, items):
        super(MockResponse, self).__init__()
        self.status = items['status']
        for key, value in items.iteritems():
          self[key] = value
    old_logging = apiclient.model.logging
    apiclient.model.logging = MockLogging()
    apiclient.model.FLAGS = copy.deepcopy(FLAGS)
    apiclient.model.FLAGS.dump_request_response = True
    model = JsonModel()
    request_body = {
        'field1': 'value1',
        'field2': 'value2'
        }
    body_string = model.request({}, {}, {}, request_body)[-1]
    json_body = simplejson.loads(body_string)
    self.assertEqual(request_body, json_body)

    response = {'status': 200,
                'response_field_1': 'response_value_1',
                'response_field_2': 'response_value_2'}
    response_body = model.response(MockResponse(response), body_string)
    self.assertEqual(request_body, response_body)
    self.assertEqual(apiclient.model.logging.info_record[:2],
                     ['--request-start--',
                      '-headers-start-'])
    self.assertTrue('response_field_1: response_value_1' in
                    apiclient.model.logging.info_record)
    self.assertTrue('response_field_2: response_value_2' in
                    apiclient.model.logging.info_record)
    self.assertEqual(simplejson.loads(apiclient.model.logging.info_record[-2]),
                     request_body)
    self.assertEqual(apiclient.model.logging.info_record[-1],
                     '--response-end--')
    apiclient.model.logging = old_logging
 def test_assertion_refresh(self):
   http = HttpMockSequence([
     ({'status': '200'}, '{"access_token":"1/3w"}'),
     ({'status': '200'}, 'echo_request_headers'),
     ])
   http = self.credentials.authorize(http)
   resp, content = http.request('http://example.com')
   self.assertEqual('Bearer 1/3w', simplejson.loads(content.decode())['Authorization'])
Example #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)
    content = content.decode()
    if resp.status == 200:
      # TODO(jcgregorio) Raise an error if loads fails?
      d = simplejson.loads(content)
      self.token_response = d
      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 Exception:
        pass
      raise AccessTokenRefreshError(error_msg)
Example #21
0
  def test_set_user_agent(self):
    http = HttpMockSequence([
      ({'status': '200'}, 'echo_request_headers'),
      ])

    http = set_user_agent(http, "my_app/5.5")
    resp, content = http.request("http://example.com")
    content = simplejson.loads(content.decode())
    self.assertEqual('my_app/5.5', content['user-agent'])
Example #22
0
def get_directory_doc():
  http = httplib2.Http(memcache)
  ip = os.environ.get('REMOTE_ADDR', None)
  uri = DISCOVERY_URI
  if ip:
    uri += ('&userIp=' + ip)
  resp, content = http.request(uri)
  directory = simplejson.loads(content)['items']
  return directory
Example #23
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
     return reason
 def getLatLng(self, addr):
   url = self.geourl[:] # copy
   url.append('&address=%s' % urllib.quote_plus(addr.encode('utf-8')))
   http = httplib2.Http()
   headers, body = http.request(''.join(url))
   if headers.status != 200: return None
   obj = simplejson.loads(body.decode('utf-8'))
   if obj['status'] != 'OK': return None
   loc = obj['results'][0]['geometry']['location']
   return (loc['lat'], loc['lng']) # carefully drift of floating point number
Example #25
0
    def get(self, credentials, action):
        http = Http()
        http = credentials.authorize(http)

        time_diff = datetime.now() - self.last_call
        if time_diff < self.rate:
            time.sleep(time_diff.total_seconds())

        headers, content = http.request('https://oauth.reddit.com' + action)
        return simplejson.loads(content)
Example #26
0
    def get(self):
        try:
            # NB we have to decode "credentials" as it is stored as a string in the DB
            current_user = User.get_by_google_id(self.session['current_user']).to_dict()
            current_user["credentials"] = json.loads(current_user["credentials"])
            self.response.write('{"response":"success","body":%s}' % json.dumps(current_user, ensure_ascii=False))

        except Exception as e:
            log_api_error(self, e)
            self.response.write('{"response":"error","body":"Unknown problem fetching user profile"}')
            self.response.set_status(500)
Example #27
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
 def getLatLng(self, addr):
     url = self.geourl[:]  # copy
     url.append('&address=%s' % urllib.quote_plus(addr.encode('utf-8')))
     http = httplib2.Http()
     headers, body = http.request(''.join(url))
     if headers.status != 200: return None
     obj = simplejson.loads(body.decode('utf-8'))
     if obj['status'] != 'OK': return None
     loc = obj['results'][0]['geometry']['location']
     return (loc['lat'], loc['lng']
             )  # carefully drift of floating point number
    def test_set_user_agent(self):
        http = HttpMockSequence([
            ({
                'status': '200'
            }, 'echo_request_headers'),
        ])

        http = set_user_agent(http, "my_app/5.5")
        resp, content = http.request("http://example.com")
        content = simplejson.loads(content.decode())
        self.assertEqual('my_app/5.5', content['user-agent'])
Example #30
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
Example #31
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
  def test_required(self):
    # An initial request to an oauth_required decorated path should be a
    # redirect to start the OAuth dance.
    response = self.app.get('http://localhost/foo_path')
    self.assertTrue(response.status.startswith('302'))
    q = parse_qs(response.headers['Location'].split('?', 1)[1])
    self.assertEqual('http://localhost/oauth2callback', q['redirect_uri'][0])
    self.assertEqual('foo_client_id', q['client_id'][0])
    self.assertEqual('foo_scope bar_scope', q['scope'][0])
    self.assertEqual('http://localhost/foo_path',
                     q['state'][0].rsplit(':', 1)[0])
    self.assertEqual('code', q['response_type'][0])
    self.assertEqual(False, self.decorator.has_credentials())

    m = mox.Mox()
    m.StubOutWithMock(appengine, '_parse_state_value')
    appengine._parse_state_value('foo_path:xsrfkey123',
                       mox.IgnoreArg()).AndReturn('foo_path')
    m.ReplayAll()

    # Now simulate the callback to /oauth2callback.
    response = self.app.get('/oauth2callback', {
        'code': 'foo_access_code',
        'state': 'foo_path:xsrfkey123',
        })
    parts = response.headers['Location'].split('?', 1)
    self.assertEqual('http://localhost/foo_path', parts[0])
    self.assertEqual(None, self.decorator.credentials)
    if self.decorator._token_response_param:
        response = parse_qs(parts[1])[self.decorator._token_response_param][0]
        self.assertEqual(Http2Mock.content,
                         simplejson.loads(urllib.unquote(response)))

    m.UnsetStubs()
    m.VerifyAll()

    # Now requesting the decorated path should work.
    response = self.app.get('/foo_path')
    self.assertEqual('200 OK', response.status)
    self.assertEqual(True, self.decorator.has_credentials())
    self.assertEqual('foo_refresh_token',
                     self.decorator.credentials.refresh_token)
    self.assertEqual('foo_access_token',
                     self.decorator.credentials.access_token)

    # Invalidate the stored Credentials.
    self.decorator.credentials.invalid = True
    self.decorator.credentials.store.put(self.decorator.credentials)

    # Invalid Credentials should start the OAuth dance again.
    response = self.app.get('/foo_path')
    self.assertTrue(response.status.startswith('302'))
    q = parse_qs(response.headers['Location'].split('?', 1)[1])
    self.assertEqual('http://localhost/oauth2callback', q['redirect_uri'][0])
Example #33
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
Example #34
0
def get_directory_doc():
    http = httplib2.Http(memcache)
    ip = os.environ.get('REMOTE_ADDR', None)
    uri = DISCOVERY_URI
    if ip:
        uri += ('&userIp=' + ip)
    resp, content = http.request(uri)
    directory = simplejson.loads(content)['items']
    for item in directory:
        item['title'] = item.get('title', item.get('description', ''))
        item['safe_version'] = describe.safe_version(item['version'])
    return directory
Example #35
0
def to_dict(credentials):
    """
    Convert a Credentials object to a dictionary.

    The Credentials object is first converted to JSON by the native implementation
    to ensure it is converted correctly and make updates to the oauth2client module
    easier.
    """
    jsonRepr = credentials.to_json()
    dictRepr = simplejson.loads(jsonRepr)

    return dictRepr
Example #36
0
def get_directory_doc():
  http = httplib2.Http(memcache)
  ip = os.environ.get('REMOTE_ADDR', None)
  uri = DISCOVERY_URI
  if ip:
    uri += ('&userIp=' + ip)
  resp, content = http.request(uri)
  directory = simplejson.loads(content)['items']
  for item in directory:
    item['title'] = item.get('title', item.get('description', ''))
    item['safe_version'] = describe.safe_version(item['version'])
  return directory
Example #37
0
 def test_assertion_refresh(self):
     http = HttpMockSequence([
         ({
             'status': '200'
         }, '{"access_token":"1/3w"}'),
         ({
             'status': '200'
         }, 'echo_request_headers'),
     ])
     http = self.credentials.authorize(http)
     resp, content = http.request('http://example.com')
     self.assertEqual('Bearer 1/3w',
                      simplejson.loads(content.decode())['Authorization'])
Example #38
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'])
Example #39
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
Example #40
0
    def upload(self, id, name, create=False):
        logger = logging.getLogger()
        foldername = os.path.join(self.folder, name)
        logger.info('prepare folder: %s' % foldername)
        manifest_path = os.path.join(foldername, MANIFEST)
        mfile = open(manifest_path, 'rb')
        data = simplejson.loads(mfile.read())
        mfile.close()
        # import files in the directory
        for i, fileInProject in enumerate(data['files']):
            extension = '.html'  # default
            if fileInProject['type'] == 'server_js': extension = '.gs'
            filename = '%s%s' % (fileInProject['name'], extension)
            logger.info('- file%04d: %s' % (i, filename))
            f = open(os.path.join(foldername, filename), 'rb')
            fileInProject['source'] = f.read().decode(
                'utf-8')  # to unicode json
            f.close()
        # last import manifest.json
        logger.info('- manifest: %s' % MANIFEST)
        mfile = open(manifest_path, 'wb')
        mfile.write(simplejson.dumps(data))
        mfile.close()

        mbody = MediaFileUpload(manifest_path,
                                mimetype=SCRIPT_TYPE,
                                resumable=True)
        if create:  # create new Apps Script project
            body = {
                'title': name,
                'mimeType': SCRIPT_TYPE,
                'description': name
            }
            fileobj = self.service.files().insert(body=body,
                                                  media_body=mbody).execute()
            id = fileobj['id']
            # export manifest.json to refresh new file id
            download_url = fileobj['exportLinks'][SCRIPT_TYPE]
            resp, content = self.service._http.request(download_url)
            if resp.status != 200:
                raise Exception('An error occurred: %s' % resp)
            logger.info('- refresh: %s' % MANIFEST)
            mfile = open(manifest_path, 'wb')
            mfile.write(content)  # raw string
            mfile.close()
        else:  # overwrite exists Apps Script project
            body = {'mimeType': SCRIPT_TYPE}
            fileobj = self.service.files().update(fileId=id,
                                                  body=body,
                                                  media_body=mbody).execute()
        return (id, fileobj)
Example #41
0
def build_from_document(service,
                        base=None,
                        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 or object, the JSON discovery document describing the API.
      The value passed in may either be the JSON string or the deserialized
      JSON.
    base: string, base URI for all HTTP requests, usually the discovery URI.
      This parameter is no longer used as rootUrl and servicePath are included
      within the discovery document. (deprecated)
    future: string, discovery document with future capabilities (deprecated).
    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.
  """

    # future is no longer used.
    future = {}

    if isinstance(service, str):
        service = simplejson.loads(service)
    base = urllib.parse.urljoin(service['rootUrl'], service['servicePath'])
    schema = Schemas(service)

    if model is None:
        features = service.get('features', [])
        model = JsonModel('dataWrapper' in features)
    return Resource(http=http,
                    baseUrl=base,
                    model=model,
                    developerKey=developerKey,
                    requestBuilder=requestBuilder,
                    resourceDesc=service,
                    rootDesc=service,
                    schema=schema)
  def test_assertion(self):
    assertion = self.credentials._generate_assertion()

    parts = assertion.split(".")
    self.assertTrue(len(parts) == 3)

    header, body, signature = [base64.b64decode(part) for part in parts]

    header_dict = simplejson.loads(header)
    self.assertEqual(header_dict['typ'], 'JWT')
    self.assertEqual(header_dict['alg'], 'RS256')

    body_dict = simplejson.loads(body)
    self.assertEqual(body_dict['aud'],
                     'https://accounts.google.com/o/oauth2/token')
    self.assertEqual(body_dict['scope'], self.scope)
    self.assertEqual(body_dict['iss'], self.account_name)

    issuedAt = body_dict['iat']
    self.assertTrue(issuedAt > 0)
    self.assertEqual(body_dict['exp'], issuedAt + 3600)

    self.assertEqual(signature, self.signature)
 def first_authorize(self):
     '''OAuth2 save credentials'''
     print 'client secret open. CI=%s' % self.clientId
     fn = os.path.join(self.basedir, CLIENT_FILE % self.clientId)
     if not os.path.exists(fn):
         raise Exception('client secret does not exist.')
     while True:
         pid = getpass.getpass()
         try:
             d = readJsonClient(self.basedir, pid, self.clientId)
             cli = simplejson.loads(d)['installed']
         except (Exception, ), e:
             cli = None
         if cli is None: print 'password may be incorrect.'
         else: break
Example #44
0
def buildDiscoveryObject(api, api_ver):
    params = {'api': api, 'apiVersion': api_ver}
    http = httplib2.Http()
    requested_url = uritemplate.expand(apiclient.discovery.DISCOVERY_URI,
                                       params)
    resp, content = http.request(requested_url)
    if resp.status == 404:
        raise UnknownApiNameOrVersion("name: %s  version: %s" %
                                      (main_options.api, main_options.api_ver))
    if resp.status >= 400:
        raise HttpError(resp, content, uri=requested_url)
    try:
        return simplejson.loads(content)
    except ValueError, e:
        logger.error('Failed to parse as JSON: ' + content)
        raise InvalidJsonError()
Example #45
0
def handle_error(request, e):
    """Handles an API exception, preparing it for display to the user."""
    if (e.content):
        content_obj = simplejson.loads(e.content)
        if ('error' in content_obj and 'errors' in content_obj['error']):
            return render(
                request,
                "blog/error.html",
                {"e": [x['message'] for x in content_obj['error']['errors']]}
            )
        else:
            return render(
                request,
                "blog/error.html",
                {"e": [str(e)]}
            )
 def getLocation(self, lat, lng):
     url = self.geourl[:]  # copy
     url.append('&latlng=%s,%s' % (lat, lng))
     http = httplib2.Http()
     headers, body = http.request(''.join(url))
     if headers.status != 200: return None
     obj = simplejson.loads(body.decode('utf-8'))
     if obj['status'] != 'OK': return None
     for result in obj['results']:
         if 'sublocality' in result['types']:
             fa = result['formatted_address']
             if self.ignoreCountryHead:
                 return fa.replace(u'%s, ' % self.countryStr, u'', 1)
             else:
                 return fa
     return None
Example #47
0
 def download(self, id):
     logger = logging.getLogger()
     fileobj = self.service.files().get(fileId=id).execute()
     download_url = fileobj['exportLinks'][SCRIPT_TYPE]
     resp, content = self.service._http.request(download_url)
     if resp.status != 200: raise Exception('An error occurred: %s' % resp)
     data = simplejson.loads(content)
     foldername = os.path.join(self.folder, fileobj['title'])
     logger.info('prepare folder: %s' % foldername)
     if not os.path.exists(foldername): os.makedirs(foldername)
     # Delete any files in the directory
     for the_file in os.listdir(foldername):
         file_path = os.path.join(foldername, the_file)
         try:
             if os.path.isfile(file_path): os.unlink(file_path)
         except (Exception, ), e:
             print e
Example #48
0
def document_api_from_discovery_document(uri):
  """Document the given API.

  Args:
    uri: string, URI of discovery document.
  """
  http = httplib2.Http()
  response, content = http.request(FLAGS.discovery_uri)
  discovery = simplejson.loads(content)

  service = build_from_document(discovery)

  name = discovery['version']
  version = safe_version(discovery['version'])

  document_collection_recursive(
      service, '%s_%s.' % (name, version), discovery, discovery)
Example #49
0
    def get(self, service_name, version, collection):

        real_version = describe.unsafe_version(version)

        logging.info('%s %s %s', service_name, version, collection)
        http = httplib2.Http(memcache)
        try:
            resource = discovery.build(service_name, real_version, http=http)
        except:
            logging.error('Failed to build service.')
            return self.error(404)

        DISCOVERY_URI = ('https://www.googleapis.com/discovery/v1/apis/'
                         '{api}/{apiVersion}/rest')
        response, content = http.request(
            uritemplate.expand(DISCOVERY_URI, {
                'api': service_name,
                'apiVersion': real_version
            }))
        root_discovery = simplejson.loads(content)
        collection_discovery = root_discovery

        # descend the object path
        if collection:
            try:
                path = collection.split('.')
                if path:
                    for method in path:
                        resource = getattr(resource, method)()
                        collection_discovery = collection_discovery[
                            'resources'][method]
            except:
                logging.error('Failed to parse the collections.')
                return self.error(404)
        logging.info('Built everything successfully so far.')

        path = '%s_%s.' % (service_name, version)
        if collection:
            path += '.'.join(collection.split('/'))
            path += '.'

        page = describe.document_collection(resource, path, root_discovery,
                                            collection_discovery)

        self.response.out.write(page)
Example #50
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: {0!s}'.format(id_token))

    return simplejson.loads(_urlsafe_b64decode(segments[1]))
Example #51
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)
Example #52
0
def document_api(name, version):
    """Document the given API.

  Args:
    name: string, Name of the API.
    version: string, Version of the API.
  """
    service = build(name, version)
    response, content = http.request(
        uritemplate.expand(FLAGS.discovery_uri_template, {
            'api': name,
            'apiVersion': version
        }))
    discovery = simplejson.loads(content)

    version = safe_version(version)

    document_collection_recursive(service, '%s_%s.' % (name, version),
                                  discovery, discovery)
Example #53
0
    def FetchAccessToken(self):
        response = None
        try:
            http = httplib2.Http()
            response, content = http.request(META_TOKEN_URI,
                                             method='GET',
                                             body=None,
                                             headers=META_HEADERS)
        except Exception:
            raise GsAccessTokenRefreshError()

        if response.status == 200:
            d = simplejson.loads(content)

            return AccessToken(
                d['access_token'],
                datetime.datetime.now() +
                datetime.timedelta(seconds=d.get('expires_in', 0)),
                datetime_strategy=self.datetime_strategy)
Example #54
0
    def test_resumable_media_handle_resume_of_upload_of_unknown_size(self):
        http = HttpMockSequence([
            ({
                'status': '200',
                'location': 'http://upload.example.com'
            }, ''),
            ({
                'status': '400'
            }, ''),
        ])

        self.http = HttpMock(datafile('zoo.json'), {'status': '200'})
        zoo = build('zoo', 'v1', http=self.http)

        # Create an upload that doesn't know the full size of the media.
        fd = io.StringIO('data goes here')

        upload = MediaIoBaseUpload(fd=fd,
                                   mimetype='image/png',
                                   chunksize=500,
                                   resumable=True)

        request = zoo.animals().insert(media_body=upload, body=None)

        # Put it in an error state.
        self.assertRaises(HttpError, request.next_chunk, http=http)

        http = HttpMockSequence([
            ({
                'status': '400',
                'range': '0-5'
            }, 'echo_request_headers_as_json'),
        ])
        try:
            # Should resume the upload by first querying the status of the upload.
            request.next_chunk(http=http)
        except HttpError as e:
            expected = {'Content-Range': 'bytes */14', 'content-length': '0'}
            self.assertEqual(
                expected, simplejson.loads(e.content),
                'Should send an empty body when requesting the current upload status.'
            )
Example #55
0
    def _refresh(self, http_request):
        """Refreshes the access_token.

    Skip all the storage hoops and just refresh using the API.

    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.
    """
        uri = uritemplate.expand(META, {'scope': self.scope})
        response, content = http_request(uri)
        if response.status == 200:
            try:
                d = simplejson.loads(content)
            except StandardError, e:
                raise AccessTokenRefreshError(str(e))
            self.access_token = d['accessToken']
Example #56
0
 def test_token_refresh_success(self):
     for status_code in REFRESH_STATUS_CODES:
         token_response = {'access_token': '1/3w', 'expires_in': 3600}
         http = HttpMockSequence([
             ({
                 'status': status_code
             }, ''),
             ({
                 'status': '200'
             }, simplejson.dumps(token_response)),
             ({
                 'status': '200'
             }, 'echo_request_headers'),
         ])
         http = self.credentials.authorize(http)
         resp, content = http.request('http://example.com')
         self.assertEqual(
             'Bearer 1/3w',
             simplejson.loads(content.decode())['Authorization'])
         self.assertFalse(self.credentials.access_token_expired)
         self.assertEqual(token_response, self.credentials.token_response)
    def test_turn_get_into_post(self):
        def _postproc(resp, content):
            return content

        http = HttpMockSequence([
            ({
                'status': '200'
            }, 'echo_request_body'),
            ({
                'status': '200'
            }, 'echo_request_headers'),
        ])

        # Send a long query parameter.
        query = {'q': 'a' * MAX_URI_LENGTH + '?&'}
        req = HttpRequest(http,
                          _postproc,
                          'http://example.com?' +
                          urllib.parse.urlencode(query),
                          method='GET',
                          body=None,
                          headers={},
                          methodId='foo',
                          resumable=None)

        # Query parameters should be sent in the body.
        response = req.execute()
        self.assertEqual('q=' + 'a' * MAX_URI_LENGTH + '%3F%26', response)

        # Extra headers should be set.
        response = req.execute()
        response = simplejson.loads(response.decode())
        self.assertEqual('GET', response['x-http-method-override'])
        self.assertEqual(str(MAX_URI_LENGTH + 8), response['content-length'])
        self.assertEqual('application/x-www-form-urlencoded',
                         response['content-type'])
Example #58
0
 def from_json(cls, json):
   data = simplejson.loads(json)
   return AppAssertionCredentials(data['scope'])
Example #59
0
    uri: string, URI of discovery document.
  """
  http = httplib2.Http()
  response, content = http.request(FLAGS.discovery_uri)
  discovery = simplejson.loads(content)

  service = build_from_document(discovery)

  name = discovery['version']
  version = safe_version(discovery['version'])

  document_collection_recursive(
      service, '%s_%s.' % (name, version), discovery, discovery)


if __name__ == '__main__':
  FLAGS = parser.parse_args(sys.argv[1:])
  if FLAGS.discovery_uri:
    document_api_from_discovery_document(FLAGS.discovery_uri)
  else:
    http = httplib2.Http()
    resp, content = http.request(
        FLAGS.directory_uri,
        headers={'X-User-IP': '0.0.0.0'})
    if resp.status == 200:
      directory = simplejson.loads(content)['items']
      for api in directory:
        document_api(api['name'], api['version'])
    else:
      sys.exit("Failed to load the discovery document.")
Example #60
0
  def test_required(self):
    # An initial request to an oauth_required decorated path should be a
    # redirect to start the OAuth dance.
    self.assertEqual(self.decorator.flow, None)
    self.assertEqual(self.decorator.credentials, None)
    response = self.app.get('http://localhost/foo_path')
    self.assertTrue(response.status.startswith('302'))
    q = parse_qs(response.headers['Location'].split('?', 1)[1])
    self.assertEqual('http://localhost/oauth2callback', q['redirect_uri'][0])
    self.assertEqual('foo_client_id', q['client_id'][0])
    self.assertEqual('foo_scope bar_scope', q['scope'][0])
    self.assertEqual('http://localhost/foo_path',
                     q['state'][0].rsplit(':', 1)[0])
    self.assertEqual('code', q['response_type'][0])
    self.assertEqual(False, self.decorator.has_credentials())

    m = mox.Mox()
    m.StubOutWithMock(appengine, '_parse_state_value')
    appengine._parse_state_value('foo_path:xsrfkey123',
                       mox.IgnoreArg()).AndReturn('foo_path')
    m.ReplayAll()

    # Now simulate the callback to /oauth2callback.
    response = self.app.get('/oauth2callback', {
        'code': 'foo_access_code',
        'state': 'foo_path:xsrfkey123',
        })
    parts = response.headers['Location'].split('?', 1)
    self.assertEqual('http://localhost/foo_path', parts[0])
    self.assertEqual(None, self.decorator.credentials)
    if self.decorator._token_response_param:
      response = parse_qs(parts[1])[self.decorator._token_response_param][0]
      self.assertEqual(Http2Mock.content,
                       simplejson.loads(urllib.unquote(response)))
    self.assertEqual(self.decorator.flow, self.decorator._tls.flow)
    self.assertEqual(self.decorator.credentials,
                     self.decorator._tls.credentials)

    m.UnsetStubs()
    m.VerifyAll()

    # Now requesting the decorated path should work.
    response = self.app.get('/foo_path')
    self.assertEqual('200 OK', response.status)
    self.assertEqual(True, self.had_credentials)
    self.assertEqual('foo_refresh_token',
                     self.found_credentials.refresh_token)
    self.assertEqual('foo_access_token',
                     self.found_credentials.access_token)
    self.assertEqual(None, self.decorator.credentials)

    # Raising an exception still clears the Credentials.
    self.should_raise = True
    try:
      response = self.app.get('/foo_path')
      self.fail('Should have raised an exception.')
    except Exception:
      pass
    self.assertEqual(None, self.decorator.credentials)
    self.should_raise = False

    # Invalidate the stored Credentials.
    self.found_credentials.invalid = True
    self.found_credentials.store.put(self.found_credentials)

    # Invalid Credentials should start the OAuth dance again.
    response = self.app.get('/foo_path')
    self.assertTrue(response.status.startswith('302'))
    q = parse_qs(response.headers['Location'].split('?', 1)[1])
    self.assertEqual('http://localhost/oauth2callback', q['redirect_uri'][0])