Beispiel #1
0
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))
Beispiel #2
0
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}