Search in sources :

Example 6 with PasswordCredential

use of org.eclipse.hono.service.management.credentials.PasswordCredential in project hono by eclipse.

the class CredentialsManagementIT method testUpdateCredentialsSucceeds.

/**
 * Verifies that the service accepts an update credentials request for existing credentials.
 *
 * @param ctx The vert.x test context.
 */
@Test
public void testUpdateCredentialsSucceeds(final VertxTestContext ctx) {
    final AtomicReference<PasswordSecret> originalSecret = new AtomicReference<>();
    // GIVEN a device with a set of hashed password credentials
    registry.addCredentials(tenantId, deviceId, List.of(hashedPasswordCredential)).compose(ok -> registry.getCredentials(tenantId, deviceId)).compose(httpResponse -> {
        ctx.verify(() -> assertResourceVersionHasChanged(resourceVersion, httpResponse.headers()));
        // WHEN updating the existing password
        final JsonArray bodyAsJsonArray = httpResponse.bodyAsJsonArray();
        LOG.debug("received original credentials list: {}", bodyAsJsonArray.encodePrettily());
        ctx.verify(() -> assertThat(bodyAsJsonArray).hasSize(1));
        final PasswordCredential existingCredentials = bodyAsJsonArray.getJsonObject(0).mapTo(PasswordCredential.class);
        ctx.verify(() -> {
            assertThat(existingCredentials.getSecrets()).hasSize(1);
            final PasswordSecret existingSecret = existingCredentials.getSecrets().get(0);
            assertThat(existingSecret.getId()).isNotNull();
            originalSecret.set(existingSecret);
        });
        final PasswordSecret changedSecret = new PasswordSecret();
        changedSecret.setId(originalSecret.get().getId());
        changedSecret.setPasswordPlain("completely-different-password");
        changedSecret.setComment("updated");
        // and adding a new one
        final PasswordSecret newSecret = new PasswordSecret();
        newSecret.setPasswordPlain("future-password");
        newSecret.setNotBefore(Instant.now().plus(1, ChronoUnit.DAYS));
        final PasswordCredential updatedCredentials = new PasswordCredential(existingCredentials.getAuthId(), List.of(changedSecret, newSecret));
        return registry.updateCredentialsWithVersion(tenantId, deviceId, List.of(updatedCredentials), resourceVersion.get(), HttpURLConnection.HTTP_NO_CONTENT);
    }).compose(httpResponse -> {
        ctx.verify(() -> assertResourceVersionHasChanged(resourceVersion, httpResponse.headers()));
        return registry.getCredentials(tenantId, deviceId);
    }).onComplete(ctx.succeeding(httpResponse -> {
        final JsonArray bodyAsJsonArray = httpResponse.bodyAsJsonArray();
        LOG.debug("received updated credentials list: {}", bodyAsJsonArray.encodePrettily());
        ctx.verify(() -> {
            assertThat(bodyAsJsonArray).hasSize(1);
            final PasswordCredential updatedCredentials = bodyAsJsonArray.getJsonObject(0).mapTo(PasswordCredential.class);
            assertThat(updatedCredentials.getSecrets()).hasSize(2);
            // THEN the original secret has been updated
            final PasswordSecret updatedSecret = updatedCredentials.getSecrets().stream().filter(s -> originalSecret.get().getId().equals(s.getId())).findAny().orElse(null);
            assertThat(updatedSecret).isNotNull();
            assertThat(updatedSecret.getComment()).isEqualTo("updated");
        });
        ctx.completeNow();
    }));
}
Also used : HttpURLConnection(java.net.HttpURLConnection) VertxTestContext(io.vertx.junit5.VertxTestContext) BeforeEach(org.junit.jupiter.api.BeforeEach) Arrays(java.util.Arrays) BCryptPasswordEncoder(org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder) LoggerFactory(org.slf4j.LoggerFactory) MultiMap(io.vertx.core.MultiMap) Credentials(org.eclipse.hono.service.management.credentials.Credentials) GenericCredential(org.eclipse.hono.service.management.credentials.GenericCredential) PasswordSecret(org.eclipse.hono.service.management.credentials.PasswordSecret) X509CertificateCredential(org.eclipse.hono.service.management.credentials.X509CertificateCredential) OptionalInt(java.util.OptionalInt) AtomicReference(java.util.concurrent.atomic.AtomicReference) Timeout(io.vertx.junit5.Timeout) ArrayList(java.util.ArrayList) IntegrationTestSupport(org.eclipse.hono.tests.IntegrationTestSupport) ExtendWith(org.junit.jupiter.api.extension.ExtendWith) PskCredential(org.eclipse.hono.service.management.credentials.PskCredential) Map(java.util.Map) Assertions(org.assertj.core.api.Assertions) HttpUtils(org.eclipse.hono.service.http.HttpUtils) JsonObject(io.vertx.core.json.JsonObject) RegistryManagementConstants(org.eclipse.hono.util.RegistryManagementConstants) Logger(org.slf4j.Logger) RecursiveComparisonConfiguration(org.assertj.core.api.recursive.comparison.RecursiveComparisonConfiguration) X509CertificateSecret(org.eclipse.hono.service.management.credentials.X509CertificateSecret) HttpHeaders(io.vertx.core.http.HttpHeaders) UUID(java.util.UUID) Truth.assertThat(com.google.common.truth.Truth.assertThat) Instant(java.time.Instant) VertxExtension(io.vertx.junit5.VertxExtension) Collectors(java.util.stream.Collectors) CredentialsConstants(org.eclipse.hono.util.CredentialsConstants) TestInfo(org.junit.jupiter.api.TestInfo) TimeUnit(java.util.concurrent.TimeUnit) Test(org.junit.jupiter.api.Test) JsonArray(io.vertx.core.json.JsonArray) List(java.util.List) ChronoUnit(java.time.temporal.ChronoUnit) CommonCredential(org.eclipse.hono.service.management.credentials.CommonCredential) CrudHttpClient(org.eclipse.hono.tests.CrudHttpClient) DeviceRegistryHttpClient(org.eclipse.hono.tests.DeviceRegistryHttpClient) Optional(java.util.Optional) GenericSecret(org.eclipse.hono.service.management.credentials.GenericSecret) PasswordCredential(org.eclipse.hono.service.management.credentials.PasswordCredential) JsonArray(io.vertx.core.json.JsonArray) PasswordSecret(org.eclipse.hono.service.management.credentials.PasswordSecret) PasswordCredential(org.eclipse.hono.service.management.credentials.PasswordCredential) AtomicReference(java.util.concurrent.atomic.AtomicReference) Test(org.junit.jupiter.api.Test)

Example 7 with PasswordCredential

use of org.eclipse.hono.service.management.credentials.PasswordCredential in project hono by eclipse.

the class MqttConnectionIT method testConnectFailsForDisabledDevice.

/**
 * Verifies that the adapter rejects connection attempts from devices for which credentials exist but the device is
 * disabled.
 *
 * @param ctx The test context
 */
@Test
public void testConnectFailsForDisabledDevice(final VertxTestContext ctx) {
    final Tenant tenant = new Tenant();
    helper.registry.addTenant(tenantId, tenant).compose(ok -> {
        final var device = new Device();
        device.setEnabled(false);
        return helper.registry.registerDevice(tenantId, deviceId, device);
    }).compose(ok -> {
        final PasswordCredential secret = IntegrationTestSupport.createPasswordCredential(deviceId, password);
        return helper.registry.addCredentials(tenantId, deviceId, Collections.singleton(secret));
    }).compose(ok -> connectToAdapter(IntegrationTestSupport.getUsername(deviceId, tenantId), password)).onComplete(ctx.failing(t -> {
        // THEN the connection is refused with a NOT_AUTHORIZED code
        ctx.verify(() -> {
            assertThat(t).isInstanceOf(MqttConnectionException.class);
            assertThat(((MqttConnectionException) t).code()).isEqualTo(MqttConnectReturnCode.CONNECTION_REFUSED_NOT_AUTHORIZED);
        });
        ctx.completeNow();
    }));
}
Also used : HttpURLConnection(java.net.HttpURLConnection) VertxTestContext(io.vertx.junit5.VertxTestContext) BeforeEach(org.junit.jupiter.api.BeforeEach) X500Principal(javax.security.auth.x500.X500Principal) MqttConnectReturnCode(io.netty.handler.codec.mqtt.MqttConnectReturnCode) SelfSignedCertificate(io.vertx.core.net.SelfSignedCertificate) X509CertificateCredential(org.eclipse.hono.service.management.credentials.X509CertificateCredential) Supplier(java.util.function.Supplier) Constants(org.eclipse.hono.util.Constants) Tenant(org.eclipse.hono.service.management.tenant.Tenant) Timeout(io.vertx.junit5.Timeout) IntegrationTestSupport(org.eclipse.hono.tests.IntegrationTestSupport) ExtendWith(org.junit.jupiter.api.extension.ExtendWith) Assumptions.assumeTrue(org.junit.jupiter.api.Assumptions.assumeTrue) JsonObject(io.vertx.core.json.JsonObject) MqttConnectionException(io.vertx.mqtt.MqttConnectionException) Tenants(org.eclipse.hono.tests.Tenants) RegistryManagementConstants(org.eclipse.hono.util.RegistryManagementConstants) ValueSource(org.junit.jupiter.params.provider.ValueSource) Device(org.eclipse.hono.service.management.device.Device) Promise(io.vertx.core.Promise) X509CertificateSecret(org.eclipse.hono.service.management.credentials.X509CertificateSecret) RegistrationConstants(org.eclipse.hono.util.RegistrationConstants) UUID(java.util.UUID) Truth.assertThat(com.google.common.truth.Truth.assertThat) VertxExtension(io.vertx.junit5.VertxExtension) Future(io.vertx.core.Future) TimeUnit(java.util.concurrent.TimeUnit) Test(org.junit.jupiter.api.Test) List(java.util.List) Adapter(org.eclipse.hono.util.Adapter) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest) Collections(java.util.Collections) PasswordCredential(org.eclipse.hono.service.management.credentials.PasswordCredential) Tenant(org.eclipse.hono.service.management.tenant.Tenant) Device(org.eclipse.hono.service.management.device.Device) PasswordCredential(org.eclipse.hono.service.management.credentials.PasswordCredential) MqttConnectionException(io.vertx.mqtt.MqttConnectionException) Test(org.junit.jupiter.api.Test) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest)

Example 8 with PasswordCredential

use of org.eclipse.hono.service.management.credentials.PasswordCredential in project hono by eclipse.

the class MqttConnectionIT method testConnectFailsForDisabledCredentials.

/**
 * Verifies that the adapter rejects connection attempts from devices for which credentials exist but are disabled.
 *
 * @param ctx The test context
 */
@Test
public void testConnectFailsForDisabledCredentials(final VertxTestContext ctx) {
    helper.registry.addTenant(tenantId).compose(ok -> {
        return helper.registry.registerDevice(tenantId, deviceId);
    }).compose(ok -> {
        final PasswordCredential secret = IntegrationTestSupport.createPasswordCredential(deviceId, password);
        secret.setEnabled(false);
        return helper.registry.addCredentials(tenantId, deviceId, Collections.singleton(secret));
    }).compose(ok -> connectToAdapter(IntegrationTestSupport.getUsername(deviceId, tenantId), password)).onComplete(ctx.failing(t -> {
        // THEN the connection is refused with a NOT_AUTHORIZED code
        ctx.verify(() -> {
            assertThat(t).isInstanceOf(MqttConnectionException.class);
            assertThat(((MqttConnectionException) t).code()).isEqualTo(MqttConnectReturnCode.CONNECTION_REFUSED_BAD_USER_NAME_OR_PASSWORD);
        });
        ctx.completeNow();
    }));
}
Also used : HttpURLConnection(java.net.HttpURLConnection) VertxTestContext(io.vertx.junit5.VertxTestContext) BeforeEach(org.junit.jupiter.api.BeforeEach) X500Principal(javax.security.auth.x500.X500Principal) MqttConnectReturnCode(io.netty.handler.codec.mqtt.MqttConnectReturnCode) SelfSignedCertificate(io.vertx.core.net.SelfSignedCertificate) X509CertificateCredential(org.eclipse.hono.service.management.credentials.X509CertificateCredential) Supplier(java.util.function.Supplier) Constants(org.eclipse.hono.util.Constants) Tenant(org.eclipse.hono.service.management.tenant.Tenant) Timeout(io.vertx.junit5.Timeout) IntegrationTestSupport(org.eclipse.hono.tests.IntegrationTestSupport) ExtendWith(org.junit.jupiter.api.extension.ExtendWith) Assumptions.assumeTrue(org.junit.jupiter.api.Assumptions.assumeTrue) JsonObject(io.vertx.core.json.JsonObject) MqttConnectionException(io.vertx.mqtt.MqttConnectionException) Tenants(org.eclipse.hono.tests.Tenants) RegistryManagementConstants(org.eclipse.hono.util.RegistryManagementConstants) ValueSource(org.junit.jupiter.params.provider.ValueSource) Device(org.eclipse.hono.service.management.device.Device) Promise(io.vertx.core.Promise) X509CertificateSecret(org.eclipse.hono.service.management.credentials.X509CertificateSecret) RegistrationConstants(org.eclipse.hono.util.RegistrationConstants) UUID(java.util.UUID) Truth.assertThat(com.google.common.truth.Truth.assertThat) VertxExtension(io.vertx.junit5.VertxExtension) Future(io.vertx.core.Future) TimeUnit(java.util.concurrent.TimeUnit) Test(org.junit.jupiter.api.Test) List(java.util.List) Adapter(org.eclipse.hono.util.Adapter) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest) Collections(java.util.Collections) PasswordCredential(org.eclipse.hono.service.management.credentials.PasswordCredential) PasswordCredential(org.eclipse.hono.service.management.credentials.PasswordCredential) MqttConnectionException(io.vertx.mqtt.MqttConnectionException) Test(org.junit.jupiter.api.Test) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest)

Example 9 with PasswordCredential

use of org.eclipse.hono.service.management.credentials.PasswordCredential in project hono by eclipse.

the class DeviceRegistryUtils method checkCredential.

/**
 * Validates the given credentials for consistency.
 * <p>
 * The following checks are performed
 * <ol>
 * <li>The credential's <em>checkValidity</em> method is invoked and</li>
 * <li>if the given credentials object is of type {@link PasswordCredential}, for
 * each of the credential's hashed password secrets the secret's
 * {@link PasswordSecret#encode(HonoPasswordEncoder)}, {@link PasswordSecret#checkValidity()}
 * and {@link PasswordSecret#verifyHashAlgorithm(Set, int)} methods are invoked.</li>
 * </ol>
 *
 * @param credential The secret to validate.
 * @param passwordEncoder The password encoder.
 * @param hashAlgorithmsWhitelist The list of supported hashing algorithms for pre-hashed passwords.
 * @param maxBcryptCostFactor The maximum cost factor to use for bcrypt password hashes.
 * @throws IllegalStateException if any of the checks fail.
 * @throws NullPointerException if any of the parameters is {@code null}.
 */
public static void checkCredential(final CommonCredential credential, final HonoPasswordEncoder passwordEncoder, final Set<String> hashAlgorithmsWhitelist, final int maxBcryptCostFactor) {
    Objects.requireNonNull(credential);
    Objects.requireNonNull(passwordEncoder);
    Objects.requireNonNull(hashAlgorithmsWhitelist);
    credential.checkValidity();
    if (credential instanceof PasswordCredential) {
        for (final PasswordSecret passwordSecret : ((PasswordCredential) credential).getSecrets()) {
            passwordSecret.encode(passwordEncoder);
            passwordSecret.checkValidity();
            passwordSecret.verifyHashAlgorithm(hashAlgorithmsWhitelist, maxBcryptCostFactor);
        }
    }
}
Also used : PasswordCredential(org.eclipse.hono.service.management.credentials.PasswordCredential) PasswordSecret(org.eclipse.hono.service.management.credentials.PasswordSecret)

Aggregations

PasswordCredential (org.eclipse.hono.service.management.credentials.PasswordCredential)9 JsonObject (io.vertx.core.json.JsonObject)6 HttpURLConnection (java.net.HttpURLConnection)6 List (java.util.List)6 X509CertificateCredential (org.eclipse.hono.service.management.credentials.X509CertificateCredential)6 X509CertificateSecret (org.eclipse.hono.service.management.credentials.X509CertificateSecret)6 RegistryManagementConstants (org.eclipse.hono.util.RegistryManagementConstants)6 Test (org.junit.jupiter.api.Test)6 Truth.assertThat (com.google.common.truth.Truth.assertThat)5 Timeout (io.vertx.junit5.Timeout)5 VertxExtension (io.vertx.junit5.VertxExtension)5 VertxTestContext (io.vertx.junit5.VertxTestContext)5 UUID (java.util.UUID)5 TimeUnit (java.util.concurrent.TimeUnit)5 PasswordSecret (org.eclipse.hono.service.management.credentials.PasswordSecret)5 IntegrationTestSupport (org.eclipse.hono.tests.IntegrationTestSupport)5 BeforeEach (org.junit.jupiter.api.BeforeEach)5 ExtendWith (org.junit.jupiter.api.extension.ExtendWith)5 MultiMap (io.vertx.core.MultiMap)4 HttpHeaders (io.vertx.core.http.HttpHeaders)4