Ejemplo n.º 1
0
    def create_from_symmetric_key(cls, provisioning_host, registration_id,
                                  id_scope, symmetric_key, **kwargs):
        """
        Create a client which can be used to run the registration of a device with provisioning service
        using Symmetric Key authentication.

        :param str provisioning_host: Host running the Device Provisioning Service.
            Can be found in the Azure portal in the Overview tab as the string Global device endpoint.
        :param str registration_id: The registration ID used to uniquely identify a device in the
            Device Provisioning Service. The registration ID is alphanumeric, lowercase string
            and may contain hyphens.
        :param str id_scope: The ID scope used to uniquely identify the specific provisioning
            service the device will register through. The ID scope is assigned to a
            Device Provisioning Service when it is created by the user and is generated by the
            service and is immutable, guaranteeing uniqueness.
        :param str symmetric_key: The key which will be used to create the shared access signature
            token to authenticate the device with the Device Provisioning Service. By default,
            the Device Provisioning Service creates new symmetric keys with a default length of
            32 bytes when new enrollments are saved with the Auto-generate keys option enabled.
            Users can provide their own symmetric keys for enrollments by disabling this option
            within 16 bytes and 64 bytes and in valid Base64 format.
        :param bool websockets: The switch for enabling MQTT over websockets. Defaults to false (no websockets).
        :returns: A ProvisioningDeviceClient instance which can register via Symmetric Key.
        """
        security_client = SymmetricKeySecurityClient(provisioning_host,
                                                     registration_id, id_scope,
                                                     symmetric_key)
        pipeline_configuration = BasePipelineConfig(**kwargs)
        mqtt_provisioning_pipeline = ProvisioningPipeline(
            security_client, pipeline_configuration)
        return cls(mqtt_provisioning_pipeline)
    def test_security_client_failure(
        self,
        mocker,
        params_security_clients,
        input_security_client,
        arbitrary_exception,
        pipeline_configuration,
    ):
        old_run_op = pipeline_stages_base.PipelineRootStage._run_op

        def fail_set_security_client(self, op):
            if isinstance(op, params_security_clients["set_args_op_class"]):
                op.complete(error=arbitrary_exception)
            else:
                old_run_op(self, op)

        mocker.patch.object(
            pipeline_stages_base.PipelineRootStage,
            "_run_op",
            side_effect=fail_set_security_client,
            autospec=True,
        )

        # auth_provider = SymmetricKeyAuthenticationProvider.parse(device_connection_string)
        with pytest.raises(arbitrary_exception.__class__) as e_info:
            ProvisioningPipeline(input_security_client, pipeline_configuration)
        assert e_info.value is arbitrary_exception
Ejemplo n.º 3
0
    def create_from_x509_certificate(cls, provisioning_host, registration_id,
                                     id_scope, x509, **kwargs):
        """
        Create a client which can be used to run the registration of a device with
        provisioning service using X509 certificate authentication.

        :param str provisioning_host: Host running the Device Provisioning Service. Can be found in
            the Azure portal in the Overview tab as the string Global device endpoint.
        :param str registration_id: The registration ID used to uniquely identify a device in the
            Device Provisioning Service. The registration ID is alphanumeric, lowercase string
            and may contain hyphens.
        :param str id_scope: The ID scope is used to uniquely identify the specific
            provisioning service the device will register through. The ID scope is assigned to a
            Device Provisioning Service when it is created by the user and is generated by the
            service and is immutable, guaranteeing uniqueness.
        :param x509: The x509 certificate, To use the certificate the enrollment object needs to
            contain cert (either the root certificate or one of the intermediate CA certificates).
            If the cert comes from a CER file, it needs to be base64 encoded.
        :type x509: :class:`azure.iot.device.X509`
        :param bool websockets: The switch for enabling MQTT over websockets. Defaults to false (no websockets).
        :returns: A ProvisioningDeviceClient which can register via Symmetric Key.
        """
        security_client = X509SecurityClient(provisioning_host,
                                             registration_id, id_scope, x509)
        pipeline_configuration = BasePipelineConfig(**kwargs)
        mqtt_provisioning_pipeline = ProvisioningPipeline(
            security_client, pipeline_configuration)
        return cls(mqtt_provisioning_pipeline)
    def test_pipeline_configuration(self, input_security_client, pipeline_configuration):
        pipeline = ProvisioningPipeline(input_security_client, pipeline_configuration)
        curr_stage = pipeline._pipeline

        expected_stage_order = [
            pipeline_stages_base.PipelineRootStage,
            pipeline_stages_provisioning.UseSecurityClientStage,
            pipeline_stages_provisioning.RegistrationStage,
            pipeline_stages_provisioning.PollingStatusStage,
            pipeline_stages_base.CoordinateRequestAndResponseStage,
            pipeline_stages_provisioning_mqtt.ProvisioningMQTTTranslationStage,
            pipeline_stages_base.AutoConnectStage,
            pipeline_stages_base.ReconnectStage,
            pipeline_stages_base.ConnectionLockStage,
            pipeline_stages_base.RetryStage,
            pipeline_stages_base.OpTimeoutStage,
            pipeline_stages_mqtt.MQTTTransportStage,
        ]

        # Assert that all PipelineStages are there, and they are in the right order
        for i in range(len(expected_stage_order)):
            expected_stage = expected_stage_order[i]
            assert isinstance(curr_stage, expected_stage)
            curr_stage = curr_stage.next

        # Assert there are no more additional stages
        assert curr_stage is None
    def test_passes_security_client_args(self, mocker, params_security_clients,
                                         input_security_client):
        mocker.spy(pipeline_stages_base.PipelineRootStage, "run_op")
        provisioning_pipeline = ProvisioningPipeline(input_security_client)

        op = provisioning_pipeline._pipeline.run_op.call_args[0][1]
        assert provisioning_pipeline._pipeline.run_op.call_count == 1
        assert isinstance(op, params_security_clients["set_args_op_class"])
        assert op.security_client is input_security_client
def mock_provisioning_pipeline(mocker, input_security_client,
                               mock_mqtt_transport):
    provisioning_pipeline = ProvisioningPipeline(input_security_client)
    provisioning_pipeline.on_connected = mocker.MagicMock()
    provisioning_pipeline.on_disconnected = mocker.MagicMock()
    provisioning_pipeline.on_message_received = mocker.MagicMock()
    helpers.add_mock_method_waiter(provisioning_pipeline, "on_connected")
    helpers.add_mock_method_waiter(provisioning_pipeline, "on_disconnected")
    helpers.add_mock_method_waiter(mock_mqtt_transport, "publish")

    yield provisioning_pipeline
    provisioning_pipeline.disconnect()
Ejemplo n.º 7
0
def mock_provisioning_pipeline(mocker, params_security_clients):
    input_security_client = params_security_clients["client_class"](
        **params_security_clients["init_kwargs"])
    mock_transport = mocker.patch(
        "azure.iot.device.provisioning.pipeline.provisioning_pipeline.pipeline_stages_mqtt.MQTTTransport"
    ).return_value
    provisioning_pipeline = ProvisioningPipeline(input_security_client)
    provisioning_pipeline._mock_transport = mock_transport
    provisioning_pipeline.on_connected = mocker.MagicMock()
    provisioning_pipeline.on_disconnected = mocker.MagicMock()
    provisioning_pipeline.on_message_received = mocker.MagicMock()
    helpers.add_mock_method_waiter(provisioning_pipeline, "on_connected")
    helpers.add_mock_method_waiter(provisioning_pipeline, "on_disconnected")
    helpers.add_mock_method_waiter(mock_transport, "publish")

    yield provisioning_pipeline
    provisioning_pipeline.disconnect()
    def test_security_client_success(self, mocker, input_security_client,
                                     pipeline_configuration):
        mocker.spy(pipeline_stages_base.PipelineRootStage, "run_op")
        pipeline = ProvisioningPipeline(input_security_client,
                                        pipeline_configuration)

        op = pipeline._pipeline.run_op.call_args[0][1]
        assert pipeline._pipeline.run_op.call_count == 1
        if isinstance(input_security_client, X509SecurityClient):
            assert isinstance(
                op, pipeline_ops_provisioning.SetX509SecurityClientOperation)
        else:
            assert isinstance(
                op, pipeline_ops_provisioning.
                SetSymmetricKeySecurityClientOperation)
        assert op.security_client is input_security_client
    def create_from_symmetric_key(cls,
                                  provisioning_host,
                                  registration_id,
                                  id_scope,
                                  symmetric_key,
                                  protocol_choice=None):
        """
        Create a client which can be used to run the registration of a device with provisioning service
        using Symmetric Key authentication.

        :param str provisioning_host: Host running the Device Provisioning Service.
            Can be found in the Azure portal in the Overview tab as the string Global device endpoint.
        :param str registration_id: The registration ID used to uniquely identify a device in the
            Device Provisioning Service. The registration ID is alphanumeric, lowercase string
            and may contain hyphens.
        :param str id_scope: The ID scope used to uniquely identify the specific provisioning
            service the device will register through. The ID scope is assigned to a
            Device Provisioning Service when it is created by the user and is generated by the
            service and is immutable, guaranteeing uniqueness.
        :param str symmetric_key: The key which will be used to create the shared access signature
            token to authenticate the device with the Device Provisioning Service. By default,
            the Device Provisioning Service creates new symmetric keys with a default length of
            32 bytes when new enrollments are saved with the Auto-generate keys option enabled.
            Users can provide their own symmetric keys for enrollments by disabling this option
            within 16 bytes and 64 bytes and in valid Base64 format.
        :param str protocol_choice: The choice for the protocol to be used. This is optional and
            will default to protocol MQTT currently.

        :returns: An ProvisioningDeviceClient instance which can register via Symmetric Key.
        """
        if protocol_choice is not None:
            protocol_name = protocol_choice.lower()
        else:
            protocol_name = "mqtt"
        if protocol_name == "mqtt":
            security_client = SymmetricKeySecurityClient(
                provisioning_host, registration_id, id_scope, symmetric_key)
            mqtt_provisioning_pipeline = ProvisioningPipeline(security_client)
            return cls(mqtt_provisioning_pipeline)
        else:
            raise NotImplementedError(
                "A symmetric key can only create symmetric key security client which is compatible "
                "only with MQTT protocol.Any other protocol has not been implemented."
            )
    def create_from_x509_certificate(cls,
                                     provisioning_host,
                                     registration_id,
                                     id_scope,
                                     x509,
                                     protocol_choice=None):
        """
        Create a client which can be used to run the registration of a device with
        provisioning service using X509 certificate authentication.

        :param str provisioning_host: Host running the Device Provisioning Service. Can be found in
            the Azure portal in the Overview tab as the string Global device endpoint.
        :param str registration_id: The registration ID used to uniquely identify a device in the
            Device Provisioning Service. The registration ID is alphanumeric, lowercase string
            and may contain hyphens.
        :param str id_scope: The ID scope is used to uniquely identify the specific
            provisioning service the device will register through. The ID scope is assigned to a
            Device Provisioning Service when it is created by the user and is generated by the
            service and is immutable, guaranteeing uniqueness.
        :param x509: The x509 certificate, To use the certificate the enrollment object needs to
            contain cert (either the root certificate or one of the intermediate CA certificates).
            If the cert comes from a CER file, it needs to be base64 encoded.
        :type x509: :class:`azure.iot.device.X509`
        :param str protocol_choice: The choice for the protocol to be used. This is optional and
            will default to protocol MQTT currently.

        :returns: A ProvisioningDeviceClient which can register via Symmetric Key.
        """
        if protocol_choice is None:
            protocol_name = "mqtt"
        else:
            protocol_name = protocol_choice.lower()
        if protocol_name == "mqtt":
            security_client = X509SecurityClient(provisioning_host,
                                                 registration_id, id_scope,
                                                 x509)
            mqtt_provisioning_pipeline = ProvisioningPipeline(security_client)
            return cls(mqtt_provisioning_pipeline)
        else:
            raise NotImplementedError(
                "A x509 certificate can only create x509 security client which is compatible only "
                "with MQTT protocol.Any other protocol has not been implemented."
            )
    def test_passes_security_client_args_failure(self, mocker,
                                                 params_security_clients,
                                                 input_security_client,
                                                 fake_exception):
        old_execute_op = pipeline_stages_base.PipelineRootStage._execute_op

        def fail_set_auth_provider(self, op):
            if isinstance(op, params_security_clients["set_args_op_class"]):
                op.error = fake_exception
                operation_flow.complete_op(stage=self, op=op)
            else:
                old_execute_op(self, op)

        mocker.patch.object(
            pipeline_stages_base.PipelineRootStage,
            "_execute_op",
            side_effect=fail_set_auth_provider,
        )

        with pytest.raises(fake_exception.__class__):
            ProvisioningPipeline(input_security_client)
Ejemplo n.º 12
0
    def test_passes_security_client_args_failure(self, mocker,
                                                 params_security_clients,
                                                 input_security_client,
                                                 arbitrary_exception):
        old_execute_op = pipeline_stages_base.PipelineRootStage._execute_op

        def fail_set_auth_provider(self, op):
            if isinstance(op, params_security_clients["set_args_op_class"]):
                self._complete_op(op, error=arbitrary_exception)
            else:
                old_execute_op(self, op)

        mocker.patch.object(
            pipeline_stages_base.PipelineRootStage,
            "_execute_op",
            side_effect=fail_set_auth_provider,
            autospec=True,
        )

        with pytest.raises(arbitrary_exception.__class__) as e_info:
            ProvisioningPipeline(input_security_client)
        assert e_info.value is arbitrary_exception
    def test_security_client_failure(self, mocker, input_security_client,
                                     arbitrary_exception,
                                     pipeline_configuration):
        old_run_op = pipeline_stages_base.PipelineRootStage._run_op

        def fail_set_security_client(self, op):
            if isinstance(
                    input_security_client, X509SecurityClient) or isinstance(
                        input_security_client, SymmetricKeySecurityClient):
                op.complete(error=arbitrary_exception)
            else:
                old_run_op(self, op)

        mocker.patch.object(
            pipeline_stages_base.PipelineRootStage,
            "_run_op",
            side_effect=fail_set_security_client,
            autospec=True,
        )

        with pytest.raises(arbitrary_exception.__class__) as e_info:
            ProvisioningPipeline(input_security_client, pipeline_configuration)
        assert e_info.value is arbitrary_exception
Ejemplo n.º 14
0
 def test_instantiates_correctly(self, input_security_client):
     provisioning_pipeline = ProvisioningPipeline(input_security_client)
     assert provisioning_pipeline._pipeline is not None
Ejemplo n.º 15
0
 def test_instantiates_correctly(self, params_security_clients,
                                 input_security_client,
                                 pipeline_configuration):
     provisioning_pipeline = ProvisioningPipeline(input_security_client,
                                                  pipeline_configuration)
     assert provisioning_pipeline._pipeline is not None
Ejemplo n.º 16
0
 def test_features_disabled(self, input_security_client,
                            pipeline_configuration):
     pipeline = ProvisioningPipeline(input_security_client,
                                     pipeline_configuration)
     assert not pipeline.responses_enabled[feature]
Ejemplo n.º 17
0
def pipeline(mocker, input_security_client, pipeline_configuration):
    pipeline = ProvisioningPipeline(input_security_client,
                                    pipeline_configuration)
    mocker.patch.object(pipeline._pipeline, "run_op")
    return pipeline
 def test_handlers_set_to_none(self, input_security_client, pipeline_configuration):
     pipeline = ProvisioningPipeline(input_security_client, pipeline_configuration)
     assert pipeline.on_connected is None
     assert pipeline.on_disconnected is None
     assert pipeline.on_message_received is None
 def test_handlers_configured(self, input_security_client, pipeline_configuration):
     pipeline = ProvisioningPipeline(input_security_client, pipeline_configuration)
     assert pipeline._pipeline.on_pipeline_event_handler is not None
     assert pipeline._pipeline.on_connected_handler is not None
     assert pipeline._pipeline.on_disconnected_handler is not None