Ejemplo n.º 1
0
 def __init__(self, url):
     Error.__init__(self, 302, "redirect")
     self.url = url
Ejemplo n.º 2
0
 def validate_options(self, scrapy_request_args, api_params):
     url = scrapy_request_args.get("url")
     start_requests = api_params.get("start_requests")
     if not url and not start_requests:
         raise Error('400',
                     "'url' is required if start_requests are disabled")
Ejemplo n.º 3
0
    def _secretreq(self, minfo):
        # unpack the request
        try:
            enclave_id = minfo['enclave_id']
            contract_id = minfo['contract_id']
            opk = minfo['opk']
            signature = minfo['signature']

        except KeyError as ke:
            raise Error(http.BAD_REQUEST,
                        'missing required field {0}'.format(ke))

        logger.debug('request for key for contract %s, enclave %s',
                     contract_id, enclave_id)

        # verify the signature, that is, make sure that the request was really signed by opk
        try:
            opkkey = pcrypto.SIG_PublicKey(opk)
            opkkey.VerifySignature(
                pcrypto.string_to_byte_array(enclave_id + contract_id),
                pcrypto.hex_to_byte_array(signature))
        except:
            logger.warn("Signature verification failed")
            raise Error(http.BAD_REQUEST, 'Signature Mismatch')

        # Get enclave state
        try:
            logger.debug('retrieve information for enclave %s', enclave_id)
            enclave_info = self.__registry_helper.get_enclave_info(enclave_id)
            logger.debug("enclave information retrieved: %s", enclave_info)
        except Exception as err:
            logger.error(
                'exception occurred when getting ledger information for enclave %s; %s',
                enclave_id, str(err))
            raise Exception(
                'could not retrieve enclave state; {0}'.format(err))

        # Get contract state
        try:
            logger.debug('retrieve information for contract <%s>', contract_id)
            contract_info = self.__registry_helper.get_contract_info(
                contract_id)
            logger.debug("contract_info from ledger: %s", contract_info)
        except Exception as err:
            logger.error(
                'exception occurred when getting ledger information for contract %s; %s',
                contract_id, str(err))
            raise Exception(
                'could not retrieve contract state; {0}'.format(err))

        # make sure that the signer of this request is really the owner of the contract
        try:
            # make sure that the signer of this request is really the owner of the contract
            # PdoContractInfo.pdo_contract_creator_pem_key is the VerifyingKey
            logger.debug("Contract creator's public key: %s",
                         contract_info['pdo_contract_creator_pem_key'])
            logger.debug("Expected public key: %s", opk)
            assert contract_info['pdo_contract_creator_pem_key'] == opk
        except:
            logger.error(
                'request to create secret did not come from the contract owner; %s != %s',
                contracttxn.OriginatorID, opk)
            raise Error(http.NOT_ALLOWED,
                        'operation not allowed for {0}'.format(opk))

        # make sure the provisioning service is allowed to access contract by the checking the list of allowed provisioning services
        try:
            logger.debug("Contract allowed service ids: %s",
                         contract_info['provisioning_service_ids'])
            logger.debug("Expected provisioning service id: %s", self.PSPK)
            assert self.PSPK in contract_info['provisioning_service_ids']
        except:
            logger.error(
                'This Pservice is not the list of allowed provisioning services, PSerivce ID: %s',
                self.PSPK)
            raise Error(http.NOT_ALLOWED,
                        'operation not allowed for {0}'.format(self.PSPK))

        # retrieve the sealed secret
        sealed_secret = self._GetContractSecret(contract_id)

        logger.debug("Enclave Info: %s", str(enclave_info))

        # Generate Secret for Contract Enclave, signs unsealed secret with contract enclave encryption key
        esecret = self.Enclave.generate_enclave_secret(
            self.SealedData,
            sealed_secret,
            contract_id,
            opk,
            json.dumps(enclave_info),
        )["enclave_secret"]

        logger.debug("Encrypted secret for contract %s: %s", contract_id,
                     esecret)

        # create the response
        response = dict()
        response['pspk'] = self.PSPK
        response['encrypted_secret'] = esecret

        logger.info('created secret for contract %s and enclave %s',
                    contract_id, enclave_id)
        return response
Ejemplo n.º 4
0
 def trapNotFound(failure):
     failure.trap(error.NodeNotFound)
     raise Error(http.NOT_FOUND, "Node not found")
Ejemplo n.º 5
0
 def trapXMPPURIParseError(failure):
     failure.trap(XMPPURIParseError)
     raise Error(http.BAD_REQUEST,
                 "Malformed XMPP URI: %s" % failure.value)
Ejemplo n.º 6
0
 def renderQuery(self, query):
     query = self.graphql.parse(query)
     errors = self.graphql.validate(self.schema, query)
     if errors:
         raise Error(400, [e.formatted for e in errors])
Ejemplo n.º 7
0
 def fail(url, timeout=None):
     raise Error(code=404)
Ejemplo n.º 8
0
    def _secretreq(self, minfo):
        # unpack the request
        try:
            enclave_id = minfo['enclave_id']
            contract_id = minfo['contract_id']
            opk = minfo['opk']
            signature = minfo['signature']

        except KeyError as ke:
            raise Error(http.BAD_REQUEST,
                        'missing required field {0}'.format(ke))

        logger.debug('request for key for contract %s, enclave %s',
                     contract_id, enclave_id)

        # verify the signature, that is, make sure that the request was really signed by opk
        try:
            opkkey = pcrypto.SIG_PublicKey(opk)
            opkkey.VerifySignature(
                pcrypto.string_to_byte_array(enclave_id + contract_id),
                pcrypto.hex_to_byte_array(signature))
        except:
            logger.warn("Signature verification failed")
            raise Error(http.BAD_REQUEST, 'Signature Mismatch')

        # Get enclave state
        try:
            logger.debug('retrieve information for enclave %s', enclave_id)
            enclave_info = self.__registry_helper.get_enclave_dict(enclave_id)
            logger.debug("enclave information retrieved: %s", enclave_info)
        except BaseException as err:
            logger.warn(
                'exception occurred when getting ledger information for enclave %s; %s',
                enclave_id, str(err))
            raise Error(http.BAD_REQUEST,
                        'could not retrieve enclave state; {0}'.format(err))
        except ClientConnectException as err:
            logger.warn(
                'client exception occurred when getting ledger information for enclave %s; %s',
                enclave_id, str(err))
            raise Error(http.BAD_REQUEST,
                        'could not retrieve enclave state; {0}'.format(err))

        # Get contract state
        try:
            logger.debug('retrieve information for contract <%s>', contract_id)
            contract_info = self.__registry_helper.get_contract_dict(
                contract_id)
            logger.debug("contract_info from ledger: %s", contract_info)
        except BaseException as err:
            logger.warn(
                'exception occurred when getting ledger information for contract %s; %s',
                contract_id, str(err))
            raise Error(http.BAD_REQUEST,
                        'could not retrieve contract state; {0}'.format(err))
        except ClientConnectException as err:
            logger.warn(
                'client exception occurred when getting ledger information for contract %s; %s',
                contract_id, str(err))
            raise Error(http.BAD_REQUEST,
                        'could not retrieve contract state; {0}'.format(err))

        # make sure that the signer of this request is really the owner of the contract
        try:
            # make sure that the signer of this request is really the owner of the contract
            # PdoContractInfo.pdo_contract_creator_pem_key is the VerifyingKey
            logger.debug("Contract creator's public key: %s",
                         contract_info['pdo_contract_creator_pem_key'])
            logger.debug("Expected public key: %s", opk)
            assert contract_info['pdo_contract_creator_pem_key'] == opk
        except:
            logger.error(
                'request to create secret did not come from the contract owner; %s != %s',
                contracttxn.OriginatorID, opk)
            raise Error(http.NOT_ALLOWED,
                        'operation not allowed for {0}'.format(opk))

        # make sure the provisioning service is allowed to access contract by the checking the list of allowed provisioning services
        try:
            logger.debug("Contract allowed service ids: %s",
                         contract_info['provisioning_service_ids'])
            logger.debug("Expected provisioning service id: %s",
                         self.PSPK.Serialize())
            assert self.PSPK.Serialize(
            ) in contract_info['provisioning_service_ids']
        except:
            logger.error(
                'This Pservice is not the list of allowed provisioning services, PSerivce ID: %s',
                self.PSPK.Serialize())
            raise Error(
                http.NOT_ALLOWED,
                'operation not allowed for {0}'.format(self.PSPK.Serialize()))

        # retrieve the secret
        secret = self._GetContractSecret(contract_id)

        # create the signature
        message = secret + enclave_id + contract_id + opk
        secretsig = pcrypto.byte_array_to_hex(
            self.SigningKey.SignMessage(pcrypto.string_to_byte_array(message)))

        # pad secret to required max size
        # TODO: Eventually this requirement needs to be fixed in the crypto library itself
        required_padding = 2 * pcrypto.MAX_SIG_SIZE - len(secretsig)
        secretsig = secretsig + ('0' * required_padding)

        enclavekey = pcrypto.PKENC_PublicKey(enclave_info['encryption_key'])
        esecret = pcrypto.byte_array_to_base64(
            enclavekey.EncryptMessage(
                pcrypto.string_to_byte_array(secret + secretsig)))

        logger.debug("Encrypted secret for contract %s: %s", contract_id,
                     esecret)

        # create the response
        response = dict()
        response['pspk'] = self.PSPK.Serialize()
        response['encrypted_secret'] = esecret

        logger.info('created secret for contract %s and enclave %s',
                    contract_id, enclave_id)
        return response
Ejemplo n.º 9
0
 def __init__(self, url):
     Error.__init__(self, 302, "redirect")
     self.url = protect_redirect_url(unicode2bytes(url))
Ejemplo n.º 10
0
 def test_get_bad_code(self):
     return self.check_get_error(
         fail(Error("999")), ProviderError,
         "Unexpected HTTP 999 trying to GET "
         "http://somewhe.re/rubber/chicken")
Ejemplo n.º 11
0
    def data_acquisition(self, bucket):

        request = bucket.request

        content_type = request.getHeader('Content-Type')

        # Read and decode request body
        body = request.content.read()
        bucket.body = body

        # Decode data from request body
        if body:

            # Decode data from JSON format
            if content_type.startswith('application/json'):
                return json.loads(body)

            # Decode data from x-www-form-urlencoded format
            elif content_type.startswith('application/x-www-form-urlencoded'):
                # TODO: Honor charset when receiving "application/x-www-form-urlencoded; charset=utf-8"
                payload = parse_qs(body, 1)
                # TODO: Decapsulate multiple values of same reading into "{name}-{N}", where N=1...
                decoded = {}
                for key, value in payload.items():
                    key = key.decode()
                    if type(value) is list:
                        decoded[key] = value[0].decode()
                return decoded

            # Decode data from CSV format
            elif content_type.startswith('text/csv'):

                if not self.metastore:
                    log.error(
                        'Generic decoding of CSV format requires metastore')

                # Prepare alias for metastore table
                csv_header_store = self.metastore.kotori['channel-csv-headers']

                # 1. Decode CSV header like '## weight,temperature, humidity' and remember for upcoming data readings
                def parse_header(channel_info, data_lines):

                    first_line = data_lines[0]
                    header_line = None
                    options = {}

                    # Regular header announcement
                    if first_line.startswith('## '):
                        header_line = first_line[3:].strip()
                        data_lines.pop(0)

                    # Convenience hack to support Open Hive CSV import
                    elif first_line.startswith(
                            'Date/Time') or first_line.startswith(
                                'Datum/Zeit'):
                        header_line = first_line
                        data_lines.pop(0)

                    # Convenience hack to support Beelogger CSV import
                    elif first_line.startswith('Datum,Uhrzeit'):
                        header_line = first_line
                        data_lines.pop(0)
                        options['rules'] = [{
                            'type': 'fuse',
                            'source': ['Datum', 'Uhrzeit'],
                            'target': 'time',
                            'join': 'T',
                            'suffix': 'Z'
                        }]

                    # Convenience hack to support import from http://archive.luftdaten.info/
                    elif first_line.startswith('sensor_id'):
                        header_line = first_line
                        data_lines.pop(0)

                    if header_line:
                        # Streamline various differences for even more convenience.
                        header_line = header_line.replace(';', ',')
                        # FIXME: Unify with ``kotori.daq.storage.influx.format_chunk()``.
                        date_fields = [
                            'Date/Time', 'Date', 'Datum/Zeit', 'timestamp'
                        ]
                        for date_field in date_fields:
                            header_line = header_line.replace(
                                date_field, 'time')
                        header_fields = list(
                            map(str.strip, header_line.split(',')))
                        msg = u'CSV Header: fields={fields}, key={key}'.format(
                            fields=header_fields,
                            key=request.channel_identifier)
                        log.info(msg)

                        csv_header_store.update_one(
                            {"channel": request.channel_identifier}, {
                                "$set": {
                                    "header_fields": header_fields,
                                    "options": options
                                }
                            },
                            upsert=True)

                        message = u'Received header fields {}'.format(
                            header_fields)
                        request.messages.append({
                            'type': 'info',
                            'message': message
                        })

                        channel_info['header_fields'] = header_fields
                        channel_info['options'] = options

                    #print('header_fields, data_lines:', header_fields, data_lines)
                    #return header_fields, data_lines

                # 2. Decode data, map to full-qualified payload container
                def parse_data(channel_info):
                    channel_info = channel_info or {}
                    data_raw = body.decode().strip()
                    data_lines = list(map(str.strip, data_raw.split('\n')))
                    parse_header(channel_info, data_lines)
                    header_fields = channel_info.get('header_fields')
                    if not header_fields:
                        raise Error(
                            http.BAD_REQUEST,
                            response=
                            b'Could not process data, please supply field names '
                            b'via CSV header before sending readings')

                    #print('data_lines:', data_lines; pprint(data_lines))

                    data_list = []
                    for data_line in data_lines:
                        data_fields = list(
                            map(str.strip,
                                data_line.replace(';', ',').split(',')))
                        #print 'header_fields, data_fields:', header_fields, data_fields
                        data = OrderedDict(
                            list(zip(header_fields, data_fields)))
                        self.manipulate_data(data, channel_info)
                        data_list.append(data)

                    return data_list

                try:
                    channel_info = csv_header_store.find_one(
                        filter={"channel": request.channel_identifier})
                except Exception as ex:
                    log.failure(
                        'Could not process CSV data, unknown database error: {0}'
                        .format(ex))
                    raise Error(
                        http.INTERNAL_SERVER_ERROR,
                        response=
                        b'Could not process CSV data, unknown database error: {0}'
                        .format(ex))

                return parse_data(channel_info)

            else:
                msg = u"Unable to handle Content-Type '{content_type}'".format(
                    content_type=content_type)
                log.warn(msg)
                raise Error(http.UNSUPPORTED_MEDIA_TYPE, response=msg)

        else:
            msg = u'Empty request body'
            log.warn(msg)
            raise Error(http.BAD_REQUEST, response=msg)
Ejemplo n.º 12
0
 def test_get_404(self):
     return self.check_get_error(
         fail(Error("404")), FileNotFound,
         "File was not found: 'http://somewhe.re/rubber/chicken'")
Ejemplo n.º 13
0
 def raise_error(body):
     raise Error(response.code, response=body)
Ejemplo n.º 14
0
 def __str__(self):
     return Error.__str__(self) + " " + ensure_str(self.response)
Ejemplo n.º 15
0
 def directoryListing(self):
     raise Error(NOT_ALLOWED, b"Not allowed")
Ejemplo n.º 16
0
 def directoryListing(self):
     # type: () -> None
     raise Error(NOT_ALLOWED, b"Not allowed")
Ejemplo n.º 17
0
 def __init__(self, msg):
     Error.__init__(self, 403, msg)
Ejemplo n.º 18
0
 def test_error_403(self, log_msg_mock):
     exc = Error('403', 'blah_403')
     result = self.resource.handle_error(exc, self.request)
     self.assertEqual(self.request.code, 403)
     self.assertFalse(log_msg_mock.called)
     self.assertEqual(result['message'], exc.message)
Ejemplo n.º 19
0
 def mock_fs_get(self, url, code, content=None):
     self.getPage(url)
     if code == 200:
         self.mocker.result(succeed(content))
     else:
         self.mocker.result(fail(Error(str(code))))
    def render_post(self, request, components, msg):
        """
        Forward a signed message through the gossip network.
        """
        encoding = request.getHeader('Content-Type')
        data = request.content.getvalue()
        try:
            if encoding == 'application/json':
                minfo = json2dict(data)

            elif encoding == 'application/cbor':
                minfo = cbor2dict(data)
            else:
                raise Error(
                    "", 'unknown message'
                    ' encoding: {0}'.format(encoding))
            typename = minfo.get('__TYPE__', '**UNSPECIFIED**')
            if typename not in self.Ledger.MessageHandlerMap:
                raise Error(
                    "", 'received request for unknown message'
                    ' type, {0}'.format(typename))
            msg = self.Ledger.MessageHandlerMap[typename][0](minfo)
        except Error as e:
            LOGGER.info('exception while decoding http request %s; %s',
                        request.path, traceback.format_exc(20))
            raise Error(http.BAD_REQUEST,
                        'unable to decode incoming request: {0}'.format(e))

        if self.Validator.Config.get("LocalValidation", True):
            # determine if the message contains a valid transaction before
            # we send the message to the network

            # we need to start with a copy of the message due to cases
            # where side effects of the validity check may impact objects
            # related to msg
            mymsg = copy.deepcopy(msg)

            if hasattr(mymsg, 'Transaction') and mymsg.Transaction is not None:
                mytxn = mymsg.Transaction
                LOGGER.info(
                    'starting local validation '
                    'for txn id: %s type: %s', mytxn.Identifier,
                    mytxn.TransactionTypeName)

                pending_block_txns = None
                if self.Ledger.PendingTransactionBlock is not None:
                    pending_block_txns = \
                        self.Ledger.PendingTransactionBlock.TransactionIDs

                block_id = self.Ledger.MostRecentCommittedBlockID

                real_store_map = \
                    self.Ledger.GlobalStoreMap.get_block_store(block_id)
                temp_store_map = \
                    global_store_manager.BlockStore(real_store_map)
                if not temp_store_map:
                    LOGGER.info('no store map for block %s', block_id)
                    raise Error(
                        http.BAD_REQUEST, 'unable to validate enclosed'
                        ' transaction {0}'.format(data))

                pending_txns = copy.copy(self.Ledger.PendingTransactions)
                pending_txn_ids = [x for x in pending_txns.iterkeys()]

                # clone a copy of the ledger's message queue so we can
                # temporarily play forward all locally submitted yet
                # uncommitted transactions
                my_queue = copy.deepcopy(self.Ledger.MessageQueue)

                transaction_type = mytxn.TransactionTypeName
                if transaction_type not in temp_store_map.TransactionStores:
                    LOGGER.info('transaction type %s not in global store map',
                                transaction_type)
                    raise Error(
                        http.BAD_REQUEST, 'unable to validate enclosed'
                        ' transaction {0}'.format(data))

                if pending_block_txns is not None:
                    pending_txn_ids = pending_block_txns + pending_txn_ids

                # apply any local pending transactions
                for txn_id in pending_txn_ids:
                    pend_txn = self.Ledger.TransactionStore[txn_id]
                    my_store = temp_store_map.get_transaction_store(
                        pend_txn.TransactionTypeName)
                    if pend_txn and pend_txn.is_valid(my_store):
                        my_pend_txn = copy.copy(pend_txn)
                        my_pend_txn.apply(my_store)

                # apply any enqueued messages
                while len(my_queue) > 0:
                    qmsg = my_queue.pop()
                    if qmsg and \
                            qmsg.MessageType in self.Ledger.MessageHandlerMap:
                        if (hasattr(qmsg, 'Transaction')
                                and qmsg.Transaction is not None):
                            my_store = temp_store_map.get_transaction_store(
                                qmsg.Transaction.TransactionTypeName)
                            if qmsg.Transaction.is_valid(my_store):
                                myqtxn = copy.copy(qmsg.Transaction)
                                myqtxn.apply(my_store)

                # determine validity of the POSTed transaction against our
                # new temporary state
                my_store = temp_store_map.get_transaction_store(
                    mytxn.TransactionTypeName)
                try:
                    mytxn.check_valid(my_store)
                except InvalidTransactionError as e:
                    LOGGER.info(
                        'submitted transaction fails transaction '
                        'family validation check: %s; %s', request.path,
                        mymsg.dump())
                    raise Error(
                        http.BAD_REQUEST,
                        "enclosed transaction failed transaction "
                        "family validation check: {}".format(str(e)))
                except:
                    LOGGER.info(
                        'submitted transaction is '
                        'not valid %s; %s; %s', request.path, mymsg.dump(),
                        traceback.format_exc(20))
                    raise Error(
                        http.BAD_REQUEST, "enclosed transaction is not"
                        " valid {}".format(data))

                LOGGER.info('transaction %s is valid',
                            msg.Transaction.Identifier)

        # and finally execute the associated method
        # and send back the results

        self.Ledger.handle_message(msg)
        return msg
Ejemplo n.º 21
0
 def getLoginResource(self):
     raise Error(501, b"not implemented")
Ejemplo n.º 22
0
 def __init__(self, url):
     Error.__init__(self, 302, "redirect")
     self.url = url
Ejemplo n.º 23
0
 def trapNotFound(failure):
     err = failure.trap(*self.errorMap.keys())
     status, message = self.errorMap[err]
     raise Error(status, message)
Ejemplo n.º 24
0
 def fail_unauthorized(url, timeout=None, headers=None):
     if headers != expected_headers:
         raise Error(code=403)
Ejemplo n.º 25
0
 def trapNotFound(failure):
     failure.trap(StanzaError)
     if not failure.value.condition == 'item-not-found':
         raise failure
     raise Error(http.NOT_FOUND, "Node not found")
Ejemplo n.º 26
0
 def _missing_parameter(self, parameter):
     raise Error(400, "Missing required parameter: %s" % parameter)
Ejemplo n.º 27
0
    def _handletxnrequest(self, pathcomponents, args, testonly):
        """
        Handle a transaction request. There are four types of requests:
            empty path -- return a list of the committed transactions ids
            txnid -- return the contents of the specified transaction
            txnid and field name -- return the contents of the specified
                transaction
            txnid and HEAD request -- return success only if the transaction
                                      has been committed
                404 -- transaction does not exist
                302 -- transaction exists but has not been committed
                200 -- transaction has been committed

        The request may specify additional parameters:
            blockcount -- the number of blocks (newest to oldest) from which to
                pull txns

        Transactions are returned from oldest to newest.
        """
        if len(pathcomponents) == 0:
            blkcount = 0
            if 'blockcount' in args:
                blkcount = int(args.get('blockcount').pop(0))

            txnids = []
            blockids = self.Ledger.commited_block_ids(blkcount)
            while blockids:
                blockid = blockids.pop()
                txnids.extend(self.Ledger.BlockStore[blockid].TransactionIDs)
            return txnids

        txnid = pathcomponents.pop(0)

        if txnid not in self.Ledger.TransactionStore:
            raise Error(http.NOT_FOUND,
                        'no such transaction {0}'.format(txnid))

        txn = self.Ledger.TransactionStore[txnid]

        if testonly:
            if txn.Status == transaction.Status.committed:
                return None
            else:
                raise Error(http.FOUND,
                            'transaction not committed {0}'.format(txnid))

        tinfo = txn.dump()
        tinfo['Identifier'] = txnid
        tinfo['Status'] = txn.Status
        if txn.Status == transaction.Status.committed:
            tinfo['InBlock'] = txn.InBlock

        if not pathcomponents:
            return tinfo

        field = pathcomponents.pop(0)
        if field not in tinfo:
            raise Error(http.BAD_REQUEST,
                        'unknown transaction field {0}'.format(field))

        return tinfo[field]
Ejemplo n.º 28
0
 def _get_active_view():
     view = simple.GetActiveView()
     if not view:
         raise Error(404, "No view provided to WebGL resource")
     return view
Ejemplo n.º 29
0
 def parse(self, val):
     # type: (bytes) -> Tuple[int, ...]
     try:
         return tuple(map(int, val.split(b".")))
     except (TypeError, ValueError):
         raise Error(BAD_REQUEST, b"Invalid version literal")
Ejemplo n.º 30
0
 def validate_options(self, api_params):
     if not api_params.get("urls"):
         raise Error('400', "A list of urls to crawl must be specified.")
Ejemplo n.º 31
0
 def __init__(self, msg):
     Error.__init__(self, 403, msg)
Ejemplo n.º 32
0
 def test_error_400(self, log_err_mock):
     exc = Error('400', 'blah_400')
     result = self.resource.handle_render_errors(self.request, exc)
     self.assertEqual(self.request.code, 400)
     self.assertFalse(log_err_mock.called)
     self.assertEqual(result['message'], exc.message)