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));
}
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;
});
}
}
}
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);
}
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));
}
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);
}
Aggregations