Search in sources :

Example 6 with MqttEndpoint

use of io.vertx.mqtt.MqttEndpoint in project hono by eclipse.

the class AbstractVertxBasedMqttProtocolAdapterTest method testEndpointHandlerRetrievesCredentialsOnRecord.

/**
 * Verifies that an adapter retrieves credentials on record for a device connecting to the adapter.
 */
@SuppressWarnings("unchecked")
@Test
public void testEndpointHandlerRetrievesCredentialsOnRecord() {
    // GIVEN an adapter requiring devices to authenticate endpoint
    final MqttServer server = getMqttServer(false);
    config.setAuthenticationRequired(true);
    final AbstractVertxBasedMqttProtocolAdapter<ProtocolAdapterProperties> adapter = getAdapter(server);
    forceClientMocksToConnected();
    final MqttEndpoint endpoint = getMqttEndpointAuthenticated();
    adapter.handleEndpointConnection(endpoint);
    verify(credentialsAuthProvider).authenticate(any(UsernamePasswordCredentials.class), any(Handler.class));
}
Also used : ProtocolAdapterProperties(org.eclipse.hono.config.ProtocolAdapterProperties) MqttEndpoint(io.vertx.mqtt.MqttEndpoint) MqttServer(io.vertx.mqtt.MqttServer) Handler(io.vertx.core.Handler) UsernamePasswordCredentials(org.eclipse.hono.service.auth.device.UsernamePasswordCredentials) Test(org.junit.Test)

Example 7 with MqttEndpoint

use of io.vertx.mqtt.MqttEndpoint in project hono by eclipse.

the class AbstractVertxBasedMqttProtocolAdapter method handleEndpointConnectionWithAuthentication.

private void handleEndpointConnectionWithAuthentication(final MqttEndpoint endpoint) {
    if (endpoint.auth() == null) {
        LOG.debug("connection request from device [clientId: {}] rejected: {}", endpoint.clientIdentifier(), "device did not provide credentials in CONNECT packet");
        endpoint.reject(MqttConnectReturnCode.CONNECTION_REFUSED_BAD_USER_NAME_OR_PASSWORD);
    } else {
        final DeviceCredentials credentials = getCredentials(endpoint.auth());
        if (credentials == null) {
            LOG.debug("connection request from device [clientId: {}] rejected: {}", endpoint.clientIdentifier(), "device provided malformed credentials in CONNECT packet");
            endpoint.reject(MqttConnectReturnCode.CONNECTION_REFUSED_BAD_USER_NAME_OR_PASSWORD);
        } else {
            getTenantConfiguration(credentials.getTenantId()).compose(tenantConfig -> {
                if (tenantConfig.isAdapterEnabled(getTypeName())) {
                    LOG.debug("protocol adapter [{}] is enabled for tenant [{}]", getTypeName(), credentials.getTenantId());
                    return Future.succeededFuture(tenantConfig);
                } else {
                    LOG.debug("protocol adapter [{}] is disabled for tenant [{}]", getTypeName(), credentials.getTenantId());
                    return Future.failedFuture(new ClientErrorException(HttpURLConnection.HTTP_FORBIDDEN, "adapter disabled for tenant"));
                }
            }).compose(tenantConfig -> {
                final Future<Device> result = Future.future();
                getCredentialsAuthProvider().authenticate(credentials, result.completer());
                return result;
            }).map(authenticatedDevice -> {
                LOG.debug("successfully authenticated device [tenant-id: {}, auth-id: {}, device-id: {}]", authenticatedDevice.getTenantId(), credentials.getAuthId(), authenticatedDevice.getDeviceId());
                onAuthenticationSuccess(endpoint, authenticatedDevice);
                return null;
            }).otherwise(t -> {
                LOG.debug("cannot authenticate device [tenant-id: {}, auth-id: {}]", credentials.getTenantId(), credentials.getAuthId(), t);
                if (ServerErrorException.class.isInstance(t)) {
                    // one of the services we depend on might not be available (yet)
                    endpoint.reject(MqttConnectReturnCode.CONNECTION_REFUSED_SERVER_UNAVAILABLE);
                } else {
                    // validation of credentials has failed
                    endpoint.reject(MqttConnectReturnCode.CONNECTION_REFUSED_NOT_AUTHORIZED);
                }
                return null;
            });
        }
    }
}
Also used : HttpURLConnection(java.net.HttpURLConnection) MqttQoS(io.netty.handler.codec.mqtt.MqttQoS) MqttConnectReturnCode(io.netty.handler.codec.mqtt.MqttConnectReturnCode) LoggerFactory(org.slf4j.LoggerFactory) MqttEndpoint(io.vertx.mqtt.MqttEndpoint) Autowired(org.springframework.beans.factory.annotation.Autowired) ClientErrorException(org.eclipse.hono.client.ClientErrorException) ServiceInvocationException(org.eclipse.hono.client.ServiceInvocationException) Constants(org.eclipse.hono.util.Constants) MqttServer(io.vertx.mqtt.MqttServer) CompositeFuture(io.vertx.core.CompositeFuture) TelemetryConstants(org.eclipse.hono.util.TelemetryConstants) MessageSender(org.eclipse.hono.client.MessageSender) AbstractProtocolAdapterBase(org.eclipse.hono.service.AbstractProtocolAdapterBase) Message(org.apache.qpid.proton.message.Message) ResourceIdentifier(org.eclipse.hono.util.ResourceIdentifier) JsonObject(io.vertx.core.json.JsonObject) ProtocolAdapterProperties(org.eclipse.hono.config.ProtocolAdapterProperties) UsernamePasswordCredentials(org.eclipse.hono.service.auth.device.UsernamePasswordCredentials) Logger(org.slf4j.Logger) MqttServerOptions(io.vertx.mqtt.MqttServerOptions) DeviceCredentials(org.eclipse.hono.service.auth.device.DeviceCredentials) ServerErrorException(org.eclipse.hono.client.ServerErrorException) EndpointType(org.eclipse.hono.util.EndpointType) EventConstants(org.eclipse.hono.util.EventConstants) Future(io.vertx.core.Future) TenantObject(org.eclipse.hono.util.TenantObject) Objects(java.util.Objects) Buffer(io.vertx.core.buffer.Buffer) MqttAuth(io.vertx.mqtt.MqttAuth) Device(org.eclipse.hono.service.auth.device.Device) Device(org.eclipse.hono.service.auth.device.Device) ClientErrorException(org.eclipse.hono.client.ClientErrorException) DeviceCredentials(org.eclipse.hono.service.auth.device.DeviceCredentials)

Example 8 with MqttEndpoint

use of io.vertx.mqtt.MqttEndpoint in project hono by eclipse.

the class AbstractVertxBasedMqttProtocolAdapterTest method testEndpointHandlerFailsWithoutConnect.

// TODO: startup fail test
/**
 * Verifies that a connection attempt from a device is refused if the adapter is not
 * connected to all of the services it depends on.
 */
@Test
public void testEndpointHandlerFailsWithoutConnect() {
    // GIVEN an endpoint
    final MqttEndpoint endpoint = mock(MqttEndpoint.class);
    final MqttServer server = getMqttServer(false);
    final AbstractVertxBasedMqttProtocolAdapter<ProtocolAdapterProperties> adapter = getAdapter(server);
    adapter.handleEndpointConnection(endpoint);
    verify(endpoint).reject(MqttConnectReturnCode.CONNECTION_REFUSED_SERVER_UNAVAILABLE);
}
Also used : ProtocolAdapterProperties(org.eclipse.hono.config.ProtocolAdapterProperties) MqttEndpoint(io.vertx.mqtt.MqttEndpoint) MqttServer(io.vertx.mqtt.MqttServer) Test(org.junit.Test)

Example 9 with MqttEndpoint

use of io.vertx.mqtt.MqttEndpoint in project hono by eclipse.

the class AbstractVertxBasedMqttProtocolAdapterTest method testAuthenticatedMqttAdapterCreatesMessageHandlersForAuthenticatedDevices.

/**
 * Verifies that on successful authentication the adapter sets appropriate message and close
 * handlers on the client endpoint.
 */
@SuppressWarnings({ "unchecked" })
@Test
public void testAuthenticatedMqttAdapterCreatesMessageHandlersForAuthenticatedDevices() {
    // GIVEN an adapter
    final MqttServer server = getMqttServer(false);
    final AbstractVertxBasedMqttProtocolAdapter<ProtocolAdapterProperties> adapter = getAdapter(server);
    forceClientMocksToConnected();
    doAnswer(invocation -> {
        Handler<AsyncResult<Device>> resultHandler = invocation.getArgument(1);
        resultHandler.handle(Future.succeededFuture(new Device("DEFAULT_TENANT", "4711")));
        return null;
    }).when(credentialsAuthProvider).authenticate(any(DeviceCredentials.class), any(Handler.class));
    // WHEN a device tries to connect with valid credentials
    final MqttEndpoint endpoint = getMqttEndpointAuthenticated();
    adapter.handleEndpointConnection(endpoint);
    // THEN the device's logical ID is successfully established and corresponding handlers
    // are registered
    final ArgumentCaptor<DeviceCredentials> credentialsCaptor = ArgumentCaptor.forClass(DeviceCredentials.class);
    verify(credentialsAuthProvider).authenticate(credentialsCaptor.capture(), any(Handler.class));
    assertThat(credentialsCaptor.getValue().getAuthId(), is("sensor1"));
    verify(endpoint).accept(false);
    verify(endpoint).publishHandler(any(Handler.class));
    verify(endpoint).closeHandler(any(Handler.class));
}
Also used : ProtocolAdapterProperties(org.eclipse.hono.config.ProtocolAdapterProperties) MqttEndpoint(io.vertx.mqtt.MqttEndpoint) Device(org.eclipse.hono.service.auth.device.Device) MqttServer(io.vertx.mqtt.MqttServer) Handler(io.vertx.core.Handler) DeviceCredentials(org.eclipse.hono.service.auth.device.DeviceCredentials) AsyncResult(io.vertx.core.AsyncResult) Test(org.junit.Test)

Example 10 with MqttEndpoint

use of io.vertx.mqtt.MqttEndpoint in project hono by eclipse.

the class AbstractVertxBasedMqttProtocolAdapterTest method testEndpointHandlerRejectsUnauthenticatedDevices.

/**
 * Verifies that an adapter that is configured to require devices to authenticate,
 * rejects connections from devices not providing any credentials.
 */
@Test
public void testEndpointHandlerRejectsUnauthenticatedDevices() {
    // GIVEN an adapter that does require devices to authenticate
    final MqttServer server = getMqttServer(false);
    final AbstractVertxBasedMqttProtocolAdapter<ProtocolAdapterProperties> adapter = getAdapter(server);
    forceClientMocksToConnected();
    // WHEN a device connects without providing any credentials
    final MqttEndpoint endpoint = mock(MqttEndpoint.class);
    adapter.handleEndpointConnection(endpoint);
    // THEN the connection is refused
    verify(endpoint).reject(MqttConnectReturnCode.CONNECTION_REFUSED_BAD_USER_NAME_OR_PASSWORD);
}
Also used : ProtocolAdapterProperties(org.eclipse.hono.config.ProtocolAdapterProperties) MqttEndpoint(io.vertx.mqtt.MqttEndpoint) MqttServer(io.vertx.mqtt.MqttServer) Test(org.junit.Test)

Aggregations

MqttEndpoint (io.vertx.mqtt.MqttEndpoint)12 MqttServer (io.vertx.mqtt.MqttServer)11 ProtocolAdapterProperties (org.eclipse.hono.config.ProtocolAdapterProperties)11 Test (org.junit.Test)9 Buffer (io.vertx.core.buffer.Buffer)4 Handler (io.vertx.core.Handler)3 MqttAuth (io.vertx.mqtt.MqttAuth)3 MqttPublishMessage (io.vertx.mqtt.messages.MqttPublishMessage)3 DeviceCredentials (org.eclipse.hono.service.auth.device.DeviceCredentials)3 JsonObject (io.vertx.core.json.JsonObject)2 ProtonDelivery (io.vertx.proton.ProtonDelivery)2 ClientErrorException (org.eclipse.hono.client.ClientErrorException)2 Device (org.eclipse.hono.service.auth.device.Device)2 UsernamePasswordCredentials (org.eclipse.hono.service.auth.device.UsernamePasswordCredentials)2 ResourceIdentifier (org.eclipse.hono.util.ResourceIdentifier)2 TenantObject (org.eclipse.hono.util.TenantObject)2 MqttConnectReturnCode (io.netty.handler.codec.mqtt.MqttConnectReturnCode)1 MqttQoS (io.netty.handler.codec.mqtt.MqttQoS)1 AsyncResult (io.vertx.core.AsyncResult)1 CompositeFuture (io.vertx.core.CompositeFuture)1