def step4_userinfo(self, credentials, http=None): """Obtains UserInfo from the UserInfo endpoint. Args: credentials Returns: OpenIDConnectCredentials Raises: FlowUserInfoError """ if http is None: http = httplib2.Http() http = credentials.authorize(http) resp, content = http.request(self.userinfo_uri) if resp.status == 200: d = simplejson.loads(content) userinfo = UserInfo(d) logging.debug('Successfully retrieved user info: %s' % userinfo) return OpenIDConnectCredentials(credentials, userinfo) else: logging.error('Failed to retrieve user info: %s' % content) error_msg = 'Invalid user info response %s.' % resp['status'] try: data = simplejson.loads(content) if 'error' in data: error_msg = data['error'] except Exception: pass raise FlowUserInfoError(error_msg)
def step3_verify_access_token(self, credentials, http=None): """Verifies access token at the TokenInfo endpoint. Args: credentials Returns: VerifiedTokenCredentials Raises: FlowTokenInfoError """ if http is None: http = httplib2.Http() resp, content = http.request(self.tokeninfo_uri, method="POST", body=urllib.urlencode({'access_token': credentials.access_token}), headers={'Content-Type': 'application/x-www-form-urlencoded'} ) if resp.status == 200: # Process the response d = simplejson.loads(content) tokeninfo = TokenInfo(d) logging.debug('Successfully retrieved token info: %s' % tokeninfo) verified_token_credentials = VerifiedTokenCredentials(credentials, tokeninfo) # Perform checks on the token info if verified_token_credentials.tokeninfo.audience \ != credentials.client_id: logging.error('token issued for a different client ' \ '- issued to %s, ' 'expected %s.' % (verified_token_credentials.tokeninfo.audience, credentials.client_id)) raise FlowTokenInfoError('invalid token') if int(verified_token_credentials.tokeninfo.expires_in) < 1: logging.error('token expired') raise FlowTokenInfoError('token expired') return verified_token_credentials else: logging.error('Failed to retrieve token info: %s' % content) error_msg = 'Invalid token info response %s.' % resp['status'] try: data = simplejson.loads(content) if 'error' in data: error_msg = data['error'] except Exception: pass raise FlowTokenInfoError(error_msg)
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
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
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 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()
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 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
def LoadBatchInfo(self, user_email, batch_name, bucket): logging.info('Loading batch info: %s' % batch_name) output_prefix = '%s/%s/output/' key = bucket.get_key('%s/%s/output/stitch.state' % (user_email, batch_name)) if key: batch_info = simplejson.loads(key.get_contents_as_string()) batch_info['name'] = batch_name return batch_info return { 'name': batch_name, 'status': 'WAITING', 'update_time': 0.0 }
def LoadBatchInfo(self, user_email, batch_name, bucket): logging.info('Loading batch info: %s' % batch_name) output_prefix = '%s/%s/output/' key = bucket.get_key('%s/%s/output/stitch.state' % (user_email, batch_name)) if key: batch_info = simplejson.loads(key.get_contents_as_string()) batch_info['name'] = batch_name return batch_info return {'name': batch_name, 'status': 'WAITING', 'update_time': 0.0}
def get(self): http = httplib2.Http(memcache) resp, content = http.request('https://www.googleapis.com/discovery/v1/apis?preferred=true') directory = simplejson.loads(content)['items'] for item in directory: item['title'] = item.get('title', item.get('description', '')) path = os.path.join(os.path.dirname(__file__), 'index.html') self.response.out.write( template.render( path, {'directory': directory, }))
def get(self): http = httplib2.Http(memcache) resp, content = http.request( 'https://www.googleapis.com/discovery/v1/apis?preferred=true') directory = simplejson.loads(content)['items'] for item in directory: item['title'] = item.get('title', item.get('description', '')) path = os.path.join(os.path.dirname(__file__), 'index.html') self.response.out.write( template.render(path, { 'directory': directory, }))
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 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)
if not "_" in name and callable(getattr(resource, name)) and hasattr( getattr(resource, name), '__is_resource__'): collections.append(name) obj, name = pydoc.resolve(type(resource)) page = pydoc.html.page( pydoc.describe(obj), pydoc.html.document(obj, name)) for name in collections: page = re.sub('strong>(%s)<' % name, r'strong><a href="%s">\1</a><' % (path + name + ".html"), page) for name in collections: document(getattr(resource, name)(), path + name + ".") f = open(os.path.join(BASE, path + 'html'), 'w') f.write(page) f.close() def document_api(name, version): service = build(name, version) document(service, '%s.%s.' % (name, version)) if __name__ == '__main__': http = httplib2.Http() resp, content = http.request('https://www.googleapis.com/discovery/v0.3/directory?preferred=true') 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.")
s.netloc, s.path, s.params, query, s.fragment) uri = urlparse.urlunparse(d) if FLAGS.dump_request: print '--request-start--' print '%s %s' % (method, uri) if headers: for (h, v) in headers.iteritems(): print '%s: %s' % (h, v) print '' if body: print json.dumps(json.loads(body), sort_keys=True, indent=2) print '--request-end--' return request_orig(uri, method, body, headers, redirections, connection_type) http.request = new_request return http def Run(self, argv): """Run the command, printing the result. Args: argv: The non-flag arguments to the command.
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()
d = urlparse.ParseResult(s.scheme, s.netloc, s.path, s.params, query, s.fragment) uri = urlparse.urlunparse(d) if FLAGS.dump_request: print '--request-start--' print '%s %s' % (method, uri) if headers: for (h, v) in headers.iteritems(): print '%s: %s' % (h, v) print '' if body: print json.dumps(json.loads(body), sort_keys=True, indent=2) print '--request-end--' return request_orig(uri, method, body, headers, redirections, connection_type) http.request = new_request return http def print_result(self, result): """Pretty-print the result of the command.
obj, name = pydoc.resolve(type(resource)) page = pydoc.html.page(pydoc.describe(obj), pydoc.html.document(obj, name)) for name in collections: page = re.sub('strong>(%s)<' % name, r'strong><a href="%s">\1</a><' % (path + name + ".html"), page) for name in collections: document(getattr(resource, name)(), path + name + ".") f = open(os.path.join(BASE, path + 'html'), 'w') f.write(page) f.close() def document_api(name, version): service = build(name, version) document(service, '%s.%s.' % (name, version)) if __name__ == '__main__': http = httplib2.Http() resp, content = http.request( 'https://www.googleapis.com/discovery/v0.3/directory?preferred=true') 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.")
def setUp(self): f = file(datafile('zoo.json')) discovery = f.read() f.close() discovery = simplejson.loads(discovery) self.sc = Schemas(discovery)