@Override public final void getAll(final String tenantId, final String deviceId, final Handler<AsyncResult<CredentialsResult<JsonObject>>> resultHandler) { getAll(tenantId, deviceId, NoopSpan.INSTANCE, resultHandler); }
/** * {@inheritDoc} * * This default implementation simply returns an empty result with status code 501 (Not Implemented). * Subclasses should override this method in order to provide a reasonable implementation. */ @Override public void update(final String tenantId, final JsonObject otherKeys, final Handler<AsyncResult<CredentialsResult<JsonObject>>> resultHandler) { handleUnimplementedOperation(resultHandler); }
return Future.failedFuture(new ClientErrorException(HttpURLConnection.HTTP_BAD_REQUEST)); } else { final String type = getTypesafeValueForField(String.class, payload, CredentialsConstants.FIELD_TYPE); final String authId = getTypesafeValueForField(String.class, payload, CredentialsConstants.FIELD_AUTH_ID); final String deviceId = getTypesafeValueForField(String.class, payload, CredentialsConstants.FIELD_PAYLOAD_DEVICE_ID); remove(tenantId, type, authId, result.completer()); return result.map(res -> { return request.getResponse(res.getStatus()) removeAll(tenantId, deviceId, result.completer()); return result.map(res -> { return request.getResponse(res.getStatus())
/** * Hashes clear text passwords contained in hashed-password credentials * provided by a client. * * @param credentials The credentials to hash the clear text passwords for. * @return A future containing the (updated) credentials. */ protected final Future<CredentialsObject> hashPlainPasswords(final CredentialsObject credentials) { final Future<CredentialsObject> result = Future.future(); if (CredentialsConstants.SECRETS_TYPE_HASHED_PASSWORD.equals(credentials.getType())) { getVertx().executeBlocking(blockingCodeHandler -> { log.debug("hashing password on vert.x worker thread [{}]", Thread.currentThread().getName()); credentials.getSecrets().forEach(secret -> hashPwdAndUpdateSecret((JsonObject) secret)); blockingCodeHandler.complete(credentials); }, result); } else { result.complete(credentials); } return result; }
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) { return Future.failedFuture(new ClientErrorException( HttpURLConnection.HTTP_BAD_REQUEST, "missing tenant ID")); } else if (payload == null) { return Future.failedFuture(new ClientErrorException( HttpURLConnection.HTTP_BAD_REQUEST, "missing payload")); } else { return hashPlainPasswords(payload).compose(credentials -> doAdd(request, tenantId, credentials)); } }
private Future<EventBusMessage> processUpdateRequest(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) { return Future.failedFuture(new ClientErrorException( HttpURLConnection.HTTP_BAD_REQUEST, "missing tenant ID")); } else if (payload == null) { return Future.failedFuture(new ClientErrorException( HttpURLConnection.HTTP_BAD_REQUEST, "missing payload")); } else { return hashPlainPasswords(payload).compose(credentials -> doUpdate(request, tenantId, credentials)); } }
/** * Verifies that a hash value is a valid BCrypt password hash. * <p> * The hash must be a version 2a hash and must not use more than the configured * maximum number of iterations as returned by {@link #getMaxBcryptIterations()}. * * @param pwdHash The hash to verify. * @throws IllegalStateException if the secret does not match the criteria. */ protected void verifyBcryptPasswordHash(final String pwdHash) { Objects.requireNonNull(pwdHash); if (BCryptHelper.getIterations(pwdHash) > getMaxBcryptIterations()) { throw new IllegalStateException("password hash uses too many iterations, max is " + getMaxBcryptIterations()); } } }
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) { return Future.failedFuture(new ClientErrorException( HttpURLConnection.HTTP_BAD_REQUEST, "missing tenant ID")); } else if (payload == null) { return Future.failedFuture(new ClientErrorException( HttpURLConnection.HTTP_BAD_REQUEST, "missing payload")); } else { try { payload.checkValidity(this::checkSecret); 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()); }); } catch (IllegalStateException e) { return Future.failedFuture(new ClientErrorException( HttpURLConnection.HTTP_BAD_REQUEST, e.getMessage())); } } }
return Future.failedFuture(new ClientErrorException(HttpURLConnection.HTTP_BAD_REQUEST)); } else { final String type = getTypesafeValueForField(String.class, payload, CredentialsConstants.FIELD_TYPE); final String authId = getTypesafeValueForField(String.class, payload, CredentialsConstants.FIELD_AUTH_ID); final String deviceId = getTypesafeValueForField(String.class, payload, CredentialsConstants.FIELD_PAYLOAD_DEVICE_ID); remove(tenantId, type, authId, result.completer()); return result.map(res -> { return request.getResponse(res.getStatus()) removeAll(tenantId, deviceId, result.completer()); return result.map(res -> { return request.getResponse(res.getStatus())
/** * Invoked as part of payload validation when adding or updating <em>hashed password</em> * credentials using the <em>bcrypt</em> hash algorithm. * <p> * Verifies that the hashed password matches the bcrypt hash pattern and doesn't use more * than the configured maximum number of iterations as returned by {@link #getMaxBcryptIterations()}. * * @param secret The secret to verify. * @throws IllegalArgumentException if the password hash is invalid. */ protected void verifyBcryptPasswordHash(final JsonObject secret) { final String pwdHash = ((JsonObject) secret).getString(CredentialsConstants.FIELD_SECRETS_PWD_HASH); final Matcher matcher = BCRYPT_PATTERN.matcher(pwdHash); if (matcher.matches()) { // check that hash doesn't use more iterations than configured maximum final int iterations = Integer.valueOf(matcher.group(1)); if (iterations > getMaxBcryptIterations()) { throw new IllegalArgumentException("max number of BCrypt iterations exceeded"); } } else { // not a valid bcrypt hash throw new IllegalArgumentException("not a BCrypt hash"); } }
private Future<EventBusMessage> doAdd(final EventBusMessage request, final String tenantId, final CredentialsObject payload) { try { payload.checkValidity(this::checkSecret); 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()); }); } catch (IllegalStateException e) { return Future.failedFuture(new ClientErrorException( HttpURLConnection.HTTP_BAD_REQUEST, e.getMessage())); } }
/** * {@inheritDoc} * * This default implementation simply returns an empty result with status code 501 (Not Implemented). * Subclasses should override this method in order to provide a reasonable implementation. */ @Override public void add(final String tenantId, final JsonObject otherKeys, final Handler<AsyncResult<CredentialsResult<JsonObject>>> resultHandler) { handleUnimplementedOperation(resultHandler); }
/** * {@inheritDoc} * * This default implementation simply returns an empty result with status code 501 (Not Implemented). * Subclasses should override this method in order to provide a reasonable implementation. */ @Override public void removeAll(final String tenantId, final String deviceId, final Handler<AsyncResult<CredentialsResult<JsonObject>>> resultHandler) { handleUnimplementedOperation(resultHandler); }
/** * {@inheritDoc} * * This default implementation simply returns an empty result with status code 501 (Not Implemented). * Subclasses should override this method in order to provide a reasonable implementation. */ @Override public void update(final String tenantId, final JsonObject otherKeys, final Handler<AsyncResult<CredentialsResult<JsonObject>>> resultHandler) { handleUnimplementedOperation(resultHandler); }
/** * {@inheritDoc} * * This default implementation simply returns an empty result with status code 501 (Not Implemented). * Subclasses should override this method in order to provide a reasonable implementation. */ @Override public void remove(final String tenantId, final String type, final String authId, final Handler<AsyncResult<CredentialsResult<JsonObject>>> resultHandler) { handleUnimplementedOperation(resultHandler); }
/** * {@inheritDoc} * * This default implementation simply returns an empty result with status code 501 (Not Implemented). * Subclasses should override this method in order to provide a reasonable implementation. */ @Override public void add(final String tenantId, final JsonObject otherKeys, final Handler<AsyncResult<CredentialsResult<JsonObject>>> resultHandler) { handleUnimplementedOperation(resultHandler); }
/** * {@inheritDoc} * * This default implementation simply returns an empty result with status code 501 (Not Implemented). * Subclasses should override this method in order to provide a reasonable implementation. */ @Override public void remove(final String tenantId, final String type, final String authId, final Handler<AsyncResult<CredentialsResult<JsonObject>>> resultHandler) { handleUnimplementedOperation(resultHandler); }
/** * {@inheritDoc} * * This default implementation simply returns an empty result with status code 501 (Not Implemented). * Subclasses should override this method in order to provide a reasonable implementation. */ @Override public void removeAll(final String tenantId, final String deviceId, final Handler<AsyncResult<CredentialsResult<JsonObject>>> resultHandler) { handleUnimplementedOperation(resultHandler); } }