def __process_worker_update(self, worker_id, input_json_str, response):
        """
        Function to update the worker details.
        Parameters:
            - worker_id is the worker id specified in the input json str.
            - input_json_str is a worker request json as per TCF API 5.3.2 Worker Update JSON Payload
            - response is the response object to be returned to client.
        """

        jrpc_id = json.loads(input_json_str)["id"]

        # value retrieved is 'result' field as per Spec 5.3.8 Worker Retrieve Response Payload
        value = self.kv_helper.get("workers", worker_id)

        if value is not None:
            json_dict = json.loads(value)
            input_value = json.loads(input_json_str)
            worker_details = input_value["params"]["details"]
            for item in worker_details:
                json_dict["details"][item] = worker_details[item]

            value = json.dumps(json_dict)
            self.kv_helper.set("workers", worker_id, value)
            response = utility.create_error_response(WorkerError.SUCCESS,
                                                     jrpc_id,
                                                     "Successfully Updated")
        else:
            response = utility.create_error_response(
                WorkerError.INVALID_PARAMETER_FORMAT_OR_VALUE, jrpc_id,
                "Worker Id not found in the database. \
                 Hence invalid parameter")
        return response
    def __process_work_order_get_result(self, wo_id, jrpc_id, response):
        """
        Function to process work order get result
        This API corresponds to TCF API 6.1.4 Work Order Pull Request Payload
        Parameters:
            - wo_id is work order id
            - jrpc_id is JRPC id of response
            - response is the response object to be returned
        """

        # Work order is processed if it is in wo-response table
        value = self.kv_helper.get("wo-responses", wo_id)
        if value:
            input_value = json.loads(value)
            if 'result' in value:
                response['result'] = input_value['result']
            else:
                response['result'] = input_value['error']
        else:
            if (self.kv_helper.get("wo-timestamps", wo_id) is not None):
                # work order is yet to be processed
                response = utility.create_error_response(
                    WorkorderError.PENDING, jrpc_id,
                    "Work order result is yet to be updated")
            else:
                # work order not in 'wo-timestamps' table
                response = utility.create_error_response(
                    WorkorderError.INVALID_PARAMETER_FORMAT_OR_VALUE, jrpc_id,
                    "Work order Id not found in the database. \
                     Hence invalid parameter")

        return response
    def __process_worker_set_status(self, worker_id, input_json_str, response):
        """
        Function to set the status of worker
        Parameters:
            - worker_id is the worker id specified in the input json str.
            - input_json_str is a worker request json as per TCF API 5.3.3 Worker Set Status JSON Payload
            - response is the response object to be returned to client.
        """

        #status can be one of active, offline, decommissioned, or compromised

        input_value = json.loads(input_json_str)
        jrpc_id = input_value["id"]

        value = self.kv_helper.get("workers", worker_id)
        if value:
            json_dict = json.loads(value)
            json_dict['status'] = input_value['params']['status']

            value = json.dumps(json_dict)
            self.kv_helper.set("workers", worker_id, value)
            response = utility.create_error_response(
                WorkerError.SUCCESS, jrpc_id, "Successfully Set Status")
        else:
            response = utility.create_error_response(
                WorkerError.INVALID_PARAMETER_FORMAT_OR_VALUE, jrpc_id,
                "Worker Id not found in the database. \
                 Hence invalid parameter")

        return response
    def __process_worker_register(self, worker_id, input_json_str, response):
        """
        Function to register a new worker to the enclave
        Parameters:
            - worker_id is the worker id specified in the input json str.
            - input_json_str is a worker request json as per TCF API 5.3.1 Worker Register JSON Payload.
            - response is the response object to be returned to client.
        """

        input_value_json = json.loads(input_json_str)
        jrpc_id = input_value_json["id"]

        if (self.kv_helper.get("workers", worker_id) is None):
            input_value = {}
            input_value = input_value_json['params']

            # Worker Initial Status is set to Active
            input_value["status"] = WorkerStatus.ACTIVE

            input_json_str = json.dumps(input_value)
            self.kv_helper.set("workers", worker_id, input_json_str)
            response = utility.create_error_response(
                WorkerError.SUCCESS, jrpc_id, "Successfully Registered")
        else:
            response = utility.create_error_response(
                WorkerError.INVALID_PARAMETER_FORMAT_OR_VALUE, jrpc_id,
                "Worker Id already exists in the database. \
                 Hence invalid parameter")
        return response
Exemplo n.º 5
0
    def render_POST(self, request):
        response = {}

        logger.info('Received a new request from the client')
        try:
            # process the message encoding
            encoding = request.getHeader('Content-Type')
            data = request.content.read()
            if encoding == 'application/json':

                try:
                    input_json_str = json.loads(data.decode('utf-8'))
                    input_json = json.loads(input_json_str)
                    jrpc_id = input_json["id"]
                    response = self._process_request(input_json_str)

                except AttributeError:
                    logger.error("Error while loading input json")
                    response = utility.create_error_response(
                        WorkorderError.UNKNOWN_ERROR, jrpc_id,
                        "UNKNOWN_ERROR: Error while loading the input JSON file"
                    )
                    return response

            else:
                # JRPC response with 0 as id is returned because id can't be fecthed
                # from a request with unknown encoding
                response = utility.create_error_response(
                    WorkorderError.UNKNOWN_ERROR, 0,
                    "UNKNOWN_ERROR: unknown message encoding")
                return response

        except:
            logger.exception('exception while decoding http request %s',
                             request.path)
            # JRPC response with 0 as id is returned because id can't be
            # fetched from improper request
            response = utility.create_error_response(
                WorkorderError.UNKNOWN_ERROR, 0,
                "UNKNOWN_ERROR: unable to decode incoming request")
            return response

        # send back the results
        try:
            if encoding == 'application/json':
                response = json.dumps(response)
            logger.info('response[%s]: %s', encoding, response)
            request.setHeader('content-type', encoding)
            request.setResponseCode(http.OK)
            return response.encode('utf8')

        except:
            logger.exception('unknown exception while processing request %s',
                             request.path)
            response = utility.create_error_response(
                WorkorderError.UNKNOWN_ERROR, jrpc_id,
                "UNKNOWN_ERROR: unknown exception processing http \
                    request {0}".format(request.path))
            return response
Exemplo n.º 6
0
    def __process_workorder_receipt_retrieve(self,wo_id, jrpc_id, response):
        """
        Function to retrieve the details of worker
        Parameters:
            - worker_id is the worker id specified in worker request json
              as per TCF API 7.2.4 Receipt Retrieve Request Payload
            - response is the response object to be returned to client
            - jrpc_id is the jrpc id of response object to be returned to client
        """

        # value retrieved is 'result' field as per Spec 7.2.5 Receipt Retrieve Response Payload
        value = self.kv_helper.get("wo-receipts", wo_id)
        
        if value:
            input_value = json.loads(value)
            response['result'] = {}
            if 'result' in value :
                response['result'] = input_value['result']
            else:
                #Need to revisit code when actual receipts are created
                response['result'] = input_value['error']
        else :
           response = utility.create_error_response(
                WorkorderError.INVALID_PARAMETER_FORMAT_OR_VALUE,
                jrpc_id,
                "Work order id not found in the database. \
                 Hence invalid parameter")
           return response

        return response
    def __process_worker_retrieve(self, worker_id, response):
        """
        Function to retrieve the details of worker
        Parameters:
            - worker_id is the worker id specified in worker request json as per TCF API 5.3.7 Worker Retrieve JSON Payload
            - response is the response object to be returned to client.
        """

        # value retrieved is 'result' field as per Spec 5.3.8 Worker Retrieve Response Payload
        value = self.kv_helper.get("workers", worker_id)

        if value is not None:
            json_dict = json.loads(value)
            response["result"] = {}
            response["result"]["workerType"] = json_dict["workerType"]
            response["result"]["organizationId"] = json_dict["organizationId"]
            response["result"]["applicationTypeId"] = json_dict[
                "applicationTypeId"]
            response["result"]["details"] = json_dict["details"]
            response["result"]["status"] = json_dict["status"]
        else:
            jrpc_id = json.loads(response)["id"]
            response = utility.create_error_response(
                WorkerError.INVALID_PARAMETER_FORMAT_OR_VALUE, jrpc_id,
                "Worker Id not found in the database. Hence invalid parameter")
        return response
Exemplo n.º 8
0
    def __process_workorder_receipt_update(self, wo_id, input_json_str, response):
        """
        Function to process update work order request
        Parameters:
            - wo_id is work order id
            - input_json_str is work order receipt update json as per
              TCF API 7.2.6 Receipt Update Retrieve Request Payload
            - response is the response object to be returned to client
        """

        input_value = json.loads(input_json_str)
        jrpc_id = input_value["id"]

        # value retrieved is 'result' field as per Spec 7.2.5 Receipt Retrieve Response Payload
        value = self.kv_helper.get("wo-receipts", wo_id)
        response['error'] = {}

        if value :
            updater_value = input_value['params']
            # WorkorderId already a part of receipt. And will be not change for a given receipt. Hence it's not stored in updater param.
            del updater_value['workOrderId']

            json_dict = json.loads(value)
            updater_objects = json_dict['result']['updater']

            if len(updater_objects)>0 :
                # Updater Object is sorted based on index and then last index is chosen
                index = int(sorted(updater_objects.keys())[-1]) + 1
            else :
                index = 0

            updater_objects[index] = updater_value
            json_dict['result']['receiptCurrentStatus'] = updater_value['updateType']
            json_dict['result']['updater'] = updater_objects

            value = json.dumps(json_dict)
            self.kv_helper.set("wo-receipts", wo_id, value)
            response = utility.create_error_response(
                    WorkorderError.SUCCESS, jrpc_id,
                    "Receipt Successfully Updated")
        else:
            response = utility.create_error_response(
                WorkorderError.INVALID_PARAMETER_FORMAT_OR_VALUE,
                jrpc_id,
                "Work order id not found in the database. \
                 Hence invalid parameter")
        return response
Exemplo n.º 9
0
    def render_GET(self, request):
        # JRPC response with id 0 is returned because id parameter
        # will not be found in GET request
        response = utility.create_error_response(
            WorkorderError.INVALID_PARAMETER_FORMAT_OR_VALUE, "0",
            "Only POST request is supported")
        logger.error(
            "GET request is not supported. Only POST request is supported")

        return response
Exemplo n.º 10
0
    def __process_encryption_key_set(self, input_json_str, response):
        """
        Function to process set encryption key request.
        Parameters:
            - input_json_str is a work order request json as per TCF API 6.1.11 Set Encryption Key Request Payload
            - response is the response object to be returned
        """

        input_json = json.loads(input_json_str)
        jrpc_id = input_json["id"]
        response = utility.create_error_response(
                WorkerError.INVALID_PARAMETER_FORMAT_OR_VALUE, jrpc_id,
                "Operation is not supported. Hence invalid parameter")
        return response
Exemplo n.º 11
0
    def __process_store_workorder_receipt(self, wo_id, input_json_str, response):
        """
        Function to process work order request
        Parameters:
            - wo_id is work order id
            - input_json_str is create work order receipt json
              as per TCF API 7.2.2 Receipt Create Request Payload
            - response is the response object to be returned to client
        """

        input_value_json = json.loads(input_json_str)
        jrpc_id = input_value_json["id"]
        input_value = {}
        input_value['result'] =  input_value_json['params']
        input_value['result']['receiptCurrentStatus'] = ReceiptCreateStatus.PENDING
        #Updater is introduced to maintain multiple update details on a receipt
        input_value['result']['updater'] = {}
        input_json_str = json.dumps(input_value)

        if(self.kv_helper.get("wo-receipts",wo_id) is None):
            value = self.kv_helper.get("wo-requests", wo_id)
            if value:
                self.kv_helper.set("wo-receipts",wo_id,input_json_str)
                response = utility.create_error_response(
                        WorkorderError.SUCCESS, jrpc_id,
                        "Receipt created successfully")
            else:
                response = utility.create_error_response(
                        WorkorderError.INVALID_PARAMETER_FORMAT_OR_VALUE, jrpc_id,
                        "Work order does not exists. Hence invalid parameter")
        else:
            response = utility.create_error_response(
                    WorkorderError.INVALID_PARAMETER_FORMAT_OR_VALUE, jrpc_id,
                    "Work order receipt already exist in the database. Hence invalid parameter")

        return response
Exemplo n.º 12
0
    def __process_workorder_receipt_update_retrieve(self,wo_id, input_json_str, response):
        """
        Function to process work order receipt update retrieve
        Parameters:
            - wo_id is work order id
            - input_json_str is work order receipt update json
              as per TCF API 7.2.6 Receipt Update Retrieve Request Payload
            - response is the response object to be returned to client
        """

        input_value = json.loads(input_json_str)
        jrpc_id = input_value["id"]

        # value retrieved is 'result' field as per Spec 7.2.5 Receipt Retrieve Response Payload
        value = self.kv_helper.get("wo-receipts",wo_id)

        if value :
            updater_id = input_value["params"]['updaterId']
            update_index = input_value["params"]['updateIndex']

            json_dict = json.loads(value)
            updater_objects = json_dict['result']['updater']

            update_count = 0
            result_item = {}
            for item in updater_objects:
                id = updater_objects[item]['updaterId']
                if id == updater_id :
                    #Considering Index 0 as  first update
                    if update_count == update_index :
                        result_item = updater_objects[item]
                #the total number of updates made by the updaterId.
                update_count = update_count+1

            response['result'] = {}
            response['result'] = result_item
            response['result']['updateCount'] = update_count

        else:
            response = utility.create_error_response(
                WorkorderError.INVALID_PARAMETER_FORMAT_OR_VALUE,
                jrpc_id,
                "Work order id not found in the database. \
                 Hence invalid parameter")

        return response
Exemplo n.º 13
0
    def __process_encryption_key_get(self, input_json_str, response):
        """
        Function to process get encryption key request.
        Parameters:
            - input_json_str is a work order request json as per TCF API 6.1.10 Get Encryption Key Request Payload
            - response is the response object to be returned
        """

        input_json = json.loads(input_json_str)
        jrpc_id = input_json["id"]
        worker_id = str(input_json['params']['workerId'])
        value = self.kv_helper.get("workers", worker_id)

        if value is not None:
            json_dict = json.loads(value)
            response["result"] = {}
            response["result"]["workerId"] = worker_id
            encryptionKey = json_dict["details"]["workerTypeData"]["encryptionKey"]
            try :
                encryptionKeyNonce = json_dict["details"]["workerTypeData"]["encryptionKeyNonce"]
            except :
                encryptionKeyNonce = crypto.random_bit_string(NO_OF_BYTES)
            tag = ""
            response["result"]["encryptionKey"] = encryptionKey
            response["result"]["encryptionKeyNonce"] = encryptionKeyNonce
            response["result"]["tag"] = tag
            #calculate signature
            concat_string = worker_id.encode('UTF-8') + encryptionKey.encode('UTF-8') + encryptionKeyNonce.encode('UTF-8') + tag.encode('UTF-8')
            concat_hash =  bytes()
            concat_hash =  bytes(concat_string)
            hash_1 = crypto.compute_message_hash(concat_hash)
            s1 = crypto.byte_array_to_base64(hash_1)
            # Requires worker private key to sign.
            # signature =  self.PrivateKey.SignMessage(hash)
            response["result"]["signature"] = s1
        else :
            # Workorder id already exists
            response = utility.create_error_response(
                    WorkerError.INVALID_PARAMETER_FORMAT_OR_VALUE, jrpc_id,
                    "Worker id not found in the database. Hence invalid parameter")

        return response
    def worker_registry_handler(self, input_json_str):
        """
        Function to process worker request
        Parameters:
            - input_json_str is a worker request json as per TCF API 5.3 Off-Chain Worker Registry JSON RPC API
        """

        input_json = json.loads(input_json_str)
        response = {}
        response['jsonrpc'] = '2.0'
        response['id'] = input_json['id']

        logger.info("Received Worker request : %s", input_json['method'])

        if (input_json['method'] == "WorkerLookUp"):
            return self.__process_worker_lookup(input_json_str, response)
        elif (input_json['method'] == "WorkerLookUpNext"):
            return self.__process_worker_lookup_next(input_json_str, response)

        if 'workerId' in input_json_str:
            worker_id = str(input_json['params']['workerId'])
        else:
            return utility.create_error_response(
                WorkerError.INVALID_PARAMETER_FORMAT_OR_VALUE,
                input_json["id"], "Worker Id not found in the database. \
                     Hence invalid parameter")

        if (input_json['method'] == "WorkerRegister"):
            return self.__process_worker_register(worker_id, input_json_str,
                                                  response)
        elif (input_json['method'] == "WorkerSetStatus"):
            return self.__process_worker_set_status(worker_id, input_json_str,
                                                    response)
        elif (input_json['method'] == "WorkerRetrieve"):
            return self.__process_worker_retrieve(worker_id, response)
        elif (input_json['method'] == "WorkerUpdate"):
            return self.__process_worker_update(worker_id, input_json_str,
                                                response)
Exemplo n.º 15
0
    def workorder_receipt_handler(self, input_json_str):
        """
        Function to process work order receipt request
        Parameters:
            - input_json_str is a work order receipt request json
              as per TCF API 7.2 Direct Model Receipt Handling
        """
        input_json = json.loads(input_json_str)
        response = {}
        response['jsonrpc'] = input_json['jsonrpc']
        response['id'] = input_json['id']

        logger.info("Received Work order Receipt request : %s",input_json['method'])
        if(input_json['method'] == "WorkOrderReceiptLookUp") :
            return self.__process_workorder_receipt_lookup(input_json_str, response)
        elif(input_json['method'] == "WorkOrderReceiptLookUpNext") :
            return self.__process_workorder_receipt_lookup_next(input_json_str, response)

        if 'workOrderId' in input_json_str:
           wo_id = str(input_json['params']['workOrderId'])
        else :
           response = utility.create_error_response(
                WorkorderError.INVALID_PARAMETER_FORMAT_OR_VALUE,
                input_json['id'],
                "Work order id not found in the database. \
                 Hence invalid parameter")
           return response

        jrpc_id = input_json['id']
        if(input_json['method'] == "WorkOrderReceiptCreate") :
            return self.__process_store_workorder_receipt(wo_id, input_json_str, response)
        elif(input_json['method'] == "WorkOrderReceiptUpdate") :
            return self.__process_workorder_receipt_update(wo_id, input_json_str, response)
        elif(input_json['method'] == "WorkOrderReceiptRetrieve") :
            return self.__process_workorder_receipt_retrieve(wo_id, jrpc_id, response)
        elif(input_json['method'] == "WorkOrderReceiptUpdateRetrieve") :
            return self.__process_workorder_receipt_update_retrieve(wo_id,input_json_str, response)
    def __process_work_order_submission(self, wo_id, input_json_str, response):
        """
        Function to process work order request
        Parameters:
            - wo_id is work order id
            - input_json_str is a work order request json as per TCF API 6.1.1 Work Order Request Payload
            - response is the response object to be returned to client
        """

        input_value_json = json.loads(input_json_str)
        jrpc_id = input_value_json["id"]

        if ((self.workorder_count + 1) > self.max_workorder_count):

            #if max count reached clear a processed entry
            work_orders = self.kv_helper.lookup("wo-timestamps")
            for id in work_orders:

                # If work order is processed then remove from table
                if (self.kv_helper.get("wo-processed", id) is not None):
                    self.kv_helper.remove("wo-processed", id)
                    self.kv_helper.remove("wo-requests", id)
                    self.kv_helper.remove("wo-responses", id)
                    self.kv_helper.remove("wo-receipts", id)
                    self.kv_helper.remove("wo-timestamps", id)

                    self.workorder_list.remove(id)
                    self.workorder_count -= 1
                    break

            # If no work order is processed then return busy
            if ((self.workorder_count + 1) > self.max_workorder_count):
                response = utility.create_error_response(
                    WorkorderError.BUSY, jrpc_id,
                    "Work order handler is busy updating the result")
                return response

        if (self.kv_helper.get("wo-timestamps", wo_id) is None):

            # Create a new work order entry. Dont change the order of table updation.
            # The order is important for clean up if the TCS is restarted in middle
            epoch_time = str(time.time())

            # Update the tables
            self.kv_helper.set("wo-timestamps", wo_id, epoch_time)
            self.kv_helper.set("wo-requests", wo_id, input_json_str)
            self.kv_helper.set("wo-scheduled", wo_id, input_json_str)
            #Add to the internal FIFO
            self.workorder_list.append(wo_id)
            self.workorder_count += 1

            response = utility.create_error_response(
                WorkorderError.PENDING, jrpc_id,
                "Work order is computing. Please query for WorkOrderGetResult \
                 to view the result")

        else:
            # Workorder id already exists
            response = utility.create_error_response(
                WorkorderError.INVALID_PARAMETER_FORMAT_OR_VALUE, jrpc_id,
                "Work order id already exists in the database. \
                 Hence invalid parameter")

        return response