Search in sources :

Example 11 with CredentialsObject

use of org.eclipse.hono.util.CredentialsObject in project hono by eclipse.

the class CredentialsApiTests method testGetCredentialsSucceedsForNonExistingClientContext.

/**
 * Verifies that a request for credentials using a client context succeeds if the credentials on record
 * do not have any extension properties with keys matching the provided client context.
 *
 * @param ctx The vert.x test context.
 */
@Timeout(value = 5, timeUnit = TimeUnit.SECONDS)
@Test
public void testGetCredentialsSucceedsForNonExistingClientContext(final VertxTestContext ctx) {
    final String deviceId = getHelper().getRandomDeviceId(tenantId);
    final String authId = UUID.randomUUID().toString();
    final CommonCredential credentials = getRandomHashedPasswordCredential(authId).putExtension("other", "property");
    final JsonObject clientContext = new JsonObject().put("client-id", "gateway-one");
    getHelper().registry.registerDevice(tenantId, deviceId).compose(httpResponse -> getHelper().registry.addCredentials(tenantId, deviceId, List.of(credentials))).compose(httpResponse -> getClient().get(tenantId, CredentialsConstants.SECRETS_TYPE_HASHED_PASSWORD, authId, clientContext, spanContext)).onComplete(ctx.succeeding(credentialsObject -> {
        ctx.verify(() -> {
            assertThat(credentialsObject.getSecrets()).isNotEmpty();
        });
        ctx.completeNow();
    }));
}
Also used : HttpURLConnection(java.net.HttpURLConnection) X509Certificate(java.security.cert.X509Certificate) VertxTestContext(io.vertx.junit5.VertxTestContext) BeforeEach(org.junit.jupiter.api.BeforeEach) X500Principal(javax.security.auth.x500.X500Principal) DownstreamMessage(org.eclipse.hono.application.client.DownstreamMessage) CertificateFactory(java.security.cert.CertificateFactory) LoggerFactory(org.slf4j.LoggerFactory) Credentials(org.eclipse.hono.service.management.credentials.Credentials) SelfSignedCertificate(io.vertx.core.net.SelfSignedCertificate) OptionalInt(java.util.OptionalInt) Tenant(org.eclipse.hono.service.management.tenant.Tenant) Timeout(io.vertx.junit5.Timeout) IntegrationTestSupport(org.eclipse.hono.tests.IntegrationTestSupport) CredentialsClient(org.eclipse.hono.client.registry.CredentialsClient) JsonObject(io.vertx.core.json.JsonObject) Tenants(org.eclipse.hono.tests.Tenants) RegistryManagementConstants(org.eclipse.hono.util.RegistryManagementConstants) Device(org.eclipse.hono.service.management.device.Device) Logger(org.slf4j.Logger) Truth.assertWithMessage(com.google.common.truth.Truth.assertWithMessage) Vertx(io.vertx.core.Vertx) FileInputStream(java.io.FileInputStream) CertificateException(java.security.cert.CertificateException) UUID(java.util.UUID) Truth.assertThat(com.google.common.truth.Truth.assertThat) Instant(java.time.Instant) DeviceStatus(org.eclipse.hono.service.management.device.DeviceStatus) MessageHelper(org.eclipse.hono.util.MessageHelper) EventConstants(org.eclipse.hono.util.EventConstants) FileNotFoundException(java.io.FileNotFoundException) CredentialsConstants(org.eclipse.hono.util.CredentialsConstants) AuthenticationConstants(org.eclipse.hono.util.AuthenticationConstants) SpanContext(io.opentracing.SpanContext) TimeUnit(java.util.concurrent.TimeUnit) Test(org.junit.jupiter.api.Test) List(java.util.List) CommonCredential(org.eclipse.hono.service.management.credentials.CommonCredential) Checkpoint(io.vertx.junit5.Checkpoint) NoopSpan(io.opentracing.noop.NoopSpan) Collections(java.util.Collections) CredentialsObject(org.eclipse.hono.util.CredentialsObject) PasswordCredential(org.eclipse.hono.service.management.credentials.PasswordCredential) CertificateEncodingException(java.security.cert.CertificateEncodingException) CommonCredential(org.eclipse.hono.service.management.credentials.CommonCredential) JsonObject(io.vertx.core.json.JsonObject) Test(org.junit.jupiter.api.Test) Timeout(io.vertx.junit5.Timeout)

Example 12 with CredentialsObject

use of org.eclipse.hono.util.CredentialsObject in project hono by eclipse.

the class CredentialsApiAuthProvider method validateCredentials.

/**
 * Verifies that the credentials provided by a device during the authentication
 * process match the credentials on record for that device.
 *
 * @param deviceCredentials The credentials provided by the device.
 * @param credentialsOnRecord The credentials to match against.
 * @param spanContext The OpenTracing context to use for tracking the operation.
 * @return A future that is succeeded with the authenticated device if the
 *         credentials have been validated successfully. Otherwise, the
 *         future is failed with a {@link ServiceInvocationException}.
 */
private Future<Device> validateCredentials(final T deviceCredentials, final CredentialsObject credentialsOnRecord, final SpanContext spanContext) {
    final Span currentSpan = TracingHelper.buildServerChildSpan(tracer, spanContext, "validate credentials", getClass().getSimpleName()).withTag(MessageHelper.APP_PROPERTY_TENANT_ID, deviceCredentials.getTenantId()).withTag(TracingHelper.TAG_AUTH_ID.getKey(), deviceCredentials.getAuthId()).withTag(TracingHelper.TAG_CREDENTIALS_TYPE.getKey(), deviceCredentials.getType()).start();
    final Promise<Device> result = Promise.promise();
    if (!deviceCredentials.getAuthId().equals(credentialsOnRecord.getAuthId())) {
        currentSpan.log(String.format("Credentials service returned wrong credentials-on-record [auth-id: %s]", credentialsOnRecord.getAuthId()));
        result.fail(new ServerErrorException(HttpURLConnection.HTTP_INTERNAL_ERROR));
    } else if (!deviceCredentials.getType().equals(credentialsOnRecord.getType())) {
        currentSpan.log(String.format("Credentials service returned wrong credentials-on-record [type: %s]", credentialsOnRecord.getType()));
        result.fail(new ServerErrorException(HttpURLConnection.HTTP_INTERNAL_ERROR));
    } else if (!credentialsOnRecord.isEnabled()) {
        currentSpan.log("credentials-on-record are disabled");
        result.fail(new ClientErrorException(HttpURLConnection.HTTP_UNAUTHORIZED));
    } else {
        doValidateCredentials(deviceCredentials, credentialsOnRecord).onComplete(result);
    }
    return result.future().map(device -> {
        currentSpan.log("validation of credentials succeeded");
        currentSpan.finish();
        return device;
    }).recover(t -> {
        currentSpan.log("validation of credentials failed");
        TracingHelper.logError(currentSpan, t);
        currentSpan.finish();
        return Future.failedFuture(t);
    });
}
Also used : HttpURLConnection(java.net.HttpURLConnection) Logger(org.slf4j.Logger) Tracer(io.opentracing.Tracer) Promise(io.vertx.core.Promise) LoggerFactory(org.slf4j.LoggerFactory) ServerErrorException(org.eclipse.hono.client.ServerErrorException) ClientErrorException(org.eclipse.hono.client.ClientErrorException) ServiceInvocationException(org.eclipse.hono.client.ServiceInvocationException) MessageHelper(org.eclipse.hono.util.MessageHelper) Future(io.vertx.core.Future) Device(org.eclipse.hono.auth.Device) DeviceUser(org.eclipse.hono.service.auth.DeviceUser) SpanContext(io.opentracing.SpanContext) Objects(java.util.Objects) User(io.vertx.ext.auth.User) CredentialsClient(org.eclipse.hono.client.registry.CredentialsClient) Span(io.opentracing.Span) JsonObject(io.vertx.core.json.JsonObject) TracingHelper(org.eclipse.hono.tracing.TracingHelper) AsyncResult(io.vertx.core.AsyncResult) Handler(io.vertx.core.Handler) CredentialsObject(org.eclipse.hono.util.CredentialsObject) Device(org.eclipse.hono.auth.Device) ClientErrorException(org.eclipse.hono.client.ClientErrorException) ServerErrorException(org.eclipse.hono.client.ServerErrorException) Span(io.opentracing.Span)

Example 13 with CredentialsObject

use of org.eclipse.hono.util.CredentialsObject in project hono by eclipse.

the class FileBasedCredentialsServiceTest method testLoadCredentialsCanReadOutputOfSaveToFile.

/**
 * Verifies that the file written by the registry when persisting the registry's contents can
 * be loaded in again.
 *
 * @param ctx The vert.x test context.
 */
@SuppressWarnings({ "unchecked", "rawtypes" })
@Test
public void testLoadCredentialsCanReadOutputOfSaveToFile(final TestContext ctx) {
    // GIVEN a service configured to persist credentials to file
    // that contains some credentials
    props.setFilename(FILE_NAME);
    props.setSaveToFile(true);
    when(fileSystem.existsBlocking(FILE_NAME)).thenReturn(Boolean.TRUE);
    final Async add = ctx.async(2);
    final CredentialsObject hashedPassword = CredentialsObject.fromHashedPassword("4700", "bumlux", "secret", "sha-512", null, null, null);
    final CredentialsObject psk = CredentialsObject.fromPresharedKey("4711", "sensor1", "sharedkey".getBytes(StandardCharsets.UTF_8), null, null);
    svc.add(Constants.DEFAULT_TENANT, JsonObject.mapFrom(psk), ctx.asyncAssertSuccess(s -> {
        ctx.assertEquals(HttpURLConnection.HTTP_CREATED, s.getStatus());
        add.countDown();
    }));
    svc.add("OTHER_TENANT", JsonObject.mapFrom(hashedPassword), ctx.asyncAssertSuccess(s -> {
        ctx.assertEquals(HttpURLConnection.HTTP_CREATED, s.getStatus());
        add.countDown();
    }));
    add.await(2000);
    // WHEN saving the registry content to the file and clearing the registry
    final Async write = ctx.async();
    doAnswer(invocation -> {
        Handler handler = invocation.getArgument(2);
        handler.handle(Future.succeededFuture());
        write.complete();
        return null;
    }).when(fileSystem).writeFile(eq(FILE_NAME), any(Buffer.class), any(Handler.class));
    svc.saveToFile();
    write.await(2000);
    ArgumentCaptor<Buffer> buffer = ArgumentCaptor.forClass(Buffer.class);
    verify(fileSystem).writeFile(eq(FILE_NAME), buffer.capture(), any(Handler.class));
    svc.clear();
    assertNotRegistered(svc, Constants.DEFAULT_PATH_SEPARATOR, "sensor1", CredentialsConstants.SECRETS_TYPE_PRESHARED_KEY, ctx);
    // THEN the credentials can be loaded back in from the file
    final Async read = ctx.async();
    doAnswer(invocation -> {
        Handler handler = invocation.getArgument(1);
        handler.handle(Future.succeededFuture(buffer.getValue()));
        read.complete();
        return null;
    }).when(fileSystem).readFile(eq(FILE_NAME), any(Handler.class));
    svc.loadCredentials();
    read.await(2000);
    assertRegistered(svc, Constants.DEFAULT_TENANT, "sensor1", CredentialsConstants.SECRETS_TYPE_PRESHARED_KEY, ctx);
    assertRegistered(svc, "OTHER_TENANT", "bumlux", CredentialsConstants.SECRETS_TYPE_HASHED_PASSWORD, ctx);
}
Also used : CoreMatchers.is(org.hamcrest.CoreMatchers.is) HttpURLConnection(java.net.HttpURLConnection) TestContext(io.vertx.ext.unit.TestContext) Async(io.vertx.ext.unit.Async) RunWith(org.junit.runner.RunWith) Constants(org.eclipse.hono.util.Constants) Context(io.vertx.core.Context) Assert.assertThat(org.junit.Assert.assertThat) ArgumentCaptor(org.mockito.ArgumentCaptor) EventBus(io.vertx.core.eventbus.EventBus) Matchers.eq(org.mockito.Matchers.eq) JsonObject(io.vertx.core.json.JsonObject) Before(org.junit.Before) Vertx(io.vertx.core.Vertx) Test(org.junit.Test) VertxUnitRunner(io.vertx.ext.unit.junit.VertxUnitRunner) Future(io.vertx.core.Future) StandardCharsets(java.nio.charset.StandardCharsets) CredentialsConstants(org.eclipse.hono.util.CredentialsConstants) Matchers.any(org.mockito.Matchers.any) Mockito(org.mockito.Mockito) JsonArray(io.vertx.core.json.JsonArray) Buffer(io.vertx.core.buffer.Buffer) FileSystem(io.vertx.core.file.FileSystem) CredentialsService(org.eclipse.hono.service.credentials.CredentialsService) Handler(io.vertx.core.Handler) CredentialsObject(org.eclipse.hono.util.CredentialsObject) Buffer(io.vertx.core.buffer.Buffer) Async(io.vertx.ext.unit.Async) CredentialsObject(org.eclipse.hono.util.CredentialsObject) Handler(io.vertx.core.Handler) Test(org.junit.Test)

Example 14 with CredentialsObject

use of org.eclipse.hono.util.CredentialsObject in project hono by eclipse.

the class BaseCredentialsService method processAddRequest.

private Future<EventBusMessage> processAddRequest(final EventBusMessage request) {
    final String tenantId = request.getTenant();
    final CredentialsObject payload = Optional.ofNullable(request.getJsonPayload()).map(json -> json.mapTo(CredentialsObject.class)).orElse(null);
    if (tenantId == null || payload == null) {
        return Future.failedFuture(new ClientErrorException(HttpURLConnection.HTTP_BAD_REQUEST));
    } else if (payload.isValid()) {
        final Future<CredentialsResult<JsonObject>> result = Future.future();
        add(tenantId, JsonObject.mapFrom(payload), result.completer());
        return result.map(res -> {
            return request.getResponse(res.getStatus()).setDeviceId(payload.getDeviceId()).setCacheDirective(res.getCacheDirective());
        });
    } else {
        return Future.failedFuture(new ClientErrorException(HttpURLConnection.HTTP_BAD_REQUEST));
    }
}
Also used : HttpURLConnection(java.net.HttpURLConnection) CredentialsResult(org.eclipse.hono.util.CredentialsResult) TenantConstants(org.eclipse.hono.util.TenantConstants) ClientErrorException(org.eclipse.hono.client.ClientErrorException) EventBusMessage(org.eclipse.hono.util.EventBusMessage) Future(io.vertx.core.Future) CredentialsConstants(org.eclipse.hono.util.CredentialsConstants) Objects(java.util.Objects) EventBusService(org.eclipse.hono.service.EventBusService) Optional(java.util.Optional) JsonObject(io.vertx.core.json.JsonObject) AsyncResult(io.vertx.core.AsyncResult) Handler(io.vertx.core.Handler) CredentialsObject(org.eclipse.hono.util.CredentialsObject) CredentialsObject(org.eclipse.hono.util.CredentialsObject) ClientErrorException(org.eclipse.hono.client.ClientErrorException) Future(io.vertx.core.Future) JsonObject(io.vertx.core.json.JsonObject)

Example 15 with CredentialsObject

use of org.eclipse.hono.util.CredentialsObject in project hono by eclipse.

the class AbstractDeviceCredentialsTest method testValidateFailsIfCredentialsAreDisabled.

/**
 * Verifies that credentials validation fails if the credentials on record are disabled.
 */
@Test
public void testValidateFailsIfCredentialsAreDisabled() {
    final AbstractDeviceCredentials creds = getDeviceCredentials("type", "identity", true);
    final CredentialsObject credentialsOnRecord = getCredentialsObject("type", "identity", "device", false).addSecret(CredentialsObject.emptySecret(Instant.now().minusSeconds(120), null));
    assertFalse(creds.validate(credentialsOnRecord));
}
Also used : CredentialsObject(org.eclipse.hono.util.CredentialsObject) Test(org.junit.Test)

Aggregations

CredentialsObject (org.eclipse.hono.util.CredentialsObject)20 JsonObject (io.vertx.core.json.JsonObject)16 HttpURLConnection (java.net.HttpURLConnection)14 Future (io.vertx.core.Future)13 CredentialsConstants (org.eclipse.hono.util.CredentialsConstants)12 Handler (io.vertx.core.Handler)10 ClientErrorException (org.eclipse.hono.client.ClientErrorException)10 CredentialsResult (org.eclipse.hono.util.CredentialsResult)10 MessageHelper (org.eclipse.hono.util.MessageHelper)7 Truth.assertThat (com.google.common.truth.Truth.assertThat)6 Span (io.opentracing.Span)6 Tracer (io.opentracing.Tracer)6 Vertx (io.vertx.core.Vertx)6 Timeout (io.vertx.junit5.Timeout)6 VertxTestContext (io.vertx.junit5.VertxTestContext)6 Instant (java.time.Instant)6 AnnotatedCacheKey (org.eclipse.hono.client.util.AnnotatedCacheKey)6 VertxExtension (io.vertx.junit5.VertxExtension)5 Constants (org.eclipse.hono.util.Constants)5 Cache (com.github.benmanes.caffeine.cache.Cache)4