use of org.eclipse.hono.service.management.credentials.PasswordSecret in project hono by eclipse.
the class CredentialsManagementIT method testAddCredentialsFailsForBCryptWithTooManyIterations.
/**
* Verifies that the service returns a 400 status code for an add credentials request with hashed password
* credentials that use a BCrypt hash with more than the configured max iterations.
*
* @param context The vert.x test context.
*/
@Test
public void testAddCredentialsFailsForBCryptWithTooManyIterations(final VertxTestContext context) {
// GIVEN a hashed password using bcrypt with more than the configured max iterations
final BCryptPasswordEncoder encoder = new BCryptPasswordEncoder(IntegrationTestSupport.MAX_BCRYPT_COST_FACTOR + 1);
final PasswordSecret secret = new PasswordSecret();
secret.setHashFunction(CredentialsConstants.HASH_FUNCTION_BCRYPT);
secret.setPasswordHash(encoder.encode("thePassword"));
final PasswordCredential credential = new PasswordCredential(authId, List.of(secret));
// WHEN adding the credentials
testAddCredentialsWithErroneousPayload(context, new JsonArray().add(JsonObject.mapFrom(credential)), // THEN the request fails with 400
HttpURLConnection.HTTP_BAD_REQUEST);
}
use of org.eclipse.hono.service.management.credentials.PasswordSecret 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();
}));
}
use of org.eclipse.hono.service.management.credentials.PasswordSecret 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);
}
}
}
Aggregations