def log_message(self, format, *args): #args: ('POST /foo/bar/ HTTP/1.1', '200', '-') log.log( WebHttpHandler, log.level.Info, "Request from %s: %s" % (get_context().get_ip_address(), format % args) )
def log_message(self, format, *args): #args: ('POST /weblab/xmlrpc/ HTTP/1.1', '200', '-') log.log( XmlRpcRequestHandler, log.level.Info, "Request from %s: %s" % (get_context().get_ip_address(), format % args) )
def log_message(self, format, *args): #args: ('POST /weblab/soap/ HTTP/1.1', '200', '-') log.log( WebLabRequestHandlerClass, log.level.Info, "Request from %s: %s" % (get_context().get_ip_address(), format % args) )
def _reserve_session(self, db_session_id): ups_server = self._locator.get_easy_server(ServerType.UserProcessing) session_id, server_route = ups_server.reserve_session(db_session_id) context = RemoteFacadeContext.get_context() context.route = server_route if hasattr(session_id, 'id'): context.session_id = session_id.id else: context.session_id = session_id return session_id
def finish_post(self, response): """ Finishes a JSON POST request that was successful, reporting the result to the caller. @param response JSON-encoded response to the successfully executed JSON request. """ self.send_response(200) self.send_header("Content-type", "application/json") self.send_header("Content-length", str(len(response))) if self.server_route is not None: ctx = get_context() route = ctx.route if route is None: route = self.server_route if ctx.session_id: session_id = ctx.session_id else: raw_cookies = ctx.headers.get('Cookie') or '' cookies = [ cookie.strip().split('=')[:2] for cookie in raw_cookies.split(';') ] valid_cookies = [ cookie for cookie in cookies if len(cookie) == 2 ] weblab_cookies = [ value for name, value in valid_cookies if name == 'weblabsessionid' ] weblab_cookie = weblab_cookies[0] if len( weblab_cookies) > 0 else None if weblab_cookie is not None and weblab_cookie.endswith( '.%s' % route): session_id = weblab_cookie.split('.%s' % route)[0] else: session_id = 'anythinglikeasessid' if self.location is not None: location = self.location else: location = '/' self.send_header( "Set-Cookie", "weblabsessionid=%s.%s; path=%s; Expires=%s" % (session_id, route, location, strdate(days=100))) self.send_header( "Set-Cookie", "loginweblabsessionid=%s.%s; path=%s; Expires=%s" % (session_id, route, location, strdate(hours=1))) self.end_headers() self.wfile.write(response) self.wfile.flush() try: self.connection.shutdown(1) except: pass
def end_headers(self): if self.server_route is not None: route = get_context().route if route is None: route = self.server_route if self.location is not None: location = self.location else: location = '/weblab/' self.send_header("Set-Cookie","weblabsessionid=anythinglikeasessid.%s; path=%s" % (route, location)) self.send_header("Set-Cookie","loginweblabsessionid=anythinglikeasessid.%s; path=%s; Expires=%s" % (route, location, strdate(hours=1))) ServiceContainer.SOAPRequestHandler.end_headers(self)
def _reserve_session(self, db_session_id): """ Contact the Core server and reserve a session there that we will return to the user. From this point, users will use this session identifier with the core server.""" ups_server = self._locator.get_easy_server(ServerType.UserProcessing) session_id, server_route = ups_server.reserve_session(db_session_id) context = RemoteFacadeContext.get_context() context.route = server_route if hasattr(session_id, 'id'): context.session_id = session_id.id else: context.session_id = session_id return session_id
def end_headers(self): if self.server_route is not None: route = get_context().route if route is None: route = self.server_route if self.location is not None: location = self.location else: location = '/' self.send_header( "Set-Cookie", "weblabsessionid=anythinglikeasessid.%s; path=%s" % (route, location)) self.send_header( "Set-Cookie", "loginweblabsessionid=anythinglikeasessid.%s; path=%s; Expires=%s" % (route, location, strdate(hours=1))) ServiceContainer.SOAPRequestHandler.end_headers(self)
def run(self): experiment_id_str = self.get_argument(EXPERIMENT_ID) if experiment_id_str is None: return "%s argument is missing" % EXPERIMENT_ID session_id_str = self.get_argument(SESSION_ID) if session_id_str is None: return "%s argument is missing" % EXPERIMENT_ID experiment_id = ExperimentId.parse(experiment_id_str) session_id = SessionId(session_id_str) address = RemoteFacadeContext.get_context().get_ip_address() client_address = ClientAddress.ClientAddress(address) try: reservation_id = self.server.reserve_experiment(session_id, experiment_id, "{}", "{}", client_address) except Exception: return HTML_ERROR_TEMPLATE new_location = "../../client/federated.html#reservation_id=%s" % reservation_id.reservation_id.id self.set_status(302) self.add_other_header('Location', new_location) return """<html><body><a href="%s">Click here</a></body></html>""" % new_location
def finish_post(self, response): """ Finishes a JSON POST request that was successful, reporting the result to the caller. @param response JSON-encoded response to the successfully executed JSON request. """ self.send_response(200) self.send_header("Content-type", "application/json") self.send_header("Content-length", str(len(response))) if self.server_route is not None: ctx = get_context() route = ctx.route if route is None: route = self.server_route if ctx.session_id: session_id = ctx.session_id else: raw_cookies = ctx.headers.get('Cookie') or '' cookies = [ cookie.strip().split('=')[:2] for cookie in raw_cookies.split(';') ] valid_cookies = [ cookie for cookie in cookies if len(cookie) == 2 ] weblab_cookies = [ value for name, value in valid_cookies if name == 'weblabsessionid' ] weblab_cookie = weblab_cookies[0] if len(weblab_cookies) > 0 else None if weblab_cookie is not None and weblab_cookie.endswith('.%s' % route): session_id = weblab_cookie.split('.%s' % route)[0] else: session_id = 'anythinglikeasessid' if self.location is not None: location = self.location else: location = '/weblab/' self.send_header("Set-Cookie", "weblabsessionid=%s.%s; path=%s; Expires=%s" % (session_id, route, location, strdate(days=100))) self.send_header("Set-Cookie", "loginweblabsessionid=%s.%s; path=%s; Expires=%s" % (session_id, route, location, strdate(hours=1))) self.end_headers() self.wfile.write(response) self.wfile.flush() try: self.connection.shutdown(1) except: pass
def run(self): experiment_id_str = self.get_argument(EXPERIMENT_ID) if experiment_id_str is None: return "%s argument is missing" % EXPERIMENT_ID session_id_str = self.get_argument(SESSION_ID) if session_id_str is None: return "%s argument is missing" % EXPERIMENT_ID experiment_id = ExperimentId.parse(experiment_id_str) session_id = SessionId(session_id_str) address = RemoteFacadeContext.get_context().get_ip_address() client_address = ClientAddress.ClientAddress(address) try: reservation_id = self.server.reserve_experiment( session_id, experiment_id, "{}", "{}", client_address) except Exception: return HTML_ERROR_TEMPLATE new_location = "../../client/federated.html#reservation_id=%s" % reservation_id.reservation_id.id self.set_status(302) self.add_other_header('Location', new_location) return """<html><body><a href="%s">Click here</a></body></html>""" % new_location
def do_POST(self): """ This do_POST callback handles an HTTP request containing a JSON-encoded RPC request. """ create_context(self.server, self.client_address, self.headers) try: length = int(self.headers['content-length']) post_content = self.rfile.read(length) # The contents of the POST contain a string with the JSON-encoded request. Decode that string. try: decoded = json.loads(post_content) except ValueError: response = { "is_exception": True, "code": WEBLAB_GENERAL_EXCEPTION_CODE, "message": "Couldn't deserialize message" } self.finish_error(response) return # Retrieve the name of the method being invoked. method_name = decoded.get('method') if method_name is None: response = { "is_exception": True, "code": WEBLAB_GENERAL_EXCEPTION_CODE, "message": "Missing 'method' attr" } self.finish_error(response) return # Retrieve the parameters of the method being invoked. params = decoded.get('params') if params is None: response = { "is_exception": True, "code": WEBLAB_GENERAL_EXCEPTION_CODE, "message": "Missing 'params' attr" } self.finish_error(response) return # Ensure that we actually have a facade manager, as we should. # (The method specified in the JSON request, which we are going to invoke, # is actually located in the facade manager). if self.facade_manager is None: response = { "is_exception": True, "code": WEBLAB_GENERAL_EXCEPTION_CODE, "message": "Facade manager not set" } self.finish_error(response) return # Ensure that the method that is remotely being called does exist. if not hasattr(self.facade_manager, method_name): response = { "is_exception": True, "code": WEBLAB_GENERAL_EXCEPTION_CODE, "message": "Method not recognized" } self.finish_error(response) return # Retrieve a reference to the method. method = getattr(self.facade_manager, method_name) # Build a standard dictionary with the parameters to call the actual method. newparams = {} try: for param in params: newparams[str(param)] = params[param] except Exception as e: response = { "is_exception": True, "code": WEBLAB_GENERAL_EXCEPTION_CODE, "message": "unicode not accepted in param names" } self.finish_error(response) return # Call the method specified in the request, # with the parameters from the dictionary we just built. try: return_value = method(**newparams) except RemoteFacadeManager.JSONError as jsone: response = jsone.args[0] self.finish_error(response) return except Exception as e: response = { "is_exception": True, "code": WEBLAB_GENERAL_EXCEPTION_CODE, "message": "Unexpected exception: %s" % e } self.finish_error(response) return # No exception was raised so the request was successful. We will now return the response to # the remote caller. try: # Serialize the response to a JSON dictionary. parsed_return_value = simplify_response(return_value) response = json.dumps({ "result": parsed_return_value, "is_exception": False }) except Exception as e: response = { "is_exception": True, "code": WEBLAB_GENERAL_EXCEPTION_CODE, "message": "Error encoding return value" } log.log( JsonHttpHandler, log.level.Error, "Request from %s: %s" % (get_context().get_ip_address(), "Error encoding return value: %s" % e)) log.log(JsonHttpHandler, log.level.Error, "Message was: %s" % return_value) log.log_exc(JsonHttpHandler, log.level.Warning) self.finish_error(response) return self.finish_post(response) finally: delete_context()
def do_POST(self): """ This do_POST callback handles an HTTP request containing a JSON-encoded RPC request. """ create_context(self.server, self.client_address, self.headers) try: length = int(self.headers['content-length']) post_content = self.rfile.read(length) # The contents of the POST contain a string with the JSON-encoded request. Decode that string. try: decoded = json.loads(post_content) except ValueError: response = {"is_exception":True,"code":WEBLAB_GENERAL_EXCEPTION_CODE,"message":"Couldn't deserialize message"} self.finish_error(response) return # Retrieve the name of the method being invoked. method_name = decoded.get('method') if method_name is None: response = {"is_exception":True,"code":WEBLAB_GENERAL_EXCEPTION_CODE,"message":"Missing 'method' attr"} self.finish_error(response) return # Retrieve the parameters of the method being invoked. params = decoded.get('params') if params is None: response = {"is_exception":True,"code":WEBLAB_GENERAL_EXCEPTION_CODE,"message":"Missing 'params' attr"} self.finish_error(response) return # Ensure that we actually have a facade manager, as we should. # (The method specified in the JSON request, which we are going to invoke, # is actually located in the facade manager). if self.facade_manager is None: response = {"is_exception":True,"code":WEBLAB_GENERAL_EXCEPTION_CODE,"message":"Facade manager not set"} self.finish_error(response) return # Ensure that the method that is remotely being called does exist. if not hasattr(self.facade_manager, method_name): response = {"is_exception":True,"code":WEBLAB_GENERAL_EXCEPTION_CODE,"message":"Method not recognized"} self.finish_error(response) return # Retrieve a reference to the method. method = getattr(self.facade_manager,method_name) # Build a standard dictionary with the parameters to call the actual method. newparams = {} try: for param in params: newparams[str(param)] = params[param] except Exception as e: response = {"is_exception":True,"code":WEBLAB_GENERAL_EXCEPTION_CODE,"message":"unicode not accepted in param names"} self.finish_error(response) return # Call the method specified in the request, # with the parameters from the dictionary we just built. try: return_value = method(**newparams) except RemoteFacadeManager.JSONError as jsone: response = jsone.args[0] self.finish_error(response) return except Exception as e: response = {"is_exception":True,"code":WEBLAB_GENERAL_EXCEPTION_CODE,"message":"Unexpected exception: %s" % e} self.finish_error(response) return # No exception was raised so the request was successful. We will now return the response to # the remote caller. try: # Serialize the response to a JSON dictionary. parsed_return_value = simplify_response(return_value) response = json.dumps({"result":parsed_return_value, "is_exception" : False}) except Exception as e: response = {"is_exception":True,"code":WEBLAB_GENERAL_EXCEPTION_CODE,"message":"Error encoding return value"} log.log( JsonHttpHandler, log.level.Error, "Request from %s: %s" % (get_context().get_ip_address(), "Error encoding return value: %s" % e)) log.log( JsonHttpHandler, log.level.Error, "Message was: %s" % return_value) log.log_exc( JsonHttpHandler, log.level.Warning ) self.finish_error(response) return self.finish_post(response) finally: delete_context()
def log_message(self, format, *args): #args: ('POST /weblab/xmlrpc/ HTTP/1.1', '200', '-') log.log( XmlRpcRequestHandler, log.level.Info, "Request from %s: %s" % (get_context().get_ip_address(), format % args))
def reserve_experiment(self, experiment_id, serialized_client_initial_data, serialized_consumer_data, client_address, core_server_universal_id): context = RemoteFacadeContext.get_context() # Put user information in the session self.get_user_information() self._session['experiment_id'] = experiment_id reservation_info = self._session['reservation_information'] = {} reservation_info['user_agent'] = context.get_user_agent() reservation_info['referer'] = context.get_referer() reservation_info['mobile'] = context.is_mobile() reservation_info['facebook'] = context.is_facebook() reservation_info['route'] = self._server_route or 'no-route-found' reservation_info['from_ip'] = client_address.client_address reservation_info['from_direct_ip'] = client_address.client_address reservation_info['username'] = self._session['db_session_id'].username # reservation_info['full_name'] = self._session['user_information'].full_name reservation_info['role'] = self._session['db_session_id'].role try: client_initial_data = json.loads(serialized_client_initial_data) except ValueError: # TODO: to be tested raise core_exc.WebLabCoreError( "Invalid client_initial_data provided: a json-serialized object expected" ) if self.is_access_forward_enabled(): try: consumer_data = json.loads(serialized_consumer_data) for forwarded_key in FORWARDED_KEYS: if forwarded_key in consumer_data: if consumer_data[forwarded_key] is not None: reservation_info[forwarded_key] = consumer_data[ forwarded_key] server_uuids = consumer_data.get(SERVER_UUIDS, []) for server_uuid, server_uuid_human in server_uuids: if server_uuid == core_server_universal_id: return 'replicated' reservation_info[SERVER_UUIDS] = server_uuids except ValueError: raise core_exc.WebLabCoreError( "Invalid serialized_consumer_data provided: a json-serialized object expected" ) else: consumer_data = {} experiments = [ exp for exp in self.list_experiments() if exp.experiment.name == experiment_id.exp_name and exp.experiment.category.name == experiment_id.cat_name ] if len(experiments) == 0: raise core_exc.UnknownExperimentIdError( "User can't access that experiment (or that experiment type does not exist)" ) experiment_allowed = experiments[0] try: # Retrieve the most restrictive values between what was requested and what was permitted: # # The smallest time allowed time_allowed = min( experiment_allowed.time_allowed, consumer_data.get('time_allowed', experiment_allowed.time_allowed)) # # The lowest priority (lower number is higher) # TODO: whenever possible, there should be an argument in the permission as # a parameter to the access_forward, such as: # "how much you want to decrement the requested priority to this user" priority = max( experiment_allowed.priority, consumer_data.get('priority', experiment_allowed.priority)) # # Don't take into account initialization unless both agree initialization_in_accounting = experiment_allowed.initialization_in_accounting and consumer_data.get( 'initialization_in_accounting', experiment_allowed.initialization_in_accounting) status, reservation_id = self._coordinator.reserve_experiment( experiment_allowed.experiment.to_experiment_id(), time_allowed, priority, initialization_in_accounting, client_initial_data, reservation_info, consumer_data) except coord_exc.ExperimentNotFoundError: raise core_exc.NoAvailableExperimentFoundError( "No experiment of type <%s,%s> is currently deployed" % (experiment_id.exp_name, experiment_id.cat_name)) self._session['reservation_information'].pop('from_ip', None) self._session['reservation_id'] = reservation_id return status
def _get_client_address(self): return RemoteFacadeContext.get_context().get_ip_address()
def log_message(self, format, *args): #args: ('POST /weblab/soap/ HTTP/1.1', '200', '-') log.log( WebLabRequestHandlerClass, log.level.Info, "Request from %s: %s" % (get_context().get_ip_address(), format % args))
def authenticate(self, login, password): return get_context().ip_address in self.addresses
def headers(self): return get_context().headers
def wrapper(self, session_id, *args, **kwargs): ctx = get_context() if ctx is not None and hasattr(session_id, 'id'): ctx.session_id = session_id.id return func(self, session_id, *args, **kwargs)
def get_context(self): return get_context()
def reserve_experiment(self, experiment_id, serialized_client_initial_data, serialized_consumer_data, client_address, core_server_universal_id ): context = RemoteFacadeContext.get_context() # Put user information in the session self.get_user_information() self._session['experiment_id'] = experiment_id reservation_info = self._session['reservation_information'] = {} reservation_info['user_agent'] = context.get_user_agent() reservation_info['referer'] = context.get_referer() reservation_info['mobile'] = context.is_mobile() reservation_info['locale'] = context.get_locale() reservation_info['facebook'] = context.is_facebook() reservation_info['route'] = self._server_route or 'no-route-found' reservation_info['from_ip'] = client_address.client_address reservation_info['from_direct_ip'] = client_address.client_address reservation_info['username'] = self._session['db_session_id'].username # reservation_info['full_name'] = self._session['user_information'].full_name reservation_info['role'] = self._session['db_session_id'].role try: client_initial_data = json.loads(serialized_client_initial_data) except ValueError: # TODO: to be tested raise core_exc.WebLabCoreError( "Invalid client_initial_data provided: a json-serialized object expected" ) if self.is_access_forward_enabled(): try: consumer_data = json.loads(serialized_consumer_data) for forwarded_key in FORWARDED_KEYS: if forwarded_key in consumer_data: if consumer_data[forwarded_key] is not None: reservation_info[forwarded_key] = consumer_data[forwarded_key] server_uuids = consumer_data.get(SERVER_UUIDS, []) for server_uuid, server_uuid_human in server_uuids: if server_uuid == core_server_universal_id: return 'replicated' reservation_info[SERVER_UUIDS] = server_uuids except ValueError: raise core_exc.WebLabCoreError( "Invalid serialized_consumer_data provided: a json-serialized object expected" ) else: consumer_data = {} experiments = [ exp for exp in self.list_experiments() if exp.experiment.name == experiment_id.exp_name and exp.experiment.category.name == experiment_id.cat_name ] if len(experiments) == 0: raise core_exc.UnknownExperimentIdError( "User can't access that experiment (or that experiment type does not exist)" ) experiment_allowed = experiments[0] try: # Retrieve the most restrictive values between what was requested and what was permitted: # # The smallest time allowed time_allowed = min(experiment_allowed.time_allowed, consumer_data.get('time_allowed', experiment_allowed.time_allowed)) # # The lowest priority (lower number is higher) # TODO: whenever possible, there should be an argument in the permission as # a parameter to the access_forward, such as: # "how much you want to decrement the requested priority to this user" priority = max(experiment_allowed.priority, consumer_data.get('priority', experiment_allowed.priority)) # # Don't take into account initialization unless both agree initialization_in_accounting = experiment_allowed.initialization_in_accounting and consumer_data.get('initialization_in_accounting', experiment_allowed.initialization_in_accounting) status, reservation_id = self._coordinator.reserve_experiment( experiment_allowed.experiment.to_experiment_id(), time_allowed, priority, initialization_in_accounting, client_initial_data, reservation_info, consumer_data ) except coord_exc.ExperimentNotFoundError: raise core_exc.NoAvailableExperimentFoundError( "No experiment of type <%s,%s> is currently deployed" % ( experiment_id.exp_name, experiment_id.cat_name ) ) self._session['reservation_information'].pop('from_ip', None) self._session['reservation_id'] = reservation_id return status