use of org.eclipse.hono.service.auth.DeviceUser in project hono by eclipse.
the class AbstractVertxBasedMqttProtocolAdapterTest method testConnectionsLimitExceeded.
/**
* Verifies that the connection is rejected due to the limit exceeded.
*/
@Test
public void testConnectionsLimitExceeded() {
// 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.isConnectionLimitReached(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.TENANT_CONNECTIONS_EXCEEDED, Constants.DEFAULT_TENANT, "BUMLUX_CIPHER");
}
use of org.eclipse.hono.service.auth.DeviceUser in project hono by eclipse.
the class CredentialsApiAuthProvider method authenticate.
@Override
public final void authenticate(final T deviceCredentials, final SpanContext spanContext, final Handler<AsyncResult<DeviceUser>> resultHandler) {
Objects.requireNonNull(deviceCredentials);
Objects.requireNonNull(resultHandler);
final Span currentSpan = TracingHelper.buildServerChildSpan(tracer, spanContext, "authenticate device", getClass().getSimpleName()).withTag(MessageHelper.APP_PROPERTY_TENANT_ID, deviceCredentials.getTenantId()).withTag(TracingHelper.TAG_AUTH_ID.getKey(), deviceCredentials.getAuthId()).start();
getCredentialsForDevice(deviceCredentials, currentSpan.context()).recover(t -> Future.failedFuture(mapNotFoundToBadCredentialsException(t))).compose(credentialsOnRecord -> validateCredentials(deviceCredentials, credentialsOnRecord, currentSpan.context())).map(device -> new DeviceUser(device.getTenantId(), device.getDeviceId())).onComplete(authAttempt -> {
if (authAttempt.succeeded()) {
currentSpan.log("successfully authenticated device");
} else {
currentSpan.log("authentication of device failed");
TracingHelper.logError(currentSpan, authAttempt.cause());
}
currentSpan.finish();
resultHandler.handle(authAttempt);
});
}
use of org.eclipse.hono.service.auth.DeviceUser in project hono by eclipse.
the class LoraProtocolAdapterTest method newHttpContext.
private HttpContext newHttpContext() {
final LoraMetaData metaData = new LoraMetaData();
metaData.setFunctionPort(TEST_FUNCTION_PORT);
final HttpServerRequest request = mock(HttpServerRequest.class);
when(request.uri()).thenReturn("/lora");
final RoutingContext context = mock(RoutingContext.class);
when(context.getBody()).thenReturn(Buffer.buffer());
when(context.user()).thenReturn(new DeviceUser(TEST_TENANT_ID, TEST_GATEWAY_ID));
when(context.request()).thenReturn(request);
when(context.response()).thenReturn(mock(HttpServerResponse.class));
when(context.get(LoraConstants.APP_PROPERTY_ORIG_LORA_PROVIDER)).thenReturn(TEST_PROVIDER);
when(context.get(LoraConstants.APP_PROPERTY_META_DATA)).thenReturn(metaData);
final Span parentSpan = mock(Span.class);
when(parentSpan.context()).thenReturn(mock(SpanContext.class));
when(context.get(TracingHandler.CURRENT_SPAN)).thenReturn(parentSpan);
return HttpContext.from(context);
}
use of org.eclipse.hono.service.auth.DeviceUser in project hono by eclipse.
the class AbstractVertxBasedHttpProtocolAdapterTest method testUploadCommandResponseFailsForOtherDevice.
/**
* Verifies that an authenticated device that is not a gateway fails to
* upload a command response for another device.
*/
@Test
public void testUploadCommandResponseFailsForOtherDevice() {
givenAnAdapter(properties);
final Buffer payload = Buffer.buffer("some payload");
final HttpContext ctx = newHttpContext(payload, "application/text", mock(HttpServerRequest.class), mock(HttpServerResponse.class));
final TenantObject to = TenantObject.from("tenant", true);
// Given an adapter that is enabled for a device's tenant
to.addAdapter(new Adapter(ADAPTER_TYPE).setEnabled(Boolean.TRUE));
when(tenantClient.get(eq("tenant"), (SpanContext) any())).thenReturn(Future.succeededFuture(to));
// which is connected to a Credentials service that has credentials on record for device 9999
when(ctx.getAuthenticatedDevice()).thenReturn(new DeviceUser("tenant", "9999"));
// but for which no registration information is available
when(registrationClient.assertRegistration(anyString(), anyString(), any(), any())).thenReturn(Future.failedFuture(new ClientErrorException(HttpURLConnection.HTTP_NOT_FOUND, "cannot publish data for device of other tenant")));
adapter.uploadCommandResponseMessage(ctx, "tenant", "device", CMD_REQ_ID, 200);
// Then the device gets a 404
assertContextFailedWithClientError(ctx, HttpURLConnection.HTTP_NOT_FOUND);
// and the response has not been reported as forwarded
verify(metrics).reportCommand(eq(Direction.RESPONSE), eq("tenant"), eq(to), eq(ProcessingOutcome.UNPROCESSABLE), eq(payload.length()), any());
}
use of org.eclipse.hono.service.auth.DeviceUser in project hono by eclipse.
the class ChainAuthHandlerTest method testPreCredentialsValidationHandlerGetsInvoked.
/**
* Verifies that the PreCredentialsValidationHandler given for the ChainAuthHandler is invoked
* when authenticating.
*
* @param ctx The vert.x test context.
*/
@SuppressWarnings({ "unchecked", "rawtypes" })
@Test
public void testPreCredentialsValidationHandlerGetsInvoked(final VertxTestContext ctx) {
final Checkpoint preCredValidationHandlerInvokedCheckpoint = ctx.checkpoint();
final Checkpoint testPassedCheckpoint = ctx.checkpoint();
final TestExecutionContext context = new TestExecutionContext();
final JsonObject parsedCredentials = new JsonObject().put("someKey", "someValue");
final AbstractDeviceCredentials deviceCredentials = mock(AbstractDeviceCredentials.class);
final DeviceUser deviceUser = new DeviceUser("tenant", "device");
// prepare nestedAuthHandler1
final AuthHandler<TestExecutionContext> nestedAuthHandler1 = newMockedAuthHandler();
when(nestedAuthHandler1.parseCredentials(any(TestExecutionContext.class))).thenReturn(Future.failedFuture("parseCredentials failed"));
// prepare nestedAuthHandler2
final AuthHandler<TestExecutionContext> nestedAuthHandler2 = newMockedAuthHandler();
when(nestedAuthHandler2.parseCredentials(any(TestExecutionContext.class))).thenReturn(Future.succeededFuture(parsedCredentials));
// prepare authProvider
final DeviceCredentialsAuthProvider<?> provider = mock(DeviceCredentialsAuthProvider.class);
doReturn(deviceCredentials).when(provider).getCredentials(any(JsonObject.class));
doAnswer(invocation -> {
final Handler handler = invocation.getArgument(2);
handler.handle(Future.succeededFuture(deviceUser));
return null;
}).when(provider).authenticate(any(), any(), any());
doReturn(provider).when(nestedAuthHandler2).getAuthProvider(eq(context));
// prepare PreCredentialsValidationHandler
final PreCredentialsValidationHandler<TestExecutionContext> preCredValidationHandler = mock(PreCredentialsValidationHandler.class);
doAnswer(invocation -> {
preCredValidationHandlerInvokedCheckpoint.flag();
return Future.succeededFuture();
}).when(preCredValidationHandler).handle(eq(deviceCredentials), eq(context));
// GIVEN an chain auth handler where the 2nd contained auth handler successfully parses credentials
// and returns an auth provider that successfully authenticates
final ChainAuthHandler<TestExecutionContext> chainAuthHandler = new ChainAuthHandler<>(preCredValidationHandler);
chainAuthHandler.append(nestedAuthHandler1);
chainAuthHandler.append(nestedAuthHandler2);
// WHEN a device gets authenticated
chainAuthHandler.authenticateDevice(context).onComplete(ctx.succeeding(user -> {
// THEN the returned user is the one return by the auth provider
ctx.verify(() -> {
assertThat(user).isEqualTo(deviceUser);
});
testPassedCheckpoint.flag();
}));
}
Aggregations