Esempio n. 1
0
class CancelSlrFlow(Resource):
    def __init__(self):
        """

        """
        super(CancelSlrFlow, self).__init__()
        self.helper = Helpers(current_app.config)

    @error_handler
    @api_logging
    def delete(self, account_id, code):
        AM = get_am(current_app, request.headers)
        key_check = AM.verify_user_key(account_id)
        debug_log.info("Verifying User Key resulted: {}".format(key_check))

        sq.task("Load json payload as object")
        js = request.json

        sq.task("Load account_id from database")
        code = js["code"]
        try:
            stored_session_from_db = self.helper.restore_session(code)
        except TypeError as e:
            debug_log.info("Failed restoring session from DB with code '{}'".format(code))
            debug_log.exception(e)
            raise DetailedHTTPException(status=403,
                                        detail={"msg": "Invalid or expired session"},
                                        title="Invalid session")
        debug_log.debug("The session data contains: {}".format(stored_session_from_db))
        session_data = loads(stored_session_from_db)
        debug_log.debug("{}  {}".format(type(stored_session_from_db), stored_session_from_db))
        account_id_from_session = session_data["account_id"]

        if account_id_from_session == account_id:
            self.helper.delete_session(code)

        return {"msg": {"status": "deleted", "id": code}}, 200
Esempio n. 2
0
class RegisterSurrogate(Resource):
    def __init__(self):
        super(RegisterSurrogate, self).__init__()
        self.app = current_app
        self.helpers = Helpers(self.app.config)
        operator_id = self.app.config["UID"]
        self.service_registry_handler = ServiceRegistryHandler(
            current_app.config["SERVICE_REGISTRY_SEARCH_DOMAIN"],
            current_app.config["SERVICE_REGISTRY_SEARCH_ENDPOINT"])
        self.operator_key = self.helpers.get_key()
        self.request_timeout = self.app.config["TIMEOUT"]

        self.payload = \
            {
                "version": "1.3",
                "link_id": "",
                "operator_id": operator_id,
                "service_id": "",
                "surrogate_id": "",
                "operator_key": self.operator_key["pub"],
                "cr_keys": "",
                "iat": 0,  # Set below once we know link_id
            }
        debug_log.info("SLR payload in init is: \n{}".format(
            dumps(self.payload, indent=2)))
        self.service_registry_handler = ServiceRegistryHandler(
            current_app.config["SERVICE_REGISTRY_SEARCH_DOMAIN"],
            current_app.config["SERVICE_REGISTRY_SEARCH_ENDPOINT"])
        self.am_url = current_app.config["ACCOUNT_MANAGEMENT_URL"]
        self.am_user = current_app.config["ACCOUNT_MANAGEMENT_USER"]
        self.am_password = current_app.config["ACCOUNT_MANAGEMENT_PASSWORD"]
        self.timeout = current_app.config["TIMEOUT"]

    @error_handler
    @api_logging
    def post(self):
        try:
            sq.task("Load json payload as object")
            js = request.json

            sq.task("Load account_id and service_id from database")
            code = js["code"]
            try:
                stored_session_from_db = self.helpers.restore_session(code)
            except TypeError as e:
                debug_log.info(
                    "Failed restoring session from DB with code '{}'".format(
                        code))
                debug_log.exception(e)
                raise DetailedHTTPException(
                    status=403,
                    detail={"msg": "Invalid or expired session"},
                    title="Invalid session")
            debug_log.debug(
                "Type of session data fetched from db is: {}".format(
                    type(stored_session_from_db)))
            debug_log.debug(
                "The session data contains: {}".format(stored_session_from_db))
            session_data = loads(stored_session_from_db)
            debug_log.debug("{}  {}".format(type(stored_session_from_db),
                                            stored_session_from_db))
            account_id = session_data["account_id"]

            # Get Account Manager Handler
            AM = get_am(current_app, request.headers)
            key_check = AM.verify_user_key(account_id,
                                           user_key=session_data["user_key"])
            debug_log.info("Verifying User Key resulted: {}".format(key_check))

            self.payload["service_id"] = session_data["service_id"]
            service_info = self.service_registry_handler.getService(
                self.payload["service_id"])
            # TODO: Use serviceType field added into ServiceDescription
            service_type = service_info["serviceDescription"][
                "serviceDataDescription"][0]["dataset"][0]["serviceDataType"]

            # Check Surrogate_ID exists.
            # Fill token_key
            try:
                sq.task(
                    "Verify surrogate_id and token_key exist in the payload json"
                )
                self.payload["surrogate_id"] = js["surrogate_id"]
                #self.payload["token_key"] = {"key": token_key}

                if service_type == "input" or service_type == "both":
                    sq.task(
                        "Store surrogate_id and keys for CR steps later on.")
                    token_key = js[
                        "token_key"]  # Todo: source has no need to send this, make the difference.
                    service_keys = {
                        "token_key": token_key,
                        "pop_key": token_key
                    }

                    self.helpers.store_service_key_json(
                        kid=token_key["kid"],
                        surrogate_id=js["surrogate_id"],
                        key_json=service_keys,
                        service_id=service_info["id"])
            except Exception as e:
                debug_log.exception(e)
                if "code" in locals():
                    self.helper.delete_session(code)
                raise DetailedHTTPException(
                    exception=e,
                    detail={
                        "msg":
                        "Received Invalid JSON that may not contain surrogate_id",
                        "json": js
                    })

            # Create template
            # TODO: Currently you can generate endlessly new slr even if one exists already
            if service_type == "input" or service_type == "both":
                result = AM.init_slr(code, pop_key=token_key)
            else:
                result = AM.init_slr(code)

            self.payload["link_id"] = result
            self.payload["iat"] = int(time.time())

            sq.task("Fill template for Account Manager")

            template = {
                "code": code,
                "data": {
                    "type": "ServiceLinkRecord",
                    "attributes": self.payload
                }
            }

            debug_log.info("########### Template for Account Manager #")
            debug_log.info(dumps(template, indent=2))
            debug_log.info("########################################")

            sq.send_to("Account Manager", "Sign SLR at Account Manager")
            try:
                reply = AM.sign_slr(template, account_id)
            except AttributeError as e:
                self.helpers.delete_session(code)
                raise DetailedHTTPException(
                    status=502,
                    title=
                    "It would seem initiating Account Manager Handler has failed.",
                    detail="Account Manager might be down or unresponsive.",
                    trace=traceback.format_exc(limit=100).splitlines())
            debug_log.info(dumps(reply, indent=2))

            # Parse JSON form Account Manager to format Service_Mgmnt understands.
            try:
                req = {
                    "data": {
                        "code": code,
                    },
                    "slr": reply["data"]["attributes"]
                }

                debug_log.info(
                    "SLR in format sent to Service Mgmnt: {}".format(
                        dumps(req, indent=2)))
            except Exception as e:
                raise DetailedHTTPException(
                    exception=e,
                    detail="Parsing JSON form Account Manager "
                    "to format Service_Mgmnt understands has failed.",
                    trace=traceback.format_exc(limit=100).splitlines())

            try:
                sq.send_to(
                    "Service_Components Mgmnt",
                    "Send created and signed SLR to Service_Components Mgmnt")
                endpoint = "/api/1.3/slr/slr"  # TODO Where do we get this endpoint?
                service_url = self.service_registry_handler.getService_url(
                    self.payload["service_id"].encode())
                debug_log.info("Service_ulr = {}, type: {}".format(
                    service_url, type(service_url)))
                response = post("{}{}".format(service_url, endpoint),
                                json=req,
                                timeout=self.request_timeout)
                debug_log.info(
                    "Service Mgmnt replied with status code ({})".format(
                        response.status_code))
                if not response.ok:
                    self.helpers.delete_session(code)
                    raise DetailedHTTPException(
                        status=response.status_code,
                        detail={
                            "Error from Service_Components Mgmnt":
                            loads(response.text)
                        },
                        title=response.reason)
            except DetailedHTTPException as e:
                raise e
            except Exception as e:
                self.helpers.delete_session(code)
                raise DetailedHTTPException(
                    exception=e,
                    detail="Sending SLR to service has failed",
                    trace=traceback.format_exc(limit=100).splitlines())

        except DetailedHTTPException as e:
            if "code" in locals():
                self.helpers.delete_session(code)
            raise e
        except Exception as e:
            if "code" in locals():
                self.helpers.delete_session(code)
            raise DetailedHTTPException(
                title="Creation of SLR has failed.",
                exception=e,
                trace=traceback.format_exc(limit=100).splitlines())
        # SLR is made at this point and returned to the Service Mgmnt, session can be deleted.
        if "code" in locals():
            self.helpers.delete_session(code)
        return loads(response.text), 201