def get_AuthToken(cr_id, operator_url, app_config): print(operator_url, cr_id) helpers = Helpers(app_config) print(cr_id) token = get("{}/api/1.3/cr/auth_token/{}".format( operator_url, cr_id)) # TODO Get api path from some config? print(token.url, token.reason, token.status_code, token.text) store_dict = {cr_id: dumps(loads(token.text.encode()))} helpers.storeToken(store_dict) cr_csr = helpers.get_cr_json(cr_id) cr_tool = CR_tool() cr_tool.cr = cr_csr user_id = cr_tool.get_surrogate_id() rs_id = cr_tool.get_rs_id() #req = get("http://service_components:7000/api/1.3/sink_flow/init") #print(req.url, req.status_code, req.content) data = { "cr_id": cr_id, "user_id": user_id, "rs_id": urllib.quote_plus(rs_id) } print(dumps(data, indent=2))
class DataFlow(Resource): def __init__(self): super(DataFlow, self).__init__() self.service_url = current_app.config["SERVICE_URL"] self.operator_url = current_app.config["OPERATOR_URL"] self.helpers = Helpers(current_app.config) @error_handler @api_logging def post(self): # TODO Make this a GET, is this valid anymore? def renew_token(operator_url, record_id): sq.task("Renewing Auth Token.") token = requests.get("{}/api/1.3/cr/auth_token/{}".format( operator_url, record_id)) # TODO Get api path from some config? debug_log.info("{}, {}, {}, {}".format(token.url, token.reason, token.status_code, token.text)) store_dict = {cr_id: dumps(loads(token.text.encode()))} self.helpers.storeToken(store_dict) def fetch_data_request_urls(): params = request.json debug_log.info(params) debug_log.info(request.json) user_id = params["user_id"] cr_id = params["cr_id"] rs_id = params["rs_id"] sq.task("Get data_set_id from POST json") data_set_id = request.args.get("dataset_id", None) debug_log.info( "data_set_id is ({}), cr_id is ({}), user_id ({}) and rs_id ({})" .format(data_set_id, cr_id, user_id, rs_id)) sq.task("Create request") req = {"we want": "data"} sq.task("Validate CR") cr = self.helpers.validate_cr(cr_id, surrogate_id=user_id) sq.task("Validate Request from UI") distribution_urls = self.helpers.validate_request_from_ui( cr, data_set_id, rs_id) # Fetch data request urls # Data request urls fetched. debug_log.info("Data request urls fetched.") return cr_id, cr, distribution_urls cr_id, cr, distribution_urls = fetch_data_request_urls() sq.task("Validate Authorisation Token") surrogate_id = cr["cr"]["common_part"]["surrogate_id"] our_key = self.helpers.get_key() our_key_pub = our_key["pub"] tries = 3 # TODO: Get this from config while True: try: aud = self.helpers.validate_authorization_token( cr_id, surrogate_id, our_key_pub) break except ValueError as e: debug_log.exception(e) renew_token(self.operator_url, cr_id) if tries == 0: raise EnvironmentError( "Auth token validation failed and retry counter exceeded." ) tries -= 1 except TypeError as e: debug_log.exception(e) raise EnvironmentError("Token used too soon, halting.") # Most verifying and checking below is done in the validate_authorization_token function by jwcrypto # Fetch Authorisation Token related to CR from data storage by rs_id (cr_id?) # Check Integrity ( Signed by operator, Operator's public key can be found from SLR) # Check "Issued" timestamp # Check "Not Before" timestamp # Check "Not After" timestamp # Check that "sub" contains correct public key(Our key.) # OPT: Token expired # Get new Authorization token, start again from validation. # TODO: Make these steps work as functions that call the next step. # Check URL patterns in "aud" field # Check that fetched distribution urls can be found from "aud" field # Token validated debug_log.info("Auth Token Validated.") # With these two steps Sink has verified that it's allowed to make request. # Construct request sq.task("Construct request") # Select request URL from "aud" field # Add Authorisation Token to request # Request constructed. # Sign request # Fetch private key pair of public key specified in Authorisation Token's "sub" field. # Sign with fetched private key sq.task("Fetch key used to sign request") our_key_full = jwk.JWK() our_key_full.import_key(**our_key["key"]) # Add signature to request # Request signed. # Request created. sq.send_to("Service_Components Mgmnt (Source)", "Data Request (PoP stuff)") # Make Data Request data = [] for url in distribution_urls: req = requests.get(url, auth=SignedRequest(token=aud, sign_method=True, sign_path=True, key=our_key_full, protected=dumps( our_key["prot"]))) if req.ok: data.append(loads(req.content)) debug_log.info( "Made data request and received following data from Source: \n{}". format(dumps(loads(req.content), indent=2))) return {"response_data": data}