use of org.eclipse.hono.service.management.credentials.Credentials in project hono by eclipse.
the class MongoDbBasedCredentialServiceTest method testCredentialsDaoUsesIndex.
/**
* Verifies that the credentials DAO uses a proper index to retrieve credentials by auth-id and type.
*
* @param ctx The vert.x test context.
*/
@Test
public void testCredentialsDaoUsesIndex(final VertxTestContext ctx) {
final var tenantId = UUID.randomUUID().toString();
final MongoClient mongoClient = MongoDbTestUtils.getMongoClient(vertx, DB_NAME);
final var dto1 = CredentialsDto.forCreation(tenantId, UUID.randomUUID().toString(), List.of(Credentials.createPasswordCredential("device1a", "secret"), Credentials.createPSKCredential("device1b", "shared-secret")), UUID.randomUUID().toString());
final var dto2 = CredentialsDto.forCreation(tenantId, UUID.randomUUID().toString(), List.of(Credentials.createPasswordCredential("device2a", "secret"), Credentials.createPSKCredential("device2b", "shared-secret")), UUID.randomUUID().toString());
final var dto3 = CredentialsDto.forCreation(tenantId, UUID.randomUUID().toString(), List.of(Credentials.createPasswordCredential("device3a", "secret"), Credentials.createPSKCredential("device3b", "shared-secret")), UUID.randomUUID().toString());
final var dto4 = CredentialsDto.forCreation(UUID.randomUUID().toString(), UUID.randomUUID().toString(), List.of(Credentials.createPasswordCredential("device1a", "secret"), Credentials.createPSKCredential("device1b", "shared-secret")), UUID.randomUUID().toString());
credentialsDao.create(dto1, NoopSpan.INSTANCE.context()).compose(ok -> credentialsDao.create(dto2, NoopSpan.INSTANCE.context())).compose(ok -> credentialsDao.create(dto3, NoopSpan.INSTANCE.context())).compose(ok -> credentialsDao.create(dto4, NoopSpan.INSTANCE.context())).compose(ok -> {
final Promise<JsonObject> resultHandler = Promise.promise();
final var filter = MongoDbDocumentBuilder.builder().withTenantId(tenantId).withAuthId("device1a").withType(CredentialsConstants.SECRETS_TYPE_HASHED_PASSWORD).document();
final var commandRight = new JsonObject().put("find", "credentials").put("batchSize", 1).put("singleBatch", true).put("filter", filter).put("projection", MongoDbBasedCredentialsDao.PROJECTION_CREDS_BY_TYPE_AND_AUTH_ID);
final var explain = new JsonObject().put("explain", commandRight).put("verbosity", "executionStats");
mongoClient.runCommand("explain", explain, resultHandler);
return resultHandler.future();
}).onComplete(ctx.succeeding(result -> {
if (LOG.isTraceEnabled()) {
LOG.trace("result:{}{}", System.lineSeparator(), result.encodePrettily());
}
ctx.verify(() -> {
final var indexScan = (JsonObject) JsonPointer.from("/queryPlanner/winningPlan/inputStage/inputStage").queryJson(result);
assertThat(indexScan.getString("indexName")).isEqualTo(MongoDbBasedCredentialsDao.IDX_CREDENTIALS_TYPE_AND_AUTH_ID);
final var executionStats = result.getJsonObject("executionStats", new JsonObject());
// there are two credentials with auth-id "device1a" and type "hashed-password"
assertThat(executionStats.getInteger("totalKeysExamined")).isEqualTo(2);
assertThat(executionStats.getInteger("totalDocsExamined")).isEqualTo(2);
});
ctx.completeNow();
}));
}
use of org.eclipse.hono.service.management.credentials.Credentials in project hono by eclipse.
the class CredentialsManagementIT method testAddCredentialsSucceedsForAdditionalProperties.
/**
* Verifies that the service accepts an add credentials request containing a clear text password.
*
* @param context The vert.x test context.
*/
@Test
public void testAddCredentialsSucceedsForAdditionalProperties(final VertxTestContext context) {
final PasswordCredential credential = IntegrationTestSupport.createPasswordCredential(authId, "thePassword");
credential.getExtensions().put("client-id", "MQTT-client-2384236854");
registry.addCredentials(tenantId, deviceId, List.of(credential)).compose(httpResponse -> {
context.verify(() -> assertResourceVersionHasChanged(resourceVersion, httpResponse.headers()));
return registry.getCredentials(tenantId, deviceId);
}).onComplete(context.succeeding(httpResponse -> {
context.verify(() -> {
final JsonArray response = httpResponse.bodyAsJsonArray();
assertThat(response.size()).isEqualTo(1);
final JsonObject credentialObject = response.getJsonObject(0);
final var ext = credentialObject.getJsonObject(RegistryManagementConstants.FIELD_EXT);
assertThat(ext).isNotNull();
assertThat(ext.getString("client-id")).isEqualTo("MQTT-client-2384236854");
// the device-id must not be part of the "ext" section
assertThat(ext.getString("device-id")).isNull();
});
context.completeNow();
}));
}
use of org.eclipse.hono.service.management.credentials.Credentials in project hono by eclipse.
the class CredentialsManagementIT method testAddCredentialsSucceeds.
/**
* Verifies that a newly added device has an empty set of credentials and that the
* service successfully adds arbitrary types of credentials.
*
* @param context The vert.x test context.
*/
@Test
public void testAddCredentialsSucceeds(final VertxTestContext context) {
final PasswordCredential pwdCredential = IntegrationTestSupport.createPasswordCredential(authId, "thePassword");
pwdCredential.getExtensions().put("client-id", "MQTT-client-2384236854");
final PskCredential pskCredential = IntegrationTestSupport.createPskCredentials("psk-id", "psk-key");
final var x509Credential = X509CertificateCredential.fromSubjectDn("emailAddress=foo@bar.com, CN=foo, O=bar", List.of(new X509CertificateSecret()));
x509Credential.setComment("non-standard attribute type");
final List<CommonCredential> credentials = List.of(pwdCredential, pskCredential, x509Credential);
registry.getCredentials(tenantId, deviceId).compose(httpResponse -> {
context.verify(() -> {
assertResourceVersionHasChanged(resourceVersion, httpResponse.headers());
assertThat(httpResponse.bodyAsJsonArray()).isEmpty();
});
return registry.addCredentials(tenantId, deviceId, credentials);
}).compose(httpResponse -> {
context.verify(() -> assertResourceVersionHasChanged(resourceVersion, httpResponse.headers()));
return registry.getCredentials(tenantId, deviceId);
}).onComplete(context.succeeding(httpResponse -> {
context.verify(() -> {
final CommonCredential[] credsOnRecord = httpResponse.bodyAsJson(CommonCredential[].class);
assertThat(credsOnRecord).hasLength(3);
Arrays.stream(credsOnRecord).forEach(creds -> {
assertThat(creds.getExtensions().get("device-id")).isNull();
if (creds instanceof PasswordCredential) {
assertThat(creds.getExtensions().get("client-id")).isEqualTo("MQTT-client-2384236854");
} else if (creds instanceof X509CertificateCredential) {
assertThat(creds.getComment()).isEqualTo("non-standard attribute type");
}
creds.getSecrets().forEach(secret -> {
assertThat(secret.isEnabled()).isTrue();
assertThat(secret.getId()).isNotNull();
});
});
});
context.completeNow();
}));
}
use of org.eclipse.hono.service.management.credentials.Credentials in project hono by eclipse.
the class CredentialsManagementIT method testGetAllCredentialsForDeviceSucceeds.
/**
* Verifies that the service returns all credentials registered for a given device regardless of
* authentication identifier and type.
* <p>
* The returned JsonArray must contain exactly the same credentials as originally added.
*
* @param context The vert.x test context.
*/
@Test
public void testGetAllCredentialsForDeviceSucceeds(final VertxTestContext context) {
final List<CommonCredential> credentialsListToAdd = new ArrayList<>();
credentialsListToAdd.add(pskCredentials);
credentialsListToAdd.add(hashedPasswordCredential);
credentialsListToAdd.add(X509CertificateCredential.fromSubjectDn("CN=Acme", List.of(new X509CertificateSecret())));
for (int i = 0; i < 3; i++) {
final GenericSecret secret = new GenericSecret();
secret.setAdditionalProperties(Map.of("field-" + i, "setec astronomy"));
final GenericCredential credential = new GenericCredential("type-" + i, getRandomAuthId(PREFIX_AUTH_ID), List.of(secret));
credentialsListToAdd.add(credential);
}
registry.addCredentials(tenantId, deviceId, credentialsListToAdd).compose(ar -> registry.getCredentials(tenantId, deviceId)).onComplete(context.succeeding(httpResponse -> {
context.verify(() -> assertResponseBodyContainsAllCredentials(httpResponse.bodyAsJsonArray(), credentialsListToAdd));
context.completeNow();
}));
}
use of org.eclipse.hono.service.management.credentials.Credentials 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();
}));
}
Aggregations