use of org.eclipse.hono.service.auth.DeviceUser in project hono by eclipse.
the class HonoBasicAuthHandlerTest method testPreCredentialsValidationHandlerGetsInvoked.
/**
* Verifies that the PreCredentialsValidationHandler given for the AuthHandler is invoked
* when authenticating.
*/
@SuppressWarnings({ "unchecked", "rawtypes" })
@Test
public void testPreCredentialsValidationHandlerGetsInvoked() {
final AbstractDeviceCredentials deviceCredentials = mock(AbstractDeviceCredentials.class);
final DeviceUser deviceUser = new DeviceUser("tenant", "device");
// prepare authProvider
final DeviceCredentialsAuthProvider<AbstractDeviceCredentials> authProvider = mock(DeviceCredentialsAuthProvider.class);
doReturn(deviceCredentials).when(authProvider).getCredentials(any(JsonObject.class));
doAnswer(invocation -> {
final Handler handler = invocation.getArgument(2);
handler.handle(Future.succeededFuture(deviceUser));
return null;
}).when(authProvider).authenticate(any(AbstractDeviceCredentials.class), any(), VertxMockSupport.anyHandler());
// prepare PreCredentialsValidationHandler
final PreCredentialsValidationHandler<HttpContext> preCredValidationHandler = mock(PreCredentialsValidationHandler.class);
when(preCredValidationHandler.handle(eq(deviceCredentials), any(HttpContext.class))).thenReturn(Future.succeededFuture());
// GIVEN an auth handler with a PreCredentialsValidationHandler
final HonoBasicAuthHandler authHandler = new HonoBasicAuthHandler(authProvider, "test", preCredValidationHandler);
// WHEN the auth handler handles a request
final String authorization = "BASIC " + Base64.getEncoder().encodeToString("user:password".getBytes(StandardCharsets.UTF_8));
final MultiMap headers = mock(MultiMap.class);
when(headers.get(eq(HttpHeaders.AUTHORIZATION))).thenReturn(authorization);
final HttpServerRequest req = mock(HttpServerRequest.class);
when(req.headers()).thenReturn(headers);
final HttpServerResponse resp = mock(HttpServerResponse.class);
final RoutingContext routingContext = mock(RoutingContext.class);
final Map<String, Object> routingContextMap = new HashMap<>();
when(routingContext.put(any(), any())).thenAnswer(invocation -> {
routingContextMap.put(invocation.getArgument(0), invocation.getArgument(1));
return routingContext;
});
when(routingContext.get(any())).thenAnswer(invocation -> routingContextMap.get(invocation.getArgument(0)));
when(routingContext.request()).thenReturn(req);
when(routingContext.response()).thenReturn(resp);
when(routingContext.currentRoute()).thenReturn(mock(Route.class));
authHandler.handle(routingContext);
// THEN authentication succeeds and the PreCredentialsValidationHandler has been invoked
verify(routingContext).setUser(eq(deviceUser));
verify(preCredValidationHandler).handle(eq(deviceCredentials), any(HttpContext.class));
}
use of org.eclipse.hono.service.auth.DeviceUser in project hono by eclipse.
the class AbstractVertxBasedMqttProtocolAdapterTest method testConnectionMetrics.
/**
* Verifies the connection metrics for authenticated connections.
* <p>
* This test should check if the metrics receive a call to increment and decrement when a connection is being
* established and then closed.
*/
@Test
public void testConnectionMetrics() {
givenAnAdapter(properties);
when(authHandler.authenticateDevice(any(MqttConnectContext.class))).thenReturn(Future.succeededFuture(new DeviceUser("DEFAULT_TENANT", "4711")));
final MqttEndpoint endpoint = getMqttEndpointAuthenticated();
adapter.handleEndpointConnection(endpoint);
verify(metrics).incrementConnections("DEFAULT_TENANT");
final ArgumentCaptor<Handler<Void>> closeHandlerCaptor = VertxMockSupport.argumentCaptorHandler();
verify(endpoint, times(2)).closeHandler(closeHandlerCaptor.capture());
closeHandlerCaptor.getValue().handle(null);
verify(metrics).decrementConnections("DEFAULT_TENANT");
}
use of org.eclipse.hono.service.auth.DeviceUser in project hono by eclipse.
the class AbstractVertxBasedMqttProtocolAdapterTest method testConnectionDurationLimitExceeded.
/**
* Verifies that the connection is rejected due to the connection duration limit exceeded.
*/
@Test
public void testConnectionDurationLimitExceeded() {
// GIVEN an adapter requiring devices to authenticate endpoint
properties.setAuthenticationRequired(true);
givenAnAdapter(properties);
// WHEN a device tries to establish a connection
when(authHandler.authenticateDevice(any(MqttConnectContext.class))).thenReturn(Future.succeededFuture(new DeviceUser(Constants.DEFAULT_TENANT, "4711")));
when(resourceLimitChecks.isConnectionDurationLimitReached(any(TenantObject.class), any(SpanContext.class))).thenReturn(Future.succeededFuture(Boolean.TRUE));
final MqttEndpoint endpoint = getMqttEndpointAuthenticated();
adapter.handleEndpointConnection(endpoint);
// THEN the adapter has tried to authenticate the device
verify(authHandler).authenticateDevice(any(MqttConnectContext.class));
// THEN the connection request is rejected
verify(endpoint).reject(MqttConnectReturnCode.CONNECTION_REFUSED_NOT_AUTHORIZED);
verify(metrics).reportConnectionAttempt(ConnectionAttemptOutcome.CONNECTION_DURATION_EXCEEDED, Constants.DEFAULT_TENANT, "BUMLUX_CIPHER");
}
use of org.eclipse.hono.service.auth.DeviceUser in project hono by eclipse.
the class AbstractVertxBasedMqttProtocolAdapterTest method testEndpointHandlerRejectsDeviceOfDisabledTenant.
/**
* Verifies that an adapter rejects a connection attempt from a device that belongs to a tenant for which the
* adapter is disabled.
*/
@Test
public void testEndpointHandlerRejectsDeviceOfDisabledTenant() {
// GIVEN an adapter
givenAnAdapter(properties);
// which is disabled for tenant "my-tenant"
final TenantObject myTenantConfig = TenantObject.from("my-tenant", true);
myTenantConfig.addAdapter(new Adapter(ADAPTER_TYPE).setEnabled(Boolean.FALSE));
when(tenantClient.get(eq("my-tenant"), (SpanContext) any())).thenReturn(Future.succeededFuture(myTenantConfig));
when(authHandler.authenticateDevice(any(MqttConnectContext.class))).thenReturn(Future.succeededFuture(new DeviceUser("my-tenant", "4711")));
// WHEN a device of "my-tenant" tries to connect
final MqttEndpoint endpoint = mockEndpoint();
adapter.handleEndpointConnection(endpoint);
// THEN the connection is not established
verify(endpoint).reject(MqttConnectReturnCode.CONNECTION_REFUSED_NOT_AUTHORIZED);
verify(metrics).reportConnectionAttempt(ConnectionAttemptOutcome.ADAPTER_DISABLED, "my-tenant", null);
}
use of org.eclipse.hono.service.auth.DeviceUser in project hono by eclipse.
the class AbstractVertxBasedMqttProtocolAdapterTest method testAuthenticatedMqttAdapterRejectsConnectionForNonExistingDevice.
/**
* Verifies that unregistered devices with valid credentials cannot establish connection.
*/
@Test
public void testAuthenticatedMqttAdapterRejectsConnectionForNonExistingDevice() {
// GIVEN an adapter
givenAnAdapter(properties);
// which is connected to a Credentials service that has credentials on record for device 9999
when(authHandler.authenticateDevice(any(MqttConnectContext.class))).thenReturn(Future.succeededFuture(new DeviceUser(Constants.DEFAULT_TENANT, "9999")));
// but for which no registration information is available
when(registrationClient.assertRegistration(anyString(), eq("9999"), (String) any(), (SpanContext) any())).thenReturn(Future.failedFuture(new ClientErrorException(HttpURLConnection.HTTP_NOT_FOUND, "device unknown or disabled")));
// WHEN a device tries to connect with valid credentials
final MqttEndpoint endpoint = getMqttEndpointAuthenticated();
adapter.handleEndpointConnection(endpoint);
// THEN the device's credentials are verified successfully
verify(authHandler).authenticateDevice(any(MqttConnectContext.class));
// but the connection is refused
verify(endpoint).reject(MqttConnectReturnCode.CONNECTION_REFUSED_NOT_AUTHORIZED);
verify(metrics).reportConnectionAttempt(ConnectionAttemptOutcome.REGISTRATION_ASSERTION_FAILURE, Constants.DEFAULT_TENANT, "BUMLUX_CIPHER");
}
Aggregations