Beispiel #1
0
    def test_signature_overwriting(self):
        msg = message.p2p.Ping()

        # First signature generated
        serialized = msg.serialize()
        msg2 = message.base.Message.deserialize(serialized, None)
        self.assertIsNotNone(msg2.sig)

        # Serialization with default sig_func should succeed
        msg2.serialize()

        with self.assertRaises(exceptions.SignatureAlreadyExists):
            golem_messages.dump(msg, self.ecc.raw_privkey, self.ecc.raw_pubkey)
Beispiel #2
0
    def setUp(self):
        super().setUp()

        deadline_offset = 10
        message_timestamp = get_current_utc_timestamp() + deadline_offset
        self.compute_task_def = ComputeTaskDefFactory()
        self.compute_task_def['deadline'] = message_timestamp
        want_to_compute_task = WantToComputeTaskFactory(
            provider_public_key=encode_hex(PROVIDER_PUBLIC_KEY), )
        want_to_compute_task = sign_message(want_to_compute_task,
                                            PROVIDER_PRIVATE_KEY)
        task_to_compute = tasks.TaskToComputeFactory(
            compute_task_def=self.compute_task_def,
            requestor_public_key=encode_hex(REQUESTOR_PUBLIC_KEY),
            requestor_ethereum_public_key=encode_hex(
                REQUESTOR_ETHERUM_PUBLIC_KEY),
            want_to_compute_task=want_to_compute_task,
            price=1,
        )
        task_to_compute.generate_ethsig(REQUESTOR_ETHEREUM_PRIVATE_KEY)
        task_to_compute.sign_all_promissory_notes(
            deposit_contract_address=settings.GNT_DEPOSIT_CONTRACT_ADDRESS,
            private_key=REQUESTOR_ETHEREUM_PRIVATE_KEY,
        )
        self.task_to_compute = load(
            dump(
                task_to_compute,
                REQUESTOR_PRIVATE_KEY,
                settings.CONCENT_PUBLIC_KEY,
            ),
            settings.CONCENT_PRIVATE_KEY,
            REQUESTOR_PUBLIC_KEY,
            check_time=False,
        )
        report_computed_task = tasks.ReportComputedTaskFactory(
            task_to_compute=self.task_to_compute)
        self.report_computed_task = load(
            dump(
                report_computed_task,
                PROVIDER_PRIVATE_KEY,
                settings.CONCENT_PUBLIC_KEY,
            ),
            settings.CONCENT_PRIVATE_KEY,
            PROVIDER_PUBLIC_KEY,
            check_time=False,
        )
        self.force_report_computed_task = message.concents.ForceReportComputedTask(
            report_computed_task=self.report_computed_task)

        self.force_get_task_result = message.concents.ForceGetTaskResult(
            report_computed_task=self.report_computed_task)
Beispiel #3
0
    def wrapper(
        request: HttpRequest,
        client_message: message.Message,
        client_public_key: bytes,
        *args: list,
        **kwargs: dict,
    ) -> Union[HttpResponse, JsonResponse]:

        if not is_given_golem_messages_version_supported_by_concent(
                request=request):
            log(
                logger,
                f'Wrong version of golem messages. Clients version is {request.META["HTTP_X_Golem_Messages"]}, '
                f'Concent version is {settings.GOLEM_MESSAGES_VERSION}.',
                client_public_key=client_public_key,
            )
            serialized_message = dump(
                message.concents.ServiceRefused(
                    reason=message.concents.ServiceRefused.REASON.
                    UnsupportedProtocolVersion, ),
                settings.CONCENT_PRIVATE_KEY,
                client_public_key,
            )
            return HttpResponse(serialized_message,
                                content_type='application/octet-stream')
        return view(request, client_message, client_public_key, *args, *kwargs)
Beispiel #4
0
 def test_deserialization_with_time_verification(self, vft_mock):
     msg = message.Ping()
     payload = golem_messages.dump(msg, self.ecc.raw_privkey,
                                   self.ecc.raw_pubkey)
     self.assertEqual(vft_mock.call_count, 0)
     golem_messages.load(payload, self.ecc.raw_privkey, self.ecc.raw_pubkey)
     self.assertEqual(vft_mock.call_count, 1)
Beispiel #5
0
    def setUp(self):
        super().setUp()

        deadline_offset = 10
        message_timestamp = get_current_utc_timestamp() + deadline_offset
        compute_task_def = message.ComputeTaskDef()
        compute_task_def['task_id'] = '8'
        compute_task_def['subtask_id'] = '8'
        compute_task_def['deadline'] = message_timestamp
        task_to_compute = tasks.TaskToComputeFactory(
            compute_task_def=compute_task_def,
            requestor_public_key=encode_hex(REQUESTOR_PUBLIC_KEY),
            provider_public_key=encode_hex(PROVIDER_PUBLIC_KEY),
            price=0,
        )
        task_to_compute = load(
            dump(
                task_to_compute,
                REQUESTOR_PRIVATE_KEY,
                settings.CONCENT_PUBLIC_KEY,
            ),
            settings.CONCENT_PRIVATE_KEY,
            REQUESTOR_PUBLIC_KEY,
            check_time=False,
        )
        report_computed_task = tasks.ReportComputedTaskFactory(
            task_to_compute=task_to_compute)
        self.force_report_computed_task = message.ForceReportComputedTask(
            report_computed_task=report_computed_task)
Beispiel #6
0
    def test_api_view_should_rollback_changes_on_400_error(self):

        store_subtask(
            task_id=self.compute_task_def['task_id'],
            subtask_id=self.compute_task_def['subtask_id'],
            provider_public_key=hex_to_bytes_convert(
                self.report_computed_task.task_to_compute.provider_public_key),
            requestor_public_key=hex_to_bytes_convert(
                self.report_computed_task.task_to_compute.requestor_public_key
            ),
            state=Subtask.SubtaskState.FORCING_RESULT_TRANSFER,
            next_deadline=(get_current_utc_timestamp() - 10),
            task_to_compute=self.task_to_compute,
            report_computed_task=self.report_computed_task,
            force_get_task_result=self.force_get_task_result,
        )
        self.assertEqual(Client.objects.count(), 2)
        with mock.patch('core.subtask_helpers.verify_file_status',
                        side_effect=_create_client_and_raise_http400_error_mock
                        ) as _create_client_and_raise_error_mock_function:
            self.client.post(
                reverse('core:send'),
                data=dump(self.force_report_computed_task,
                          PROVIDER_PRIVATE_KEY, CONCENT_PUBLIC_KEY),
                content_type='application/octet-stream',
                HTTP_X_GOLEM_MESSAGES=settings.GOLEM_MESSAGES_VERSION,
            )

        _create_client_and_raise_error_mock_function.assert_called()
        self.assertEqual(Client.objects.count(), 2)
Beispiel #7
0
    def test_request_with_not_allowed_http_method_should_return_405_error(
            self):
        """
        Tests if request to Concent with will return HTTP 405 error
        if not allowed HTTP method by view is used.
        """
        raw_message = dump(
            self.force_report_computed_task,
            settings.CONCENT_PRIVATE_KEY,
            settings.CONCENT_PUBLIC_KEY,
        )

        @require_golem_message
        @handle_errors_and_responses(database_name='default')
        @require_POST
        def dummy_view(_request, _message, _client_public_key):
            self.fail()

        request = self.request_factory.put(
            "/dummy-url/",
            content_type='application/octet-stream',
            data=raw_message,
            HTTP_X_GOLEM_MESSAGES=settings.GOLEM_MESSAGES_VERSION,
        )

        response = dummy_view(request)  # pylint: disable=no-value-for-parameter,assignment-from-no-return

        self.assertEqual(response.status_code, 405)
Beispiel #8
0
    def test_golem_messages_version_middleware_should_attach_http_header_to_response(
            self):
        """
        Tests that response from Concent:

        * Contains HTTP header 'Concent-Version'.
        * Header contains version of Concent taken from settings.
        """
        ping_message = message.Ping()
        serialized_ping_message = dump(ping_message, PROVIDER_PRIVATE_KEY,
                                       CONCENT_PUBLIC_KEY)

        with mock.patch(
                'concent_api.middleware.ConcentVersionMiddleware._concent_version',
                '1.0'):
            response = self.client.post(
                reverse('core:send'),
                data=serialized_ping_message,
                content_type='application/octet-stream',
                HTTP_X_Golem_Messages=settings.GOLEM_MESSAGES_VERSION,
            )

        self.assertFalse(500 <= response.status_code < 600)
        self.assertIn('concent-golem-messages-version', response._headers)
        self.assertEqual(response._headers['concent-version'][0],
                         'Concent-Version')
        self.assertEqual(response._headers['concent-version'][1], '1.0')
Beispiel #9
0
    def test_api_view_should_return_golem_message_as_octet_stream(self):
        raw_message = dump(
            self.force_report_computed_task,
            settings.CONCENT_PRIVATE_KEY,
            settings.CONCENT_PUBLIC_KEY,
        )

        decoded_message = None

        @require_golem_message
        @handle_errors_and_responses(database_name='default')
        def dummy_view(request, _message, _client_public_key):  # pylint: disable=unused-argument
            nonlocal decoded_message
            decoded_message = _message
            return None

        request = self.request_factory.post(
            "/dummy-url/",
            content_type='application/octet-stream',
            data=raw_message,
            HTTP_X_GOLEM_MESSAGES=settings.GOLEM_MESSAGES_VERSION,
        )

        dummy_view(request)  # pylint: disable=no-value-for-parameter

        self.assertIsInstance(decoded_message,
                              message.concents.ForceReportComputedTask)
        self.assertEqual(decoded_message, self.force_report_computed_task)
Beispiel #10
0
 def test_dump_load(self):
     msg = message.Ping()
     payload = golem_messages.dump(msg, self.ecc.raw_privkey,
                                   self.ecc.raw_pubkey)
     msg2 = golem_messages.load(payload, self.ecc.raw_privkey,
                                self.ecc.raw_pubkey)
     self.assertEqual(msg, msg2)
Beispiel #11
0
def receive_from_concent(
        signing_key,
        public_key,
        concent_variant: dict,
        path: str = '/api/v1/receive/') -> typing.Optional[bytes]:
    concent_receive_url = urljoin(concent_variant['url'], path)
    headers = {
        'Content-Type': 'application/octet-stream',
        'X-Golem-Messages': golem_messages.__version__,
    }
    authorization_msg = message.concents.ClientAuthorization(
        client_public_key=public_key, )
    data = golem_messages.dump(authorization_msg, signing_key,
                               concent_variant['pubkey'])
    try:
        logger.debug(
            'receive_from_concent(): GET %r hdr: %r',
            concent_receive_url,
            headers,
        )
        response = requests.post(
            concent_receive_url,
            data=data,
            headers=headers,
            **ssl_kwargs(concent_variant),
        )
    except requests.exceptions.RequestException as e:
        raise exceptions.ConcentUnavailableError(
            'Failed to receive_from_concent() {}'.format(e), ) from e

    verify_response(response)
    return response.content or None
Beispiel #12
0
    def test_golem_messages_version_middleware_should_attach_http_header_to_response(
            self):
        """
        Tests that response from Concent:

        * Contains HTTP header 'Concent-Golem-Messages-Version'.
        * Header contains latest version of golem_messages package.
        """
        ping_message = message.Ping()
        serialized_ping_message = dump(ping_message, PROVIDER_PRIVATE_KEY,
                                       CONCENT_PUBLIC_KEY)

        response = self.client.post(
            reverse('core:send'),
            data=serialized_ping_message,
            content_type='application/octet-stream',
        )

        self.assertFalse(500 <= response.status_code < 600)
        self.assertIn('concent-golem-messages-version', response._headers)
        self.assertEqual(
            response._headers['concent-golem-messages-version'][0],
            'Concent-Golem-Messages-Version')
        self.assertEqual(
            response._headers['concent-golem-messages-version'][1],
            __version__)
Beispiel #13
0
    def test_deserialize_verify_sender(self):
        msg = message.Hello()
        data = golem_messages.dump(msg, self.ecc.raw_privkey, None)

        msg_deserialized = message.base.Message.deserialize(
            data, lambda d: d, sender_public_key=self.ecc.raw_pubkey)

        self.assertEqual(msg, msg_deserialized)
Beispiel #14
0
    def test_deserialize_verify_sender_fails(self):
        ecc2 = golem_messages.ECCx(None)
        msg = message.Hello()
        data = golem_messages.dump(msg, self.ecc.raw_privkey, None)

        with self.assertRaises(exceptions.InvalidSignature):
            message.base.Message.deserialize(data,
                                             lambda d: d,
                                             sender_public_key=ecc2.raw_pubkey)
Beispiel #15
0
    def setUp(self):
        super().setUp()

        deadline_offset = 10
        message_timestamp = get_current_utc_timestamp() + deadline_offset
        self.compute_task_def = ComputeTaskDefFactory()
        self.compute_task_def['deadline'] = message_timestamp
        want_to_compute_task = WantToComputeTaskFactory(
            provider_public_key=encode_hex(PROVIDER_PUBLIC_KEY), )
        want_to_compute_task = sign_message(want_to_compute_task,
                                            PROVIDER_PRIVATE_KEY)
        task_to_compute = tasks.TaskToComputeFactory(
            compute_task_def=self.compute_task_def,
            requestor_public_key=encode_hex(REQUESTOR_PUBLIC_KEY),
            want_to_compute_task=want_to_compute_task,
            price=1,
        )
        self.task_to_compute = load(
            dump(
                task_to_compute,
                REQUESTOR_PRIVATE_KEY,
                settings.CONCENT_PUBLIC_KEY,
            ),
            settings.CONCENT_PRIVATE_KEY,
            REQUESTOR_PUBLIC_KEY,
            check_time=False,
        )
        report_computed_task = tasks.ReportComputedTaskFactory(
            task_to_compute=self.task_to_compute)
        self.report_computed_task = load(
            dump(
                report_computed_task,
                PROVIDER_PRIVATE_KEY,
                settings.CONCENT_PUBLIC_KEY,
            ),
            settings.CONCENT_PRIVATE_KEY,
            PROVIDER_PUBLIC_KEY,
            check_time=False,
        )
        self.force_report_computed_task = message.concents.ForceReportComputedTask(
            report_computed_task=self.report_computed_task)

        self.force_get_task_result = message.concents.ForceGetTaskResult(
            report_computed_task=self.report_computed_task)
Beispiel #16
0
    def setUp(self):
        super().setUp()

        deadline_offset = 10
        message_timestamp = get_current_utc_timestamp() + deadline_offset
        compute_task_def = message.ComputeTaskDef()
        compute_task_def['task_id'] = '8'
        compute_task_def['subtask_id'] = '8'
        compute_task_def['deadline'] = message_timestamp
        compute_task_def['extra_data'] = {
            'frames': [1],
            'output_format': 'PNG',
            'scene_file': 'kitten.blend',
        }
        task_to_compute = tasks.TaskToComputeFactory(
            compute_task_def=compute_task_def,
            requestor_public_key=encode_hex(REQUESTOR_PUBLIC_KEY),
            provider_public_key=encode_hex(PROVIDER_PUBLIC_KEY),
            price=0,
        )
        task_to_compute = load(
            dump(
                task_to_compute,
                REQUESTOR_PRIVATE_KEY,
                settings.CONCENT_PUBLIC_KEY,
            ),
            settings.CONCENT_PRIVATE_KEY,
            REQUESTOR_PUBLIC_KEY,
            check_time=False,
        )
        report_computed_task = tasks.ReportComputedTaskFactory(
            task_to_compute=task_to_compute)
        report_computed_task = load(
            dump(
                report_computed_task,
                PROVIDER_PRIVATE_KEY,
                settings.CONCENT_PUBLIC_KEY,
            ),
            settings.CONCENT_PRIVATE_KEY,
            PROVIDER_PUBLIC_KEY,
            check_time=False,
        )
        self.force_report_computed_task = message.ForceReportComputedTask(
            report_computed_task=report_computed_task)
Beispiel #17
0
 def test_that_middleware_does_not_intercept_bad_requests(self):
     ping_message = message.Ping()
     serialized_ping_message = dump(ping_message, PROVIDER_PRIVATE_KEY,
                                    CONCENT_PUBLIC_KEY)
     response = self.client.post(
         reverse('core:receive'),
         data=serialized_ping_message,
         content_type='application/octet-stream',
     )
     self.assertEqual(response.status_code, 400)
Beispiel #18
0
 def _get_serialized_force_report_computed_task(
     self,
     force_report_computed_task: ForceReportComputedTask,
     timestamp: Union[str, datetime.datetime, None] = None,
     provider_private_key: Optional[bytes] = None,
 ) -> bytes:
     with freeze_time(timestamp or get_timestamp_string()):
         return dump(
             force_report_computed_task,
             provider_private_key if provider_private_key is not None else
             self.PROVIDER_PRIVATE_KEY, settings.CONCENT_PUBLIC_KEY)
Beispiel #19
0
 def _get_serialized_reject_report_computed_task(
     self,
     reject_report_computed_task: RejectReportComputedTask,
     timestamp: Union[str, datetime.datetime, None] = None,
     requestor_private_key: Optional[bytes] = None,
 ) -> bytes:
     with freeze_time(timestamp or get_timestamp_string()):
         return dump(
             reject_report_computed_task,
             requestor_private_key if requestor_private_key is not None else
             self.REQUESTOR_PRIVATE_KEY, settings.CONCENT_PUBLIC_KEY)
Beispiel #20
0
def send_to_concent(msg: message.base.Message, signing_key: bytes,
                    concent_variant: dict) -> typing.Optional[bytes]:
    """Sends a message to the concent server

    :return: Raw reply message, None or exception
    :rtype: Bytes|None
    """

    logger.debug('send_to_concent(): Updating timestamp msg %r', msg)
    # Delayed messages are prepared before they're needed
    # and only sent to Concent if they're not cancelled
    # before. This can cause a situation where previously
    # prepared message will be too old to send when enqueued.
    # Also messages with no delay could have stayed in queue
    # long enough to eat significant amount of Message Transport Time
    # SEE: golem_messages.constants
    header = msg_datastructures.MessageHeader(
        msg.header.type_,
        # Using this tricky approach instead of time.time()
        # because of AppVeyor issues.
        calendar.timegm(time.gmtime()),
        msg.header.encrypted,
    )
    msg.header = header

    logger.debug('send_to_concent(): Encrypting msg %r', msg)
    # if signature already exists, it must be set to None explicitly
    if msg.sig is not None:
        msg.sig = None
    data = golem_messages.dump(msg, signing_key, concent_variant['pubkey'])
    logger.debug('send_to_concent(): data: %r', data)
    concent_post_url = urljoin(concent_variant['url'], '/api/v1/send/')
    headers = {
        'Content-Type': 'application/octet-stream',
        'X-Golem-Messages': golem_messages.__version__,
    }
    try:
        logger.debug(
            'send_to_concent(): POST %r hdr: %r',
            concent_post_url,
            headers,
        )
        response = requests.post(
            concent_post_url,
            data=data,
            headers=headers,
            **ssl_kwargs(concent_variant),
        )
    except requests.exceptions.RequestException as e:
        logger.warning('Concent RequestException %r', e)
        response = e.response

    verify_response(response)
    return response.content or None
Beispiel #21
0
    def test_slots_reselialization_optimization(self, dumps_mock):
        """Don't reserialize message slots immediately after deserialization"""
        msg = message.p2p.Tasks()  # Choose msg type with SIGN = True
        payload = golem_messages.dump(msg, self.ecc.raw_privkey,
                                      self.ecc.raw_pubkey)
        # One call for slots and second for hash_header
        self.assertEqual(dumps_mock.call_count, 2)

        dumps_mock.reset_mock()
        golem_messages.load(payload, self.ecc.raw_privkey, self.ecc.raw_pubkey)
        # One call for hash_header
        dumps_mock.assert_called_once_with(mock.ANY)
Beispiel #22
0
 def _send_force_report_computed_task(self):
     report_computed_task = message.tasks.ReportComputedTask(
         task_to_compute=self.task_to_compute  # pylint: disable=no-member
     )
     force_report_computed_task = message.ForceReportComputedTask(
         report_computed_task=report_computed_task, )
     return self.client.post(
         reverse('core:send'),
         data=dump(force_report_computed_task, self.PROVIDER_PRIVATE_KEY,
                   settings.CONCENT_PUBLIC_KEY),
         content_type='application/octet-stream',
     )
Beispiel #23
0
 def _get_serialized_force_report_computed_task(
     self,
     timestamp                   = None,
     force_report_computed_task  = None,
     provider_private_key        = None,
 ):
     with freeze_time(timestamp or self._get_timestamp_string()):
         return dump(
             force_report_computed_task,
             provider_private_key if provider_private_key is not None else self.PROVIDER_PRIVATE_KEY,
             settings.CONCENT_PUBLIC_KEY
         )
Beispiel #24
0
 def _get_serialized_subtask_results_verify(
     self,
     timestamp=None,
     subtask_results_verify=None,
     provider_private_key=None
 ):
     return dump(
         msg=(subtask_results_verify if subtask_results_verify is not None
              else self._get_deserialized_subtask_results_verify(timestamp)),
         privkey=provider_private_key if provider_private_key is not None else self.PROVIDER_PRIVATE_KEY,
         pubkey=settings.CONCENT_PUBLIC_KEY,
     )
Beispiel #25
0
 def _get_serialized_reject_report_computed_task(
     self,
     timestamp                   = None,
     reject_report_computed_task = None,
     requestor_private_key       = None,
 ):
     with freeze_time(timestamp or self._get_timestamp_string()):
         return dump(
             reject_report_computed_task,
             requestor_private_key if requestor_private_key is not None else self.REQUESTOR_PRIVATE_KEY,
             settings.CONCENT_PUBLIC_KEY
         )
Beispiel #26
0
    def test_require_golem_auth_message_decorator_should_return_http_400_when_auth_message_not_send(
            self):
        dumped_message = dump(self._create_test_ping_message(),
                              CONCENT_PRIVATE_KEY, CONCENT_PUBLIC_KEY)

        request = self.request_factory.post(
            "/dummy-url/",
            content_type='application/octet-stream',
            data=dumped_message)
        response = dummy_view_require_golem_auth_message(request)  # pylint: disable=no-value-for-parameter

        self.assertEqual(response.status_code, 400)
        self.assertIn('error', json.loads(response.content))
Beispiel #27
0
 def test_hello_version_verify(self, v_mock):
     msg = message.Hello()
     serialized = golem_messages.dump(
         msg,
         self.ecc.raw_privkey,
         self.ecc.raw_pubkey,
     )
     golem_messages.load(
         serialized,
         self.ecc.raw_privkey,
         self.ecc.raw_pubkey,
     )
     v_mock.assert_called_once_with(golem_messages.__version__)
Beispiel #28
0
 def _get_serialized_transaction_signing_request(
     self,
     signed_transaction: SignedTransaction,
     concent_private_key: bytes,
     public_key: bytes,
     timestamp: Union[str, datetime.datetime, None] = None,
 ) -> bytes:
     return dump(
         msg=(
             signed_transaction if signed_transaction is not None else
             self._get_deserialized_transaction_signing_request(timestamp)),
         privkey=concent_private_key,
         pubkey=public_key,
     )
Beispiel #29
0
 def _get_serialized_subtask_results_rejected(
     self,
     subtask_results_rejected: SubtaskResultsRejected,
     timestamp: Union[str, datetime.datetime, None] = None,
     requestor_private_key: Optional[bytes] = None,
 ) -> bytes:
     """ Return SubtaskResultsRejected serialized """
     with freeze_time(timestamp or get_timestamp_string()):
         return dump(
             subtask_results_rejected,
             requestor_private_key if requestor_private_key is not None else
             self.REQUESTOR_PRIVATE_KEY,
             settings.CONCENT_PUBLIC_KEY,
         )
Beispiel #30
0
 def _get_serialized_transaction_rejected(
     self,
     transaction_rejected: TransactionRejected,
     concent_private_key: bytes,
     public_key: bytes,
     timestamp: Union[str, datetime.datetime, None] = None,
 ) -> bytes:
     return dump(
         msg=(
             transaction_rejected if transaction_rejected is not None else
             self._get_deserialized_transaction_signing_request(timestamp)),
         privkey=concent_private_key,
         pubkey=public_key,
     )