Reformat code with Eclipse 2019-03 formatter.
This commit is contained in:
@@ -27,9 +27,9 @@ import org.springframework.context.annotation.Import;
|
||||
|
||||
/**
|
||||
* Annotation providing a convenient and declarative mechanism for adding a
|
||||
* {@link VaultPropertySource} to Spring's
|
||||
* {@link org.springframework.core.env.Environment Environment}. To be used in conjunction
|
||||
* with @{@link Configuration} classes. <h3>Example usage</h3>
|
||||
* {@link VaultPropertySource} to Spring's {@link org.springframework.core.env.Environment
|
||||
* Environment}. To be used in conjunction with @{@link Configuration} classes.
|
||||
* <h3>Example usage</h3>
|
||||
* <p>
|
||||
* Given a Vault path {@code secret/my-application} containing the configuration data pair
|
||||
* {@code database.password=mysecretpassword}, the following {@code @Configuration} class
|
||||
@@ -65,9 +65,8 @@ import org.springframework.context.annotation.Import;
|
||||
* ordering is difficult to predict. In such cases - and if overriding is important - it
|
||||
* is recommended that the user fall back to using the programmatic PropertySource API.
|
||||
* See {@link org.springframework.core.env.ConfigurableEnvironment
|
||||
* ConfigurableEnvironment} and
|
||||
* {@link org.springframework.core.env.MutablePropertySources MutablePropertySources}
|
||||
* javadocs for details.
|
||||
* ConfigurableEnvironment} and {@link org.springframework.core.env.MutablePropertySources
|
||||
* MutablePropertySources} javadocs for details.
|
||||
*
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
|
||||
@@ -73,16 +73,14 @@ class VaultPropertySourceRegistrar implements ImportBeanDefinitionRegistrar,
|
||||
ConfigurableEnvironment env = beanFactory.getBean(ConfigurableEnvironment.class);
|
||||
MutablePropertySources propertySources = env.getPropertySources();
|
||||
|
||||
registerPropertySources(
|
||||
beanFactory.getBeansOfType(
|
||||
registerPropertySources(beanFactory
|
||||
.getBeansOfType(
|
||||
org.springframework.vault.core.env.VaultPropertySource.class)
|
||||
.values(), propertySources);
|
||||
.values(), propertySources);
|
||||
|
||||
registerPropertySources(
|
||||
beanFactory
|
||||
.getBeansOfType(
|
||||
org.springframework.vault.core.env.LeaseAwareVaultPropertySource.class)
|
||||
.values(), propertySources);
|
||||
registerPropertySources(beanFactory.getBeansOfType(
|
||||
org.springframework.vault.core.env.LeaseAwareVaultPropertySource.class)
|
||||
.values(), propertySources);
|
||||
}
|
||||
|
||||
private void registerPropertySources(
|
||||
@@ -134,8 +132,9 @@ class VaultPropertySourceRegistrar implements ImportBeanDefinitionRegistrar,
|
||||
"'vaultTemplateRef' in @EnableVaultPropertySource must not be empty");
|
||||
|
||||
PropertyTransformer propertyTransformer = StringUtils
|
||||
.hasText(propertyNamePrefix) ? PropertyTransformers
|
||||
.propertyNamePrefix(propertyNamePrefix) : PropertyTransformers.noop();
|
||||
.hasText(propertyNamePrefix)
|
||||
? PropertyTransformers.propertyNamePrefix(propertyNamePrefix)
|
||||
: PropertyTransformers.noop();
|
||||
|
||||
for (String propertyPath : paths) {
|
||||
|
||||
@@ -143,8 +142,8 @@ class VaultPropertySourceRegistrar implements ImportBeanDefinitionRegistrar,
|
||||
continue;
|
||||
}
|
||||
|
||||
AbstractBeanDefinition beanDefinition = createBeanDefinition(ref,
|
||||
renewal, propertyTransformer,
|
||||
AbstractBeanDefinition beanDefinition = createBeanDefinition(ref, renewal,
|
||||
propertyTransformer,
|
||||
potentiallyResolveRequiredPlaceholders(propertyPath));
|
||||
|
||||
do {
|
||||
@@ -163,8 +162,9 @@ class VaultPropertySourceRegistrar implements ImportBeanDefinitionRegistrar,
|
||||
}
|
||||
|
||||
private String potentiallyResolveRequiredPlaceholders(String expression) {
|
||||
return this.environment != null ? this.environment
|
||||
.resolveRequiredPlaceholders(expression) : expression;
|
||||
return this.environment != null
|
||||
? this.environment.resolveRequiredPlaceholders(expression)
|
||||
: expression;
|
||||
}
|
||||
|
||||
private AbstractBeanDefinition createBeanDefinition(String ref, Renewal renewal,
|
||||
@@ -173,19 +173,20 @@ class VaultPropertySourceRegistrar implements ImportBeanDefinitionRegistrar,
|
||||
BeanDefinitionBuilder builder;
|
||||
|
||||
if (isRenewable(renewal)) {
|
||||
builder = BeanDefinitionBuilder
|
||||
.rootBeanDefinition(org.springframework.vault.core.env.LeaseAwareVaultPropertySource.class);
|
||||
builder = BeanDefinitionBuilder.rootBeanDefinition(
|
||||
org.springframework.vault.core.env.LeaseAwareVaultPropertySource.class);
|
||||
|
||||
RequestedSecret requestedSecret = renewal == Renewal.ROTATE ? RequestedSecret
|
||||
.rotating(propertyPath) : RequestedSecret.renewable(propertyPath);
|
||||
RequestedSecret requestedSecret = renewal == Renewal.ROTATE
|
||||
? RequestedSecret.rotating(propertyPath)
|
||||
: RequestedSecret.renewable(propertyPath);
|
||||
|
||||
builder.addConstructorArgValue(propertyPath);
|
||||
builder.addConstructorArgReference("secretLeaseContainer");
|
||||
builder.addConstructorArgValue(requestedSecret);
|
||||
}
|
||||
else {
|
||||
builder = BeanDefinitionBuilder
|
||||
.rootBeanDefinition(org.springframework.vault.core.env.VaultPropertySource.class);
|
||||
builder = BeanDefinitionBuilder.rootBeanDefinition(
|
||||
org.springframework.vault.core.env.VaultPropertySource.class);
|
||||
|
||||
builder.addConstructorArgValue(propertyPath);
|
||||
builder.addConstructorArgReference(ref);
|
||||
@@ -210,8 +211,8 @@ class VaultPropertySourceRegistrar implements ImportBeanDefinitionRegistrar,
|
||||
addAttributesIfNotNull(result,
|
||||
metadata.getAnnotationAttributes(annotationClassName, false));
|
||||
|
||||
Map<String, Object> container = metadata.getAnnotationAttributes(
|
||||
containerClassName, false);
|
||||
Map<String, Object> container = metadata
|
||||
.getAnnotationAttributes(containerClassName, false);
|
||||
if (container != null && container.containsKey("value")) {
|
||||
for (Map<String, Object> containedAttributes : (Map<String, Object>[]) container
|
||||
.get("value")) {
|
||||
|
||||
@@ -27,10 +27,10 @@ import org.springframework.context.annotation.Import;
|
||||
* Container annotation that aggregates several {@link VaultPropertySource} annotations.
|
||||
* <p>
|
||||
* Can be used natively, declaring several nested {@link VaultPropertySource} annotations.
|
||||
* Can also be used in conjunction with Java 8's support for
|
||||
* <em>repeatable annotations</em>, where {@link VaultPropertySource} can simply be
|
||||
* declared several times on the same {@linkplain ElementType#TYPE type}, implicitly
|
||||
* generating this container annotation.
|
||||
* Can also be used in conjunction with Java 8's support for <em>repeatable
|
||||
* annotations</em>, where {@link VaultPropertySource} can simply be declared several
|
||||
* times on the same {@linkplain ElementType#TYPE type}, implicitly generating this
|
||||
* container annotation.
|
||||
*
|
||||
* @author Mark Paluch
|
||||
* @see VaultPropertySource
|
||||
|
||||
@@ -4,4 +4,3 @@
|
||||
@org.springframework.lang.NonNullApi
|
||||
@org.springframework.lang.NonNullFields
|
||||
package org.springframework.vault.annotation;
|
||||
|
||||
|
||||
@@ -60,8 +60,8 @@ import static org.springframework.vault.authentication.AuthenticationSteps.HttpR
|
||||
* @see <a href="https://www.vaultproject.io/docs/auth/approle.html">Auth Backend:
|
||||
* AppRole</a>
|
||||
*/
|
||||
public class AppRoleAuthentication implements ClientAuthentication,
|
||||
AuthenticationStepsFactory {
|
||||
public class AppRoleAuthentication
|
||||
implements ClientAuthentication, AuthenticationStepsFactory {
|
||||
|
||||
private static final Log logger = LogFactory.getLog(AppRoleAuthentication.class);
|
||||
|
||||
@@ -102,19 +102,18 @@ public class AppRoleAuthentication implements ClientAuthentication,
|
||||
RoleId roleId = options.getRoleId();
|
||||
SecretId secretId = options.getSecretId();
|
||||
|
||||
return getAuthenticationSteps(options, roleId, secretId).login(
|
||||
"auth/{mount}/login", options.getPath());
|
||||
return getAuthenticationSteps(options, roleId, secretId)
|
||||
.login("auth/{mount}/login", options.getPath());
|
||||
}
|
||||
|
||||
private static Node<Map<String, String>> getAuthenticationSteps(
|
||||
AppRoleAuthenticationOptions options,
|
||||
RoleId roleId, SecretId secretId) {
|
||||
AppRoleAuthenticationOptions options, RoleId roleId, SecretId secretId) {
|
||||
|
||||
Node<String> roleIdSteps = getRoleIdSteps(options, roleId);
|
||||
Node<String> secretIdSteps = getSecretIdSteps(options, secretId);
|
||||
|
||||
return roleIdSteps.zipWith(secretIdSteps).map(
|
||||
it -> getAppRoleLoginBody(it.getLeft(), it.getRight()));
|
||||
return roleIdSteps.zipWith(secretIdSteps)
|
||||
.map(it -> getAppRoleLoginBody(it.getLeft(), it.getRight()));
|
||||
}
|
||||
|
||||
private static Node<String> getRoleIdSteps(AppRoleAuthenticationOptions options,
|
||||
@@ -128,17 +127,18 @@ public class AppRoleAuthentication implements ClientAuthentication,
|
||||
|
||||
HttpHeaders headers = createHttpHeaders(((Pull) roleId).getInitialToken());
|
||||
|
||||
return AuthenticationSteps.fromHttpRequest(
|
||||
get("auth/{mount}/role/{role}/role-id", options.getPath(),
|
||||
options.getAppRole()).with(headers).as(VaultResponse.class))
|
||||
.map(vaultResponse -> (String) vaultResponse.getRequiredData().get(
|
||||
"role_id"));
|
||||
return AuthenticationSteps
|
||||
.fromHttpRequest(get("auth/{mount}/role/{role}/role-id",
|
||||
options.getPath(), options.getAppRole()).with(headers)
|
||||
.as(VaultResponse.class))
|
||||
.map(vaultResponse -> (String) vaultResponse.getRequiredData()
|
||||
.get("role_id"));
|
||||
}
|
||||
|
||||
if (roleId instanceof Wrapped) {
|
||||
return unwrapResponse(((Wrapped) roleId).getInitialToken()).map(
|
||||
vaultResponse -> (String) vaultResponse.getRequiredData().get(
|
||||
"role_id"));
|
||||
return unwrapResponse(((Wrapped) roleId).getInitialToken())
|
||||
.map(vaultResponse -> (String) vaultResponse.getRequiredData()
|
||||
.get("role_id"));
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException("Unknown RoleId configuration: " + roleId);
|
||||
@@ -154,18 +154,19 @@ public class AppRoleAuthentication implements ClientAuthentication,
|
||||
if (secretId instanceof Pull) {
|
||||
HttpHeaders headers = createHttpHeaders(((Pull) secretId).getInitialToken());
|
||||
|
||||
return AuthenticationSteps.fromHttpRequest(
|
||||
post("auth/{mount}/role/{role}/secret-id", options.getPath(),
|
||||
options.getAppRole()).with(headers).as(VaultResponse.class))
|
||||
.map(vaultResponse -> (String) vaultResponse.getRequiredData().get(
|
||||
"secret_id"));
|
||||
return AuthenticationSteps
|
||||
.fromHttpRequest(post("auth/{mount}/role/{role}/secret-id",
|
||||
options.getPath(), options.getAppRole()).with(headers)
|
||||
.as(VaultResponse.class))
|
||||
.map(vaultResponse -> (String) vaultResponse.getRequiredData()
|
||||
.get("secret_id"));
|
||||
}
|
||||
|
||||
if (secretId instanceof Wrapped) {
|
||||
|
||||
return unwrapResponse(((Wrapped) secretId).getInitialToken()).map(
|
||||
vaultResponse -> (String) vaultResponse.getRequiredData().get(
|
||||
"secret_id"));
|
||||
return unwrapResponse(((Wrapped) secretId).getInitialToken())
|
||||
.map(vaultResponse -> (String) vaultResponse.getRequiredData()
|
||||
.get("secret_id"));
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException("Unknown SecretId configuration: " + secretId);
|
||||
@@ -174,10 +175,9 @@ public class AppRoleAuthentication implements ClientAuthentication,
|
||||
|
||||
private static Node<VaultResponse> unwrapResponse(VaultToken token) {
|
||||
|
||||
return AuthenticationSteps.fromHttpRequest(
|
||||
get("cubbyhole/response").with(createHttpHeaders(token)).as(
|
||||
VaultResponse.class)).map(
|
||||
vaultResponse -> {
|
||||
return AuthenticationSteps.fromHttpRequest(get("cubbyhole/response")
|
||||
.with(createHttpHeaders(token)).as(VaultResponse.class))
|
||||
.map(vaultResponse -> {
|
||||
|
||||
Map<String, Object> data = vaultResponse.getRequiredData();
|
||||
return VaultResponses.unwrap((String) data.get("response"),
|
||||
@@ -235,9 +235,10 @@ public class AppRoleAuthentication implements ClientAuthentication,
|
||||
return (String) entity.getBody().getRequiredData().get("role_id");
|
||||
}
|
||||
catch (HttpStatusCodeException e) {
|
||||
throw new VaultLoginException(String.format(
|
||||
"Cannot get Role id using AppRole: %s",
|
||||
VaultResponses.getError(e.getResponseBodyAsString())), e);
|
||||
throw new VaultLoginException(
|
||||
String.format("Cannot get Role id using AppRole: %s",
|
||||
VaultResponses.getError(e.getResponseBodyAsString())),
|
||||
e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -252,15 +253,16 @@ public class AppRoleAuthentication implements ClientAuthentication,
|
||||
VaultResponse.class);
|
||||
|
||||
Map<String, Object> data = entity.getBody().getRequiredData();
|
||||
VaultResponse response = VaultResponses.unwrap(
|
||||
(String) data.get("response"), VaultResponse.class);
|
||||
VaultResponse response = VaultResponses
|
||||
.unwrap((String) data.get("response"), VaultResponse.class);
|
||||
|
||||
return (String) response.getRequiredData().get("role_id");
|
||||
}
|
||||
catch (HttpStatusCodeException e) {
|
||||
throw new VaultLoginException(String.format(
|
||||
"Cannot unwrap Role id using AppRole: %s",
|
||||
VaultResponses.getError(e.getResponseBodyAsString())), e);
|
||||
throw new VaultLoginException(
|
||||
String.format("Cannot unwrap Role id using AppRole: %s",
|
||||
VaultResponses.getError(e.getResponseBodyAsString())),
|
||||
e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -284,9 +286,10 @@ public class AppRoleAuthentication implements ClientAuthentication,
|
||||
return (String) response.getRequiredData().get("secret_id");
|
||||
}
|
||||
catch (HttpStatusCodeException e) {
|
||||
throw new VaultLoginException(String.format(
|
||||
"Cannot get Secret id using AppRole: %s",
|
||||
VaultResponses.getError(e.getResponseBodyAsString())), e);
|
||||
throw new VaultLoginException(
|
||||
String.format("Cannot get Secret id using AppRole: %s",
|
||||
VaultResponses.getError(e.getResponseBodyAsString())),
|
||||
e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -301,15 +304,16 @@ public class AppRoleAuthentication implements ClientAuthentication,
|
||||
VaultResponse.class);
|
||||
|
||||
Map<String, Object> data = entity.getBody().getRequiredData();
|
||||
VaultResponse response = VaultResponses.unwrap(
|
||||
(String) data.get("response"), VaultResponse.class);
|
||||
VaultResponse response = VaultResponses
|
||||
.unwrap((String) data.get("response"), VaultResponse.class);
|
||||
|
||||
return (String) response.getRequiredData().get("secret_id");
|
||||
}
|
||||
catch (HttpStatusCodeException e) {
|
||||
throw new VaultLoginException(String.format(
|
||||
"Cannot unwrap Role id using AppRole: %s",
|
||||
VaultResponses.getError(e.getResponseBodyAsString())), e);
|
||||
throw new VaultLoginException(
|
||||
String.format("Cannot unwrap Role id using AppRole: %s",
|
||||
VaultResponses.getError(e.getResponseBodyAsString())),
|
||||
e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -298,8 +298,7 @@ public class AppRoleAuthenticationOptions {
|
||||
}
|
||||
else {
|
||||
|
||||
Assert.notNull(
|
||||
initialToken,
|
||||
Assert.notNull(initialToken,
|
||||
"AppRole authentication configured for pull mode. InitialToken must not be null (pull mode)");
|
||||
roleId(RoleId.pull(initialToken));
|
||||
}
|
||||
|
||||
@@ -85,15 +85,15 @@ public class AuthenticationSteps {
|
||||
* Create a flow definition using a provided {@link VaultToken}.
|
||||
*
|
||||
* @param token the token to be used from this {@link AuthenticationSteps}, must not
|
||||
* be {@literal null}.
|
||||
* be {@literal null}.
|
||||
* @return the {@link AuthenticationSteps}.
|
||||
*/
|
||||
public static AuthenticationSteps just(VaultToken token) {
|
||||
|
||||
Assert.notNull(token, "Vault token must not be null");
|
||||
|
||||
return new AuthenticationSteps(new SupplierStep<>(() -> token,
|
||||
AuthenticationSteps.HEAD));
|
||||
return new AuthenticationSteps(
|
||||
new SupplierStep<>(() -> token, AuthenticationSteps.HEAD));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -106,15 +106,15 @@ public class AuthenticationSteps {
|
||||
|
||||
Assert.notNull(request, "HttpRequest must not be null");
|
||||
|
||||
return new AuthenticationSteps(new HttpRequestNode<>(request,
|
||||
AuthenticationSteps.HEAD));
|
||||
return new AuthenticationSteps(
|
||||
new HttpRequestNode<>(request, AuthenticationSteps.HEAD));
|
||||
}
|
||||
|
||||
/**
|
||||
* Start flow composition from a {@link Supplier}.
|
||||
*
|
||||
* @param supplier supplier function that will produce the flow value, must not be
|
||||
* {@literal null}.
|
||||
* {@literal null}.
|
||||
* @return the first {@link Node}.
|
||||
*/
|
||||
public static <T> Node<T> fromSupplier(Supplier<T> supplier) {
|
||||
@@ -184,7 +184,7 @@ public class AuthenticationSteps {
|
||||
* Transform the state object into a different object.
|
||||
*
|
||||
* @param mappingFunction mapping function to be applied to the state object, must
|
||||
* not be {@literal null}.
|
||||
* not be {@literal null}.
|
||||
* @param <R> resulting object type
|
||||
* @return the next {@link Node}.
|
||||
*/
|
||||
@@ -213,7 +213,7 @@ public class AuthenticationSteps {
|
||||
* Callback with the current state object.
|
||||
*
|
||||
* @param consumerFunction consumer function to be called with the state object,
|
||||
* must not be {@literal null}.
|
||||
* must not be {@literal null}.
|
||||
* @return the next {@link Node}.
|
||||
*/
|
||||
public Node<T> onNext(Consumer<? super T> consumerFunction) {
|
||||
@@ -241,7 +241,7 @@ public class AuthenticationSteps {
|
||||
* the current state to Vaults {@code uriTemplate}.
|
||||
*
|
||||
* @param uriTemplate Vault authentication endpoint, must not be {@literal null}
|
||||
* or empty.
|
||||
* or empty.
|
||||
* @param uriVariables URI variables for URI template expansion.
|
||||
* @return the {@link AuthenticationSteps}.
|
||||
*/
|
||||
@@ -249,8 +249,8 @@ public class AuthenticationSteps {
|
||||
|
||||
Assert.hasText(uriTemplate, "URI template must not be null or empty");
|
||||
|
||||
return login(HttpRequestBuilder.post(uriTemplate, uriVariables).as(
|
||||
VaultResponse.class));
|
||||
return login(HttpRequestBuilder.post(uriTemplate, uriVariables)
|
||||
.as(VaultResponse.class));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -272,7 +272,7 @@ public class AuthenticationSteps {
|
||||
* mapping {@link Function} to the current state object.
|
||||
*
|
||||
* @param mappingFunction mapping function to be applied to the state object, must
|
||||
* not be {@literal null}.
|
||||
* not be {@literal null}.
|
||||
* @return the {@link AuthenticationSteps}.
|
||||
*/
|
||||
public AuthenticationSteps login(
|
||||
@@ -331,7 +331,8 @@ public class AuthenticationSteps {
|
||||
* @param uriVariables the variables to expand the template.
|
||||
* @return a new {@link HttpRequestBuilder}.
|
||||
*/
|
||||
public static HttpRequestBuilder post(String uriTemplate, String... uriVariables) {
|
||||
public static HttpRequestBuilder post(String uriTemplate,
|
||||
String... uriVariables) {
|
||||
return new HttpRequestBuilder(HttpMethod.POST, uriTemplate, uriVariables);
|
||||
}
|
||||
|
||||
@@ -442,8 +443,8 @@ public class AuthenticationSteps {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("%s %s AS %s", getMethod(), getUri() != null ? getUri()
|
||||
: getUriTemplate(), getResponseType());
|
||||
return String.format("%s %s AS %s", getMethod(),
|
||||
getUri() != null ? getUri() : getUriTemplate(), getResponseType());
|
||||
}
|
||||
|
||||
HttpMethod getMethod() {
|
||||
|
||||
@@ -74,7 +74,6 @@ public class AuthenticationStepsExecutor implements ClientAuthentication {
|
||||
@SuppressWarnings("unchecked")
|
||||
public VaultToken login() throws VaultException {
|
||||
|
||||
|
||||
Iterable<Node<?>> steps = chain.steps;
|
||||
|
||||
Object state = evaluate(steps);
|
||||
@@ -102,8 +101,8 @@ public class AuthenticationStepsExecutor implements ClientAuthentication {
|
||||
for (Node<?> o : steps) {
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug(String
|
||||
.format("Executing %s with current state %s", o, state));
|
||||
logger.debug(
|
||||
String.format("Executing %s with current state %s", o, state));
|
||||
}
|
||||
|
||||
try {
|
||||
@@ -128,8 +127,8 @@ public class AuthenticationStepsExecutor implements ClientAuthentication {
|
||||
}
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug(String.format("Executed %s with current state %s", o,
|
||||
state));
|
||||
logger.debug(
|
||||
String.format("Executed %s with current state %s", o, state));
|
||||
}
|
||||
}
|
||||
catch (HttpStatusCodeException e) {
|
||||
@@ -139,8 +138,8 @@ public class AuthenticationStepsExecutor implements ClientAuthentication {
|
||||
VaultResponses.getError(e.getResponseBodyAsString())), e);
|
||||
}
|
||||
catch (RuntimeException e) {
|
||||
throw new VaultLoginException(String.format(
|
||||
"Authentication execution failed in %s", o), e);
|
||||
throw new VaultLoginException(
|
||||
String.format("Authentication execution failed in %s", o), e);
|
||||
}
|
||||
}
|
||||
return state;
|
||||
@@ -172,11 +171,11 @@ public class AuthenticationStepsExecutor implements ClientAuthentication {
|
||||
|
||||
if (definition.getUri() == null) {
|
||||
|
||||
ResponseEntity<?> exchange = restOperations
|
||||
.exchange(definition.getUriTemplate(), definition.getMethod(),
|
||||
getEntity(definition.getEntity(), state),
|
||||
definition.getResponseType(),
|
||||
(Object[]) definition.getUrlVariables());
|
||||
ResponseEntity<?> exchange = restOperations.exchange(
|
||||
definition.getUriTemplate(), definition.getMethod(),
|
||||
getEntity(definition.getEntity(), state),
|
||||
definition.getResponseType(),
|
||||
(Object[]) definition.getUrlVariables());
|
||||
|
||||
return exchange.getBody();
|
||||
}
|
||||
|
||||
@@ -80,31 +80,26 @@ public class AuthenticationStepsOperator implements VaultTokenSupplier {
|
||||
|
||||
Mono<Object> state = createMono(chain.steps);
|
||||
|
||||
return state
|
||||
.map(stateObject -> {
|
||||
return state.map(stateObject -> {
|
||||
|
||||
if (stateObject instanceof VaultToken) {
|
||||
return (VaultToken) stateObject;
|
||||
}
|
||||
if (stateObject instanceof VaultToken) {
|
||||
return (VaultToken) stateObject;
|
||||
}
|
||||
|
||||
if (stateObject instanceof VaultResponse) {
|
||||
if (stateObject instanceof VaultResponse) {
|
||||
|
||||
VaultResponse response = (VaultResponse) stateObject;
|
||||
VaultResponse response = (VaultResponse) stateObject;
|
||||
|
||||
Assert.state(response.getAuth() != null,
|
||||
"Auth field must not be null");
|
||||
Assert.state(response.getAuth() != null, "Auth field must not be null");
|
||||
|
||||
return LoginTokenUtil.from(response.getAuth());
|
||||
}
|
||||
return LoginTokenUtil.from(response.getAuth());
|
||||
}
|
||||
|
||||
throw new IllegalStateException(
|
||||
String.format(
|
||||
"Cannot retrieve VaultToken from authentication chain. Got instead %s",
|
||||
stateObject));
|
||||
})
|
||||
.onErrorMap(
|
||||
t -> new VaultLoginException(
|
||||
"Cannot retrieve VaultToken from authentication chain", t));
|
||||
throw new IllegalStateException(String.format(
|
||||
"Cannot retrieve VaultToken from authentication chain. Got instead %s",
|
||||
stateObject));
|
||||
}).onErrorMap(t -> new VaultLoginException(
|
||||
"Cannot retrieve VaultToken from authentication chain", t));
|
||||
}
|
||||
|
||||
private Mono<Object> createMono(Iterable<Node<?>> steps) {
|
||||
@@ -114,13 +109,14 @@ public class AuthenticationStepsOperator implements VaultTokenSupplier {
|
||||
for (Node<?> o : steps) {
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug(String
|
||||
.format("Executing %s with current state %s", o, state));
|
||||
logger.debug(
|
||||
String.format("Executing %s with current state %s", o, state));
|
||||
}
|
||||
|
||||
if (o instanceof HttpRequestNode) {
|
||||
state = state.flatMap(stateObject -> doHttpRequest(
|
||||
(HttpRequestNode<Object>) o, stateObject));
|
||||
state = state
|
||||
.flatMap(stateObject -> doHttpRequest((HttpRequestNode<Object>) o,
|
||||
stateObject));
|
||||
}
|
||||
|
||||
if (o instanceof MapStep) {
|
||||
@@ -129,13 +125,13 @@ public class AuthenticationStepsOperator implements VaultTokenSupplier {
|
||||
}
|
||||
|
||||
if (o instanceof ZipStep) {
|
||||
state = state.zipWith(doZipStep((ZipStep<Object, Object>) o)).map(
|
||||
it -> Pair.of(it.getT1(), it.getT2()));
|
||||
state = state.zipWith(doZipStep((ZipStep<Object, Object>) o))
|
||||
.map(it -> Pair.of(it.getT1(), it.getT2()));
|
||||
}
|
||||
|
||||
if (o instanceof OnNextStep) {
|
||||
state = state.doOnNext(stateObject -> doOnNext((OnNextStep<Object>) o,
|
||||
stateObject));
|
||||
state = state.doOnNext(
|
||||
stateObject -> doOnNext((OnNextStep<Object>) o, stateObject));
|
||||
}
|
||||
|
||||
if (o instanceof SupplierStep<?>) {
|
||||
@@ -144,7 +140,8 @@ public class AuthenticationStepsOperator implements VaultTokenSupplier {
|
||||
}
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug(String.format("Executed %s with current state %s", o, state));
|
||||
logger.debug(
|
||||
String.format("Executed %s with current state %s", o, state));
|
||||
}
|
||||
}
|
||||
return state;
|
||||
|
||||
@@ -46,8 +46,8 @@ import org.springframework.web.client.RestOperations;
|
||||
* @see <a href="https://www.vaultproject.io/docs/auth/aws-ec2.html">Auth Backend:
|
||||
* aws-ec2</a>
|
||||
*/
|
||||
public class AwsEc2Authentication implements ClientAuthentication,
|
||||
AuthenticationStepsFactory {
|
||||
public class AwsEc2Authentication
|
||||
implements ClientAuthentication, AuthenticationStepsFactory {
|
||||
|
||||
private static final Log logger = LogFactory.getLog(AwsEc2Authentication.class);
|
||||
|
||||
@@ -81,7 +81,8 @@ public class AwsEc2Authentication implements ClientAuthentication,
|
||||
* @param awsMetadataRestOperations must not be {@literal null}.
|
||||
*/
|
||||
public AwsEc2Authentication(AwsEc2AuthenticationOptions options,
|
||||
RestOperations vaultRestOperations, RestOperations awsMetadataRestOperations) {
|
||||
RestOperations vaultRestOperations,
|
||||
RestOperations awsMetadataRestOperations) {
|
||||
|
||||
Assert.notNull(options, "AwsEc2AuthenticationOptions must not be null");
|
||||
Assert.notNull(vaultRestOperations, "Vault RestOperations must not be null");
|
||||
@@ -116,10 +117,9 @@ public class AwsEc2Authentication implements ClientAuthentication,
|
||||
Supplier<char[]> nonceSupplier) {
|
||||
|
||||
return AuthenticationSteps
|
||||
.fromHttpRequest(
|
||||
HttpRequestBuilder.get(
|
||||
options.getIdentityDocumentUri().toString()).as(
|
||||
String.class)) //
|
||||
.fromHttpRequest(HttpRequestBuilder
|
||||
.get(options.getIdentityDocumentUri().toString())
|
||||
.as(String.class)) //
|
||||
.map(pkcs7 -> pkcs7.replaceAll("\\r", "")) //
|
||||
.map(pkcs7 -> pkcs7.replace("\\n", "")) //
|
||||
.map(pkcs7 -> {
|
||||
@@ -169,10 +169,9 @@ public class AwsEc2Authentication implements ClientAuthentication,
|
||||
if (response.getAuth().get("metadata") instanceof Map) {
|
||||
Map<Object, Object> metadata = (Map<Object, Object>) response
|
||||
.getAuth().get("metadata");
|
||||
logger.debug(String
|
||||
.format("Login successful using AWS-EC2 authentication for instance %s, AMI %s",
|
||||
metadata.get("instance_id"),
|
||||
metadata.get("instance_id")));
|
||||
logger.debug(String.format(
|
||||
"Login successful using AWS-EC2 authentication for instance %s, AMI %s",
|
||||
metadata.get("instance_id"), metadata.get("instance_id")));
|
||||
}
|
||||
else {
|
||||
logger.debug("Login successful using AWS-EC2 authentication");
|
||||
@@ -201,8 +200,8 @@ public class AwsEc2Authentication implements ClientAuthentication,
|
||||
login.put("nonce", new String(this.nonce.get()));
|
||||
|
||||
try {
|
||||
String pkcs7 = this.awsMetadataRestOperations.getForObject(
|
||||
this.options.getIdentityDocumentUri(), String.class);
|
||||
String pkcs7 = this.awsMetadataRestOperations
|
||||
.getForObject(this.options.getIdentityDocumentUri(), String.class);
|
||||
if (StringUtils.hasText(pkcs7)) {
|
||||
login.put("pkcs7", pkcs7.replaceAll("\\r", "").replace("\\n", ""));
|
||||
}
|
||||
@@ -210,9 +209,10 @@ public class AwsEc2Authentication implements ClientAuthentication,
|
||||
return login;
|
||||
}
|
||||
catch (RestClientException e) {
|
||||
throw new VaultLoginException(String.format(
|
||||
"Cannot obtain Identity Document from %s",
|
||||
options.getIdentityDocumentUri()), e);
|
||||
throw new VaultLoginException(
|
||||
String.format("Cannot obtain Identity Document from %s",
|
||||
options.getIdentityDocumentUri()),
|
||||
e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -203,7 +203,8 @@ public class AwsEc2AuthenticationOptions {
|
||||
|
||||
Assert.notNull(identityDocumentUri, "IdentityDocumentUri must not be null");
|
||||
|
||||
return new AwsEc2AuthenticationOptions(path, identityDocumentUri, role, nonce);
|
||||
return new AwsEc2AuthenticationOptions(path, identityDocumentUri, role,
|
||||
nonce);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -62,12 +62,12 @@ import org.springframework.web.client.RestOperations;
|
||||
* @see RestOperations
|
||||
* @see <a href="https://www.vaultproject.io/docs/auth/aws.html">Auth Backend: aws
|
||||
* (IAM)</a>
|
||||
* @see <a
|
||||
* href="https://docs.aws.amazon.com/STS/latest/APIReference/API_GetCallerIdentity.html">AWS:
|
||||
* @see <a href=
|
||||
* "https://docs.aws.amazon.com/STS/latest/APIReference/API_GetCallerIdentity.html">AWS:
|
||||
* GetCallerIdentity</a>
|
||||
*/
|
||||
public class AwsIamAuthentication implements ClientAuthentication,
|
||||
AuthenticationStepsFactory {
|
||||
public class AwsIamAuthentication
|
||||
implements ClientAuthentication, AuthenticationStepsFactory {
|
||||
|
||||
private static final Log logger = LogFactory.getLog(AwsIamAuthentication.class);
|
||||
|
||||
@@ -123,8 +123,8 @@ public class AwsIamAuthentication implements ClientAuthentication,
|
||||
protected static AuthenticationSteps createAuthenticationSteps(
|
||||
AwsIamAuthenticationOptions options, AWSCredentials credentials) {
|
||||
|
||||
return AuthenticationSteps.fromSupplier(
|
||||
() -> createRequestBody(options, credentials)) //
|
||||
return AuthenticationSteps
|
||||
.fromSupplier(() -> createRequestBody(options, credentials)) //
|
||||
.login("auth/{mount}/login", options.getPath());
|
||||
}
|
||||
|
||||
@@ -135,8 +135,8 @@ public class AwsIamAuthentication implements ClientAuthentication,
|
||||
|
||||
@Override
|
||||
public AuthenticationSteps getAuthenticationSteps() {
|
||||
return createAuthenticationSteps(this.options, this.options
|
||||
.getCredentialsProvider().getCredentials());
|
||||
return createAuthenticationSteps(this.options,
|
||||
this.options.getCredentialsProvider().getCredentials());
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@@ -157,10 +157,10 @@ public class AwsIamAuthentication implements ClientAuthentication,
|
||||
if (response.getAuth().get("metadata") instanceof Map) {
|
||||
Map<Object, Object> metadata = (Map<Object, Object>) response
|
||||
.getAuth().get("metadata");
|
||||
logger.debug(String
|
||||
.format("Login successful using AWS-IAM authentication for user id %s, ARN %s",
|
||||
metadata.get("client_user_id"),
|
||||
metadata.get("canonical_arn")));
|
||||
logger.debug(String.format(
|
||||
"Login successful using AWS-IAM authentication for user id %s, ARN %s",
|
||||
metadata.get("client_user_id"),
|
||||
metadata.get("canonical_arn")));
|
||||
}
|
||||
else {
|
||||
logger.debug("Login successful using AWS-IAM authentication");
|
||||
@@ -183,8 +183,8 @@ public class AwsIamAuthentication implements ClientAuthentication,
|
||||
*/
|
||||
protected static Map<String, String> createRequestBody(
|
||||
AwsIamAuthenticationOptions options) {
|
||||
return createRequestBody(options, options.getCredentialsProvider()
|
||||
.getCredentials());
|
||||
return createRequestBody(options,
|
||||
options.getCredentialsProvider().getCredentials());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -200,8 +200,8 @@ public class AwsIamAuthentication implements ClientAuthentication,
|
||||
Map<String, String> login = new HashMap<>();
|
||||
|
||||
login.put("iam_http_request_method", "POST");
|
||||
login.put("iam_request_url", Base64Utils.encodeToString(options.getEndpointUri()
|
||||
.toString().getBytes()));
|
||||
login.put("iam_request_url", Base64Utils
|
||||
.encodeToString(options.getEndpointUri().toString().getBytes()));
|
||||
login.put("iam_request_body", REQUEST_BODY_BASE64_ENCODED);
|
||||
|
||||
String headerJson = getSignedHeaders(options, credentials);
|
||||
@@ -252,7 +252,8 @@ public class AwsIamAuthentication implements ClientAuthentication,
|
||||
Map<String, String> headers = new LinkedHashMap<>();
|
||||
|
||||
headers.put(HttpHeaders.CONTENT_LENGTH, "" + REQUEST_BODY.length());
|
||||
headers.put(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_FORM_URLENCODED_VALUE);
|
||||
headers.put(HttpHeaders.CONTENT_TYPE,
|
||||
MediaType.APPLICATION_FORM_URLENCODED_VALUE);
|
||||
|
||||
if (StringUtils.hasText(options.getServerId())) {
|
||||
headers.put("X-Vault-AWS-IAM-Server-ID", options.getServerId());
|
||||
|
||||
@@ -184,7 +184,8 @@ public class AwsIamAuthenticationOptions {
|
||||
* @return {@code this} {@link AwsIamAuthenticationOptionsBuilder}.
|
||||
* @see #credentialsProvider(AWSCredentialsProvider)
|
||||
*/
|
||||
public AwsIamAuthenticationOptionsBuilder credentials(AWSCredentials credentials) {
|
||||
public AwsIamAuthenticationOptionsBuilder credentials(
|
||||
AWSCredentials credentials) {
|
||||
|
||||
Assert.notNull(credentials, "Credentials must not be null");
|
||||
|
||||
@@ -203,7 +204,8 @@ public class AwsIamAuthenticationOptions {
|
||||
public AwsIamAuthenticationOptionsBuilder credentialsProvider(
|
||||
AWSCredentialsProvider credentialsProvider) {
|
||||
|
||||
Assert.notNull(credentialsProvider, "AWSCredentialsProvider must not be null");
|
||||
Assert.notNull(credentialsProvider,
|
||||
"AWSCredentialsProvider must not be null");
|
||||
|
||||
this.credentialsProvider = credentialsProvider;
|
||||
return this;
|
||||
|
||||
@@ -92,7 +92,8 @@ public class AzureMsiAuthentication implements ClientAuthentication {
|
||||
* @param azureMetadataRestOperations must not be {@literal null}.
|
||||
*/
|
||||
public AzureMsiAuthentication(AzureMsiAuthenticationOptions options,
|
||||
RestOperations vaultRestOperations, RestOperations azureMetadataRestOperations) {
|
||||
RestOperations vaultRestOperations,
|
||||
RestOperations azureMetadataRestOperations) {
|
||||
|
||||
Assert.notNull(options, "AzureAuthenticationOptions must not be null");
|
||||
Assert.notNull(vaultRestOperations, "Vault RestOperations must not be null");
|
||||
@@ -123,17 +124,19 @@ public class AzureMsiAuthentication implements ClientAuthentication {
|
||||
AzureMsiAuthenticationOptions options,
|
||||
@Nullable AzureVmEnvironment environment) {
|
||||
|
||||
Node<String> msiToken = AuthenticationSteps.fromHttpRequest(
|
||||
HttpRequestBuilder.get(options.getIdentityTokenServiceUri())
|
||||
.with(METADATA_HEADERS).as(Map.class)) //
|
||||
Node<String> msiToken = AuthenticationSteps
|
||||
.fromHttpRequest(
|
||||
HttpRequestBuilder.get(options.getIdentityTokenServiceUri())
|
||||
.with(METADATA_HEADERS).as(Map.class)) //
|
||||
.map(token -> (String) token.get("access_token"));
|
||||
|
||||
Node<AzureVmEnvironment> environmentSteps;
|
||||
|
||||
if (environment == null) {
|
||||
|
||||
environmentSteps = AuthenticationSteps.fromHttpRequest(
|
||||
HttpRequestBuilder.get(options.getInstanceMetadataServiceUri())
|
||||
environmentSteps = AuthenticationSteps
|
||||
.fromHttpRequest(HttpRequestBuilder
|
||||
.get(options.getInstanceMetadataServiceUri())
|
||||
.with(METADATA_HEADERS).as(Map.class)) //
|
||||
.map(AzureMsiAuthentication::toAzureVmEnvironment);
|
||||
}
|
||||
@@ -141,8 +144,7 @@ public class AzureMsiAuthentication implements ClientAuthentication {
|
||||
environmentSteps = AuthenticationSteps.fromSupplier(() -> environment);
|
||||
}
|
||||
|
||||
return environmentSteps
|
||||
.zipWith(msiToken)
|
||||
return environmentSteps.zipWith(msiToken)
|
||||
.map(tuple -> getAzureLogin(options.getRole(), tuple.getLeft(),
|
||||
tuple.getRight())) //
|
||||
.login("auth/{mount}/login", options.getPath());
|
||||
@@ -211,8 +213,8 @@ public class AzureMsiAuthentication implements ClientAuthentication {
|
||||
private AzureVmEnvironment fetchAzureVmEnvironment() {
|
||||
|
||||
ResponseEntity<Map> response = this.azureMetadataRestOperations.exchange(
|
||||
options.getInstanceMetadataServiceUri(), HttpMethod.GET,
|
||||
METADATA_HEADERS, Map.class);
|
||||
options.getInstanceMetadataServiceUri(), HttpMethod.GET, METADATA_HEADERS,
|
||||
Map.class);
|
||||
|
||||
return toAzureVmEnvironment(response.getBody());
|
||||
}
|
||||
|
||||
@@ -40,8 +40,8 @@ public class AzureMsiAuthenticationOptions {
|
||||
public static final URI DEFAULT_INSTANCE_METADATA_SERVICE_URI = URI
|
||||
.create("http://169.254.169.254/metadata/instance?api-version=2017-08-01");
|
||||
|
||||
public static final URI DEFAULT_IDENTITY_TOKEN_SERVICE_URI = URI
|
||||
.create("http://169.254.169.254/metadata/identity/oauth2/token?resource=https://vault.hashicorp.com&api-version=2018-02-01");
|
||||
public static final URI DEFAULT_IDENTITY_TOKEN_SERVICE_URI = URI.create(
|
||||
"http://169.254.169.254/metadata/identity/oauth2/token?resource=https://vault.hashicorp.com&api-version=2018-02-01");
|
||||
|
||||
/**
|
||||
* Path of the azure authentication backend mount.
|
||||
|
||||
@@ -32,8 +32,8 @@ import org.springframework.vault.support.VaultToken;
|
||||
* @see VaultTokenSupplier
|
||||
* @see VaultToken
|
||||
*/
|
||||
public class CachingVaultTokenSupplier implements VaultTokenSupplier,
|
||||
ReactiveSessionManager {
|
||||
public class CachingVaultTokenSupplier
|
||||
implements VaultTokenSupplier, ReactiveSessionManager {
|
||||
|
||||
private static final Mono<VaultToken> EMPTY = Mono.empty();
|
||||
|
||||
|
||||
@@ -33,8 +33,8 @@ import static org.springframework.vault.authentication.AuthenticationSteps.HttpR
|
||||
*
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
public class ClientCertificateAuthentication implements ClientAuthentication,
|
||||
AuthenticationStepsFactory {
|
||||
public class ClientCertificateAuthentication
|
||||
implements ClientAuthentication, AuthenticationStepsFactory {
|
||||
|
||||
private static final Log logger = LogFactory
|
||||
.getLog(ClientCertificateAuthentication.class);
|
||||
|
||||
@@ -137,8 +137,8 @@ import static org.springframework.vault.authentication.AuthenticationSteps.HttpR
|
||||
* "https://www.vaultproject.io/docs/concepts/response-wrapping.html">Response
|
||||
* Wrapping</a>
|
||||
*/
|
||||
public class CubbyholeAuthentication implements ClientAuthentication,
|
||||
AuthenticationStepsFactory {
|
||||
public class CubbyholeAuthentication
|
||||
implements ClientAuthentication, AuthenticationStepsFactory {
|
||||
|
||||
private static final Log logger = LogFactory.getLog(CubbyholeAuthentication.class);
|
||||
|
||||
@@ -194,8 +194,8 @@ public class CubbyholeAuthentication implements ClientAuthentication,
|
||||
|
||||
if (shouldEnhanceTokenWithSelfLookup(tokenToUse)) {
|
||||
|
||||
LoginTokenAdapter adapter = new LoginTokenAdapter(new TokenAuthentication(
|
||||
tokenToUse), restOperations);
|
||||
LoginTokenAdapter adapter = new LoginTokenAdapter(
|
||||
new TokenAuthentication(tokenToUse), restOperations);
|
||||
tokenToUse = adapter.login();
|
||||
}
|
||||
|
||||
@@ -261,10 +261,9 @@ public class CubbyholeAuthentication implements ClientAuthentication,
|
||||
}
|
||||
|
||||
if (data == null || data.isEmpty()) {
|
||||
throw new VaultLoginException(
|
||||
String.format(
|
||||
"Cannot retrieve Token from Cubbyhole: Response at %s does not contain a token",
|
||||
options.getPath()));
|
||||
throw new VaultLoginException(String.format(
|
||||
"Cannot retrieve Token from Cubbyhole: Response at %s does not contain a token",
|
||||
options.getPath()));
|
||||
}
|
||||
|
||||
if (data.size() == 1) {
|
||||
@@ -272,9 +271,8 @@ public class CubbyholeAuthentication implements ClientAuthentication,
|
||||
return VaultToken.of(token);
|
||||
}
|
||||
|
||||
throw new VaultLoginException(
|
||||
String.format(
|
||||
"Cannot retrieve Token from Cubbyhole: Response at %s does not contain an unique token",
|
||||
options.getPath()));
|
||||
throw new VaultLoginException(String.format(
|
||||
"Cannot retrieve Token from Cubbyhole: Response at %s does not contain an unique token",
|
||||
options.getPath()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -126,7 +126,8 @@ public class CubbyholeAuthenticationOptions {
|
||||
* @param initialToken must not be {@literal null}.
|
||||
* @return {@code this} {@link CubbyholeAuthenticationOptionsBuilder}.
|
||||
*/
|
||||
public CubbyholeAuthenticationOptionsBuilder initialToken(VaultToken initialToken) {
|
||||
public CubbyholeAuthenticationOptionsBuilder initialToken(
|
||||
VaultToken initialToken) {
|
||||
|
||||
Assert.notNull(initialToken, "Initial Vault Token must not be null");
|
||||
|
||||
@@ -166,7 +167,7 @@ public class CubbyholeAuthenticationOptions {
|
||||
* {@literal true}.
|
||||
*
|
||||
* @param selfLookup {@literal true} to perform a self-lookup or {@literal false}
|
||||
* to disable it.
|
||||
* to disable it.
|
||||
* @return {@code this} {@link CubbyholeAuthenticationOptionsBuilder}.
|
||||
* @since 1.0.1
|
||||
*/
|
||||
|
||||
@@ -29,8 +29,8 @@ import org.springframework.util.StringUtils;
|
||||
* @since 2.1
|
||||
* @see GcpIamAuthentication
|
||||
*/
|
||||
enum DefaultGcpCredentialAccessors implements GcpProjectIdAccessor,
|
||||
GcpServiceAccountIdAccessor {
|
||||
enum DefaultGcpCredentialAccessors
|
||||
implements GcpProjectIdAccessor, GcpServiceAccountIdAccessor {
|
||||
|
||||
INSTANCE;
|
||||
|
||||
@@ -44,8 +44,7 @@ enum DefaultGcpCredentialAccessors implements GcpProjectIdAccessor,
|
||||
public String getServiceAccountId(GoogleCredential credential) {
|
||||
|
||||
Assert.notNull(credential, "GoogleCredential must not be null");
|
||||
Assert.notNull(
|
||||
credential.getServiceAccountId(),
|
||||
Assert.notNull(credential.getServiceAccountId(),
|
||||
"The configured GoogleCredential does not represent a service account. Configure the service account id with GcpIamAuthenticationOptionsBuilder#serviceAccountId(String).");
|
||||
|
||||
return credential.getServiceAccountId();
|
||||
|
||||
@@ -45,12 +45,12 @@ import static org.springframework.vault.authentication.AuthenticationSteps.HttpR
|
||||
* @see GcpComputeAuthenticationOptions
|
||||
* @see <a href="https://www.vaultproject.io/docs/auth/gcp.html">Auth Backend: gcp
|
||||
* (IAM)</a>
|
||||
* @see <a
|
||||
* href="https://cloud.google.com/compute/docs/instances/verifying-instance-identity">Google
|
||||
* @see <a href=
|
||||
* "https://cloud.google.com/compute/docs/instances/verifying-instance-identity">Google
|
||||
* Compute Engine: Verifying the Identity of Instances</a>
|
||||
*/
|
||||
public class GcpComputeAuthentication extends GcpJwtAuthenticationSupport implements
|
||||
ClientAuthentication, AuthenticationStepsFactory {
|
||||
public class GcpComputeAuthentication extends GcpJwtAuthenticationSupport
|
||||
implements ClientAuthentication, AuthenticationStepsFactory {
|
||||
|
||||
public static final String COMPUTE_METADATA_URL_TEMPLATE = "http://metadata/computeMetadata/v1/instance/service-accounts/{serviceAccount}/identity"
|
||||
+ "?audience={audience}&format={format}";
|
||||
@@ -112,8 +112,8 @@ public class GcpComputeAuthentication extends GcpJwtAuthenticationSupport implem
|
||||
|
||||
HttpRequest<String> jwtRequest = get(COMPUTE_METADATA_URL_TEMPLATE,
|
||||
serviceAccount, audience, "full") //
|
||||
.with(getMetadataHttpHeaders()) //
|
||||
.as(String.class);
|
||||
.with(getMetadataHttpHeaders()) //
|
||||
.as(String.class);
|
||||
|
||||
return AuthenticationSteps.fromHttpRequest(jwtRequest)
|
||||
//
|
||||
|
||||
@@ -122,7 +122,8 @@ public class GcpComputeAuthenticationOptions {
|
||||
* @param serviceAccount must not be empty or {@literal null}.
|
||||
* @return {@code this} {@link GcpComputeAuthenticationOptionsBuilder}.
|
||||
*/
|
||||
public GcpComputeAuthenticationOptionsBuilder serviceAccount(String serviceAccount) {
|
||||
public GcpComputeAuthenticationOptionsBuilder serviceAccount(
|
||||
String serviceAccount) {
|
||||
|
||||
Assert.hasText(serviceAccount, "Service account must not be null");
|
||||
|
||||
|
||||
@@ -59,12 +59,12 @@ import org.springframework.web.client.RestOperations;
|
||||
* @see RestOperations
|
||||
* @see <a href="https://www.vaultproject.io/docs/auth/gcp.html">Auth Backend: gcp
|
||||
* (IAM)</a>
|
||||
* @see <a
|
||||
* href="https://cloud.google.com/iam/reference/rest/v1/projects.serviceAccounts/signJwt">GCP:
|
||||
* @see <a href=
|
||||
* "https://cloud.google.com/iam/reference/rest/v1/projects.serviceAccounts/signJwt">GCP:
|
||||
* projects.serviceAccounts.signJwt</a>
|
||||
*/
|
||||
public class GcpIamAuthentication extends GcpJwtAuthenticationSupport implements
|
||||
ClientAuthentication {
|
||||
public class GcpIamAuthentication extends GcpJwtAuthenticationSupport
|
||||
implements ClientAuthentication {
|
||||
|
||||
private static final JsonFactory JSON_FACTORY = new JacksonFactory();
|
||||
|
||||
@@ -82,9 +82,9 @@ public class GcpIamAuthentication extends GcpJwtAuthenticationSupport implements
|
||||
* @param options must not be {@literal null}.
|
||||
* @param restOperations HTTP client for for Vault login, must not be {@literal null}.
|
||||
* @throws GeneralSecurityException thrown by
|
||||
* {@link GoogleApacheHttpTransport#newTrustedTransport()}.
|
||||
* {@link GoogleApacheHttpTransport#newTrustedTransport()}.
|
||||
* @throws IOException thrown by
|
||||
* {@link GoogleApacheHttpTransport#newTrustedTransport()}.
|
||||
* {@link GoogleApacheHttpTransport#newTrustedTransport()}.
|
||||
*/
|
||||
public GcpIamAuthentication(GcpIamAuthenticationOptions options,
|
||||
RestOperations restOperations) throws GeneralSecurityException, IOException {
|
||||
@@ -139,12 +139,9 @@ public class GcpIamAuthentication extends GcpJwtAuthenticationSupport implements
|
||||
SignJwtRequest request = new SignJwtRequest();
|
||||
request.setPayload(payload);
|
||||
|
||||
SignJwt signJwt = iam
|
||||
.projects()
|
||||
.serviceAccounts()
|
||||
.signJwt(
|
||||
String.format("projects/%s/serviceAccounts/%s", projectId,
|
||||
serviceAccount), request);
|
||||
SignJwt signJwt = iam.projects().serviceAccounts().signJwt(String
|
||||
.format("projects/%s/serviceAccounts/%s", projectId, serviceAccount),
|
||||
request);
|
||||
|
||||
SignJwtResponse response = signJwt.execute();
|
||||
|
||||
|
||||
@@ -194,7 +194,8 @@ public class GcpIamAuthenticationOptions {
|
||||
* @return {@code this} {@link GcpIamAuthenticationOptionsBuilder}.
|
||||
* @see #credentialSupplier(GcpCredentialSupplier)
|
||||
*/
|
||||
public GcpIamAuthenticationOptionsBuilder credential(GoogleCredential credential) {
|
||||
public GcpIamAuthenticationOptionsBuilder credential(
|
||||
GoogleCredential credential) {
|
||||
|
||||
Assert.notNull(credential, "Credential must not be null");
|
||||
|
||||
@@ -227,11 +228,13 @@ public class GcpIamAuthenticationOptions {
|
||||
* @return {@code this} {@link GcpIamAuthenticationOptionsBuilder}.
|
||||
* @since 2.1
|
||||
*/
|
||||
public GcpIamAuthenticationOptionsBuilder serviceAccountId(String serviceAccountId) {
|
||||
public GcpIamAuthenticationOptionsBuilder serviceAccountId(
|
||||
String serviceAccountId) {
|
||||
|
||||
Assert.notNull(serviceAccountId, "Service account id may not be null");
|
||||
|
||||
return serviceAccountIdAccessor((GoogleCredential credential) -> serviceAccountId);
|
||||
return serviceAccountIdAccessor(
|
||||
(GoogleCredential credential) -> serviceAccountId);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -276,7 +279,7 @@ public class GcpIamAuthenticationOptions {
|
||||
* {@link GoogleCredential#getServiceAccountProjectId()}.
|
||||
*
|
||||
* @param projectIdAccessor the GCP project id supplier to use in GCP IAM API
|
||||
* calls
|
||||
* calls
|
||||
* @return {@code this} {@link GcpIamAuthenticationOptionsBuilder}.
|
||||
* @since 2.1
|
||||
*/
|
||||
|
||||
@@ -18,8 +18,8 @@ package org.springframework.vault.authentication;
|
||||
import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
|
||||
|
||||
/**
|
||||
* Interface to obtain a service account id for GCP IAM authentication.
|
||||
* Implementations are used by {@link GcpIamAuthentication}.
|
||||
* Interface to obtain a service account id for GCP IAM authentication. Implementations
|
||||
* are used by {@link GcpIamAuthentication}.
|
||||
*
|
||||
* @author Magnus Jungsbluth
|
||||
* @since 2.1
|
||||
|
||||
@@ -42,8 +42,8 @@ import org.springframework.web.client.RestOperations;
|
||||
* @see <a href="https://www.vaultproject.io/docs/auth/kubernetes.html">Auth Backend:
|
||||
* Kubernetes</a>
|
||||
*/
|
||||
public class KubernetesAuthentication implements ClientAuthentication,
|
||||
AuthenticationStepsFactory {
|
||||
public class KubernetesAuthentication
|
||||
implements ClientAuthentication, AuthenticationStepsFactory {
|
||||
|
||||
private static final Log logger = LogFactory.getLog(KubernetesAuthentication.class);
|
||||
|
||||
@@ -81,16 +81,16 @@ public class KubernetesAuthentication implements ClientAuthentication,
|
||||
Assert.notNull(options, "CubbyholeAuthenticationOptions must not be null");
|
||||
|
||||
String token = options.getJwtSupplier().get();
|
||||
return AuthenticationSteps.fromSupplier(
|
||||
() -> getKubernetesLogin(options.getRole(), token)) //
|
||||
return AuthenticationSteps
|
||||
.fromSupplier(() -> getKubernetesLogin(options.getRole(), token)) //
|
||||
.login("auth/{mount}/login", options.getPath());
|
||||
}
|
||||
|
||||
@Override
|
||||
public VaultToken login() throws VaultException {
|
||||
|
||||
Map<String, String> login = getKubernetesLogin(options.getRole(), options
|
||||
.getJwtSupplier().get());
|
||||
Map<String, String> login = getKubernetesLogin(options.getRole(),
|
||||
options.getJwtSupplier().get());
|
||||
|
||||
try {
|
||||
VaultResponse response = restOperations.postForObject("auth/{mount}/login",
|
||||
|
||||
@@ -124,7 +124,7 @@ public class KubernetesAuthenticationOptions {
|
||||
* Configure the role.
|
||||
*
|
||||
* @param role name of the role against which the login is being attempted, must
|
||||
* not be {@literal null} or empty.
|
||||
* not be {@literal null} or empty.
|
||||
* @return {@code this} {@link KubernetesAuthenticationOptionsBuilder}.
|
||||
*/
|
||||
public KubernetesAuthenticationOptionsBuilder role(String role) {
|
||||
@@ -161,8 +161,8 @@ public class KubernetesAuthenticationOptions {
|
||||
Assert.notNull(role, "Role must not be null");
|
||||
|
||||
return new KubernetesAuthenticationOptions(path, role,
|
||||
jwtSupplier == null ? new KubernetesServiceAccountTokenFile()
|
||||
.cached() : jwtSupplier);
|
||||
jwtSupplier == null ? new KubernetesServiceAccountTokenFile().cached()
|
||||
: jwtSupplier);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,7 +52,7 @@ public class KubernetesServiceAccountTokenFile implements KubernetesJwtSupplier
|
||||
* exception if the file does not exist.
|
||||
*
|
||||
* @throws IllegalArgumentException if the
|
||||
* {@link #DEFAULT_KUBERNETES_SERVICE_ACCOUNT_TOKEN_FILE} does not exist.
|
||||
* {@link #DEFAULT_KUBERNETES_SERVICE_ACCOUNT_TOKEN_FILE} does not exist.
|
||||
*/
|
||||
public KubernetesServiceAccountTokenFile() {
|
||||
this(DEFAULT_KUBERNETES_SERVICE_ACCOUNT_TOKEN_FILE);
|
||||
@@ -102,8 +102,8 @@ public class KubernetesServiceAccountTokenFile implements KubernetesJwtSupplier
|
||||
return new String(readToken(this.resource), StandardCharsets.US_ASCII);
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new VaultException(String.format(
|
||||
"Kube JWT token retrieval from %s failed", this.resource), e);
|
||||
throw new VaultException(String
|
||||
.format("Kube JWT token retrieval from %s failed", this.resource), e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -177,8 +177,8 @@ public class LifecycleAwareSessionManager extends LifecycleAwareSessionManagerSu
|
||||
|
||||
try {
|
||||
dispatch(new BeforeLoginTokenRevocationEvent(token));
|
||||
restOperations.postForObject("auth/token/revoke-self", new HttpEntity<>(
|
||||
VaultHttpHeaders.from(token)), Map.class);
|
||||
restOperations.postForObject("auth/token/revoke-self",
|
||||
new HttpEntity<>(VaultHttpHeaders.from(token)), Map.class);
|
||||
dispatch(new AfterLoginTokenRevocationEvent(token));
|
||||
}
|
||||
catch (RuntimeException e) {
|
||||
@@ -251,11 +251,11 @@ public class LifecycleAwareSessionManager extends LifecycleAwareSessionManagerSu
|
||||
if (isExpired(renewed)) {
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
Duration validTtlThreshold = getRefreshTrigger().getValidTtlThreshold(
|
||||
renewed);
|
||||
logger.info(String
|
||||
.format("Token TTL (%s) exceeded validity TTL threshold (%s). Dropping token.",
|
||||
renewed.getLeaseDuration(), validTtlThreshold));
|
||||
Duration validTtlThreshold = getRefreshTrigger()
|
||||
.getValidTtlThreshold(renewed);
|
||||
logger.info(String.format(
|
||||
"Token TTL (%s) exceeded validity TTL threshold (%s). Dropping token.",
|
||||
renewed.getLeaseDuration(), validTtlThreshold));
|
||||
}
|
||||
else {
|
||||
logger.info("Token TTL exceeded validity TTL threshold. Dropping token.");
|
||||
@@ -285,8 +285,8 @@ public class LifecycleAwareSessionManager extends LifecycleAwareSessionManagerSu
|
||||
}
|
||||
}
|
||||
|
||||
return getToken().map(TokenWrapper::getToken).orElseThrow(
|
||||
() -> new IllegalStateException("Cannot obtain VaultToken"));
|
||||
return getToken().map(TokenWrapper::getToken)
|
||||
.orElseThrow(() -> new IllegalStateException("Cannot obtain VaultToken"));
|
||||
}
|
||||
|
||||
private void doGetSessionToken() {
|
||||
@@ -311,8 +311,8 @@ public class LifecycleAwareSessionManager extends LifecycleAwareSessionManagerSu
|
||||
wrapper = new TokenWrapper(token, false);
|
||||
}
|
||||
catch (VaultTokenLookupException e) {
|
||||
logger.warn(String.format(
|
||||
"Cannot enhance VaultToken to a LoginToken: %s", e.getMessage()));
|
||||
logger.warn(String.format("Cannot enhance VaultToken to a LoginToken: %s",
|
||||
e.getMessage()));
|
||||
dispatch(new AuthenticationErrorEvent(token, e));
|
||||
}
|
||||
}
|
||||
@@ -334,8 +334,7 @@ public class LifecycleAwareSessionManager extends LifecycleAwareSessionManagerSu
|
||||
*/
|
||||
protected boolean isTokenRenewable() {
|
||||
|
||||
return getToken().map(TokenWrapper::getToken)
|
||||
.filter(LoginToken.class::isInstance)
|
||||
return getToken().map(TokenWrapper::getToken).filter(LoginToken.class::isInstance)
|
||||
//
|
||||
.filter(it -> {
|
||||
|
||||
@@ -379,8 +378,8 @@ public class LifecycleAwareSessionManager extends LifecycleAwareSessionManagerSu
|
||||
|
||||
private OneShotTrigger createTrigger(TokenWrapper tokenWrapper) {
|
||||
|
||||
return new OneShotTrigger(getRefreshTrigger().nextExecutionTime(
|
||||
(LoginToken) tokenWrapper.getToken()));
|
||||
return new OneShotTrigger(getRefreshTrigger()
|
||||
.nextExecutionTime((LoginToken) tokenWrapper.getToken()));
|
||||
}
|
||||
|
||||
private static String format(String message, HttpStatusCodeException e) {
|
||||
|
||||
@@ -40,8 +40,8 @@ import org.springframework.vault.support.VaultToken;
|
||||
* @author Mark Paluch
|
||||
* @since 2.0
|
||||
*/
|
||||
public abstract class LifecycleAwareSessionManagerSupport extends
|
||||
AuthenticationEventPublisher {
|
||||
public abstract class LifecycleAwareSessionManagerSupport
|
||||
extends AuthenticationEventPublisher {
|
||||
|
||||
/**
|
||||
* Refresh 5 seconds before the token expires.
|
||||
@@ -125,7 +125,7 @@ public abstract class LifecycleAwareSessionManagerSupport extends
|
||||
* token is renewable and its TTL.
|
||||
*
|
||||
* @param tokenSelfLookupEnabled {@literal true} to enable self-lookup,
|
||||
* {@literal false} to disable self-lookup. Enabled by default.
|
||||
* {@literal false} to disable self-lookup. Enabled by default.
|
||||
*/
|
||||
public void setTokenSelfLookupEnabled(boolean tokenSelfLookupEnabled) {
|
||||
this.tokenSelfLookupEnabled = tokenSelfLookupEnabled;
|
||||
@@ -260,8 +260,8 @@ public abstract class LifecycleAwareSessionManagerSupport extends
|
||||
*
|
||||
* @param timeout timeout value.
|
||||
* @param validTtlThreshold minimum TTL duration to consider a Token as valid.
|
||||
* Tokens with a shorter TTL are not used anymore. Should be greater than
|
||||
* {@code timeout} to prevent token expiry.
|
||||
* Tokens with a shorter TTL are not used anymore. Should be greater than
|
||||
* {@code timeout} to prevent token expiry.
|
||||
* @since 2.0
|
||||
*/
|
||||
public FixedTimeoutRefreshTrigger(Duration timeout, Duration validTtlThreshold) {
|
||||
@@ -278,8 +278,8 @@ public abstract class LifecycleAwareSessionManagerSupport extends
|
||||
@Override
|
||||
public Date nextExecutionTime(LoginToken loginToken) {
|
||||
|
||||
long milliseconds = Math.max(ONE_SECOND.toMillis(), loginToken
|
||||
.getLeaseDuration().toMillis() - duration.toMillis());
|
||||
long milliseconds = Math.max(ONE_SECOND.toMillis(),
|
||||
loginToken.getLeaseDuration().toMillis() - duration.toMillis());
|
||||
|
||||
return new Date(System.currentTimeMillis() + milliseconds);
|
||||
}
|
||||
|
||||
@@ -108,7 +108,7 @@ public class LoginToken extends VaultToken {
|
||||
* @param token must not be {@literal null}.
|
||||
*
|
||||
* @param leaseDuration the lease duration, must not be negative and not be
|
||||
* {@literal null}.
|
||||
* {@literal null}.
|
||||
* @return the created {@link VaultToken}
|
||||
* @since 2.0
|
||||
*/
|
||||
|
||||
@@ -56,7 +56,8 @@ public class LoginTokenAdapter implements ClientAuthentication {
|
||||
* @param delegate must not be {@literal null}.
|
||||
* @param restOperations must not be {@literal null}.
|
||||
*/
|
||||
public LoginTokenAdapter(ClientAuthentication delegate, RestOperations restOperations) {
|
||||
public LoginTokenAdapter(ClientAuthentication delegate,
|
||||
RestOperations restOperations) {
|
||||
|
||||
Assert.notNull(delegate, "ClientAuthentication delegate must not be null");
|
||||
Assert.notNull(restOperations, "RestOperations must not be null");
|
||||
@@ -94,8 +95,8 @@ public class LoginTokenAdapter implements ClientAuthentication {
|
||||
|
||||
try {
|
||||
ResponseEntity<VaultResponse> entity = restOperations.exchange(
|
||||
"auth/token/lookup-self", HttpMethod.GET, new HttpEntity<>(
|
||||
VaultHttpHeaders.from(token)), VaultResponse.class);
|
||||
"auth/token/lookup-self", HttpMethod.GET,
|
||||
new HttpEntity<>(VaultHttpHeaders.from(token)), VaultResponse.class);
|
||||
|
||||
Assert.state(entity.getBody() != null && entity.getBody().getData() != null,
|
||||
"Token response is null");
|
||||
@@ -103,9 +104,9 @@ public class LoginTokenAdapter implements ClientAuthentication {
|
||||
return entity.getBody().getData();
|
||||
}
|
||||
catch (HttpStatusCodeException e) {
|
||||
throw new VaultTokenLookupException(String.format(
|
||||
"Token self-lookup failed: %s %s", e.getRawStatusCode(),
|
||||
VaultResponses.getError(e.getResponseBodyAsString())));
|
||||
throw new VaultTokenLookupException(
|
||||
String.format("Token self-lookup failed: %s %s", e.getRawStatusCode(),
|
||||
VaultResponses.getError(e.getResponseBodyAsString())));
|
||||
}
|
||||
catch (RestClientException e) {
|
||||
throw new VaultTokenLookupException("Token self-lookup failed", e);
|
||||
|
||||
@@ -80,9 +80,9 @@ import org.springframework.web.reactive.function.client.WebClientResponseExcepti
|
||||
* @see TaskScheduler
|
||||
* @see AuthenticationEventPublisher
|
||||
*/
|
||||
public class ReactiveLifecycleAwareSessionManager extends
|
||||
LifecycleAwareSessionManagerSupport implements ReactiveSessionManager,
|
||||
DisposableBean {
|
||||
public class ReactiveLifecycleAwareSessionManager
|
||||
extends LifecycleAwareSessionManagerSupport
|
||||
implements ReactiveSessionManager, DisposableBean {
|
||||
|
||||
private static final Mono<TokenWrapper> EMPTY = Mono.empty();
|
||||
|
||||
@@ -182,14 +182,9 @@ public class ReactiveLifecycleAwareSessionManager extends
|
||||
*/
|
||||
protected Mono<Void> revoke(VaultToken token) {
|
||||
|
||||
return webClient
|
||||
.post()
|
||||
.uri("auth/token/revoke-self")
|
||||
.headers(httpHeaders -> {
|
||||
httpHeaders.addAll(VaultHttpHeaders.from(token));
|
||||
})
|
||||
.retrieve()
|
||||
.bodyToMono(String.class)
|
||||
return webClient.post().uri("auth/token/revoke-self").headers(httpHeaders -> {
|
||||
httpHeaders.addAll(VaultHttpHeaders.from(token));
|
||||
}).retrieve().bodyToMono(String.class)
|
||||
.doOnSubscribe(
|
||||
ignore -> dispatch(new BeforeLoginTokenRevocationEvent(token)))
|
||||
.doOnNext(ignore -> dispatch(new AfterLoginTokenRevocationEvent(token)))
|
||||
@@ -237,55 +232,44 @@ public class ReactiveLifecycleAwareSessionManager extends
|
||||
|
||||
private Mono<TokenWrapper> doRenewToken(TokenWrapper wrapper) {
|
||||
|
||||
return doRenew(wrapper)
|
||||
.onErrorResume(
|
||||
WebClientResponseException.class,
|
||||
e -> {
|
||||
return doRenew(wrapper).onErrorResume(WebClientResponseException.class, e -> {
|
||||
|
||||
dropCurrentToken();
|
||||
dropCurrentToken();
|
||||
|
||||
String message = "Cannot renew token, resetting token and performing re-login on next token access";
|
||||
String message = "Cannot renew token, resetting token and performing re-login on next token access";
|
||||
|
||||
if (e.getStatusCode().is4xxClientError()) {
|
||||
if (e.getStatusCode().is4xxClientError()) {
|
||||
|
||||
logger.warn(format(message, e));
|
||||
dispatch(new LoginTokenRenewalFailedEvent(wrapper
|
||||
.getToken(), e));
|
||||
return EMPTY;
|
||||
}
|
||||
logger.warn(format(message, e));
|
||||
dispatch(new LoginTokenRenewalFailedEvent(wrapper.getToken(), e));
|
||||
return EMPTY;
|
||||
}
|
||||
|
||||
logger.debug(format(message, e));
|
||||
logger.debug(format(message, e));
|
||||
|
||||
return Mono.error(new VaultTokenRenewalException(format(
|
||||
"Cannot renew token", e), e));
|
||||
})
|
||||
.onErrorMap(
|
||||
it -> !(it instanceof VaultTokenRenewalException),
|
||||
e -> {
|
||||
return Mono.error(
|
||||
new VaultTokenRenewalException(format("Cannot renew token", e), e));
|
||||
}).onErrorMap(it -> !(it instanceof VaultTokenRenewalException), e -> {
|
||||
|
||||
dropCurrentToken();
|
||||
logger.debug(String
|
||||
.format("Cannot renew token, resetting token and performing re-login on next token access: %s",
|
||||
e.toString()));
|
||||
dropCurrentToken();
|
||||
logger.debug(String.format(
|
||||
"Cannot renew token, resetting token and performing re-login on next token access: %s",
|
||||
e.toString()));
|
||||
|
||||
return new VaultTokenRenewalException("Cannot renew token", e);
|
||||
});
|
||||
return new VaultTokenRenewalException("Cannot renew token", e);
|
||||
});
|
||||
}
|
||||
|
||||
private Mono<TokenWrapper> doRenew(TokenWrapper tokenWrapper) {
|
||||
|
||||
Mono<VaultResponse> exchange = webClient
|
||||
.post()
|
||||
.uri("auth/token/renew-self")
|
||||
.headers(
|
||||
httpHeaders -> httpHeaders.putAll(VaultHttpHeaders
|
||||
.from(tokenWrapper.token))).retrieve()
|
||||
.bodyToMono(VaultResponse.class);
|
||||
Mono<VaultResponse> exchange = webClient.post().uri("auth/token/renew-self")
|
||||
.headers(httpHeaders -> httpHeaders
|
||||
.putAll(VaultHttpHeaders.from(tokenWrapper.token)))
|
||||
.retrieve().bodyToMono(VaultResponse.class);
|
||||
|
||||
return exchange
|
||||
.doOnSubscribe(
|
||||
ignore -> dispatch(new BeforeLoginTokenRenewedEvent(tokenWrapper
|
||||
.getToken())))
|
||||
.doOnSubscribe(ignore -> dispatch(
|
||||
new BeforeLoginTokenRenewedEvent(tokenWrapper.getToken())))
|
||||
.handle((response, sink) -> {
|
||||
|
||||
LoginToken renewed = LoginTokenUtil.from(response.getRequiredAuth());
|
||||
@@ -300,12 +284,13 @@ public class ReactiveLifecycleAwareSessionManager extends
|
||||
|
||||
Duration validTtlThreshold = getRefreshTrigger()
|
||||
.getValidTtlThreshold(renewed);
|
||||
logger.info(String
|
||||
.format("Token TTL (%s) exceeded validity TTL threshold (%s). Dropping token.",
|
||||
renewed.getLeaseDuration(), validTtlThreshold));
|
||||
logger.info(String.format(
|
||||
"Token TTL (%s) exceeded validity TTL threshold (%s). Dropping token.",
|
||||
renewed.getLeaseDuration(), validTtlThreshold));
|
||||
}
|
||||
else {
|
||||
logger.info("Token TTL exceeded validity TTL threshold. Dropping token.");
|
||||
logger.info(
|
||||
"Token TTL exceeded validity TTL threshold. Dropping token.");
|
||||
}
|
||||
|
||||
dropCurrentToken();
|
||||
@@ -356,17 +341,16 @@ public class ReactiveLifecycleAwareSessionManager extends
|
||||
if (isTokenSelfLookupEnabled()
|
||||
&& !ClassUtils.isAssignableValue(LoginToken.class, token)) {
|
||||
|
||||
Mono<VaultToken> loginTokenMono = augmentWithSelfLookup(this.webClient, token);
|
||||
Mono<VaultToken> loginTokenMono = augmentWithSelfLookup(this.webClient,
|
||||
token);
|
||||
|
||||
return loginTokenMono.onErrorResume(
|
||||
e -> {
|
||||
return loginTokenMono.onErrorResume(e -> {
|
||||
|
||||
logger.warn(String.format(
|
||||
"Cannot enhance VaultToken to a LoginToken: %s",
|
||||
e.getMessage()));
|
||||
dispatch(new AuthenticationErrorEvent(token, e));
|
||||
return Mono.just(token);
|
||||
}).map(it -> new TokenWrapper(it, false));
|
||||
logger.warn(String.format("Cannot enhance VaultToken to a LoginToken: %s",
|
||||
e.getMessage()));
|
||||
dispatch(new AuthenticationErrorEvent(token, e));
|
||||
return Mono.just(token);
|
||||
}).map(it -> new TokenWrapper(it, false));
|
||||
}
|
||||
|
||||
return Mono.just(wrapper);
|
||||
@@ -377,8 +361,7 @@ public class ReactiveLifecycleAwareSessionManager extends
|
||||
*/
|
||||
protected boolean isTokenRenewable(VaultToken token) {
|
||||
|
||||
return Optional.of(token)
|
||||
.filter(LoginToken.class::isInstance)
|
||||
return Optional.of(token).filter(LoginToken.class::isInstance)
|
||||
//
|
||||
.filter(it -> {
|
||||
|
||||
@@ -421,8 +404,8 @@ public class ReactiveLifecycleAwareSessionManager extends
|
||||
|
||||
private OneShotTrigger createTrigger(VaultToken token) {
|
||||
|
||||
return new OneShotTrigger(getRefreshTrigger().nextExecutionTime(
|
||||
(LoginToken) token));
|
||||
return new OneShotTrigger(
|
||||
getRefreshTrigger().nextExecutionTime((LoginToken) token));
|
||||
}
|
||||
|
||||
private static Mono<VaultToken> augmentWithSelfLookup(WebClient webClient,
|
||||
@@ -448,23 +431,16 @@ public class ReactiveLifecycleAwareSessionManager extends
|
||||
private static Mono<Map<String, Object>> lookupSelf(WebClient webClient,
|
||||
VaultToken token) {
|
||||
|
||||
return webClient
|
||||
.get()
|
||||
.uri("auth/token/lookup-self")
|
||||
return webClient.get().uri("auth/token/lookup-self")
|
||||
.headers(httpHeaders -> httpHeaders.putAll(VaultHttpHeaders.from(token)))
|
||||
.retrieve()
|
||||
.bodyToMono(VaultResponse.class)
|
||||
.map(it -> {
|
||||
.retrieve().bodyToMono(VaultResponse.class).map(it -> {
|
||||
|
||||
Assert.state(it.getData() != null, "Token response is null");
|
||||
return it.getRequiredData();
|
||||
})
|
||||
.onErrorMap(
|
||||
WebClientResponseException.class,
|
||||
e -> {
|
||||
return new VaultTokenLookupException(format(
|
||||
"Token self-lookup", e), e);
|
||||
});
|
||||
}).onErrorMap(WebClientResponseException.class, e -> {
|
||||
return new VaultTokenLookupException(format("Token self-lookup", e),
|
||||
e);
|
||||
});
|
||||
}
|
||||
|
||||
private static String format(String message, WebClientResponseException e) {
|
||||
|
||||
@@ -30,8 +30,8 @@ import static org.springframework.vault.authentication.AuthenticationSteps.HttpR
|
||||
* @see VaultToken
|
||||
* @see <a href="https://www.vaultproject.io/docs/auth/token.html">Auth Backend: Token</a>
|
||||
*/
|
||||
public class TokenAuthentication implements ClientAuthentication,
|
||||
AuthenticationStepsFactory {
|
||||
public class TokenAuthentication
|
||||
implements ClientAuthentication, AuthenticationStepsFactory {
|
||||
|
||||
private final VaultToken token;
|
||||
|
||||
@@ -65,8 +65,8 @@ public class TokenAuthentication implements ClientAuthentication,
|
||||
*
|
||||
* @param token must not be {@literal null}.
|
||||
* @param selfLookup {@literal true} to perform a self-lookup using the given
|
||||
* {@link VaultToken}. Self-lookup will create a {@link LoginToken} and provide
|
||||
* renewability and TTL.
|
||||
* {@link VaultToken}. Self-lookup will create a {@link LoginToken} and provide
|
||||
* renewability and TTL.
|
||||
* @return {@link AuthenticationSteps} for token authentication.
|
||||
* @since 2.0
|
||||
*/
|
||||
@@ -77,11 +77,11 @@ public class TokenAuthentication implements ClientAuthentication,
|
||||
|
||||
if (selfLookup) {
|
||||
|
||||
HttpRequest<VaultResponse> httpRequest = get("auth/token/lookup-self").with(
|
||||
VaultHttpHeaders.from(token)).as(VaultResponse.class);
|
||||
HttpRequest<VaultResponse> httpRequest = get("auth/token/lookup-self")
|
||||
.with(VaultHttpHeaders.from(token)).as(VaultResponse.class);
|
||||
|
||||
return AuthenticationSteps.fromHttpRequest(httpRequest).login(
|
||||
response -> LoginTokenUtil.from(token.toCharArray(),
|
||||
return AuthenticationSteps.fromHttpRequest(httpRequest)
|
||||
.login(response -> LoginTokenUtil.from(token.toCharArray(),
|
||||
response.getRequiredData()));
|
||||
}
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ public class AfterLoginEvent extends AuthenticationEvent {
|
||||
* Create a new {@link AfterLoginEvent} given {@link VaultToken}.
|
||||
*
|
||||
* @param source the {@link VaultToken} associated with this event, must not be
|
||||
* {@literal null}.
|
||||
* {@literal null}.
|
||||
*/
|
||||
public AfterLoginEvent(VaultToken source) {
|
||||
super(source);
|
||||
|
||||
@@ -33,7 +33,7 @@ public class AfterLoginTokenRenewedEvent extends AuthenticationEvent {
|
||||
* Create a new {@link AfterLoginTokenRenewedEvent} given {@link VaultToken}.
|
||||
*
|
||||
* @param source the {@link VaultToken} associated with this event, must not be
|
||||
* {@literal null}.
|
||||
* {@literal null}.
|
||||
*/
|
||||
public AfterLoginTokenRenewedEvent(VaultToken source) {
|
||||
super(source);
|
||||
|
||||
@@ -33,7 +33,7 @@ public class AfterLoginTokenRevocationEvent extends AuthenticationEvent {
|
||||
* Create a new {@link AfterLoginTokenRevocationEvent} given {@link VaultToken}.
|
||||
*
|
||||
* @param source the {@link VaultToken} associated with this event, must not be
|
||||
* {@literal null}.
|
||||
* {@literal null}.
|
||||
*/
|
||||
public AfterLoginTokenRevocationEvent(VaultToken source) {
|
||||
super(source);
|
||||
|
||||
@@ -33,7 +33,7 @@ public abstract class AuthenticationEvent extends ApplicationEvent {
|
||||
* Create a new {@link AuthenticationEvent} given {@link VaultToken}.
|
||||
*
|
||||
* @param source the {@link VaultToken} associated with this event, must not be
|
||||
* {@literal null}.
|
||||
* {@literal null}.
|
||||
*/
|
||||
protected AuthenticationEvent(VaultToken source) {
|
||||
super(source);
|
||||
|
||||
@@ -33,7 +33,7 @@ public class BeforeLoginTokenRenewedEvent extends AuthenticationEvent {
|
||||
* Create a new {@link BeforeLoginTokenRenewedEvent} given {@link VaultToken}.
|
||||
*
|
||||
* @param source the {@link VaultToken} associated with this event, must not be
|
||||
* {@literal null}.
|
||||
* {@literal null}.
|
||||
*/
|
||||
public BeforeLoginTokenRenewedEvent(VaultToken source) {
|
||||
super(source);
|
||||
|
||||
@@ -33,7 +33,7 @@ public class BeforeLoginTokenRevocationEvent extends AuthenticationEvent {
|
||||
* Create a new {@link BeforeLoginTokenRevocationEvent} given {@link VaultToken}.
|
||||
*
|
||||
* @param source the {@link VaultToken} associated with this event, must not be
|
||||
* {@literal null}.
|
||||
* {@literal null}.
|
||||
*/
|
||||
public BeforeLoginTokenRevocationEvent(VaultToken source) {
|
||||
super(source);
|
||||
|
||||
@@ -38,7 +38,7 @@ public class LoginFailedEvent extends AuthenticationErrorEvent {
|
||||
* Create a new {@link LoginFailedEvent} given {@link Exception}.
|
||||
*
|
||||
* @param source the {@link ClientAuthentication} or {@link VaultTokenSupplier}
|
||||
* associated with this event, must not be {@literal null}.
|
||||
* associated with this event, must not be {@literal null}.
|
||||
* @param exception must not be {@literal null}.
|
||||
*/
|
||||
public LoginFailedEvent(Object source, Throwable exception) {
|
||||
|
||||
@@ -33,7 +33,7 @@ public class LoginTokenExpiredEvent extends AuthenticationEvent {
|
||||
* Create a new {@link LoginTokenExpiredEvent} given {@link VaultToken}.
|
||||
*
|
||||
* @param source the {@link VaultToken} associated with this event, must not be
|
||||
* {@literal null}.
|
||||
* {@literal null}.
|
||||
*/
|
||||
public LoginTokenExpiredEvent(VaultToken source) {
|
||||
super(source);
|
||||
|
||||
@@ -34,7 +34,7 @@ public class LoginTokenRenewalFailedEvent extends AuthenticationErrorEvent {
|
||||
* {@link Exception}.
|
||||
*
|
||||
* @param source the {@link VaultToken} associated with this event, must not be
|
||||
* {@literal null}.
|
||||
* {@literal null}.
|
||||
* @param exception must not be {@literal null}.
|
||||
*/
|
||||
public LoginTokenRenewalFailedEvent(VaultToken source, Throwable exception) {
|
||||
|
||||
@@ -34,7 +34,7 @@ public class LoginTokenRevocationFailedEvent extends AuthenticationErrorEvent {
|
||||
* {@link Exception}.
|
||||
*
|
||||
* @param source the {@link VaultToken} associated with this event, must not be
|
||||
* {@literal null}.
|
||||
* {@literal null}.
|
||||
* @param exception must not be {@literal null}.
|
||||
*/
|
||||
public LoginTokenRevocationFailedEvent(VaultToken source, Throwable exception) {
|
||||
|
||||
@@ -4,4 +4,3 @@
|
||||
@org.springframework.lang.NonNullApi
|
||||
@org.springframework.lang.NonNullFields
|
||||
package org.springframework.vault.authentication.event;
|
||||
|
||||
|
||||
@@ -51,9 +51,11 @@ import static org.springframework.vault.client.ClientHttpRequestFactoryFactory.h
|
||||
*/
|
||||
public class ClientHttpConnectorFactory {
|
||||
|
||||
private static final boolean REACTOR_NETTY_PRESENT = isPresent("reactor.netty.http.client.HttpClient");
|
||||
private static final boolean REACTOR_NETTY_PRESENT = isPresent(
|
||||
"reactor.netty.http.client.HttpClient");
|
||||
|
||||
private static final boolean JETTY_PRESENT = isPresent("org.eclipse.jetty.client.HttpClient");
|
||||
private static final boolean JETTY_PRESENT = isPresent(
|
||||
"org.eclipse.jetty.client.HttpClient");
|
||||
|
||||
/**
|
||||
* Checks for presence of all {@code classNames} using this class' classloader.
|
||||
@@ -106,8 +108,8 @@ public class ClientHttpConnectorFactory {
|
||||
try {
|
||||
|
||||
if (sslConfiguration.getTrustStoreConfiguration().isPresent()) {
|
||||
sslContextBuilder.trustManager(createTrustManagerFactory(sslConfiguration
|
||||
.getTrustStoreConfiguration()));
|
||||
sslContextBuilder.trustManager(createTrustManagerFactory(
|
||||
sslConfiguration.getTrustStoreConfiguration()));
|
||||
}
|
||||
|
||||
if (sslConfiguration.getKeyStoreConfiguration().isPresent()) {
|
||||
@@ -142,9 +144,9 @@ public class ClientHttpConnectorFactory {
|
||||
});
|
||||
}
|
||||
|
||||
client = client.tcpConfiguration(it -> it.option(
|
||||
ChannelOption.CONNECT_TIMEOUT_MILLIS,
|
||||
Math.toIntExact(options.getConnectionTimeout().toMillis())));
|
||||
client = client.tcpConfiguration(
|
||||
it -> it.option(ChannelOption.CONNECT_TIMEOUT_MILLIS,
|
||||
Math.toIntExact(options.getConnectionTimeout().toMillis())));
|
||||
|
||||
return new ReactorClientHttpConnector(client);
|
||||
}
|
||||
@@ -155,8 +157,8 @@ public class ClientHttpConnectorFactory {
|
||||
SslConfiguration sslConfiguration) {
|
||||
|
||||
try {
|
||||
return new JettyClientHttpConnector(configureClient(
|
||||
getHttpClient(sslConfiguration), options));
|
||||
return new JettyClientHttpConnector(
|
||||
configureClient(getHttpClient(sslConfiguration), options));
|
||||
}
|
||||
catch (GeneralSecurityException | IOException e) {
|
||||
throw new IllegalStateException(e);
|
||||
@@ -167,8 +169,8 @@ public class ClientHttpConnectorFactory {
|
||||
org.eclipse.jetty.client.HttpClient httpClient, ClientOptions options) {
|
||||
|
||||
httpClient.setConnectTimeout(options.getConnectionTimeout().toMillis());
|
||||
httpClient.setAddressResolutionTimeout(options.getConnectionTimeout()
|
||||
.toMillis());
|
||||
httpClient.setAddressResolutionTimeout(
|
||||
options.getConnectionTimeout().toMillis());
|
||||
|
||||
return httpClient;
|
||||
}
|
||||
@@ -201,8 +203,8 @@ public class ClientHttpConnectorFactory {
|
||||
}
|
||||
|
||||
if (keyConfiguration.getKeyPassword() != null) {
|
||||
sslContextFactory.setKeyManagerPassword(new String(keyConfiguration
|
||||
.getKeyPassword()));
|
||||
sslContextFactory.setKeyManagerPassword(
|
||||
new String(keyConfiguration.getKeyPassword()));
|
||||
}
|
||||
|
||||
return new org.eclipse.jetty.client.HttpClient(sslContextFactory);
|
||||
|
||||
@@ -83,7 +83,8 @@ public class ClientHttpRequestFactoryFactory {
|
||||
private static final Log logger = LogFactory
|
||||
.getLog(ClientHttpRequestFactoryFactory.class);
|
||||
|
||||
private static final boolean HTTP_COMPONENTS_PRESENT = isPresent("org.apache.http.client.HttpClient");
|
||||
private static final boolean HTTP_COMPONENTS_PRESENT = isPresent(
|
||||
"org.apache.http.client.HttpClient");
|
||||
|
||||
private static final boolean OKHTTP3_PRESENT = isPresent("okhttp3.OkHttpClient");
|
||||
|
||||
@@ -158,10 +159,10 @@ public class ClientHttpRequestFactoryFactory {
|
||||
TrustManager[] trustManagers) throws GeneralSecurityException, IOException {
|
||||
|
||||
KeyConfiguration keyConfiguration = sslConfiguration.getKeyConfiguration();
|
||||
KeyManager[] keyManagers = sslConfiguration.getKeyStoreConfiguration()
|
||||
.isPresent() ? createKeyManagerFactory(
|
||||
sslConfiguration.getKeyStoreConfiguration(), keyConfiguration)
|
||||
.getKeyManagers() : null;
|
||||
KeyManager[] keyManagers = sslConfiguration.getKeyStoreConfiguration().isPresent()
|
||||
? createKeyManagerFactory(sslConfiguration.getKeyStoreConfiguration(),
|
||||
keyConfiguration).getKeyManagers()
|
||||
: null;
|
||||
|
||||
SSLContext sslContext = SSLContext.getInstance("TLS");
|
||||
sslContext.init(keyManagers, trustManagers, null);
|
||||
@@ -172,13 +173,15 @@ public class ClientHttpRequestFactoryFactory {
|
||||
private static TrustManager[] getTrustManagers(SslConfiguration sslConfiguration)
|
||||
throws GeneralSecurityException, IOException {
|
||||
|
||||
return sslConfiguration.getTrustStoreConfiguration().isPresent() ? createTrustManagerFactory(
|
||||
sslConfiguration.getTrustStoreConfiguration()).getTrustManagers()
|
||||
return sslConfiguration.getTrustStoreConfiguration().isPresent()
|
||||
? createTrustManagerFactory(sslConfiguration.getTrustStoreConfiguration())
|
||||
.getTrustManagers()
|
||||
: null;
|
||||
}
|
||||
|
||||
static KeyManagerFactory createKeyManagerFactory(
|
||||
KeyStoreConfiguration keyStoreConfiguration, KeyConfiguration keyConfiguration)
|
||||
KeyStoreConfiguration keyStoreConfiguration,
|
||||
KeyConfiguration keyConfiguration)
|
||||
throws GeneralSecurityException, IOException {
|
||||
|
||||
KeyStore keyStore = getKeyStore(keyStoreConfiguration);
|
||||
@@ -189,7 +192,8 @@ public class ClientHttpRequestFactoryFactory {
|
||||
char[] keyPasswordToUse = keyConfiguration.getKeyPassword();
|
||||
|
||||
if (keyPasswordToUse == null) {
|
||||
keyPasswordToUse = keyStoreConfiguration.getStorePassword() == null ? new char[0]
|
||||
keyPasswordToUse = keyStoreConfiguration.getStorePassword() == null
|
||||
? new char[0]
|
||||
: keyStoreConfiguration.getStorePassword();
|
||||
}
|
||||
|
||||
@@ -206,17 +210,18 @@ public class ClientHttpRequestFactoryFactory {
|
||||
throws KeyStoreException, IOException, NoSuchAlgorithmException,
|
||||
CertificateException {
|
||||
|
||||
KeyStore keyStore = KeyStore.getInstance(StringUtils
|
||||
.hasText(keyStoreConfiguration.getStoreType()) ? keyStoreConfiguration
|
||||
.getStoreType() : KeyStore.getDefaultType());
|
||||
KeyStore keyStore = KeyStore
|
||||
.getInstance(StringUtils.hasText(keyStoreConfiguration.getStoreType())
|
||||
? keyStoreConfiguration.getStoreType()
|
||||
: KeyStore.getDefaultType());
|
||||
|
||||
loadKeyStore(keyStoreConfiguration, keyStore);
|
||||
return keyStore;
|
||||
}
|
||||
|
||||
static TrustManagerFactory createTrustManagerFactory(
|
||||
KeyStoreConfiguration keyStoreConfiguration) throws GeneralSecurityException,
|
||||
IOException {
|
||||
KeyStoreConfiguration keyStoreConfiguration)
|
||||
throws GeneralSecurityException, IOException {
|
||||
|
||||
KeyStore trustStore = getKeyStore(keyStoreConfiguration);
|
||||
|
||||
@@ -228,8 +233,8 @@ public class ClientHttpRequestFactoryFactory {
|
||||
}
|
||||
|
||||
private static void loadKeyStore(KeyStoreConfiguration keyStoreConfiguration,
|
||||
KeyStore keyStore) throws IOException, NoSuchAlgorithmException,
|
||||
CertificateException {
|
||||
KeyStore keyStore)
|
||||
throws IOException, NoSuchAlgorithmException, CertificateException {
|
||||
|
||||
InputStream inputStream = null;
|
||||
try {
|
||||
@@ -256,8 +261,8 @@ public class ClientHttpRequestFactoryFactory {
|
||||
static class HttpComponents {
|
||||
|
||||
static ClientHttpRequestFactory usingHttpComponents(ClientOptions options,
|
||||
SslConfiguration sslConfiguration) throws GeneralSecurityException,
|
||||
IOException {
|
||||
SslConfiguration sslConfiguration)
|
||||
throws GeneralSecurityException, IOException {
|
||||
|
||||
HttpClientBuilder httpClientBuilder = HttpClients.custom();
|
||||
|
||||
@@ -274,8 +279,7 @@ public class ClientHttpRequestFactoryFactory {
|
||||
httpClientBuilder.setSSLContext(sslContext);
|
||||
}
|
||||
|
||||
RequestConfig requestConfig = RequestConfig
|
||||
.custom()
|
||||
RequestConfig requestConfig = RequestConfig.custom()
|
||||
//
|
||||
.setConnectTimeout(
|
||||
Math.toIntExact(options.getConnectionTimeout().toMillis())) //
|
||||
@@ -301,8 +305,8 @@ public class ClientHttpRequestFactoryFactory {
|
||||
static class OkHttp3 {
|
||||
|
||||
static ClientHttpRequestFactory usingOkHttp3(ClientOptions options,
|
||||
SslConfiguration sslConfiguration) throws GeneralSecurityException,
|
||||
IOException {
|
||||
SslConfiguration sslConfiguration)
|
||||
throws GeneralSecurityException, IOException {
|
||||
|
||||
Builder builder = new Builder();
|
||||
|
||||
@@ -324,7 +328,7 @@ public class ClientHttpRequestFactoryFactory {
|
||||
|
||||
builder.connectTimeout(options.getConnectionTimeout().toMillis(),
|
||||
TimeUnit.MILLISECONDS).readTimeout(
|
||||
options.getReadTimeout().toMillis(), TimeUnit.MILLISECONDS);
|
||||
options.getReadTimeout().toMillis(), TimeUnit.MILLISECONDS);
|
||||
|
||||
return new OkHttp3ClientHttpRequestFactory(builder.build());
|
||||
}
|
||||
@@ -338,8 +342,8 @@ public class ClientHttpRequestFactoryFactory {
|
||||
static class Netty {
|
||||
|
||||
static ClientHttpRequestFactory usingNetty(ClientOptions options,
|
||||
SslConfiguration sslConfiguration) throws GeneralSecurityException,
|
||||
IOException {
|
||||
SslConfiguration sslConfiguration)
|
||||
throws GeneralSecurityException, IOException {
|
||||
|
||||
Netty4ClientHttpRequestFactory requestFactory = new Netty4ClientHttpRequestFactory();
|
||||
|
||||
@@ -349,9 +353,8 @@ public class ClientHttpRequestFactoryFactory {
|
||||
.forClient();
|
||||
|
||||
if (sslConfiguration.getTrustStoreConfiguration().isPresent()) {
|
||||
sslContextBuilder
|
||||
.trustManager(createTrustManagerFactory(sslConfiguration
|
||||
.getTrustStoreConfiguration()));
|
||||
sslContextBuilder.trustManager(createTrustManagerFactory(
|
||||
sslConfiguration.getTrustStoreConfiguration()));
|
||||
}
|
||||
|
||||
if (sslConfiguration.getKeyStoreConfiguration().isPresent()) {
|
||||
@@ -360,14 +363,14 @@ public class ClientHttpRequestFactoryFactory {
|
||||
sslConfiguration.getKeyConfiguration()));
|
||||
}
|
||||
|
||||
requestFactory.setSslContext(sslContextBuilder.sslProvider(
|
||||
SslProvider.JDK).build());
|
||||
requestFactory.setSslContext(
|
||||
sslContextBuilder.sslProvider(SslProvider.JDK).build());
|
||||
}
|
||||
|
||||
requestFactory.setConnectTimeout(Math.toIntExact(options
|
||||
.getConnectionTimeout().toMillis()));
|
||||
requestFactory.setReadTimeout(Math.toIntExact(options.getReadTimeout()
|
||||
.toMillis()));
|
||||
requestFactory.setConnectTimeout(
|
||||
Math.toIntExact(options.getConnectionTimeout().toMillis()));
|
||||
requestFactory
|
||||
.setReadTimeout(Math.toIntExact(options.getReadTimeout().toMillis()));
|
||||
|
||||
return requestFactory;
|
||||
}
|
||||
@@ -401,7 +404,8 @@ public class ClientHttpRequestFactoryFactory {
|
||||
&& keyManagers[0] instanceof X509ExtendedKeyManager) {
|
||||
|
||||
return new KeyManager[] { new KeySelectingX509KeyManager(
|
||||
(X509ExtendedKeyManager) keyManagers[0], keyConfiguration) };
|
||||
(X509ExtendedKeyManager) keyManagers[0],
|
||||
keyConfiguration) };
|
||||
}
|
||||
|
||||
return keyManagers;
|
||||
@@ -443,7 +447,8 @@ public class ClientHttpRequestFactoryFactory {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String chooseServerAlias(String keyType, Principal[] issuers, Socket socket) {
|
||||
public String chooseServerAlias(String keyType, Principal[] issuers,
|
||||
Socket socket) {
|
||||
return delegate.chooseServerAlias(keyType, issuers, socket);
|
||||
}
|
||||
|
||||
|
||||
@@ -234,14 +234,14 @@ public class RestTemplateBuilder {
|
||||
|
||||
ClientHttpRequestFactory requestFactory = this.requestFactory.get();
|
||||
RestTemplateBuilderClientHttpRequestFactoryWrapper wrapper = new RestTemplateBuilderClientHttpRequestFactoryWrapper(
|
||||
requestFactory, new LinkedHashMap<>(defaultHeaders), new LinkedHashSet<>(
|
||||
requestCustomizers));
|
||||
requestFactory, new LinkedHashMap<>(defaultHeaders),
|
||||
new LinkedHashSet<>(requestCustomizers));
|
||||
|
||||
return VaultClients.createRestTemplate(endpointProvider, wrapper);
|
||||
}
|
||||
|
||||
static class RestTemplateBuilderClientHttpRequestFactoryWrapper extends
|
||||
AbstractClientHttpRequestFactoryWrapper {
|
||||
static class RestTemplateBuilderClientHttpRequestFactoryWrapper
|
||||
extends AbstractClientHttpRequestFactoryWrapper {
|
||||
|
||||
private final Map<String, String> defaultHeaders;
|
||||
|
||||
|
||||
@@ -124,8 +124,8 @@ public class VaultClients {
|
||||
|
||||
RestTemplate restTemplate = new RestTemplate(messageConverters);
|
||||
|
||||
restTemplate.getInterceptors().add(
|
||||
(request, body, execution) -> execution.execute(request, body));
|
||||
restTemplate.getInterceptors()
|
||||
.add((request, body, execution) -> execution.execute(request, body));
|
||||
|
||||
return restTemplate;
|
||||
}
|
||||
@@ -140,7 +140,8 @@ public class VaultClients {
|
||||
* @see VaultHttpHeaders#VAULT_NAMESPACE
|
||||
* @since 2.2
|
||||
*/
|
||||
public static ClientHttpRequestInterceptor createNamespaceInterceptor(String namespace) {
|
||||
public static ClientHttpRequestInterceptor createNamespaceInterceptor(
|
||||
String namespace) {
|
||||
|
||||
Assert.hasText(namespace, "Vault Namespace must not be empty!");
|
||||
|
||||
@@ -220,11 +221,11 @@ public class VaultClients {
|
||||
VaultEndpoint endpoint = endpointProvider.getVaultEndpoint();
|
||||
|
||||
String baseUri = toBaseUri(endpoint);
|
||||
UriComponents uriComponents = UriComponentsBuilder.fromUriString(
|
||||
prepareUriTemplate(baseUri, uriTemplate)).build();
|
||||
UriComponents uriComponents = UriComponentsBuilder
|
||||
.fromUriString(prepareUriTemplate(baseUri, uriTemplate)).build();
|
||||
|
||||
return UriComponentsBuilder.fromUriString(baseUri).uriComponents(
|
||||
uriComponents);
|
||||
return UriComponentsBuilder.fromUriString(baseUri)
|
||||
.uriComponents(uriComponents);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -80,7 +80,7 @@ public class VaultEndpoint implements Serializable {
|
||||
* Create a {@link VaultEndpoint} given a {@link URI}.
|
||||
*
|
||||
* @param uri must contain hostname, port and scheme, must not be empty or
|
||||
* {@literal null}.
|
||||
* {@literal null}.
|
||||
* @return a new {@link VaultEndpoint}.
|
||||
*/
|
||||
public static VaultEndpoint from(URI uri) {
|
||||
@@ -93,12 +93,12 @@ public class VaultEndpoint implements Serializable {
|
||||
|
||||
vaultEndpoint.setHost(uri.getHost());
|
||||
try {
|
||||
vaultEndpoint.setPort(uri.getPort() == -1 ? uri.toURL().getDefaultPort()
|
||||
: uri.getPort());
|
||||
vaultEndpoint.setPort(
|
||||
uri.getPort() == -1 ? uri.toURL().getDefaultPort() : uri.getPort());
|
||||
}
|
||||
catch (MalformedURLException e) {
|
||||
throw new IllegalArgumentException(String.format(
|
||||
"Can't retrieve default port from %s", uri), e);
|
||||
throw new IllegalArgumentException(
|
||||
String.format("Can't retrieve default port from %s", uri), e);
|
||||
}
|
||||
vaultEndpoint.setScheme(uri.getScheme());
|
||||
|
||||
@@ -180,7 +180,7 @@ public class VaultEndpoint implements Serializable {
|
||||
|
||||
/**
|
||||
* @param path context path prefix. Must not be {@literal null} or empty and must not
|
||||
* start with a leading slash.
|
||||
* start with a leading slash.
|
||||
* @since 2.1
|
||||
*/
|
||||
public void setPath(String path) {
|
||||
|
||||
@@ -64,8 +64,9 @@ public abstract class VaultResponses {
|
||||
e.getRawStatusCode(), e.getStatusText(), message), e);
|
||||
}
|
||||
|
||||
return new VaultException(String.format("Status %s %s", e.getRawStatusCode(),
|
||||
e.getStatusText()), e);
|
||||
return new VaultException(
|
||||
String.format("Status %s %s", e.getRawStatusCode(), e.getStatusText()),
|
||||
e);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -86,17 +87,16 @@ public abstract class VaultResponses {
|
||||
e.getRawStatusCode(), e.getStatusText(), path, message), e);
|
||||
}
|
||||
|
||||
return new VaultException(String.format("Status %s %s [%s]",
|
||||
e.getRawStatusCode(), e.getStatusText(), path), e);
|
||||
return new VaultException(String.format("Status %s %s [%s]", e.getRawStatusCode(),
|
||||
e.getStatusText(), path), e);
|
||||
}
|
||||
|
||||
public static VaultException buildException(HttpStatus statusCode, String path,
|
||||
String message) {
|
||||
|
||||
if (StringUtils.hasText(message)) {
|
||||
return new VaultException(String.format("Status %s [%s]: %s", statusCode,
|
||||
path,
|
||||
message));
|
||||
return new VaultException(
|
||||
String.format("Status %s [%s]: %s", statusCode, path, message));
|
||||
}
|
||||
|
||||
return new VaultException(String.format("Status %s [%s]", statusCode, path));
|
||||
|
||||
@@ -61,8 +61,8 @@ import org.springframework.web.reactive.function.client.WebClient;
|
||||
* @since 2.0
|
||||
*/
|
||||
@Configuration
|
||||
public abstract class AbstractReactiveVaultConfiguration extends
|
||||
AbstractVaultConfiguration {
|
||||
public abstract class AbstractReactiveVaultConfiguration
|
||||
extends AbstractVaultConfiguration {
|
||||
|
||||
/**
|
||||
* Create a {@link WebClientBuilder} initialized with {@link VaultEndpointProvider}
|
||||
@@ -89,8 +89,9 @@ public abstract class AbstractReactiveVaultConfiguration extends
|
||||
*/
|
||||
@Bean
|
||||
public ReactiveVaultTemplate reactiveVaultTemplate() {
|
||||
return new ReactiveVaultTemplate(webClientBuilder(vaultEndpointProvider(),
|
||||
clientHttpConnector()), reactiveSessionManager());
|
||||
return new ReactiveVaultTemplate(
|
||||
webClientBuilder(vaultEndpointProvider(), clientHttpConnector()),
|
||||
reactiveSessionManager());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -154,11 +155,10 @@ public abstract class AbstractReactiveVaultConfiguration extends
|
||||
return CachingVaultTokenSupplier.of(stepsOperator);
|
||||
}
|
||||
|
||||
throw new IllegalStateException(
|
||||
String.format(
|
||||
"Cannot construct VaultTokenSupplier from %s. "
|
||||
+ "ClientAuthentication must implement AuthenticationStepsFactory or be TokenAuthentication",
|
||||
clientAuthentication));
|
||||
throw new IllegalStateException(String.format(
|
||||
"Cannot construct VaultTokenSupplier from %s. "
|
||||
+ "ClientAuthentication must implement AuthenticationStepsFactory or be TokenAuthentication",
|
||||
clientAuthentication));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -103,8 +103,9 @@ public abstract class AbstractVaultConfiguration implements ApplicationContextAw
|
||||
*/
|
||||
@Bean
|
||||
public VaultTemplate vaultTemplate() {
|
||||
return new VaultTemplate(restTemplateBuilder(vaultEndpointProvider(),
|
||||
clientHttpRequestFactoryWrapper().getClientHttpRequestFactory()),
|
||||
return new VaultTemplate(
|
||||
restTemplateBuilder(vaultEndpointProvider(),
|
||||
clientHttpRequestFactoryWrapper().getClientHttpRequestFactory()),
|
||||
sessionManager());
|
||||
}
|
||||
|
||||
@@ -201,8 +202,8 @@ public abstract class AbstractVaultConfiguration implements ApplicationContextAw
|
||||
*/
|
||||
@Bean
|
||||
public ClientFactoryWrapper clientHttpRequestFactoryWrapper() {
|
||||
return new ClientFactoryWrapper(ClientHttpRequestFactoryFactory.create(
|
||||
clientOptions(), sslConfiguration()));
|
||||
return new ClientFactoryWrapper(ClientHttpRequestFactoryFactory
|
||||
.create(clientOptions(), sslConfiguration()));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -43,7 +43,7 @@ public class ClientHttpConnectorFactory {
|
||||
*/
|
||||
public static ClientHttpConnector create(ClientOptions options,
|
||||
SslConfiguration sslConfiguration) {
|
||||
return org.springframework.vault.client.ClientHttpConnectorFactory.create(
|
||||
options, sslConfiguration);
|
||||
return org.springframework.vault.client.ClientHttpConnectorFactory.create(options,
|
||||
sslConfiguration);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ public class ClientHttpRequestFactoryFactory {
|
||||
*/
|
||||
public static ClientHttpRequestFactory create(ClientOptions options,
|
||||
SslConfiguration sslConfiguration) {
|
||||
return org.springframework.vault.client.ClientHttpRequestFactoryFactory.create(
|
||||
options, sslConfiguration);
|
||||
return org.springframework.vault.client.ClientHttpRequestFactoryFactory
|
||||
.create(options, sslConfiguration);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,8 +30,11 @@ import org.springframework.vault.authentication.AppIdAuthenticationOptions;
|
||||
import org.springframework.vault.authentication.AppIdUserIdMechanism;
|
||||
import org.springframework.vault.authentication.AppRoleAuthentication;
|
||||
import org.springframework.vault.authentication.AppRoleAuthenticationOptions;
|
||||
import org.springframework.vault.authentication.AppRoleAuthenticationOptions.RoleId;
|
||||
import org.springframework.vault.authentication.AppRoleAuthenticationOptions.SecretId;
|
||||
import org.springframework.vault.authentication.AwsEc2Authentication;
|
||||
import org.springframework.vault.authentication.AwsEc2AuthenticationOptions;
|
||||
import org.springframework.vault.authentication.AwsEc2AuthenticationOptions.AwsEc2AuthenticationOptionsBuilder;
|
||||
import org.springframework.vault.authentication.AzureMsiAuthentication;
|
||||
import org.springframework.vault.authentication.AzureMsiAuthenticationOptions;
|
||||
import org.springframework.vault.authentication.ClientAuthentication;
|
||||
@@ -46,13 +49,10 @@ import org.springframework.vault.authentication.KubernetesServiceAccountTokenFil
|
||||
import org.springframework.vault.authentication.MacAddressUserId;
|
||||
import org.springframework.vault.authentication.StaticUserId;
|
||||
import org.springframework.vault.authentication.TokenAuthentication;
|
||||
import org.springframework.vault.authentication.AppRoleAuthenticationOptions.RoleId;
|
||||
import org.springframework.vault.authentication.AppRoleAuthenticationOptions.SecretId;
|
||||
import org.springframework.vault.authentication.AwsEc2AuthenticationOptions.AwsEc2AuthenticationOptionsBuilder;
|
||||
import org.springframework.vault.client.VaultEndpoint;
|
||||
import org.springframework.vault.support.SslConfiguration;
|
||||
import org.springframework.vault.support.VaultToken;
|
||||
import org.springframework.vault.support.SslConfiguration.KeyStoreConfiguration;
|
||||
import org.springframework.vault.support.VaultToken;
|
||||
import org.springframework.web.client.RestOperations;
|
||||
|
||||
/**
|
||||
@@ -149,8 +149,8 @@ import org.springframework.web.client.RestOperations;
|
||||
* @see KubernetesAuthentication
|
||||
*/
|
||||
@Configuration
|
||||
public class EnvironmentVaultConfiguration extends AbstractVaultConfiguration implements
|
||||
ApplicationContextAware {
|
||||
public class EnvironmentVaultConfiguration extends AbstractVaultConfiguration
|
||||
implements ApplicationContextAware {
|
||||
|
||||
private @Nullable RestOperations cachedRestOperations;
|
||||
private @Nullable ApplicationContext applicationContext;
|
||||
@@ -317,8 +317,8 @@ public class EnvironmentVaultConfiguration extends AbstractVaultConfiguration im
|
||||
Assert.hasText(roleId,
|
||||
"Vault AWS EC2 authentication: RoleId (vault.aws-ec2.role-id) must not be empty");
|
||||
|
||||
AwsEc2AuthenticationOptionsBuilder builder = AwsEc2AuthenticationOptions
|
||||
.builder().role(roleId);
|
||||
AwsEc2AuthenticationOptionsBuilder builder = AwsEc2AuthenticationOptions.builder()
|
||||
.role(roleId);
|
||||
|
||||
if (StringUtils.hasText(identityDocument)) {
|
||||
builder.identityDocumentUri(URI.create(identityDocument));
|
||||
|
||||
@@ -4,4 +4,3 @@
|
||||
@org.springframework.lang.NonNullApi
|
||||
@org.springframework.lang.NonNullFields
|
||||
package org.springframework.vault.config;
|
||||
|
||||
|
||||
@@ -110,13 +110,13 @@ public interface ReactiveVaultOperations {
|
||||
* @param clientCallback the request.
|
||||
* @return the {@link RestOperationsCallback} return value.
|
||||
* @throws VaultException when a
|
||||
* {@link org.springframework.web.client.HttpStatusCodeException} occurs.
|
||||
* {@link org.springframework.web.client.HttpStatusCodeException} occurs.
|
||||
* @throws WebClientException exceptions from
|
||||
* {@link org.springframework.web.reactive.function.client.WebClient}.
|
||||
* {@link org.springframework.web.reactive.function.client.WebClient}.
|
||||
*/
|
||||
<V, T extends Publisher<V>> T doWithVault(
|
||||
Function<WebClient, ? extends T> clientCallback) throws VaultException,
|
||||
WebClientException;
|
||||
Function<WebClient, ? extends T> clientCallback)
|
||||
throws VaultException, WebClientException;
|
||||
|
||||
/**
|
||||
* Executes a Vault {@link RestOperationsCallback}. Allows to interact with Vault in
|
||||
@@ -125,11 +125,11 @@ public interface ReactiveVaultOperations {
|
||||
* @param sessionCallback the request.
|
||||
* @return the {@link RestOperationsCallback} return value.
|
||||
* @throws VaultException when a
|
||||
* {@link org.springframework.web.client.HttpStatusCodeException} occurs.
|
||||
* {@link org.springframework.web.client.HttpStatusCodeException} occurs.
|
||||
* @throws WebClientException exceptions from
|
||||
* {@link org.springframework.web.reactive.function.client.WebClient}.
|
||||
* {@link org.springframework.web.reactive.function.client.WebClient}.
|
||||
*/
|
||||
<V, T extends Publisher<V>> T doWithSession(
|
||||
Function<WebClient, ? extends T> sessionCallback) throws VaultException,
|
||||
WebClientException;
|
||||
Function<WebClient, ? extends T> sessionCallback)
|
||||
throws VaultException, WebClientException;
|
||||
}
|
||||
|
||||
@@ -45,8 +45,8 @@ import org.springframework.web.reactive.function.client.ClientRequest;
|
||||
import org.springframework.web.reactive.function.client.ClientResponse;
|
||||
import org.springframework.web.reactive.function.client.ExchangeFilterFunction;
|
||||
import org.springframework.web.reactive.function.client.WebClient;
|
||||
import org.springframework.web.reactive.function.client.WebClientException;
|
||||
import org.springframework.web.reactive.function.client.WebClient.RequestBodySpec;
|
||||
import org.springframework.web.reactive.function.client.WebClientException;
|
||||
|
||||
import static org.springframework.web.reactive.function.client.ExchangeFilterFunction.ofRequestProcessor;
|
||||
|
||||
@@ -76,7 +76,8 @@ public class ReactiveVaultTemplate implements ReactiveVaultOperations {
|
||||
*/
|
||||
public ReactiveVaultTemplate(VaultEndpoint vaultEndpoint,
|
||||
ClientHttpConnector connector, VaultTokenSupplier vaultTokenSupplier) {
|
||||
this(SimpleVaultEndpointProvider.of(vaultEndpoint), connector, vaultTokenSupplier);
|
||||
this(SimpleVaultEndpointProvider.of(vaultEndpoint), connector,
|
||||
vaultTokenSupplier);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -168,8 +169,8 @@ public class ReactiveVaultTemplate implements ReactiveVaultOperations {
|
||||
|
||||
private ExchangeFilterFunction getSessionFilter() {
|
||||
|
||||
return ofRequestProcessor(request -> vaultTokenSupplier.getVaultToken().map(
|
||||
token -> {
|
||||
return ofRequestProcessor(
|
||||
request -> vaultTokenSupplier.getVaultToken().map(token -> {
|
||||
|
||||
return ClientRequest.from(request).headers(headers -> {
|
||||
headers.set(VaultHttpHeaders.VAULT_TOKEN, token.getToken());
|
||||
@@ -208,8 +209,8 @@ public class ReactiveVaultTemplate implements ReactiveVaultOperations {
|
||||
.filter(response -> response.getData() != null
|
||||
&& response.getData().containsKey("keys"))
|
||||
//
|
||||
.flatMapIterable(
|
||||
response -> (List<String>) response.getRequiredData().get("keys"));
|
||||
.flatMapIterable(response -> (List<String>) response.getRequiredData()
|
||||
.get("keys"));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -239,8 +240,8 @@ public class ReactiveVaultTemplate implements ReactiveVaultOperations {
|
||||
|
||||
@Override
|
||||
public <V, T extends Publisher<V>> T doWithVault(
|
||||
Function<WebClient, ? extends T> clientCallback) throws VaultException,
|
||||
WebClientException {
|
||||
Function<WebClient, ? extends T> clientCallback)
|
||||
throws VaultException, WebClientException {
|
||||
|
||||
Assert.notNull(clientCallback, "Client callback must not be null");
|
||||
|
||||
@@ -254,8 +255,8 @@ public class ReactiveVaultTemplate implements ReactiveVaultOperations {
|
||||
|
||||
@Override
|
||||
public <V, T extends Publisher<V>> T doWithSession(
|
||||
Function<WebClient, ? extends T> sessionCallback) throws VaultException,
|
||||
WebClientException {
|
||||
Function<WebClient, ? extends T> sessionCallback)
|
||||
throws VaultException, WebClientException {
|
||||
|
||||
Assert.notNull(sessionCallback, "Session callback must not be null");
|
||||
|
||||
@@ -282,31 +283,32 @@ public class ReactiveVaultTemplate implements ReactiveVaultOperations {
|
||||
private static <T> Function<ClientResponse, Mono<? extends T>> mapResponse(
|
||||
ParameterizedTypeReference<T> typeReference, String path) {
|
||||
|
||||
return response -> isSuccess(response) ? response.body(BodyExtractors
|
||||
.toMono(typeReference)) : mapOtherwise(response, path);
|
||||
return response -> isSuccess(response)
|
||||
? response.body(BodyExtractors.toMono(typeReference))
|
||||
: mapOtherwise(response, path);
|
||||
}
|
||||
|
||||
private static boolean isSuccess(ClientResponse response) {
|
||||
return response.statusCode().is2xxSuccessful();
|
||||
}
|
||||
|
||||
private static <T> Mono<? extends T> mapOtherwise(ClientResponse response, String path) {
|
||||
private static <T> Mono<? extends T> mapOtherwise(ClientResponse response,
|
||||
String path) {
|
||||
|
||||
if (response.statusCode() == HttpStatus.NOT_FOUND) {
|
||||
return Mono.empty();
|
||||
}
|
||||
|
||||
return response.bodyToMono(String.class).flatMap(
|
||||
body -> {
|
||||
return response.bodyToMono(String.class).flatMap(body -> {
|
||||
|
||||
String error = VaultResponses.getError(body);
|
||||
String error = VaultResponses.getError(body);
|
||||
|
||||
return Mono.error(VaultResponses.buildException(
|
||||
response.statusCode(), path, error));
|
||||
});
|
||||
return Mono.error(
|
||||
VaultResponses.buildException(response.statusCode(), path, error));
|
||||
});
|
||||
}
|
||||
|
||||
private static class VaultListResponse extends
|
||||
VaultResponseSupport<Map<String, Object>> {
|
||||
private static class VaultListResponse
|
||||
extends VaultResponseSupport<Map<String, Object>> {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,8 +33,8 @@ import org.springframework.vault.support.VaultResponseSupport;
|
||||
* @since 2.1
|
||||
* @see KeyValueBackend#KV_1
|
||||
*/
|
||||
class VaultKeyValue1Template extends VaultKeyValueAccessor implements
|
||||
VaultKeyValueOperations {
|
||||
class VaultKeyValue1Template extends VaultKeyValueAccessor
|
||||
implements VaultKeyValueOperations {
|
||||
|
||||
private final VaultOperations vaultOperations;
|
||||
private final String path;
|
||||
|
||||
@@ -54,13 +54,14 @@ abstract class VaultKeyValue2Accessor extends VaultKeyValueAccessor {
|
||||
@SuppressWarnings("unchecked")
|
||||
public List<String> list(String path) {
|
||||
|
||||
String pathToUse = path.equals("/") ? "" : path.endsWith("/") ? path
|
||||
: (path + "/");
|
||||
String pathToUse = path.equals("/") ? ""
|
||||
: path.endsWith("/") ? path : (path + "/");
|
||||
|
||||
VaultListResponse read = doRead(restOperations -> {
|
||||
return restOperations.exchange(String.format("%s?list=true",
|
||||
createBackendPath("metadata", pathToUse)), HttpMethod.GET, null,
|
||||
VaultListResponse.class);
|
||||
return restOperations.exchange(
|
||||
String.format("%s?list=true",
|
||||
createBackendPath("metadata", pathToUse)),
|
||||
HttpMethod.GET, null, VaultListResponse.class);
|
||||
});
|
||||
|
||||
if (read == null) {
|
||||
|
||||
@@ -30,8 +30,8 @@ import org.springframework.vault.support.VaultResponseSupport;
|
||||
* @author Mark Paluch
|
||||
* @since 2.1
|
||||
*/
|
||||
class VaultKeyValue2Template extends VaultKeyValue2Accessor implements
|
||||
VaultKeyValueOperations {
|
||||
class VaultKeyValue2Template extends VaultKeyValue2Accessor
|
||||
implements VaultKeyValueOperations {
|
||||
|
||||
/**
|
||||
* Create a new {@link VaultKeyValue2Template} given {@link VaultOperations} and the
|
||||
|
||||
@@ -80,8 +80,7 @@ abstract class VaultKeyValueAccessor implements VaultKeyValueOperationsSupport {
|
||||
Assert.hasText(path, "Path must not be empty");
|
||||
|
||||
vaultOperations.doWithSession((restOperations -> {
|
||||
restOperations.exchange(createDataPath(path), HttpMethod.DELETE,
|
||||
null,
|
||||
restOperations.exchange(createDataPath(path), HttpMethod.DELETE, null,
|
||||
Void.class);
|
||||
|
||||
return null;
|
||||
@@ -95,7 +94,7 @@ abstract class VaultKeyValueAccessor implements VaultKeyValueOperationsSupport {
|
||||
* @param path must not be {@literal null}.
|
||||
* @param deserializeAs must not be {@literal null}.
|
||||
* @param mappingFunction Mapping function to convert from the intermediate to the
|
||||
* target data type. Must not be {@literal null}.
|
||||
* target data type. Must not be {@literal null}.
|
||||
* @param <I> intermediate data type for {@literal data} deserialization.
|
||||
* @param <T> return type. Value is created by the {@code mappingFunction}.
|
||||
* @return mapped value.
|
||||
@@ -166,8 +165,7 @@ abstract class VaultKeyValueAccessor implements VaultKeyValueOperationsSupport {
|
||||
return vaultOperations.doWithSession((restOperations) -> {
|
||||
|
||||
try {
|
||||
return callback.apply(restOperations)
|
||||
.getBody();
|
||||
return callback.apply(restOperations).getBody();
|
||||
}
|
||||
catch (HttpStatusCodeException e) {
|
||||
|
||||
@@ -196,8 +194,7 @@ abstract class VaultKeyValueAccessor implements VaultKeyValueOperationsSupport {
|
||||
|
||||
return vaultOperations.doWithSession((restOperations) -> {
|
||||
return restOperations.exchange(path, HttpMethod.POST,
|
||||
new HttpEntity<>(body), VaultResponse.class)
|
||||
.getBody();
|
||||
new HttpEntity<>(body), VaultResponse.class).getBody();
|
||||
});
|
||||
}
|
||||
catch (HttpStatusCodeException e) {
|
||||
@@ -221,26 +218,24 @@ abstract class VaultKeyValueAccessor implements VaultKeyValueOperationsSupport {
|
||||
|
||||
private static ObjectMapper extractObjectMapper(VaultOperations vaultOperations) {
|
||||
|
||||
Optional<ObjectMapper> mapper = vaultOperations
|
||||
.doWithSession(operations -> {
|
||||
Optional<ObjectMapper> mapper = vaultOperations.doWithSession(operations -> {
|
||||
|
||||
if (operations instanceof RestTemplate) {
|
||||
if (operations instanceof RestTemplate) {
|
||||
|
||||
RestTemplate template = (RestTemplate) operations;
|
||||
RestTemplate template = (RestTemplate) operations;
|
||||
|
||||
Optional<AbstractJackson2HttpMessageConverter> jackson2Converter = template
|
||||
.getMessageConverters()
|
||||
.stream()
|
||||
.filter(AbstractJackson2HttpMessageConverter.class::isInstance) //
|
||||
.map(AbstractJackson2HttpMessageConverter.class::cast) //
|
||||
.findFirst();
|
||||
Optional<AbstractJackson2HttpMessageConverter> jackson2Converter = template
|
||||
.getMessageConverters().stream()
|
||||
.filter(AbstractJackson2HttpMessageConverter.class::isInstance) //
|
||||
.map(AbstractJackson2HttpMessageConverter.class::cast) //
|
||||
.findFirst();
|
||||
|
||||
return jackson2Converter
|
||||
.map(AbstractJackson2HttpMessageConverter::getObjectMapper);
|
||||
}
|
||||
return jackson2Converter
|
||||
.map(AbstractJackson2HttpMessageConverter::getObjectMapper);
|
||||
}
|
||||
|
||||
return Optional.empty();
|
||||
});
|
||||
return Optional.empty();
|
||||
});
|
||||
|
||||
return mapper.orElseGet(ObjectMapper::new);
|
||||
}
|
||||
|
||||
@@ -176,13 +176,13 @@ public interface VaultOperations {
|
||||
* @param clientCallback the request.
|
||||
* @return the {@link RestOperationsCallback} return value.
|
||||
* @throws VaultException when a
|
||||
* {@link org.springframework.web.client.HttpStatusCodeException} occurs.
|
||||
* {@link org.springframework.web.client.HttpStatusCodeException} occurs.
|
||||
* @throws RestClientException exceptions from
|
||||
* {@link org.springframework.web.client.RestOperations}.
|
||||
* {@link org.springframework.web.client.RestOperations}.
|
||||
*/
|
||||
@Nullable
|
||||
<T> T doWithVault(RestOperationsCallback<T> clientCallback) throws VaultException,
|
||||
RestClientException;
|
||||
<T> T doWithVault(RestOperationsCallback<T> clientCallback)
|
||||
throws VaultException, RestClientException;
|
||||
|
||||
/**
|
||||
* Executes a Vault {@link RestOperationsCallback}. Allows to interact with Vault in
|
||||
@@ -191,12 +191,12 @@ public interface VaultOperations {
|
||||
* @param sessionCallback the request.
|
||||
* @return the {@link RestOperationsCallback} return value.
|
||||
* @throws VaultException when a
|
||||
* {@link org.springframework.web.client.HttpStatusCodeException} occurs.
|
||||
* {@link org.springframework.web.client.HttpStatusCodeException} occurs.
|
||||
* @throws RestClientException exceptions from
|
||||
* {@link org.springframework.web.client.RestOperations}.
|
||||
* {@link org.springframework.web.client.RestOperations}.
|
||||
*/
|
||||
@Nullable
|
||||
<T> T doWithSession(RestOperationsCallback<T> sessionCallback) throws VaultException,
|
||||
RestClientException;
|
||||
<T> T doWithSession(RestOperationsCallback<T> sessionCallback)
|
||||
throws VaultException, RestClientException;
|
||||
|
||||
}
|
||||
|
||||
@@ -49,8 +49,8 @@ public interface VaultPkiOperations {
|
||||
* @param certificateRequest must not be {@literal null}.
|
||||
* @return the {@link VaultCertificateResponse} containing a {@link CertificateBundle}
|
||||
* .
|
||||
* @see <a
|
||||
* href="https://www.vaultproject.io/docs/secrets/pki/index.html#pki-issue">POST
|
||||
* @see <a href=
|
||||
* "https://www.vaultproject.io/docs/secrets/pki/index.html#pki-issue">POST
|
||||
* /pki/issue/[role name]</a>
|
||||
*/
|
||||
VaultCertificateResponse issueCertificate(String roleName,
|
||||
@@ -68,8 +68,8 @@ public interface VaultPkiOperations {
|
||||
* @return the {@link VaultCertificateResponse} containing a
|
||||
* {@link org.springframework.vault.support.Certificate} .
|
||||
* @since 2.0
|
||||
* @see <a
|
||||
* href="https://www.vaultproject.io/docs/secrets/pki/index.html#pki-issue">POST
|
||||
* @see <a href=
|
||||
* "https://www.vaultproject.io/docs/secrets/pki/index.html#pki-issue">POST
|
||||
* /pki/sign/[role name]</a>
|
||||
*/
|
||||
VaultSignCertificateRequestResponse signCertificateRequest(String roleName,
|
||||
@@ -82,8 +82,8 @@ public interface VaultPkiOperations {
|
||||
*
|
||||
* @param serialNumber must not be empty or {@literal null}.
|
||||
* @since 2.0
|
||||
* @see <a
|
||||
* href="https://www.vaultproject.io/docs/secrets/pki/index.html#revoke-certificate">POST
|
||||
* @see <a href=
|
||||
* "https://www.vaultproject.io/docs/secrets/pki/index.html#revoke-certificate">POST
|
||||
* /pki/revoke</a>
|
||||
*/
|
||||
void revoke(String serialNumber) throws VaultException;
|
||||
|
||||
@@ -72,7 +72,8 @@ public class VaultPkiTemplate implements VaultPkiOperations {
|
||||
|
||||
@Override
|
||||
public VaultSignCertificateRequestResponse signCertificateRequest(String roleName,
|
||||
String csr, VaultCertificateRequest certificateRequest) throws VaultException {
|
||||
String csr, VaultCertificateRequest certificateRequest)
|
||||
throws VaultException {
|
||||
|
||||
Assert.hasText(roleName, "Role name must not be empty");
|
||||
Assert.hasText(csr, "CSR name must not be empty");
|
||||
@@ -136,8 +137,8 @@ public class VaultPkiTemplate implements VaultPkiOperations {
|
||||
String requestPath = encoding == Encoding.DER ? "{path}/crl"
|
||||
: "{path}/crl/pem";
|
||||
try {
|
||||
ResponseEntity<byte[]> response = restOperations.getForEntity(
|
||||
requestPath, byte[].class, path);
|
||||
ResponseEntity<byte[]> response = restOperations.getForEntity(requestPath,
|
||||
byte[].class, path);
|
||||
|
||||
return new ByteArrayInputStream(response.getBody());
|
||||
}
|
||||
@@ -163,17 +164,13 @@ public class VaultPkiTemplate implements VaultPkiOperations {
|
||||
request.put("common_name", certificateRequest.getCommonName());
|
||||
|
||||
if (!certificateRequest.getAltNames().isEmpty()) {
|
||||
request.put(
|
||||
"alt_names",
|
||||
StringUtils.collectionToDelimitedString(
|
||||
certificateRequest.getAltNames(), ","));
|
||||
request.put("alt_names", StringUtils
|
||||
.collectionToDelimitedString(certificateRequest.getAltNames(), ","));
|
||||
}
|
||||
|
||||
if (!certificateRequest.getIpSubjectAltNames().isEmpty()) {
|
||||
request.put(
|
||||
"ip_sans",
|
||||
StringUtils.collectionToDelimitedString(
|
||||
certificateRequest.getIpSubjectAltNames(), ","));
|
||||
request.put("ip_sans", StringUtils.collectionToDelimitedString(
|
||||
certificateRequest.getIpSubjectAltNames(), ","));
|
||||
}
|
||||
|
||||
if (certificateRequest.getTtl() != null) {
|
||||
|
||||
@@ -45,11 +45,11 @@ import org.springframework.vault.support.VaultHealth;
|
||||
import org.springframework.vault.support.VaultInitializationRequest;
|
||||
import org.springframework.vault.support.VaultInitializationResponse;
|
||||
import org.springframework.vault.support.VaultMount;
|
||||
import org.springframework.vault.support.VaultMount.VaultMountBuilder;
|
||||
import org.springframework.vault.support.VaultResponse;
|
||||
import org.springframework.vault.support.VaultResponseSupport;
|
||||
import org.springframework.vault.support.VaultToken;
|
||||
import org.springframework.vault.support.VaultUnsealStatus;
|
||||
import org.springframework.vault.support.VaultMount.VaultMountBuilder;
|
||||
import org.springframework.web.client.HttpStatusCodeException;
|
||||
import org.springframework.web.client.RestOperations;
|
||||
|
||||
@@ -118,14 +118,15 @@ public class VaultSysTemplate implements VaultSysOperations {
|
||||
public VaultInitializationResponse initialize(
|
||||
VaultInitializationRequest vaultInitializationRequest) {
|
||||
|
||||
Assert.notNull(vaultInitializationRequest, "VaultInitialization must not be null");
|
||||
Assert.notNull(vaultInitializationRequest,
|
||||
"VaultInitialization must not be null");
|
||||
|
||||
return requireResponse(vaultOperations.doWithVault(restOperations -> {
|
||||
|
||||
try {
|
||||
ResponseEntity<VaultInitializationResponseImpl> exchange = restOperations
|
||||
.exchange("sys/init", HttpMethod.PUT, new HttpEntity<Object>(
|
||||
vaultInitializationRequest),
|
||||
.exchange("sys/init", HttpMethod.PUT,
|
||||
new HttpEntity<Object>(vaultInitializationRequest),
|
||||
VaultInitializationResponseImpl.class);
|
||||
|
||||
Assert.state(exchange.getBody() != null,
|
||||
@@ -298,8 +299,8 @@ public class VaultSysTemplate implements VaultSysOperations {
|
||||
return response;
|
||||
}
|
||||
|
||||
private static class GetUnsealStatus implements
|
||||
RestOperationsCallback<VaultUnsealStatus> {
|
||||
private static class GetUnsealStatus
|
||||
implements RestOperationsCallback<VaultUnsealStatus> {
|
||||
|
||||
@Override
|
||||
public VaultUnsealStatus doWithRestOperations(RestOperations restOperations) {
|
||||
@@ -318,8 +319,8 @@ public class VaultSysTemplate implements VaultSysOperations {
|
||||
|
||||
}
|
||||
|
||||
private static class GetMounts implements
|
||||
RestOperationsCallback<Map<String, VaultMount>> {
|
||||
private static class GetMounts
|
||||
implements RestOperationsCallback<Map<String, VaultMount>> {
|
||||
|
||||
private static final ParameterizedTypeReference<VaultMountsResponse> MOUNT_TYPE_REF = new ParameterizedTypeReference<VaultMountsResponse>() {
|
||||
};
|
||||
@@ -331,7 +332,8 @@ public class VaultSysTemplate implements VaultSysOperations {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, VaultMount> doWithRestOperations(RestOperations restOperations) {
|
||||
public Map<String, VaultMount> doWithRestOperations(
|
||||
RestOperations restOperations) {
|
||||
|
||||
ResponseEntity<VaultMountsResponse> exchange = restOperations.exchange(path,
|
||||
HttpMethod.GET, null, MOUNT_TYPE_REF, Collections.emptyMap());
|
||||
@@ -347,8 +349,8 @@ public class VaultSysTemplate implements VaultSysOperations {
|
||||
return body.getTopLevelMounts();
|
||||
}
|
||||
|
||||
private static class VaultMountsResponse extends
|
||||
VaultResponseSupport<Map<String, VaultMount>> {
|
||||
private static class VaultMountsResponse
|
||||
extends VaultResponseSupport<Map<String, VaultMount>> {
|
||||
|
||||
private Map<String, VaultMount> topLevelMounts = new HashMap<>();
|
||||
|
||||
|
||||
@@ -179,17 +179,13 @@ public class VaultTemplate implements InitializingBean, VaultOperations, Disposa
|
||||
* @return the {@link RestTemplate} used for Vault communication.
|
||||
* @since 2.1
|
||||
*/
|
||||
protected RestTemplate doCreateSessionTemplate(
|
||||
VaultEndpointProvider endpointProvider,
|
||||
protected RestTemplate doCreateSessionTemplate(VaultEndpointProvider endpointProvider,
|
||||
ClientHttpRequestFactory requestFactory) {
|
||||
|
||||
return RestTemplateBuilder
|
||||
.builder()
|
||||
.endpointProvider(endpointProvider)
|
||||
.requestFactory(requestFactory)
|
||||
.customizer(
|
||||
restTemplate -> restTemplate.getInterceptors().add(
|
||||
getSessionInterceptor())).build();
|
||||
return RestTemplateBuilder.builder().endpointProvider(endpointProvider)
|
||||
.requestFactory(requestFactory).customizer(restTemplate -> restTemplate
|
||||
.getInterceptors().add(getSessionInterceptor()))
|
||||
.build();
|
||||
}
|
||||
|
||||
private ClientHttpRequestInterceptor getSessionInterceptor() {
|
||||
@@ -231,7 +227,8 @@ public class VaultTemplate implements InitializingBean, VaultOperations, Disposa
|
||||
}
|
||||
|
||||
@Override
|
||||
public VaultKeyValueOperations opsForKeyValue(String path, KeyValueBackend apiVersion) {
|
||||
public VaultKeyValueOperations opsForKeyValue(String path,
|
||||
KeyValueBackend apiVersion) {
|
||||
|
||||
switch (apiVersion) {
|
||||
case KV_1:
|
||||
@@ -240,8 +237,8 @@ public class VaultTemplate implements InitializingBean, VaultOperations, Disposa
|
||||
return new VaultKeyValue2Template(this, path);
|
||||
}
|
||||
|
||||
throw new UnsupportedOperationException(String.format(
|
||||
"Key/Value backend version %s not supported", apiVersion));
|
||||
throw new UnsupportedOperationException(
|
||||
String.format("Key/Value backend version %s not supported", apiVersion));
|
||||
|
||||
}
|
||||
|
||||
@@ -301,8 +298,8 @@ public class VaultTemplate implements InitializingBean, VaultOperations, Disposa
|
||||
.getTypeReference(responseType);
|
||||
|
||||
try {
|
||||
ResponseEntity<VaultResponseSupport<T>> exchange = sessionTemplate.exchange(
|
||||
path, HttpMethod.GET, null, ref);
|
||||
ResponseEntity<VaultResponseSupport<T>> exchange = sessionTemplate
|
||||
.exchange(path, HttpMethod.GET, null, ref);
|
||||
|
||||
return exchange.getBody();
|
||||
}
|
||||
|
||||
@@ -109,8 +109,9 @@ public class VaultTokenTemplate implements VaultTokenOperations {
|
||||
T response = vaultOperations.doWithSession(restOperations -> {
|
||||
try {
|
||||
ResponseEntity<T> exchange = restOperations.exchange(path,
|
||||
HttpMethod.POST, body == null ? HttpEntity.EMPTY
|
||||
: new HttpEntity<>(body), responseType);
|
||||
HttpMethod.POST,
|
||||
body == null ? HttpEntity.EMPTY : new HttpEntity<>(body),
|
||||
responseType);
|
||||
|
||||
return exchange.getBody();
|
||||
}
|
||||
@@ -132,8 +133,9 @@ public class VaultTokenTemplate implements VaultTokenOperations {
|
||||
vaultOperations.doWithSession(restOperations -> {
|
||||
|
||||
try {
|
||||
restOperations.exchange(path, HttpMethod.POST, new HttpEntity<>(
|
||||
Collections.singletonMap("token", token.getToken())),
|
||||
restOperations.exchange(path, HttpMethod.POST,
|
||||
new HttpEntity<>(
|
||||
Collections.singletonMap("token", token.getToken())),
|
||||
responseType);
|
||||
|
||||
return null;
|
||||
|
||||
@@ -143,7 +143,7 @@ public interface VaultTransitOperations {
|
||||
* @param keyName must not be empty or {@literal null}.
|
||||
* @param plaintext must not be empty or {@literal null}.
|
||||
* @param transitRequest must not be {@literal null}. Use
|
||||
* {@link VaultTransitContext#empty()} if no request options provided.
|
||||
* {@link VaultTransitContext#empty()} if no request options provided.
|
||||
* @return cipher text.
|
||||
*/
|
||||
String encrypt(String keyName, byte[] plaintext, VaultTransitContext transitRequest);
|
||||
@@ -154,7 +154,7 @@ public interface VaultTransitOperations {
|
||||
*
|
||||
* @param keyName must not be empty or {@literal null}.
|
||||
* @param batchRequest a list of {@link Plaintext} which includes plaintext and an
|
||||
* optional context.
|
||||
* optional context.
|
||||
* @return the encrypted result in the order of {@code batchRequest} plaintexts.
|
||||
* @since 1.1
|
||||
*/
|
||||
@@ -185,7 +185,7 @@ public interface VaultTransitOperations {
|
||||
* @param keyName must not be empty or {@literal null}.
|
||||
* @param ciphertext must not be empty or {@literal null}.
|
||||
* @param transitContext must not be {@literal null}. Use
|
||||
* {@link VaultTransitContext#empty()} if no request options provided.
|
||||
* {@link VaultTransitContext#empty()} if no request options provided.
|
||||
* @return cipher text.
|
||||
* @return plain text.
|
||||
*/
|
||||
@@ -198,7 +198,7 @@ public interface VaultTransitOperations {
|
||||
*
|
||||
* @param keyName must not be empty or {@literal null}.
|
||||
* @param batchRequest a list of {@link Ciphertext} which includes plaintext and an
|
||||
* optional context.
|
||||
* optional context.
|
||||
* @return the decrypted result in the order of {@code batchRequest} ciphertexts.
|
||||
* @since 1.1
|
||||
*/
|
||||
@@ -224,7 +224,7 @@ public interface VaultTransitOperations {
|
||||
* @param keyName must not be empty or {@literal null}.
|
||||
* @param ciphertext must not be empty or {@literal null}.
|
||||
* @param transitContext must not be {@literal null}. Use
|
||||
* {@link VaultTransitContext#empty()} if no request options provided.
|
||||
* {@link VaultTransitContext#empty()} if no request options provided.
|
||||
* @return cipher text.
|
||||
* @see #rotate(String)
|
||||
*/
|
||||
@@ -299,7 +299,7 @@ public interface VaultTransitOperations {
|
||||
*
|
||||
* @param keyName must not be empty or {@literal null}.
|
||||
* @param request {@link VaultSignatureVerificationRequest} must not be
|
||||
* {@literal null}.
|
||||
* {@literal null}.
|
||||
* @return the resulting {@link SignatureValidation}.
|
||||
* @since 2.0
|
||||
*/
|
||||
|
||||
@@ -89,7 +89,8 @@ public class VaultTransitTemplate implements VaultTransitOperations {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createKey(String keyName, VaultTransitKeyCreationRequest createKeyRequest) {
|
||||
public void createKey(String keyName,
|
||||
VaultTransitKeyCreationRequest createKeyRequest) {
|
||||
|
||||
Assert.hasText(keyName, "KeyName must not be empty");
|
||||
Assert.notNull(createKeyRequest,
|
||||
@@ -102,15 +103,16 @@ public class VaultTransitTemplate implements VaultTransitOperations {
|
||||
@Override
|
||||
public List<String> getKeys() {
|
||||
|
||||
VaultResponse response = vaultOperations.read(String.format("%s/keys?list=true",
|
||||
path));
|
||||
VaultResponse response = vaultOperations
|
||||
.read(String.format("%s/keys?list=true", path));
|
||||
|
||||
return response == null ? Collections.emptyList() : (List) response
|
||||
.getRequiredData().get("keys");
|
||||
return response == null ? Collections.emptyList()
|
||||
: (List) response.getRequiredData().get("keys");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void configureKey(String keyName, VaultTransitKeyConfiguration keyConfiguration) {
|
||||
public void configureKey(String keyName,
|
||||
VaultTransitKeyConfiguration keyConfiguration) {
|
||||
|
||||
Assert.hasText(keyName, "KeyName must not be empty");
|
||||
Assert.notNull(keyConfiguration, "VaultKeyConfiguration must not be empty");
|
||||
@@ -444,8 +446,8 @@ public class VaultTransitTemplate implements VaultTransitOperations {
|
||||
"Signature verification request must not be null");
|
||||
|
||||
Map<String, Object> request = new LinkedHashMap<>();
|
||||
request.put("input", Base64Utils.encodeToString(verificationRequest
|
||||
.getPlaintext().getPlaintext()));
|
||||
request.put("input", Base64Utils
|
||||
.encodeToString(verificationRequest.getPlaintext().getPlaintext()));
|
||||
|
||||
if (verificationRequest.getHmac() != null) {
|
||||
request.put("hmac", verificationRequest.getHmac().getHmac());
|
||||
@@ -459,10 +461,12 @@ public class VaultTransitTemplate implements VaultTransitOperations {
|
||||
request.put("algorithm", verificationRequest.getAlgorithm());
|
||||
}
|
||||
|
||||
Map<String, Object> response = vaultOperations.write(
|
||||
String.format("%s/verify/%s", path, keyName), request).getRequiredData();
|
||||
Map<String, Object> response = vaultOperations
|
||||
.write(String.format("%s/verify/%s", path, keyName), request)
|
||||
.getRequiredData();
|
||||
|
||||
if (response.containsKey("valid") && Boolean.valueOf("" + response.get("valid"))) {
|
||||
if (response.containsKey("valid")
|
||||
&& Boolean.valueOf("" + response.get("valid"))) {
|
||||
return SignatureValidation.valid();
|
||||
}
|
||||
|
||||
@@ -496,17 +500,17 @@ public class VaultTransitTemplate implements VaultTransitOperations {
|
||||
|
||||
Map<String, String> data = batchData.get(i);
|
||||
if (StringUtils.hasText(data.get("error"))) {
|
||||
encrypted = new VaultEncryptionResult(new VaultException(
|
||||
data.get("error")));
|
||||
encrypted = new VaultEncryptionResult(
|
||||
new VaultException(data.get("error")));
|
||||
}
|
||||
else {
|
||||
encrypted = new VaultEncryptionResult(toCiphertext(
|
||||
data.get("ciphertext"), plaintext.getContext()));
|
||||
encrypted = new VaultEncryptionResult(
|
||||
toCiphertext(data.get("ciphertext"), plaintext.getContext()));
|
||||
}
|
||||
}
|
||||
else {
|
||||
encrypted = new VaultEncryptionResult(new VaultException(
|
||||
"No result for plaintext #" + i));
|
||||
encrypted = new VaultEncryptionResult(
|
||||
new VaultException("No result for plaintext #" + i));
|
||||
}
|
||||
|
||||
result.add(encrypted);
|
||||
@@ -531,8 +535,8 @@ public class VaultTransitTemplate implements VaultTransitOperations {
|
||||
encrypted = getDecryptionResult(batchData.get(i), ciphertext);
|
||||
}
|
||||
else {
|
||||
encrypted = new VaultDecryptionResult(new VaultException(
|
||||
"No result for ciphertext #" + i));
|
||||
encrypted = new VaultDecryptionResult(
|
||||
new VaultException("No result for ciphertext #" + i));
|
||||
}
|
||||
|
||||
result.add(encrypted);
|
||||
@@ -551,8 +555,8 @@ public class VaultTransitTemplate implements VaultTransitOperations {
|
||||
if (StringUtils.hasText(data.get("plaintext"))) {
|
||||
|
||||
byte[] plaintext = Base64Utils.decodeFromString(data.get("plaintext"));
|
||||
return new VaultDecryptionResult(Plaintext.of(plaintext).with(
|
||||
ciphertext.getContext()));
|
||||
return new VaultDecryptionResult(
|
||||
Plaintext.of(plaintext).with(ciphertext.getContext()));
|
||||
}
|
||||
|
||||
return new VaultDecryptionResult(Plaintext.empty().with(ciphertext.getContext()));
|
||||
@@ -560,14 +564,14 @@ public class VaultTransitTemplate implements VaultTransitOperations {
|
||||
|
||||
private static Ciphertext toCiphertext(String ciphertext,
|
||||
@Nullable VaultTransitContext context) {
|
||||
return context != null ? Ciphertext.of(ciphertext).with(context) : Ciphertext
|
||||
.of(ciphertext);
|
||||
return context != null ? Ciphertext.of(ciphertext).with(context)
|
||||
: Ciphertext.of(ciphertext);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private static List<Map<String, String>> getBatchData(VaultResponse vaultResponse) {
|
||||
return (List<Map<String, String>>) vaultResponse.getRequiredData().get(
|
||||
"batch_results");
|
||||
return (List<Map<String, String>>) vaultResponse.getRequiredData()
|
||||
.get("batch_results");
|
||||
}
|
||||
|
||||
static class VaultTransitKeyImpl implements VaultTransitKey {
|
||||
|
||||
@@ -37,8 +37,8 @@ import org.springframework.vault.support.VaultResponse;
|
||||
import org.springframework.vault.support.VaultResponseSupport;
|
||||
import org.springframework.vault.support.Versioned;
|
||||
import org.springframework.vault.support.Versioned.Metadata;
|
||||
import org.springframework.vault.support.Versioned.Version;
|
||||
import org.springframework.vault.support.Versioned.Metadata.MetadataBuilder;
|
||||
import org.springframework.vault.support.Versioned.Version;
|
||||
import org.springframework.web.client.HttpStatusCodeException;
|
||||
|
||||
/**
|
||||
@@ -48,8 +48,8 @@ import org.springframework.web.client.HttpStatusCodeException;
|
||||
* @author Maciej Drozdzowski
|
||||
* @since 2.1
|
||||
*/
|
||||
public class VaultVersionedKeyValueTemplate extends VaultKeyValue2Accessor implements
|
||||
VaultVersionedKeyValueOperations {
|
||||
public class VaultVersionedKeyValueTemplate extends VaultKeyValue2Accessor
|
||||
implements VaultVersionedKeyValueOperations {
|
||||
|
||||
private final VaultOperations vaultOperations;
|
||||
|
||||
@@ -92,8 +92,10 @@ public class VaultVersionedKeyValueTemplate extends VaultKeyValue2Accessor imple
|
||||
@Nullable
|
||||
private <T> Versioned<T> doRead(String path, Version version, Class<T> responseType) {
|
||||
|
||||
String secretPath = version.isVersioned() ? String.format("%s?version=%d",
|
||||
createDataPath(path), version.getVersion()) : createDataPath(path);
|
||||
String secretPath = version.isVersioned()
|
||||
? String.format("%s?version=%d", createDataPath(path),
|
||||
version.getVersion())
|
||||
: createDataPath(path);
|
||||
|
||||
VersionedResponse response = vaultOperations.doWithSession(restOperations -> {
|
||||
|
||||
@@ -239,7 +241,7 @@ public class VaultVersionedKeyValueTemplate extends VaultKeyValue2Accessor imple
|
||||
Collections.singletonMap("versions", versions));
|
||||
}
|
||||
|
||||
private static class VersionedResponse extends
|
||||
VaultResponseSupport<VaultResponseSupport<JsonNode>> {
|
||||
private static class VersionedResponse
|
||||
extends VaultResponseSupport<VaultResponseSupport<JsonNode>> {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,12 +91,10 @@ public class VaultWrappingTemplate implements VaultWrappingOperations {
|
||||
@Override
|
||||
public VaultResponse read(VaultToken token) {
|
||||
|
||||
return doUnwrap(
|
||||
token,
|
||||
(restOperations, entity) -> {
|
||||
return restOperations.exchange("sys/wrapping/unwrap",
|
||||
HttpMethod.POST, entity, VaultResponse.class).getBody();
|
||||
});
|
||||
return doUnwrap(token, (restOperations, entity) -> {
|
||||
return restOperations.exchange("sys/wrapping/unwrap", HttpMethod.POST, entity,
|
||||
VaultResponse.class).getBody();
|
||||
});
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -106,12 +104,11 @@ public class VaultWrappingTemplate implements VaultWrappingOperations {
|
||||
ParameterizedTypeReference<VaultResponseSupport<T>> ref = VaultResponses
|
||||
.getTypeReference(responseType);
|
||||
|
||||
return doUnwrap(
|
||||
token,
|
||||
(restOperations, entity) -> {
|
||||
return restOperations.exchange("sys/wrapping/unwrap",
|
||||
HttpMethod.POST, entity, ref).getBody();
|
||||
});
|
||||
return doUnwrap(token, (restOperations, entity) -> {
|
||||
return restOperations
|
||||
.exchange("sys/wrapping/unwrap", HttpMethod.POST, entity, ref)
|
||||
.getBody();
|
||||
});
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -121,8 +118,8 @@ public class VaultWrappingTemplate implements VaultWrappingOperations {
|
||||
return vaultOperations.doWithVault(restOperations -> {
|
||||
|
||||
try {
|
||||
return requestFunction.apply(restOperations, new HttpEntity<>(
|
||||
VaultHttpHeaders.from(token)));
|
||||
return requestFunction.apply(restOperations,
|
||||
new HttpEntity<>(VaultHttpHeaders.from(token)));
|
||||
}
|
||||
catch (HttpStatusCodeException e) {
|
||||
|
||||
@@ -164,8 +161,10 @@ public class VaultWrappingTemplate implements VaultWrappingOperations {
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.add("X-Vault-Wrap-TTL", Long.toString(duration.getSeconds()));
|
||||
|
||||
return restOperations.exchange("sys/wrapping/wrap", HttpMethod.POST,
|
||||
new HttpEntity<>(body, headers), VaultResponse.class).getBody();
|
||||
return restOperations
|
||||
.exchange("sys/wrapping/wrap", HttpMethod.POST,
|
||||
new HttpEntity<>(body, headers), VaultResponse.class)
|
||||
.getBody();
|
||||
});
|
||||
|
||||
Map<String, String> wrapInfo = response.getWrapInfo();
|
||||
@@ -188,8 +187,9 @@ public class VaultWrappingTemplate implements VaultWrappingOperations {
|
||||
|
||||
String date = (String) ((Map) responseMetadata).getOrDefault(key, "");
|
||||
|
||||
return StringUtils.hasText(date) ? DateTimeFormatter.ISO_OFFSET_DATE_TIME
|
||||
.parse(date) : null;
|
||||
return StringUtils.hasText(date)
|
||||
? DateTimeFormatter.ISO_OFFSET_DATE_TIME.parse(date)
|
||||
: null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
||||
@@ -66,7 +66,7 @@ public class VaultPropertySource extends EnumerablePropertySource<VaultOperation
|
||||
*
|
||||
* @param vaultOperations must not be {@literal null}.
|
||||
* @param path the path inside Vault (e.g. {@code secret/myapp/myproperties}. Must not
|
||||
* be empty or {@literal null}.
|
||||
* be empty or {@literal null}.
|
||||
*/
|
||||
public VaultPropertySource(VaultOperations vaultOperations, String path) {
|
||||
this(path, vaultOperations, path);
|
||||
@@ -80,9 +80,10 @@ public class VaultPropertySource extends EnumerablePropertySource<VaultOperation
|
||||
* @param name name of the property source, must not be {@literal null}.
|
||||
* @param vaultOperations must not be {@literal null}.
|
||||
* @param path the path inside Vault (e.g. {@code secret/myapp/myproperties}. Must not
|
||||
* be empty or {@literal null}.
|
||||
* be empty or {@literal null}.
|
||||
*/
|
||||
public VaultPropertySource(String name, VaultOperations vaultOperations, String path) {
|
||||
public VaultPropertySource(String name, VaultOperations vaultOperations,
|
||||
String path) {
|
||||
this(name, vaultOperations, path, PropertyTransformers.noop());
|
||||
}
|
||||
|
||||
@@ -95,7 +96,7 @@ public class VaultPropertySource extends EnumerablePropertySource<VaultOperation
|
||||
* @param name name of the property source, must not be {@literal null}.
|
||||
* @param vaultOperations must not be {@literal null}.
|
||||
* @param path the path inside Vault (e.g. {@code secret/myapp/myproperties}. Must not
|
||||
* be empty or {@literal null}.
|
||||
* be empty or {@literal null}.
|
||||
* @param propertyTransformer object to transform properties.
|
||||
* @see PropertyTransformers
|
||||
*/
|
||||
@@ -110,8 +111,8 @@ public class VaultPropertySource extends EnumerablePropertySource<VaultOperation
|
||||
|
||||
this.path = path;
|
||||
this.keyValueDelegate = new KeyValueDelegate(vaultOperations, LinkedHashMap::new);
|
||||
this.propertyTransformer = propertyTransformer.andThen(PropertyTransformers
|
||||
.removeNullProperties());
|
||||
this.propertyTransformer = propertyTransformer
|
||||
.andThen(PropertyTransformers.removeNullProperties());
|
||||
|
||||
loadProperties();
|
||||
}
|
||||
|
||||
@@ -118,9 +118,9 @@ public enum LeaseEndpoints {
|
||||
Number leaseDuration = (Number) body.get("lease_duration");
|
||||
boolean renewable = (Boolean) body.get("renewable");
|
||||
|
||||
return Lease
|
||||
.of(leaseId, Duration.ofSeconds(leaseDuration != null ? leaseDuration
|
||||
.longValue() : 0), renewable);
|
||||
return Lease.of(leaseId,
|
||||
Duration.ofSeconds(leaseDuration != null ? leaseDuration.longValue() : 0),
|
||||
renewable);
|
||||
}
|
||||
|
||||
private static HttpEntity<Object> getLeaseRenewalBody(Lease lease) {
|
||||
|
||||
@@ -21,8 +21,8 @@ import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
@@ -117,8 +117,8 @@ import org.springframework.web.client.HttpStatusCodeException;
|
||||
* @see Lease
|
||||
* @see LeaseEndpoints
|
||||
*/
|
||||
public class SecretLeaseContainer extends SecretLeaseEventPublisher implements
|
||||
InitializingBean, DisposableBean {
|
||||
public class SecretLeaseContainer extends SecretLeaseEventPublisher
|
||||
implements InitializingBean, DisposableBean {
|
||||
|
||||
private static final AtomicIntegerFieldUpdater<SecretLeaseContainer> UPDATER = AtomicIntegerFieldUpdater
|
||||
.newUpdater(SecretLeaseContainer.class, "status");
|
||||
@@ -204,7 +204,7 @@ public class SecretLeaseContainer extends SecretLeaseEventPublisher implements
|
||||
* {@code minRenewalSeconds} prevents renewals from happening too often.
|
||||
*
|
||||
* @param minRenewalSeconds number of seconds that is at least required before
|
||||
* renewing a {@link Lease}, must not be negative.
|
||||
* renewing a {@link Lease}, must not be negative.
|
||||
* @deprecated since 2.0, use {@link #setMinRenewal(Duration)} for time unit safety.
|
||||
*/
|
||||
@Deprecated
|
||||
@@ -217,7 +217,7 @@ public class SecretLeaseContainer extends SecretLeaseEventPublisher implements
|
||||
* {@code minRenewal} prevents renewals from happening too often.
|
||||
*
|
||||
* @param minRenewal duration that is at least required before renewing a
|
||||
* {@link Lease}, must not be {@literal null} or negative.
|
||||
* {@link Lease}, must not be {@literal null} or negative.
|
||||
* @since 2.0
|
||||
*/
|
||||
public void setMinRenewal(Duration minRenewal) {
|
||||
@@ -234,7 +234,7 @@ public class SecretLeaseContainer extends SecretLeaseEventPublisher implements
|
||||
* expires.
|
||||
*
|
||||
* @param expiryThresholdSeconds number of seconds before {@link Lease} expiry, must
|
||||
* not be negative.
|
||||
* not be negative.
|
||||
* @deprecated since 2.0, use {@link #setExpiryThreshold(Duration)} for time unit
|
||||
* safety.
|
||||
*/
|
||||
@@ -248,7 +248,7 @@ public class SecretLeaseContainer extends SecretLeaseEventPublisher implements
|
||||
* expires.
|
||||
*
|
||||
* @param expiryThreshold duration before {@link Lease} expiry, must not be
|
||||
* {@literal null} or negative.
|
||||
* {@literal null} or negative.
|
||||
* @since 2.0
|
||||
*/
|
||||
public void setExpiryThreshold(Duration expiryThreshold) {
|
||||
@@ -389,8 +389,8 @@ public class SecretLeaseContainer extends SecretLeaseEventPublisher implements
|
||||
secrets.isRenewable());
|
||||
}
|
||||
else if (isRotatingGenericSecret(requestedSecret, secrets)) {
|
||||
lease = Lease.fromTimeToLive(Duration.ofSeconds(secrets
|
||||
.getLeaseDuration()));
|
||||
lease = Lease
|
||||
.fromTimeToLive(Duration.ofSeconds(secrets.getLeaseDuration()));
|
||||
}
|
||||
else {
|
||||
lease = Lease.none();
|
||||
@@ -445,8 +445,8 @@ public class SecretLeaseContainer extends SecretLeaseEventPublisher implements
|
||||
|
||||
ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
|
||||
scheduler.setDaemon(true);
|
||||
scheduler.setThreadNamePrefix(String.format("%s-%d-", getClass()
|
||||
.getSimpleName(), poolId.incrementAndGet()));
|
||||
scheduler.setThreadNamePrefix(String.format("%s-%d-",
|
||||
getClass().getSimpleName(), poolId.incrementAndGet()));
|
||||
scheduler.afterPropertiesSet();
|
||||
|
||||
this.taskScheduler = scheduler;
|
||||
@@ -454,8 +454,8 @@ public class SecretLeaseContainer extends SecretLeaseEventPublisher implements
|
||||
}
|
||||
|
||||
for (RequestedSecret requestedSecret : requestedSecrets) {
|
||||
this.renewals.put(requestedSecret, new LeaseRenewalScheduler(
|
||||
this.taskScheduler));
|
||||
this.renewals.put(requestedSecret,
|
||||
new LeaseRenewalScheduler(this.taskScheduler));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -530,7 +530,7 @@ public class SecretLeaseContainer extends SecretLeaseEventPublisher implements
|
||||
onLeaseExpired(requestedSecret, leaseToRotate);
|
||||
|
||||
return Lease.none(); // rotation creates a new lease.
|
||||
}, lease, getMinRenewal(), getExpiryThreshold());
|
||||
}, lease, getMinRenewal(), getExpiryThreshold());
|
||||
}
|
||||
|
||||
private static void logRenewalCandidate(RequestedSecret requestedSecret, Lease lease,
|
||||
@@ -557,7 +557,7 @@ public class SecretLeaseContainer extends SecretLeaseEventPublisher implements
|
||||
* Retrieve secrets from {@link VaultOperations}.
|
||||
*
|
||||
* @param requestedSecret the {@link RequestedSecret} providing the secret
|
||||
* {@code path}.
|
||||
* {@code path}.
|
||||
* @return the response.
|
||||
*/
|
||||
@Nullable
|
||||
@@ -591,8 +591,8 @@ public class SecretLeaseContainer extends SecretLeaseEventPublisher implements
|
||||
try {
|
||||
Lease renewed = lease.hasLeaseId() ? renew(lease) : lease;
|
||||
|
||||
if (!renewed.hasLeaseId() || renewed.getLeaseDuration().isZero()
|
||||
|| renewed.getLeaseDuration().getSeconds() < minRenewal.getSeconds()) {
|
||||
if (!renewed.hasLeaseId() || renewed.getLeaseDuration().isZero() || renewed
|
||||
.getLeaseDuration().getSeconds() < minRenewal.getSeconds()) {
|
||||
|
||||
onLeaseExpired(requestedSecret, lease);
|
||||
return Lease.none();
|
||||
@@ -602,7 +602,8 @@ public class SecretLeaseContainer extends SecretLeaseEventPublisher implements
|
||||
}
|
||||
catch (RuntimeException e) {
|
||||
|
||||
HttpStatusCodeException httpException = potentiallyUnwrapHttpStatusCodeException(e);
|
||||
HttpStatusCodeException httpException = potentiallyUnwrapHttpStatusCodeException(
|
||||
e);
|
||||
|
||||
if (httpException != null) {
|
||||
|
||||
@@ -610,11 +611,9 @@ public class SecretLeaseContainer extends SecretLeaseEventPublisher implements
|
||||
onLeaseExpired(requestedSecret, lease);
|
||||
}
|
||||
|
||||
onError(requestedSecret,
|
||||
lease,
|
||||
new VaultException(String.format("Cannot renew lease: %s",
|
||||
VaultResponses.getError(httpException
|
||||
.getResponseBodyAsString()))));
|
||||
onError(requestedSecret, lease, new VaultException(
|
||||
String.format("Cannot renew lease: %s", VaultResponses
|
||||
.getError(httpException.getResponseBodyAsString()))));
|
||||
}
|
||||
else {
|
||||
onError(requestedSecret, lease, e);
|
||||
@@ -641,8 +640,8 @@ public class SecretLeaseContainer extends SecretLeaseEventPublisher implements
|
||||
|
||||
private Lease renew(Lease lease) {
|
||||
|
||||
return operations.doWithSession(restOperations -> leaseEndpoints.renew(lease,
|
||||
restOperations));
|
||||
return operations.doWithSession(
|
||||
restOperations -> leaseEndpoints.renew(lease, restOperations));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -683,8 +682,7 @@ public class SecretLeaseContainer extends SecretLeaseEventPublisher implements
|
||||
onAfterLeaseRevocation(requestedSecret, lease);
|
||||
}
|
||||
catch (HttpStatusCodeException e) {
|
||||
onError(requestedSecret,
|
||||
lease,
|
||||
onError(requestedSecret, lease,
|
||||
new VaultException(String.format("Cannot revoke lease: %s",
|
||||
VaultResponses.getError(e.getResponseBodyAsString()))));
|
||||
}
|
||||
@@ -725,7 +723,7 @@ public class SecretLeaseContainer extends SecretLeaseEventPublisher implements
|
||||
* @param renewLease strategy to renew a {@link Lease}.
|
||||
* @param lease the current {@link Lease}.
|
||||
* @param minRenewal minimum duration before renewing a {@link Lease}. This is to
|
||||
* prevent too many renewals in a very short timeframe.
|
||||
* prevent too many renewals in a very short timeframe.
|
||||
* @param expiryThreshold duration to renew before {@link Lease}.
|
||||
*/
|
||||
void scheduleRenewal(RequestedSecret requestedSecret, RenewLease renewLease,
|
||||
@@ -733,16 +731,16 @@ public class SecretLeaseContainer extends SecretLeaseEventPublisher implements
|
||||
|
||||
if (log.isDebugEnabled()) {
|
||||
if (lease.hasLeaseId()) {
|
||||
log.debug(String
|
||||
.format("Scheduling renewal for secret %s with lease %s, lease duration %d",
|
||||
requestedSecret.getPath(), lease.getLeaseId(), lease
|
||||
.getLeaseDuration().getSeconds()));
|
||||
log.debug(String.format(
|
||||
"Scheduling renewal for secret %s with lease %s, lease duration %d",
|
||||
requestedSecret.getPath(), lease.getLeaseId(),
|
||||
lease.getLeaseDuration().getSeconds()));
|
||||
}
|
||||
else {
|
||||
log.debug(String
|
||||
.format("Scheduling renewal for secret %s, with cache hint duration %d",
|
||||
requestedSecret.getPath(), lease.getLeaseDuration()
|
||||
.getSeconds()));
|
||||
log.debug(String.format(
|
||||
"Scheduling renewal for secret %s, with cache hint duration %d",
|
||||
requestedSecret.getPath(),
|
||||
lease.getLeaseDuration().getSeconds()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -781,8 +779,8 @@ public class SecretLeaseContainer extends SecretLeaseEventPublisher implements
|
||||
// Renew lease may call scheduleRenewal(…) with a different lease
|
||||
// Id to alter set up its own renewal schedule. If it's the old
|
||||
// lease, then renewLease() outcome controls the current LeaseId.
|
||||
currentLeaseRef
|
||||
.compareAndSet(lease, renewLease.renewLease(lease));
|
||||
currentLeaseRef.compareAndSet(lease,
|
||||
renewLease.renewLease(lease));
|
||||
}
|
||||
catch (Exception e) {
|
||||
log.error(String.format("Cannot renew lease %s",
|
||||
@@ -791,10 +789,9 @@ public class SecretLeaseContainer extends SecretLeaseEventPublisher implements
|
||||
}
|
||||
};
|
||||
|
||||
ScheduledFuture<?> scheduledFuture = taskScheduler.schedule(
|
||||
task,
|
||||
new OneShotTrigger(getRenewalSeconds(lease, minRenewal,
|
||||
expiryThreshold)));
|
||||
ScheduledFuture<?> scheduledFuture = taskScheduler.schedule(task,
|
||||
new OneShotTrigger(
|
||||
getRenewalSeconds(lease, minRenewal, expiryThreshold)));
|
||||
|
||||
schedules.put(lease, scheduledFuture);
|
||||
}
|
||||
@@ -830,8 +827,8 @@ public class SecretLeaseContainer extends SecretLeaseEventPublisher implements
|
||||
|
||||
private long getRenewalSeconds(Lease lease, Duration minRenewal,
|
||||
Duration expiryThreshold) {
|
||||
return Math.max(minRenewal.getSeconds(), lease.getLeaseDuration()
|
||||
.getSeconds() - expiryThreshold.getSeconds());
|
||||
return Math.max(minRenewal.getSeconds(),
|
||||
lease.getLeaseDuration().getSeconds() - expiryThreshold.getSeconds());
|
||||
}
|
||||
|
||||
private boolean isLeaseRenewable(@Nullable Lease lease,
|
||||
@@ -893,8 +890,8 @@ public class SecretLeaseContainer extends SecretLeaseEventPublisher implements
|
||||
public Date nextExecutionTime(TriggerContext triggerContext) {
|
||||
|
||||
if (UPDATER.compareAndSet(this, STATUS_ARMED, STATUS_FIRED)) {
|
||||
return new Date(System.currentTimeMillis()
|
||||
+ TimeUnit.SECONDS.toMillis(seconds));
|
||||
return new Date(
|
||||
System.currentTimeMillis() + TimeUnit.SECONDS.toMillis(seconds));
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
@@ -41,8 +41,8 @@ import org.springframework.vault.core.lease.event.SecretLeaseExpiredEvent;
|
||||
* Publisher for {@link SecretLeaseEvent}s.
|
||||
* <p>
|
||||
* This publisher dispatches events to {@link LeaseListener} and
|
||||
* {@link LeaseErrorListener}. Instances are thread-safe once
|
||||
* {@link #afterPropertiesSet() initialized}.
|
||||
* {@link LeaseErrorListener}. Instances are thread-safe once {@link #afterPropertiesSet()
|
||||
* initialized}.
|
||||
*
|
||||
* @author Mark Paluch
|
||||
* @see SecretLeaseEvent
|
||||
@@ -218,9 +218,8 @@ public class SecretLeaseEventPublisher implements InitializingBean {
|
||||
|
||||
@Override
|
||||
public void onLeaseError(SecretLeaseEvent leaseEvent, Exception exception) {
|
||||
log.warn(
|
||||
String.format("[%s] %s %s", leaseEvent.getSource(),
|
||||
leaseEvent.getLease(), exception.getMessage()), exception);
|
||||
log.warn(String.format("[%s] %s %s", leaseEvent.getSource(),
|
||||
leaseEvent.getLease(), exception.getMessage()), exception);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,7 +36,8 @@ public class BeforeSecretLeaseRevocationEvent extends SecretLeaseEvent {
|
||||
* @param requestedSecret must not be {@literal null}.
|
||||
* @param lease must not be {@literal null}.
|
||||
*/
|
||||
public BeforeSecretLeaseRevocationEvent(RequestedSecret requestedSecret, Lease lease) {
|
||||
public BeforeSecretLeaseRevocationEvent(RequestedSecret requestedSecret,
|
||||
Lease lease) {
|
||||
super(requestedSecret, lease);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,8 +23,8 @@ import java.util.function.Supplier;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.ConcurrentReferenceHashMap;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.vault.core.VaultOperations;
|
||||
import org.springframework.vault.core.VaultKeyValueOperationsSupport.KeyValueBackend;
|
||||
import org.springframework.vault.core.VaultOperations;
|
||||
import org.springframework.vault.support.VaultResponse;
|
||||
|
||||
/**
|
||||
@@ -80,8 +80,8 @@ public class KeyValueDelegate {
|
||||
return this.operations.read(path);
|
||||
}
|
||||
|
||||
VaultResponse response = this.operations.read(getKeyValue2Path(
|
||||
mountInfo.getPath(), path));
|
||||
VaultResponse response = this.operations
|
||||
.read(getKeyValue2Path(mountInfo.getPath(), path));
|
||||
unwrapDataResponse(response);
|
||||
|
||||
return response;
|
||||
@@ -106,16 +106,16 @@ public class KeyValueDelegate {
|
||||
return;
|
||||
}
|
||||
|
||||
Map<String, Object> nested = new LinkedHashMap<>((Map) response.getRequiredData()
|
||||
.get("data"));
|
||||
Map<String, Object> nested = new LinkedHashMap<>(
|
||||
(Map) response.getRequiredData().get("data"));
|
||||
response.setData(nested);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private MountInfo doGetMountInfo(String path) {
|
||||
|
||||
VaultResponse response = this.operations.read(String.format(
|
||||
"sys/internal/ui/mounts/%s", path));
|
||||
VaultResponse response = this.operations
|
||||
.read(String.format("sys/internal/ui/mounts/%s", path));
|
||||
|
||||
if (response == null || response.getData() == null) {
|
||||
return MountInfo.unavailable();
|
||||
|
||||
@@ -72,7 +72,8 @@ public abstract class PropertyTransformers {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> transformProperties(Map<String, ? extends Object> input) {
|
||||
public Map<String, Object> transformProperties(
|
||||
Map<String, ? extends Object> input) {
|
||||
return (Map) input;
|
||||
}
|
||||
}
|
||||
@@ -95,10 +96,10 @@ public abstract class PropertyTransformers {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> transformProperties(Map<String, ? extends Object> input) {
|
||||
public Map<String, Object> transformProperties(
|
||||
Map<String, ? extends Object> input) {
|
||||
|
||||
Map<String, Object> target = new LinkedHashMap<>(input.size(),
|
||||
1);
|
||||
Map<String, Object> target = new LinkedHashMap<>(input.size(), 1);
|
||||
|
||||
for (Entry<String, ? extends Object> entry : input.entrySet()) {
|
||||
|
||||
@@ -131,7 +132,7 @@ public abstract class PropertyTransformers {
|
||||
* Create a new {@link KeyPrefixPropertyTransformer} that adds a prefix to each
|
||||
* key name.
|
||||
* @param propertyNamePrefix the property name prefix to be added in front of each
|
||||
* property name, must not be {@literal null}.
|
||||
* property name, must not be {@literal null}.
|
||||
* @return a new {@link KeyPrefixPropertyTransformer} that adds a prefix to each
|
||||
* key name.
|
||||
*/
|
||||
@@ -140,10 +141,10 @@ public abstract class PropertyTransformers {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> transformProperties(Map<String, ? extends Object> input) {
|
||||
public Map<String, Object> transformProperties(
|
||||
Map<String, ? extends Object> input) {
|
||||
|
||||
Map<String, Object> target = new LinkedHashMap<>(input.size(),
|
||||
1);
|
||||
Map<String, Object> target = new LinkedHashMap<>(input.size(), 1);
|
||||
|
||||
for (Entry<String, ? extends Object> entry : input.entrySet()) {
|
||||
target.put(propertyNamePrefix + entry.getKey(), entry.getValue());
|
||||
|
||||
@@ -4,4 +4,3 @@
|
||||
@org.springframework.lang.NonNullApi
|
||||
@org.springframework.lang.NonNullFields
|
||||
package org.springframework.vault.core.util;
|
||||
|
||||
|
||||
@@ -23,8 +23,8 @@ import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import org.springframework.beans.factory.FactoryBean;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.context.annotation.ComponentScan.Filter;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.data.keyvalue.core.KeyValueOperations;
|
||||
import org.springframework.data.keyvalue.repository.config.QueryCreatorType;
|
||||
import org.springframework.data.repository.config.DefaultRepositoryBaseClass;
|
||||
|
||||
@@ -39,8 +39,8 @@ import org.springframework.vault.repository.mapping.VaultMappingContext;
|
||||
* @author Mark Paluch
|
||||
* @since 2.0
|
||||
*/
|
||||
public class VaultRepositoryConfigurationExtension extends
|
||||
KeyValueRepositoryConfigurationExtension {
|
||||
public class VaultRepositoryConfigurationExtension
|
||||
extends KeyValueRepositoryConfigurationExtension {
|
||||
|
||||
private static final String VAULT_ADAPTER_BEAN_NAME = "vaultKeyValueAdapter";
|
||||
|
||||
@@ -68,7 +68,8 @@ public class VaultRepositoryConfigurationExtension extends
|
||||
Optional<String> vaultTemplateRef = configurationSource
|
||||
.getAttribute("vaultTemplateRef");
|
||||
|
||||
RootBeanDefinition mappingContextDefinition = createVaultMappingContext(configurationSource);
|
||||
RootBeanDefinition mappingContextDefinition = createVaultMappingContext(
|
||||
configurationSource);
|
||||
mappingContextDefinition.setSource(configurationSource.getSource());
|
||||
|
||||
registerIfNotAlreadyRegistered(() -> mappingContextDefinition, registry,
|
||||
@@ -83,8 +84,8 @@ public class VaultRepositoryConfigurationExtension extends
|
||||
constructorArgumentValuesForVaultKeyValueAdapter.addIndexedArgumentValue(0,
|
||||
new RuntimeBeanReference(vaultTemplateRef.orElse("vaultTemplate")));
|
||||
|
||||
vaultKeyValueAdapterDefinition
|
||||
.setConstructorArgumentValues(constructorArgumentValuesForVaultKeyValueAdapter);
|
||||
vaultKeyValueAdapterDefinition.setConstructorArgumentValues(
|
||||
constructorArgumentValuesForVaultKeyValueAdapter);
|
||||
|
||||
registerIfNotAlreadyRegistered(() -> vaultKeyValueAdapterDefinition, registry,
|
||||
VAULT_ADAPTER_BEAN_NAME, configurationSource);
|
||||
@@ -99,7 +100,8 @@ public class VaultRepositoryConfigurationExtension extends
|
||||
|
||||
registerIfNotAlreadyRegistered(
|
||||
() -> getDefaultKeyValueTemplateBeanDefinition(configurationSource),
|
||||
registry, keyValueTemplateName.get(), configurationSource.getSource());
|
||||
registry, keyValueTemplateName.get(),
|
||||
configurationSource.getSource());
|
||||
}
|
||||
|
||||
super.registerBeansForRoot(registry, configurationSource);
|
||||
@@ -132,8 +134,8 @@ public class VaultRepositoryConfigurationExtension extends
|
||||
constructorArgumentValuesForKeyValueTemplate.addIndexedArgumentValue(1,
|
||||
new RuntimeBeanReference(VAULT_MAPPING_CONTEXT_BEAN_NAME));
|
||||
|
||||
keyValueTemplateDefinition
|
||||
.setConstructorArgumentValues(constructorArgumentValuesForKeyValueTemplate);
|
||||
keyValueTemplateDefinition.setConstructorArgumentValues(
|
||||
constructorArgumentValuesForKeyValueTemplate);
|
||||
|
||||
return keyValueTemplateDefinition;
|
||||
}
|
||||
|
||||
@@ -116,8 +116,8 @@ public class DefaultVaultTypeMapper extends DefaultTypeMapper<Map<String, Object
|
||||
*
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
static class SecretDocumentTypeAliasAccessor implements
|
||||
TypeAliasAccessor<Map<String, Object>> {
|
||||
static class SecretDocumentTypeAliasAccessor
|
||||
implements TypeAliasAccessor<Map<String, Object>> {
|
||||
|
||||
private final @Nullable String typeKey;
|
||||
|
||||
|
||||
@@ -21,8 +21,8 @@ import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.springframework.core.CollectionFactory;
|
||||
import org.springframework.core.convert.support.DefaultConversionService;
|
||||
@@ -102,8 +102,8 @@ public class MappingVaultConverter extends AbstractVaultConverter {
|
||||
|
||||
SecretDocument secretDocument = getSecretDocument(source);
|
||||
|
||||
TypeInformation<? extends S> typeToUse = secretDocument != null ? typeMapper
|
||||
.readType(secretDocument.getBody(), type)
|
||||
TypeInformation<? extends S> typeToUse = secretDocument != null
|
||||
? typeMapper.readType(secretDocument.getBody(), type)
|
||||
: (TypeInformation) ClassTypeInformation.OBJECT;
|
||||
Class<? extends S> rawType = typeToUse.getType();
|
||||
|
||||
@@ -127,10 +127,8 @@ public class MappingVaultConverter extends AbstractVaultConverter {
|
||||
return (S) source;
|
||||
}
|
||||
|
||||
return read(
|
||||
(VaultPersistentEntity<S>) mappingContext
|
||||
.getRequiredPersistentEntity(typeToUse),
|
||||
secretDocument);
|
||||
return read((VaultPersistentEntity<S>) mappingContext
|
||||
.getRequiredPersistentEntity(typeToUse), secretDocument);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -159,7 +157,8 @@ public class MappingVaultConverter extends AbstractVaultConverter {
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public <T> T getParameterValue(Parameter<T, VaultPersistentProperty> parameter) {
|
||||
public <T> T getParameterValue(
|
||||
Parameter<T, VaultPersistentProperty> parameter) {
|
||||
|
||||
Object value = parameterProvider.getParameterValue(parameter);
|
||||
return value != null ? readValue(value, parameter.getType()) : null;
|
||||
@@ -206,8 +205,9 @@ public class MappingVaultConverter extends AbstractVaultConverter {
|
||||
|
||||
Object resolvedValue = documentAccessor.get(idProperty);
|
||||
|
||||
return resolvedValue != null ? readValue(resolvedValue,
|
||||
idProperty.getTypeInformation()) : null;
|
||||
return resolvedValue != null
|
||||
? readValue(resolvedValue, idProperty.getTypeInformation())
|
||||
: null;
|
||||
}
|
||||
|
||||
private void readProperties(VaultPersistentEntity<?> entity,
|
||||
@@ -261,21 +261,25 @@ public class MappingVaultConverter extends AbstractVaultConverter {
|
||||
*/
|
||||
@Nullable
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
private Object readCollectionOrArray(TypeInformation<?> targetType, List sourceValue) {
|
||||
private Object readCollectionOrArray(TypeInformation<?> targetType,
|
||||
List sourceValue) {
|
||||
|
||||
Assert.notNull(targetType, "Target type must not be null");
|
||||
|
||||
Class<?> collectionType = targetType.getType();
|
||||
|
||||
TypeInformation<?> componentType = targetType.getComponentType() != null ? targetType
|
||||
.getComponentType() : ClassTypeInformation.OBJECT;
|
||||
TypeInformation<?> componentType = targetType.getComponentType() != null
|
||||
? targetType.getComponentType()
|
||||
: ClassTypeInformation.OBJECT;
|
||||
Class<?> rawComponentType = componentType.getType();
|
||||
|
||||
collectionType = Collection.class.isAssignableFrom(collectionType) ? collectionType
|
||||
collectionType = Collection.class.isAssignableFrom(collectionType)
|
||||
? collectionType
|
||||
: List.class;
|
||||
Collection<Object> items = targetType.getType().isArray() ? new ArrayList<>(
|
||||
sourceValue.size()) : CollectionFactory.createCollection(collectionType,
|
||||
rawComponentType, sourceValue.size());
|
||||
Collection<Object> items = targetType.getType().isArray()
|
||||
? new ArrayList<>(sourceValue.size())
|
||||
: CollectionFactory.createCollection(collectionType, rawComponentType,
|
||||
sourceValue.size());
|
||||
|
||||
if (sourceValue.isEmpty()) {
|
||||
return getPotentiallyConvertedSimpleRead(items, collectionType);
|
||||
@@ -302,7 +306,7 @@ public class MappingVaultConverter extends AbstractVaultConverter {
|
||||
* {@link Map}s as well.
|
||||
*
|
||||
* @param type the {@link Map} {@link TypeInformation} to be used to unmarshal this
|
||||
* {@link Map}.
|
||||
* {@link Map}.
|
||||
* @param sourceMap must not be {@literal null}
|
||||
* @return
|
||||
*/
|
||||
@@ -344,8 +348,9 @@ public class MappingVaultConverter extends AbstractVaultConverter {
|
||||
}
|
||||
else if (value instanceof List) {
|
||||
map.put(key,
|
||||
readCollectionOrArray(valueType != null ? valueType
|
||||
: ClassTypeInformation.LIST, (List) value));
|
||||
readCollectionOrArray(
|
||||
valueType != null ? valueType : ClassTypeInformation.LIST,
|
||||
(List) value));
|
||||
}
|
||||
else {
|
||||
map.put(key, getPotentiallyConvertedSimpleRead(value, rawValueType));
|
||||
@@ -368,7 +373,8 @@ public class MappingVaultConverter extends AbstractVaultConverter {
|
||||
private Object getPotentiallyConvertedSimpleRead(@Nullable Object value,
|
||||
@Nullable Class<?> target) {
|
||||
|
||||
if (value == null || target == null || target.isAssignableFrom(value.getClass())) {
|
||||
if (value == null || target == null
|
||||
|| target.isAssignableFrom(value.getClass())) {
|
||||
return value;
|
||||
}
|
||||
|
||||
@@ -503,8 +509,8 @@ public class MappingVaultConverter extends AbstractVaultConverter {
|
||||
}
|
||||
|
||||
// Lookup potential custom target type
|
||||
Optional<Class<?>> basicTargetType = conversions.getCustomWriteTarget(obj
|
||||
.getClass());
|
||||
Optional<Class<?>> basicTargetType = conversions
|
||||
.getCustomWriteTarget(obj.getClass());
|
||||
|
||||
if (basicTargetType.isPresent()) {
|
||||
|
||||
@@ -512,9 +518,9 @@ public class MappingVaultConverter extends AbstractVaultConverter {
|
||||
return;
|
||||
}
|
||||
|
||||
VaultPersistentEntity<?> entity = isSubtype(prop.getType(), obj.getClass()) ? mappingContext
|
||||
.getRequiredPersistentEntity(obj.getClass()) : mappingContext
|
||||
.getRequiredPersistentEntity(type);
|
||||
VaultPersistentEntity<?> entity = isSubtype(prop.getType(), obj.getClass())
|
||||
? mappingContext.getRequiredPersistentEntity(obj.getClass())
|
||||
: mappingContext.getRequiredPersistentEntity(type);
|
||||
|
||||
SecretDocumentAccessor nested = accessor.writeNested(prop);
|
||||
|
||||
@@ -546,7 +552,7 @@ public class MappingVaultConverter extends AbstractVaultConverter {
|
||||
* Populates the given {@link List} with values from the given {@link Collection}.
|
||||
*
|
||||
* @param source the collection to create a {@link List} for, must not be
|
||||
* {@literal null}.
|
||||
* {@literal null}.
|
||||
* @param type the {@link TypeInformation} to consider or {@literal null} if unknown.
|
||||
* @param sink the {@link List} to write to.
|
||||
* @return
|
||||
@@ -596,7 +602,8 @@ public class MappingVaultConverter extends AbstractVaultConverter {
|
||||
Assert.notNull(map, "Given map must not be null");
|
||||
Assert.notNull(property, "PersistentProperty must not be null");
|
||||
|
||||
return writeMapInternal(map, new LinkedHashMap<>(), property.getTypeInformation());
|
||||
return writeMapInternal(map, new LinkedHashMap<>(),
|
||||
property.getTypeInformation());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -624,16 +631,15 @@ public class MappingVaultConverter extends AbstractVaultConverter {
|
||||
}
|
||||
else if (val instanceof Collection || val.getClass().isArray()) {
|
||||
|
||||
bson.put(
|
||||
simpleKey,
|
||||
writeCollectionInternal(asCollection(val),
|
||||
propertyType.getMapValueType(), new ArrayList<>()));
|
||||
bson.put(simpleKey, writeCollectionInternal(asCollection(val),
|
||||
propertyType.getMapValueType(), new ArrayList<>()));
|
||||
}
|
||||
else {
|
||||
SecretDocumentAccessor nested = new SecretDocumentAccessor(
|
||||
new SecretDocument());
|
||||
TypeInformation<?> valueTypeInfo = propertyType.isMap() ? propertyType
|
||||
.getMapValueType() : ClassTypeInformation.OBJECT;
|
||||
TypeInformation<?> valueTypeInfo = propertyType.isMap()
|
||||
? propertyType.getMapValueType()
|
||||
: ClassTypeInformation.OBJECT;
|
||||
writeInternal(val, nested, valueTypeInfo);
|
||||
bson.put(simpleKey, nested.getBody());
|
||||
}
|
||||
@@ -682,8 +688,8 @@ public class MappingVaultConverter extends AbstractVaultConverter {
|
||||
return null;
|
||||
}
|
||||
|
||||
Optional<Class<?>> customTarget = conversions.getCustomWriteTarget(value
|
||||
.getClass());
|
||||
Optional<Class<?>> customTarget = conversions
|
||||
.getCustomWriteTarget(value.getClass());
|
||||
|
||||
if (customTarget.isPresent()) {
|
||||
return conversionService.convert(value, customTarget.get());
|
||||
@@ -726,8 +732,8 @@ public class MappingVaultConverter extends AbstractVaultConverter {
|
||||
* {@link SecretDocument}.
|
||||
*
|
||||
*/
|
||||
class VaultPropertyValueProvider implements
|
||||
PropertyValueProvider<VaultPersistentProperty> {
|
||||
class VaultPropertyValueProvider
|
||||
implements PropertyValueProvider<VaultPersistentProperty> {
|
||||
|
||||
private final SecretDocumentAccessor source;
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@ class SecretDocumentAccessor {
|
||||
* Creates a new {@link SecretDocumentAccessor} for the given {@link SecretDocument}.
|
||||
*
|
||||
* @param document must be a {@link SecretDocument} effectively, must not be
|
||||
* {@literal null}.
|
||||
* {@literal null}.
|
||||
*/
|
||||
SecretDocumentAccessor(SecretDocument document) {
|
||||
|
||||
@@ -59,7 +59,7 @@ class SecretDocumentAccessor {
|
||||
* and {@link Map body}.
|
||||
*
|
||||
* @param document must be a {@link SecretDocument} effectively, must not be
|
||||
* {@literal null}
|
||||
* {@literal null}
|
||||
* @param body must not be {@literal null}.
|
||||
*/
|
||||
private SecretDocumentAccessor(SecretDocument document, Map<String, Object> body) {
|
||||
|
||||
@@ -24,7 +24,6 @@ import org.springframework.vault.repository.mapping.VaultPersistentProperty;
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public interface VaultConverter
|
||||
extends
|
||||
public interface VaultConverter extends
|
||||
EntityConverter<VaultPersistentEntity<?>, VaultPersistentProperty, Object, SecretDocument> {
|
||||
}
|
||||
|
||||
@@ -40,8 +40,8 @@ import org.springframework.vault.repository.mapping.VaultSimpleTypes;
|
||||
* @see org.springframework.data.mapping.model.SimpleTypeHolder
|
||||
* @see VaultSimpleTypes
|
||||
*/
|
||||
public class VaultCustomConversions extends
|
||||
org.springframework.data.convert.CustomConversions {
|
||||
public class VaultCustomConversions
|
||||
extends org.springframework.data.convert.CustomConversions {
|
||||
|
||||
private static final StoreConversions STORE_CONVERSIONS;
|
||||
|
||||
@@ -55,8 +55,8 @@ public class VaultCustomConversions extends
|
||||
converters.addAll(JodaTimeConverters.getConvertersToRegister());
|
||||
|
||||
STORE_CONVERTERS = Collections.unmodifiableList(converters);
|
||||
STORE_CONVERSIONS = StoreConversions
|
||||
.of(VaultSimpleTypes.HOLDER, STORE_CONVERTERS);
|
||||
STORE_CONVERSIONS = StoreConversions.of(VaultSimpleTypes.HOLDER,
|
||||
STORE_CONVERTERS);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -3,4 +3,3 @@
|
||||
*/
|
||||
@org.springframework.lang.NonNullApi
|
||||
package org.springframework.vault.repository.convert;
|
||||
|
||||
|
||||
@@ -40,10 +40,9 @@ public class MappingVaultEntityInformation<T, ID> extends
|
||||
|
||||
if (!entity.hasIdProperty()) {
|
||||
|
||||
throw new MappingException(
|
||||
String.format(
|
||||
"Entity %s requires to have an explicit id field. Did you forget to provide one using @Id?",
|
||||
entity.getName()));
|
||||
throw new MappingException(String.format(
|
||||
"Entity %s requires to have an explicit id field. Did you forget to provide one using @Id?",
|
||||
entity.getName()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,8 +40,8 @@ import org.springframework.vault.repository.query.VaultQuery;
|
||||
* @see VaultQuery
|
||||
* @see org.springframework.vault.repository.query.VaultQueryCreator
|
||||
*/
|
||||
class VaultQueryEngine extends
|
||||
QueryEngine<VaultKeyValueAdapter, VaultQuery, Comparator<?>> {
|
||||
class VaultQueryEngine
|
||||
extends QueryEngine<VaultKeyValueAdapter, VaultQuery, Comparator<?>> {
|
||||
|
||||
private static final SpelExpressionParser parser = new SpelExpressionParser();
|
||||
|
||||
|
||||
@@ -3,4 +3,3 @@
|
||||
*/
|
||||
@org.springframework.lang.NonNullApi
|
||||
package org.springframework.vault.repository.core;
|
||||
|
||||
|
||||
@@ -47,7 +47,8 @@ public class VaultMappingContext extends
|
||||
@Override
|
||||
protected <T> VaultPersistentEntity<?> createPersistentEntity(
|
||||
TypeInformation<T> typeInformation) {
|
||||
return new BasicVaultPersistentEntity<>(typeInformation, fallbackKeySpaceResolver);
|
||||
return new BasicVaultPersistentEntity<>(typeInformation,
|
||||
fallbackKeySpaceResolver);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -24,8 +24,8 @@ import org.springframework.data.mapping.PersistentEntity;
|
||||
* @author Mark Paluch
|
||||
* @since 2.0
|
||||
*/
|
||||
public interface VaultPersistentEntity<T> extends
|
||||
KeyValuePersistentEntity<T, VaultPersistentProperty> {
|
||||
public interface VaultPersistentEntity<T>
|
||||
extends KeyValuePersistentEntity<T, VaultPersistentProperty> {
|
||||
|
||||
/**
|
||||
* @return the secret backend in which this {@link PersistentEntity} is stored.
|
||||
|
||||
@@ -30,8 +30,8 @@ import org.springframework.data.mapping.model.SimpleTypeHolder;
|
||||
* @author Mark Paluch
|
||||
* @since 2.0
|
||||
*/
|
||||
public class VaultPersistentProperty extends
|
||||
KeyValuePersistentProperty<VaultPersistentProperty> {
|
||||
public class VaultPersistentProperty
|
||||
extends KeyValuePersistentProperty<VaultPersistentProperty> {
|
||||
|
||||
private static final Set<String> SUPPORTED_ID_PROPERTY_NAMES = new HashSet<String>();
|
||||
|
||||
|
||||
@@ -40,8 +40,8 @@ public abstract class VaultSimpleTypes {
|
||||
}
|
||||
|
||||
private static final Set<Class<?>> VAULT_SIMPLE_TYPES;
|
||||
public static final SimpleTypeHolder HOLDER = new SimpleTypeHolder(
|
||||
VAULT_SIMPLE_TYPES, true);
|
||||
public static final SimpleTypeHolder HOLDER = new SimpleTypeHolder(VAULT_SIMPLE_TYPES,
|
||||
true);
|
||||
|
||||
private VaultSimpleTypes() {
|
||||
}
|
||||
|
||||
@@ -3,4 +3,3 @@
|
||||
*/
|
||||
@org.springframework.lang.NonNullApi
|
||||
package org.springframework.vault.repository.mapping;
|
||||
|
||||
|
||||
@@ -56,8 +56,8 @@ public class VaultPartTreeQuery extends KeyValuePartTreeQuery {
|
||||
(MappingContext) keyValueOperations.getMappingContext()));
|
||||
}
|
||||
|
||||
static class VaultQueryCreatorFactory implements
|
||||
QueryCreatorFactory<VaultQueryCreator> {
|
||||
static class VaultQueryCreatorFactory
|
||||
implements QueryCreatorFactory<VaultQueryCreator> {
|
||||
|
||||
private final MappingContext<VaultPersistentEntity<?>, VaultPersistentProperty> mappingContext;
|
||||
|
||||
|
||||
@@ -30,9 +30,9 @@ import org.springframework.data.mapping.context.MappingContext;
|
||||
import org.springframework.data.repository.query.ParameterAccessor;
|
||||
import org.springframework.data.repository.query.parser.AbstractQueryCreator;
|
||||
import org.springframework.data.repository.query.parser.Part;
|
||||
import org.springframework.data.repository.query.parser.PartTree;
|
||||
import org.springframework.data.repository.query.parser.Part.IgnoreCaseType;
|
||||
import org.springframework.data.repository.query.parser.Part.Type;
|
||||
import org.springframework.data.repository.query.parser.PartTree;
|
||||
import org.springframework.vault.repository.mapping.VaultPersistentEntity;
|
||||
import org.springframework.vault.repository.mapping.VaultPersistentProperty;
|
||||
|
||||
@@ -44,8 +44,8 @@ import org.springframework.vault.repository.mapping.VaultPersistentProperty;
|
||||
* @author Mark Paluch
|
||||
* @since 2.0
|
||||
*/
|
||||
public class VaultQueryCreator extends
|
||||
AbstractQueryCreator<KeyValueQuery<VaultQuery>, VaultQuery> {
|
||||
public class VaultQueryCreator
|
||||
extends AbstractQueryCreator<KeyValueQuery<VaultQuery>, VaultQuery> {
|
||||
|
||||
private final MappingContext<VaultPersistentEntity<?>, VaultPersistentProperty> mappingContext;
|
||||
|
||||
@@ -57,9 +57,7 @@ public class VaultQueryCreator extends
|
||||
* @param parameters must not be {@literal null}.
|
||||
* @param mappingContext must not be {@literal null}.
|
||||
*/
|
||||
public VaultQueryCreator(
|
||||
PartTree tree,
|
||||
ParameterAccessor parameters,
|
||||
public VaultQueryCreator(PartTree tree, ParameterAccessor parameters,
|
||||
MappingContext<VaultPersistentEntity<?>, VaultPersistentProperty> mappingContext) {
|
||||
|
||||
super(tree, parameters);
|
||||
@@ -83,9 +81,9 @@ public class VaultQueryCreator extends
|
||||
|
||||
if (propertyPath.getLeafProperty() != null
|
||||
&& !propertyPath.getLeafProperty().isIdProperty()) {
|
||||
throw new InvalidDataAccessApiUsageException(String.format(
|
||||
"Cannot create criteria for non-@Id property %s",
|
||||
propertyPath.getLeafProperty()));
|
||||
throw new InvalidDataAccessApiUsageException(
|
||||
String.format("Cannot create criteria for non-@Id property %s",
|
||||
propertyPath.getLeafProperty()));
|
||||
}
|
||||
|
||||
VariableAccessor accessor = getVariableAccessor(part);
|
||||
@@ -147,8 +145,10 @@ public class VaultQueryCreator extends
|
||||
return new Criteria<>(accessor.nextString(parameters),
|
||||
(value, it) -> !it.contains(value));
|
||||
case REGEX:
|
||||
return Pattern.compile((String) parameters.next(),
|
||||
isIgnoreCase(part) ? Pattern.CASE_INSENSITIVE : 0).asPredicate();
|
||||
return Pattern
|
||||
.compile((String) parameters.next(),
|
||||
isIgnoreCase(part) ? Pattern.CASE_INSENSITIVE : 0)
|
||||
.asPredicate();
|
||||
case TRUE:
|
||||
return it -> it.equalsIgnoreCase("true");
|
||||
case FALSE:
|
||||
@@ -220,13 +220,13 @@ public class VaultQueryCreator extends
|
||||
final Criteria<?> other = (Criteria<?>) o;
|
||||
final Object this$value = this.getValue();
|
||||
final Object other$value = other.getValue();
|
||||
if (this$value == null ? other$value != null : !this$value
|
||||
.equals(other$value))
|
||||
if (this$value == null ? other$value != null
|
||||
: !this$value.equals(other$value))
|
||||
return false;
|
||||
final Object this$predicate = this.getPredicate();
|
||||
final Object other$predicate = other.getPredicate();
|
||||
if (this$predicate == null ? other$predicate != null : !this$predicate
|
||||
.equals(other$predicate))
|
||||
if (this$predicate == null ? other$predicate != null
|
||||
: !this$predicate.equals(other$predicate))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -3,4 +3,3 @@
|
||||
*/
|
||||
@org.springframework.lang.NonNullApi
|
||||
package org.springframework.vault.repository.query;
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user