def PostMiddleware(request, session, spec): tyk.log("This is my post middleware", "info") customerID = request.get_header('CustomerID') #tyk.log("customerID: " + customerID, "info") payload = { "customerID": "1234", "userID": "*****@*****.**", "country": "NL", "scope": "device:read" } my_secret = 'my_super_secret' private_key = open('/opt/tyk-gateway/id_rsa', 'r').read() key = serialization.load_ssh_private_key(private_key.encode(), password=b'') #token = jwt.encode( # payload=payload, # key=my_secret #) token = jwt.encode(payload=payload, key=key, algorithm='RS256') tyk.log("jwt: " + token, "info") request.add_header("Authorization", token) return request, session
def ResponseHook(request, response, session, metadata, spec): tyk.log("ResponseHook is called", "info") addConfigDataToResponseBody(response, spec['config_data']) tyk.log("response info: {0}".format(MessageToJson(response)), "info") return response
def check_plugintest_querystr(request, session, spec): tyk.log('[PLUGIN] [{0}::post::init] Current working dir: {1}'.format( plugin_conf['api-endpoint'], str(cwd)), 'debug') resp_status = 200 querystr = request.object.params headers = request.object.headers is_valid, err_code, resp_msg = validate_request(querystr, session) if not is_valid: construct_error_response( request.object.return_overrides, err_code, resp_msg) resp_status = 400 stats_info['profile'] = querystr['profile'] stats_info['policy'] = rules['policies'][session.apply_policy_id]['name'] stats_info['status'] = str(resp_status) stats_info['forbidden'] = forbidden[resp_status] stats_log['request'] = 'GET /{0}?{1} HTTP/2.0'.format( plugin_conf['api-endpoint'], '&'.join( ['%s=%s' % (str(k), str(v)) for (k, v) in stats_info.items()])) stats_log['status'] = str(resp_status) if 'X-Forwarded-For' in headers: stats_log['remote_addr'] = headers['X-Forwarded-For'].split(',')[0] if 'Content-Length' in headers: stats_log['body_bytes_sent'] = headers['Content-Length'] if 'Referer' in headers: stats_log['http_referer'] = headers['Referer'] if 'User-Agent' in headers: stats_log['http_user_agent'] = headers['User-Agent'] # with open(stats_log_file, 'a+') as slf: # slf.write(stats_log_formatter.format(**stats_log)) return request, session
def PostKeyAuth(request, session, metadata, spec): tyk.log("-----PostKeyAuth is called-----", "info") addConfigDataToRequestBody(request, spec['config_data']) tyk.log("request info: {0}".format(MessageToJson(request.object)), "info") return request, session, metadata
def __init__(self, filepath, bundle_root_path=None): tyk.log( "Loading module: '{0}'".format(filepath), "info") self.filepath = filepath self.handlers = {} self.bundle_id = filepath self.bundle_root_path = bundle_root_path self.imported_modules = [] module_splits = filepath.split('_') self.api_id, self.middleware_id = module_splits[0], module_splits[1] self.module_path = os.path.join(self.bundle_root_path, filepath) self.parse_manifest() self.mw_path = os.path.join(self.module_path, "middleware.py") # Fallback for single file bundles: if len(self.manifest['file_list']) == 1: self.mw_path = os.path.join(self.module_path, self.manifest['file_list'][0]) try: self.loader = MiddlewareLoader(self) sys.meta_path.append(self.loader) invalidate_caches() self.module = imp.load_source(filepath, self.mw_path) self.register_handlers() self.cleanup() except Exception as e: tyk.log_error("Middleware initialization error: {0}".format(e))
def __init__(self, filepath, bundle_root_path=None): tyk.log("Loading module: '{0}'".format(filepath), "info") self.filepath = filepath self.handlers = {} self.bundle_id = filepath self.bundle_root_path = bundle_root_path self.imported_modules = [] self.middleware_id = filepath self.module_path = os.path.join(self.bundle_root_path, filepath) self.parse_manifest() self.mw_path = os.path.join(self.module_path, "middleware.py") # Fallback for single file bundles: if len(self.manifest['file_list']) == 1: self.mw_path = os.path.join(self.module_path, self.manifest['file_list'][0]) try: self.loader = MiddlewareLoader(self) sys.meta_path.append(self.loader) invalidate_caches() self.module = imp.load_source(filepath, self.mw_path) self.register_handlers() self.cleanup() except Exception as e: tyk.log_error("Middleware initialization error: {0}".format(e)) pass
def PostKeyAuth(request, session, spec): tyk.log("PostKeyAuth is called", "info") # Log the additional metadata (set in AuthCheck): username = session.metadata["username"] tyk.log("PostKeyAuth: user '{0}' was authenticated".format(username), "info") return request, session
def reload(self): try: invalidate_caches() reload_module(self.module) self.register_handlers() except: tyk.log_error( "Reload error:" )
def ResponseMiddlewareFunction(request, response, session, metadata, spec): tyk.log("Python plugin: Response hook called", "info") tyk.log( "Python plugin: Response status code: {0}".format( response.status_code), "info") response.headers["Python-Plugin-Response-Hook"] = "Response Hook" return response
def build_hooks_and_event_handlers(self): hooks = {} for hook_type in self.handlers: for handler in self.handlers[hook_type]: handler.middleware = self hooks[handler.name] = handler tyk.log("Loading hook '{0}' ({1})".format(handler.name, self.filepath), "debug") return hooks
def dispatch_event(self, event_json): try: event = TykEvent(event_json) event_handler = self.find_event_handler(event.handler_name) if event_handler: event_handler.process(event) except: tyk.log_error("Can't dispatch, error:")
def find_module(self, module_name, package_path): module_filename = "{0}.py".format(module_name) self.base_path = "{0}_{1}".format(self.mw.api_id, self.mw.middleware_id) self.module_path = os.path.join(self.bundle_root_path, self.base_path, module_filename) if not os.path.exists(self.module_path): error_msg = "Your bundle doesn't contain '{0}'".format(module_name) tyk.log(error_msg, "error") return None return self
def purge_middlewares(self): tyk.log("Purging middlewares.", "debug") available_modules = self.get_modules(self.middleware_path) for middleware in self.middlewares: if middleware.filepath not in available_modules: tyk.log( "Purging middleware: '{0}'".format(middleware.filepath), "warning") self.middlewares.remove(middleware)
def __init__(self, module_path, module_name): tyk.log( "Loading module: '{0}'".format(module_name), "info") self.module_path = module_path self.handlers = {} try: source = SourceFileLoader(module_name, self.module_path) self.module = source.load_module() self.register_handlers() except: tyk.log_error( "Middleware initialization error:" )
def __init__(self, filepath): tyk.log("Loading module: '{0}'".format(filepath), "info") self.filepath = filepath self.handlers = {} try: self.module = import_module(filepath) self.register_handlers() except: tyk.log_error("Middleware initialization error:")
def build_hooks_and_event_handlers(self): hooks = {} for hook_type in self.handlers: for handler in self.handlers[hook_type]: handler.middleware = self hooks[handler.name] = handler tyk.log( "Loading hook '{0}' ({1})".format(handler.name, self.filepath), "debug") return hooks
def load_middlewares(self): tyk.log("Loading middlewares.", "debug") available_modules = self.get_modules(self.middleware_path) for module_name in available_modules: middleware = self.find_middleware(module_name) if middleware: middleware.reload() else: middleware = TykMiddleware(module_name) self.middlewares.append(middleware) self.update_hook_table()
def addConfigDataToResponseBody(response, config_data): tyk.log("Add config data to response body", "info") res_body = getResponseBody(response) json_config_data = json.loads(config_data) for key in json_config_data['data']['field_for_response']: res_body[key] = json_config_data['data']['field_for_response'][key] new_res_body = json.dumps(res_body) response.body = new_res_body response.raw_body = bytes(new_res_body, 'utf-8')
def __init__(self, middleware_path, event_handler_path, bundle_paths): tyk.log("Initializing dispatcher", "info") self.event_handler_path = path.join(event_handler_path, '*.py') self.event_handlers = {} self.load_event_handlers() self.middleware_path = path.join(middleware_path, '*.py') self.bundle_paths = bundle_paths.split(":") self.middlewares = [] self.hook_table = {}
def addConfigDataToRequestBody(request, config_data): tyk.log("Add config data to request body", "info") req_body = getRequestBody(request) json_config_data = json.loads(config_data) for key in json_config_data['data']['field_for_request']: req_body[key] = json_config_data['data']['field_for_request'][key] new_req_body = json.dumps(req_body) request.object.body = new_req_body request.object.raw_body = bytes(new_req_body, 'utf-8')
def check_directions_querystr(request, session, spec): tyk.log('[PLUGIN] [{0}::post::init] Current working dir: {1}'.format( plugin_conf['api-endpoint'], str(cwd)), 'debug') resp_status = 200 querystr = request.object.params headers = request.object.headers is_valid, err_code, resp_msg = validate_request(querystr, session) if not is_valid: construct_error_response( request.object.return_overrides, err_code, resp_msg) resp_status = 400 write_piwik_log(querystr, session, headers, resp_status) return request, session
def dispatch_hook(self, object_msg): try: object = TykCoProcessObject(object_msg) middleware, hook_handler = self.find_hook_by_name(object.hook_name) if hook_handler: object = middleware.process(hook_handler, object) else: tyk.log( "Can't dispatch '{0}', hook is not defined.".format( object.hook_name), "error") return object.dump() except: exc_trace = traceback.format_exc() print(exc_trace) tyk.log_error("Can't dispatch, error:") return object_msg
def AuthCheck(request, session, metadata, spec): tyk.log("AuthCheck is called", "info") # request.get_header is a helper method, to get the full header list, use request.object.headers auth_header = request.get_header('Authorization') if auth_header == '47a0c79c427728b3df4af62b9228c8ae': tyk.log("AuthCheck is successful", "info") # Initialize a session object: session.rate = 1000.0 session.per = 1.0 # Set a deadline for the ID extractor, in this case we use the current UNIX timestamp + 60 seconds: session.id_extractor_deadline = int(time()) + 60 # Attach the token, this is required (used internally by Tyk): metadata["token"] = "47a0c79c427728b3df4af62b9228c8ae" # Inject additional metadata: metadata["username"] = "******" return request, session, metadata tyk.log("AuthCheck failed: invalid token", "error") # Set a custom error: request.object.return_overrides.response_error = 'Invalid authentication' request.object.return_overrides.response_code = 403 return request, session, metadata
def PreMiddlewareFunction(request, session, spec): tyk.log("Python plugin: Pre hook called", "info") request.add_header("Python-Plugin-Pre-Hook", "Pre Hook") return request, session
def validate_request(queryparams, session): """ Check if the URL query string is valid """ try: if 'profile' not in queryparams: return False, plugin_conf['error-codes'][ 'MISSING_PARAMETER'], "Parameter 'profile' is required" if 'coordinates' not in queryparams: return False, plugin_conf['error-codes'][ 'MISSING_PARAMETER'], "Parameter 'coordinates' is required" profile = queryparams['profile'] policy = session.apply_policy_id tyk.log( "[PLUGIN] [{0}::post] Processing request with profile={1} and policy_id={2}" .format(plugin_conf['api-endpoint'], str(profile), str(policy)), 'debug') if profile not in rules['policies'][policy]['profiles']: response_msg = "Routing profile {0} is unavailale for your API subscription".format( profile) return False, plugin_conf['error-codes'][ 'INVALID_PARAMETER_VALUE'], response_msg # split each coordinate param value into the list like # [{'lon': 110.12, 'lat': 36.36}, {'lon':111.32, 'lat': 19.19}] # with the map function. Then, reduce it to get the sum-up distance coords = queryparams['coordinates'].split('|') cl = list( map( lambda c: { 'lon': float(c.split(',')[0]), 'lat': float(c.split(',')[1]) }, coords)) total_dist = reduce( lambda d, seg_d: d + seg_d, map( lambda cp: geo_distance(cp[0]['lon'], cp[0]['lat'], cp[1][ 'lon'], cp[1]['lat']), zip(cl[0:-1], cl[1:]))) tyk.log( "[PLUGIN] [{0}::post] Geodistance of the request: {1}".format( plugin_conf['api-endpoint'], str(total_dist)), 'debug') tyk.log( "[PLUGIN] [{0}::post] Policy: {1}".format( plugin_conf['api-endpoint'], ors_api_conf['policies'][policy]['name']), 'debug') stats_info['estimated_distance'] = str(round(total_dist)) stats_info['distance_class'] = str( get_distance_class(round(total_dist))) if (rules['policies'][policy]['total-distance-limit'] and total_dist > rules['policies'][policy]['total-distance-limit'][profile]): response_msg = "The approximated route distance must not be greater than {0} km".format( rules['policies'][policy]['total-distance-limit'][profile]) return False, plugin_conf['error-codes'][ 'REQUEST_EXCEEDS_SERVER_LIMIT'], response_msg except ValueError as val_err: tyk.log( "[PLUGIN] [{0}::post] [plugin ValueError] coordinates: {1}".format( plugin_conf['api-endpoint'], str(queryparams['coordinates'])), 'error') tyk.log( "[PLUGIN] [{0}::post] [plugin ValueError] {1}".format( plugin_conf['api-endpoint'], str(val_err)), 'error') response_msg = "Parameter 'coordinates' has incorrect value or format" return False, plugin_conf['error-codes'][ 'INVALID_PARAMETER_VALUE'], response_msg except IndexError as idx_err: tyk.log( "[PLUGIN] [{0}::post] [plugin IndexError] Conversion of coordinates {1} failed" .format(plugin_conf['api-endpoint'], str(queryparams['coordinates'])), 'error') tyk.log( "[PLUGIN] [{0}::post] [plugin ValueError] {1}".format( plugin_conf['api-endpoint'], str(idx_err)), 'error') response_msg = "Parameter 'coordinates' has incorrect value or format" return False, plugin_conf['error-codes'][ 'INVALID_PARAMETER_VALUE'], response_msg except Exception as err: tyk.log( "[PLUGIN] [{0}::post] [plugin unexpected error] {1}".format( plugin_conf['api-endpoint'], str(err)), 'error') tyk.log( "[PLUGIN] [{0}::post] [plugin unexpected error] trackback info: {1}" .format(plugin_conf['api-endpoint'], traceback.format_exc()), 'error') return False, plugin_conf['error-codes'][ 'UNKNOWN'], "Unexpected error: {0}".format(str(err)) return True, 0, ''
def except_hook(type, value, traceback): tyk.log_error("{0}".format(value)) pass
def __init__(self, bundle_root_path): tyk.log("Initializing dispatcher", "info") self.bundle_root_path = bundle_root_path self.bundles = [] self.hook_table = {}
def reload(self): tyk.log("Reloading event handlers and middlewares.", "info") pass
from gateway import TykGateway as tyk def except_hook(type, value, traceback): tyk.log_error("{0}".format(value)) pass sys.excepthook = except_hook try: from tyk.middleware import TykMiddleware from tyk.object import TykCoProcessObject from tyk.event import TykEvent except Exception as e: tyk.log_error(str(e)) sys.exit(1) class TykDispatcher: '''A simple dispatcher''' def __init__(self, bundle_root_path): tyk.log("Initializing dispatcher", "info") self.bundle_root_path = bundle_root_path self.bundles = [] self.hook_table = {} def find_bundle(self, bundle_id): found = None for bundle in self.bundles: if bundle.bundle_id == bundle_id:
def ResponseHook(request, response, session, metadata, spec): tyk.log("ResponseHook is called", "info") # In this hook we have access to the response object, to inspect it, uncomment the following line: # print(response) tyk.log("ResponseHook: upstream returned {0}".format(response.status_code), "info") return response
def PreHook(request, session, spec): tyk.log("PreHook is called", "info") # Inject a header: request.add_header("testheader", "testvalue") return request, session
def AuthCheck(request, session, metadata, spec): tyk.log("AuthCheck is called", "info") return request, session, metadata
def PostHook(request, session, spec): tyk.log("PostHook is called", "info") return request, session