35 Commits

Author SHA1 Message Date
bbceee35f2 test against Vault 1.8.0
All checks were successful
continuous-integration/drone/push Build is passing
2021-07-28 19:38:06 +02:00
3a920fe960 prepare release 0.9.5
All checks were successful
continuous-integration/drone/push Build is passing
2021-07-28 19:34:48 +02:00
eed61c4569 minor dependency updates
All checks were successful
continuous-integration/drone/push Build is passing
2021-07-27 21:25:20 +02:00
53d954ea12 deprecate all convenience methods to interact with "secret/" mount
All checks were successful
continuous-integration/drone/push Build is passing
Follow-up deprecation for the not yet deprecated wrapper methods.
2021-06-12 10:46:10 +02:00
e578591a49 deprecate convenience methods to interact with "secret/" mount (#52)
All checks were successful
continuous-integration/drone/push Build is passing
2021-06-11 21:33:59 +02:00
de17f48be2 move builder into main package, introduce new invocation method (#51)
Some checks failed
continuous-integration/drone/push Build is failing
The builder is target of major refactoring in the 1.0 development branch
so we introduce some delegate classes and methods to prepare migration.
2021-06-11 21:15:49 +02:00
5f9950e048 prepare release 0.9.4
All checks were successful
continuous-integration/drone/push Build is passing
2021-06-06 12:22:13 +02:00
e2c439379e switch to "main" as default branch name
All checks were successful
continuous-integration/drone/push Build is passing
2021-06-06 12:09:28 +02:00
ce33d37396 minor dependency updates; test against Vault 1.7.2
All checks were successful
continuous-integration/drone/push Build is passing
2021-06-06 12:07:02 +02:00
bdf4fc4b83 fix typo in method AppRole.Builder#wit0hTokenPeriod (#49) 2021-06-06 12:02:01 +02:00
50d485fab8 clean up unused imports
All checks were successful
continuous-integration/drone/push Build is passing
2021-04-02 11:27:24 +02:00
5b508374d9 prepare release 0.9.3
All checks were successful
continuous-integration/drone/push Build is passing
2021-04-02 11:16:04 +02:00
fbc61e065f fix argline for JDK 1.8 unit tests
All checks were successful
continuous-integration/drone/push Build is passing
2021-03-29 21:13:34 +02:00
56a52cb22a fix argline for JDK 16 unit tests
All checks were successful
continuous-integration/drone/push Build is passing
2021-03-29 20:50:16 +02:00
c43ec190ca use SystemLambda instead of custom environment mocks 2021-03-29 20:49:44 +02:00
639d0e3c5b Jackson 2.12.2, test against Vault 1.7.0
All checks were successful
continuous-integration/drone/push Build is passing
2021-03-29 18:56:24 +02:00
8e97f3c1dd build with JDK 16, test against Vault 1.6.3
All checks were successful
continuous-integration/drone/push Build is passing
2021-03-20 12:13:19 +01:00
c04d940a80 test: close static mocks
All checks were successful
continuous-integration/drone/push Build is passing
2021-02-28 13:03:25 +01:00
76a5ea4fe9 test: use assertThrows instead of try-catch blocks
All checks were successful
continuous-integration/drone/push Build is passing
2021-02-28 12:59:06 +01:00
2b0f458da3 use pre-sized maps for fixed-size payloads
All checks were successful
continuous-integration/drone/push Build is passing
2021-02-28 10:52:36 +01:00
63278c09c8 constructors of abstract VaultConnectorException protected
All checks were successful
continuous-integration/drone/push Build is passing
2021-01-24 14:57:14 +01:00
600f3d0d0f test classes package-private; use mockStatic()
All checks were successful
continuous-integration/drone/push Build is passing
2021-01-24 14:52:48 +01:00
1a19eaa87d release 0.9.2
All checks were successful
continuous-integration/drone/push Build is passing
2021-01-24 12:26:29 +01:00
a2dde38348 Jackson 2.12.1
All checks were successful
continuous-integration/drone/push Build is passing
2021-01-24 12:24:09 +01:00
dfb6d0a37c only initialize trust managers if CA certificate is provided (#43)
All checks were successful
continuous-integration/drone/push Build is passing
2021-01-24 12:20:45 +01:00
b46b59e4a0 update copyright notice to 2021
All checks were successful
continuous-integration/drone/push Build is passing
2021-01-03 11:56:33 +01:00
79ec536876 prepare release of v0.9.1
All checks were successful
continuous-integration/drone/push Build is passing
2021-01-03 11:48:51 +01:00
00d4e9acef test against Vault 1.6.1
All checks were successful
continuous-integration/drone/push Build is passing
2021-01-03 11:46:40 +01:00
48eccedad0 introduce maven profile for dependency analysis 2021-01-03 11:44:34 +01:00
ec4c4ac868 rework Travis CI configuration
Separate stages do not work as intended.
Add LTS and latest JDK (8, 11, 15) to build roster and run analysis with JDK 11 only.
2020-12-12 11:52:43 +01:00
90835aea92 dependency updates
All checks were successful
continuous-integration/drone/push Build is passing
Jackson 2.12, HTTPClient 4.5.13 and some test dependencies
2020-12-12 11:18:17 +01:00
32eed75de8 use batch mode in CI builds
All checks were successful
continuous-integration/drone/push Build is passing
Do not bloat the log with progress output.
2020-12-02 10:14:16 +01:00
c8ca5c4091 test against Vault 1.6.0
All checks were successful
continuous-integration/drone/push Build is passing
2020-11-12 19:48:08 +01:00
4ba81492d5 docs: update Travis CI badge
All checks were successful
continuous-integration/drone/push Build is passing
2020-09-08 21:28:16 +02:00
84b9877ca9 test against Vault 1.5.0 2020-07-26 14:12:13 +02:00
82 changed files with 1818 additions and 2086 deletions

View File

@ -5,10 +5,10 @@ steps:
- name: compile
image: maven:3-jdk-11
commands:
- mvn clean compile
- mvn -B clean compile
when:
branch:
- master
- main
- develop
- feature/*
- fix/*
@ -16,7 +16,7 @@ steps:
- name: unit-tests
image: maven:3-jdk-11
commands:
- mvn test -P offline-tests
- mvn -B resources:testResources compiler:testCompile surefire:test -P offline-tests
when:
branch:
- develop
@ -25,15 +25,15 @@ steps:
- name: unit-integration-tests
image: maven:3-jdk-11
environment:
VAULT_VERSION: 1.4.0
VAULT_VERSION: 1.8.0
commands:
- curl -s -o vault_1.4.0_linux_amd64.zip https://releases.hashicorp.com/vault/1.4.0/vault_1.4.0_linux_amd64.zip
- curl -s https://releases.hashicorp.com/vault/1.4.0/vault_1.4.0_SHA256SUMS | grep linux_amd64 | sha256sum -c
- unzip vault_1.4.0_linux_amd64.zip
- rm vault_1.4.0_linux_amd64.zip
- curl -s -o vault_1.8.0_linux_amd64.zip https://releases.hashicorp.com/vault/1.8.0/vault_1.8.0_linux_amd64.zip
- curl -s https://releases.hashicorp.com/vault/1.8.0/vault_1.8.0_SHA256SUMS | grep linux_amd64 | sha256sum -c
- unzip vault_1.8.0_linux_amd64.zip
- rm vault_1.8.0_linux_amd64.zip
- mv vault /bin/
- mvn test
- mvn -B resources:testResources compiler:testCompile surefire:test
when:
branch:
- master
- main
- release/*

View File

@ -1,47 +1,46 @@
language: java
jdk:
- openjdk11
install: true
addons:
sonarcloud:
organization: "stklcode-github"
token:
secure: "sM9OfX5jW764pn9cb2LSXArnXucKMws+eGeg5NnZxHRcGYt4hpBKLSregBSsBNzUoWVj0zNzPCpnh+UQvgxQzUerOqwEdjTBpy3SNPaxSn7UpoSg+Wz3aUmL9ugmx01b51/wMG4UCHEwTZt2tpgTPVtw8K6uSO78e0dSICCBHDnRcdQwOjMEQHIJJ/qHVRwuy/MzLCAP3W1JPZlsphZg9QsFyhB4hW97dE90joZezfocQIv2xI/r6k+BLz0pY6MxYCul0RiDumaiaej0CPvEJI/uSu//BAQjUdHw+mQgnKUYIbrn2ONOviwNfwdr94JyoZEN2B6zASUmNLjPf4AbIojDeyS+CrpQpm17EVm/Qk/Ds+Xra4PPPIcsZhiWzV0KoDUz9xLfXuRJ526VT5tDPiaeI7oETf0+8l+JIS1b399FyqHi7smzjpvC6GuKflQrbuHK4MuKzDh7WTHiqokGG4SS0wOQIaaHB3dfdwwQzPh6IM24e8CETxh3DjMeqUTU4DWmv5po55jZ934TtxVQvVN78bTG9O0zS9u+JmRY04OZ+OaXuFam6MfMUFQi0EPZzdGul/oWSibGUu3bNfVEBp60CnJwYNM/dKG6U7pJthLHvSwiQFOdKzHZ+l1jZJ4gPaXaIGqpwqVGr28ntqA/El1rytPixr2driE6bYMt5jw="
stages:
- Compile
- Test
- Analysis
env:
- PATH=$PATH:. VAULT_VERSION=1.4.0
- PATH=$PATH:. VAULT_VERSION=1.8.0 ANALYSIS=false
cache:
directories:
- '$HOME/.m2/repository'
- '$HOME/.sonar/cache'
jobs:
include:
- jdk: openjdk8
- jdk: openjdk11
env: PATH=$PATH:. VAULT_VERSION=1.8.0 ANALYSIS=true
- jdk: openjdk16
before_script:
- |
if [[ "$TRAVIS_BRANCH" =~ ^master|(release\/.+)$ ]]; then
if [[ "$TRAVIS_BRANCH" =~ ^main|(release\/.+)$ ]]; then
wget -q https://releases.hashicorp.com/vault/${VAULT_VERSION}/vault_${VAULT_VERSION}_linux_amd64.zip
wget -q -O - https://releases.hashicorp.com/vault/${VAULT_VERSION}/vault_${VAULT_VERSION}_SHA256SUMS | grep linux_amd64 | sha256sum -c
unzip vault_${VAULT_VERSION}_linux_amd64.zip
rm vault_${VAULT_VERSION}_linux_amd64.zip
fi
cache:
directories:
- '$HOME/.m2/repository'
- '$HOME/.sonar/cache'
jobs:
include:
- stage: Compile
name: Compile
script:
- mvn clean compile
- stage: Test
name: Unit Tests
if: NOT branch =~ ^master|(release/.+)$
script:
- mvn test -P offline-tests
- name: Unit and Integration Tests
if: branch =~ ^master|(release/.+)$
script:
- mvn -P coverage clean package
after_success:
- if [ "$TRAVIS_BRANCH" = "master" ]; then mvn sonar:sonar; fi
script:
- mvn -B clean compile
- |
if [[ "$TRAVIS_BRANCH" =~ ^main|(release\/.+)$ ]]; then
mvn -B resources:testResources compiler:testCompile surefire:test -P coverage
else
mvn -B resources:testResources compiler:testCompile surefire:test -P coverage -P offline-tests
fi
after_success:
- if [ "$ANALYSIS" == "true" ]; then mvn sonar:sonar; fi
notifications:
slack:

View File

@ -1,3 +1,55 @@
## 0.9.5 (2021-07-28)
### Deprecations
* Deprecate ` {read,write,delete}Secret()` convenience methods. Use `{read,write,delete}("secret/...")` instead (#52)
* Deprecated builder invocation `VaultConnectorBuilder.http()` in favor of `HTTPVaultConnector.builder()` (#51)
* Deprecated `de.stklcode.jvault.connector.builder.HTTPVaultConnectorBuilder` in favor of `de.stklcode.jvault.connector.HTTPVaultConnectorBuilder` (only package changed) (#51)
Old builders will be removed in 1.0
### Improvements
* Minor dependency updates
### Test
* Tested against Vault 1.8.0
## 0.9.4 (2021-06-06)
### Deprecations
* `AppRole.Builder#wit0hTokenPeriod()` is deprecated in favor of `#withTokenPeriod()` (#49)
### Improvements
* Minor dependency updates
### Test
* Tested against Vault 1.7.2
## 0.9.3 (2021-04-02)
### Improvements
* Use pre-sized map objects for fixed-size payloads
* Minor dependency updates
* Unit test adjustments for JDK 16 build environments
### Test
* Tested against Vault 1.7.0
## 0.9.2 (2021-01-24)
### Fixes
* Only initialize custom trust managers, if CA certificate is actually provided (#43)
### Improvements
* Minor dependency updates
## 0.9.1 (2021-01-03)
### Improvements
* Dependency updates
### Test
* Tested against Vault 1.6.1
## 0.9.0 (2020-04-29)
### Fixes

View File

@ -1,11 +1,11 @@
# Java Vault Connector
[![Build Status](https://travis-ci.org/stklcode/jvaultconnector.svg?branch=master)](https://travis-ci.org/stklcode/jvaultconnector)
[![Build Status](https://travis-ci.com/stklcode/jvaultconnector.svg?branch=main)](https://travis-ci.com/stklcode/jvaultconnector)
[![Quality Gate](https://sonarcloud.io/api/project_badges/measure?project=de.stklcode.jvault%3Ajvault-connector&metric=alert_status)](https://sonarcloud.io/dashboard?id=de.stklcode.jvault%3Ajvault-connector)
[![License](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](https://github.com/stklcode/jvaultconnector/blob/master/LICENSE.txt)
[![License](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](https://github.com/stklcode/jvaultconnector/blob/main/LICENSE.txt)
[![Maven Central](https://img.shields.io/maven-central/v/de.stklcode.jvault/jvault-connector.svg)](https://search.maven.org/#search%7Cga%7C1%7Cg%3A%22de.stklcode.jvault%22%20AND%20a%3A%22jvault-connector%22)
![Logo](https://raw.githubusercontent.com/stklcode/jvaultconnector/master/assets/logo.png)
![Logo](https://raw.githubusercontent.com/stklcode/jvaultconnector/main/assets/logo.png)
Java Vault Connector is a connector library for [Vault](https://www.vaultproject.io) by [Hashicorp](https://www.hashicorp.com) written in Java. The connector allows simple usage of Vault's secret store in own applications.
@ -32,7 +32,7 @@ Java Vault Connector is a connector library for [Vault](https://www.vaultproject
* SQL secret handling
* KV v1 and v2 support
* Connector Factory with builder pattern
* Tested against Vault 1.4.0
* Tested against Vault 1.8.0
## Maven Artifact
@ -40,7 +40,7 @@ Java Vault Connector is a connector library for [Vault](https://www.vaultproject
<dependency>
<groupId>de.stklcode.jvault</groupId>
<artifactId>jvault-connector</artifactId>
<version>0.9.0</version>
<version>0.9.5</version>
</dependency>
```
@ -50,21 +50,21 @@ Java Vault Connector is a connector library for [Vault](https://www.vaultproject
```java
// Instantiate using builder pattern style factory (TLS enabled by default)
VaultConnector vault = VaultConnectorBuilder.http()
VaultConnector vault = HTTPVaultConnector.builder()
.withHost("127.0.0.1")
.withPort(8200)
.withTLS()
.build();
// Instantiate with custom SSL context
VaultConnector vault = VaultConnectorBuilder.http()
VaultConnector vault = HTTPVaultConnector.builder()
.withHost("example.com")
.withPort(8200)
.withTrustedCA(Paths.get("/path/to/CA.pem"))
.build();
// Initialization from environment variables
VaultConnector vault = VaultConnectorBuilder.http()
VaultConnector vault = HTTPVaultConnector.builder()
.fromEnv()
.build();
```
@ -86,20 +86,20 @@ vault.authAppRole("01234567-89ab-cdef-0123-456789abcdef", "fedcba98-7654-3210-fe
```java
// Retrieve secret (prefix "secret/" assumed, use read() to read arbitrary paths)
String secret = vault.readSecret("some/secret/key").get("value", String.class);
String secret = vault.read("secret/some/key").get("value", String.class);
// Complex secret.
Map<String, Object> secretData = vault.readSecret("another/secret/key").getData();
Map<String, Object> secretData = vault.read("secret/another/key").getData();
// Write simple secret.
vault.writeSecret("new/secret/key", "secret value");
vault.write("secret/new/key", "secret value");
// Write complex data to arbitraty path.
// Write complex data.
Map<String, Object> map = ...;
vault.write("any/path/to/write", map);
vault.write("path/to/write", map);
// Delete secret.
vault.delete("any/path/to/write");
vault.delete("path/to/delete");
```
### Token and role creation

107
pom.xml
View File

@ -4,7 +4,7 @@
<groupId>de.stklcode.jvault</groupId>
<artifactId>jvault-connector</artifactId>
<version>0.9.0</version>
<version>0.9.5</version>
<packaging>jar</packaging>
@ -23,6 +23,7 @@
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<argLine></argLine>
</properties>
<developers>
@ -66,7 +67,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>3.1.0</version>
<version>3.2.0</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
@ -85,12 +86,18 @@
<artifactId>maven-install-plugin</artifactId>
<version>2.5.2</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.8.2</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.2</version>
<configuration>
<reuseForks>false</reuseForks>
<argLine>@{argLine} --illegal-access=permit</argLine>
</configuration>
</plugin>
</plugins>
@ -101,18 +108,18 @@
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.12</version>
<version>4.5.13</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.10.3</version>
<version>2.12.4</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.6.2</version>
<version>5.7.2</version>
<scope>test</scope>
</dependency>
<dependency>
@ -121,45 +128,22 @@
<version>2.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>3.3.3</version>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>net.bytebuddy</groupId>
<artifactId>byte-buddy</artifactId>
</exclusion>
<exclusion>
<groupId>net.bytebuddy</groupId>
<artifactId>byte-buddy-agent</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-inline</artifactId>
<version>3.3.3</version>
<scope>test</scope>
</dependency>
<!-- Updated transient dependency from mockito-core for JDK 13 compatibility -->
<dependency>
<groupId>net.bytebuddy</groupId>
<artifactId>byte-buddy</artifactId>
<version>1.10.9</version>
<version>3.11.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>net.bytebuddy</groupId>
<artifactId>byte-buddy-agent</artifactId>
<version>1.10.9</version>
<groupId>com.github.stefanbirkner</groupId>
<artifactId>system-lambda</artifactId>
<version>1.2.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
<version>2.11.0</version>
<scope>test</scope>
</dependency>
</dependencies>
@ -169,7 +153,7 @@
<dependency>
<groupId>org.sonarsource.scanner.maven</groupId>
<artifactId>sonar-maven-plugin</artifactId>
<version>3.7.0.1746</version>
<version>3.9.0.2155</version>
</dependency>
</dependencies>
</dependencyManagement>
@ -210,7 +194,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.2.0</version>
<version>3.3.0</version>
<configuration>
<source>1.8</source>
</configuration>
@ -234,7 +218,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-gpg-plugin</artifactId>
<version>1.6</version>
<version>3.0.1</version>
<executions>
<execution>
<id>sign-artifacts</id>
@ -259,17 +243,16 @@
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.5</version>
<version>0.8.7</version>
<executions>
<execution>
<id>prepare-agent</id>
<id>default-prepare-agent</id>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>report</id>
<phase>prepare-package</phase>
<id>default-report</id>
<goals>
<goal>report</goal>
</goals>
@ -297,6 +280,46 @@
</build>
</profile>
<profile>
<id>dependency-check</id>
<build>
<plugins>
<plugin>
<groupId>org.owasp</groupId>
<artifactId>dependency-check-maven</artifactId>
<version>6.2.2</version>
<executions>
<execution>
<goals>
<goal>check</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>jdk1.8</id>
<activation>
<jdk>1.8</jdk>
</activation>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<argLine>@{argLine}</argLine>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
</profile>
<profile>
<id>sonatype</id>
<distributionManagement>
@ -315,11 +338,11 @@
<id>local</id>
<distributionManagement>
<repository>
<id>local</id>
<id>stklcode</id>
<url>${dist.repo.local}</url>
</repository>
<snapshotRepository>
<id>local</id>
<id>stklcode</id>
<url>${dist.repo.local.snapshot}</url>
</snapshotRepository>
</distributionManagement>

View File

@ -1,5 +1,5 @@
/*
* Copyright 2016-2020 Stefan Kalscheuer
* Copyright 2016-2021 Stefan Kalscheuer
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -30,6 +30,9 @@ import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import static java.util.Collections.emptyMap;
import static java.util.Collections.singletonMap;
/**
* Vault Connector implementation using Vault's HTTP API.
*
@ -68,6 +71,16 @@ public class HTTPVaultConnector implements VaultConnector {
private String token; // Current token.
private long tokenTTL = 0; // Expiration time for current token.
/**
* Get a new builder for a connector.
*
* @return Builder instance.
* @since 0.9.5
*/
public static HTTPVaultConnectorBuilder builder() {
return new HTTPVaultConnectorBuilder();
}
/**
* Create connector using hostname and schema.
*
@ -222,17 +235,17 @@ public class HTTPVaultConnector implements VaultConnector {
@Override
public final SealResponse sealStatus() throws VaultConnectorException {
return request.get(PATH_SEAL_STATUS, new HashMap<>(), token, SealResponse.class);
return request.get(PATH_SEAL_STATUS, emptyMap(), token, SealResponse.class);
}
@Override
public final void seal() throws VaultConnectorException {
request.put(PATH_SEAL, new HashMap<>(), token);
request.put(PATH_SEAL, emptyMap(), token);
}
@Override
public final SealResponse unseal(final String key, final Boolean reset) throws VaultConnectorException {
Map<String, String> param = new HashMap<>();
Map<String, String> param = new HashMap<>(2, 1);
param.put("key", key);
if (reset != null) {
param.put("reset", reset.toString());
@ -244,7 +257,7 @@ public class HTTPVaultConnector implements VaultConnector {
@Override
public HealthResponse getHealth() throws VaultConnectorException {
/* Force status code to be 200, so we don't need to modify the request sequence. */
Map<String, String> param = new HashMap<>();
Map<String, String> param = new HashMap<>(3, 1);
param.put("standbycode", "200"); // Default: 429.
param.put("sealedcode", "200"); // Default: 503.
param.put("uninitcode", "200"); // Default: 501.
@ -260,7 +273,7 @@ public class HTTPVaultConnector implements VaultConnector {
@Override
public final List<AuthBackend> getAuthBackends() throws VaultConnectorException {
/* Issue request and parse response */
AuthMethodsResponse amr = request.get(PATH_AUTH, new HashMap<>(), token, AuthMethodsResponse.class);
AuthMethodsResponse amr = request.get(PATH_AUTH, emptyMap(), token, AuthMethodsResponse.class);
return amr.getSupportedMethods().values().stream().map(AuthMethod::getType).collect(Collectors.toList());
}
@ -270,7 +283,7 @@ public class HTTPVaultConnector implements VaultConnector {
/* set token */
this.token = token;
this.tokenTTL = 0;
TokenResponse res = request.post(PATH_TOKEN + PATH_LOOKUP, new HashMap<>(), token, TokenResponse.class);
TokenResponse res = request.post(PATH_TOKEN + PATH_LOOKUP, emptyMap(), token, TokenResponse.class);
authorized = true;
return res;
@ -279,15 +292,14 @@ public class HTTPVaultConnector implements VaultConnector {
@Override
public final AuthResponse authUserPass(final String username, final String password)
throws VaultConnectorException {
final Map<String, String> payload = new HashMap<>();
payload.put("password", password);
final Map<String, String> payload = singletonMap("password", password);
return queryAuth(PATH_AUTH_USERPASS + username, payload);
}
@Override
@Deprecated
public final AuthResponse authAppId(final String appID, final String userID) throws VaultConnectorException {
final Map<String, String> payload = new HashMap<>();
final Map<String, String> payload = new HashMap<>(2, 1);
payload.put("app_id", appID);
payload.put("user_id", userID);
return queryAuth(PATH_AUTH_APPID + "login", payload);
@ -295,7 +307,7 @@ public class HTTPVaultConnector implements VaultConnector {
@Override
public final AuthResponse authAppRole(final String roleID, final String secretID) throws VaultConnectorException {
final Map<String, String> payload = new HashMap<>();
final Map<String, String> payload = new HashMap<>(2, 1);
payload.put("role_id", roleID);
if (secretID != null) {
payload.put("secret_id", secretID);
@ -328,7 +340,7 @@ public class HTTPVaultConnector implements VaultConnector {
public final boolean registerAppId(final String appID, final String policy, final String displayName)
throws VaultConnectorException {
requireAuth();
Map<String, String> payload = new HashMap<>();
Map<String, String> payload = new HashMap<>(2, 1);
payload.put("value", policy);
payload.put("display_name", displayName);
@ -342,11 +354,13 @@ public class HTTPVaultConnector implements VaultConnector {
@Deprecated
public final boolean registerUserId(final String appID, final String userID) throws VaultConnectorException {
requireAuth();
Map<String, String> payload = new HashMap<>();
payload.put("value", appID);
/* Issue request and expect code 204 with empty response */
request.postWithoutResponse(PATH_AUTH_APPID + "map/user-id/" + userID, payload, token);
request.postWithoutResponse(
PATH_AUTH_APPID + "map/user-id/" + userID,
singletonMap("value", appID),
token
);
return true;
}
@ -366,7 +380,12 @@ public class HTTPVaultConnector implements VaultConnector {
public final AppRoleResponse lookupAppRole(final String roleName) throws VaultConnectorException {
requireAuth();
/* Request HTTP response and parse Secret */
return request.get(String.format(PATH_AUTH_APPROLE_ROLE, roleName, ""), new HashMap<>(), token, AppRoleResponse.class);
return request.get(
String.format(PATH_AUTH_APPROLE_ROLE, roleName, ""),
emptyMap(),
token,
AppRoleResponse.class
);
}
@Override
@ -385,7 +404,7 @@ public class HTTPVaultConnector implements VaultConnector {
/* Issue request, parse response and extract Role ID */
return request.get(
String.format(PATH_AUTH_APPROLE_ROLE, roleName, "/role-id"),
new HashMap<>(),
emptyMap(),
token,
RawDataResponse.class
).getData().get("role_id").toString();
@ -394,12 +413,13 @@ public class HTTPVaultConnector implements VaultConnector {
@Override
public final boolean setAppRoleID(final String roleName, final String roleID) throws VaultConnectorException {
requireAuth();
/* Request HTTP response and parse Secret */
Map<String, String> payload = new HashMap<>();
payload.put("role_id", roleID);
/* Issue request and expect code 204 with empty response */
request.postWithoutResponse(String.format(PATH_AUTH_APPROLE_ROLE, roleName, "/role-id"), payload, token);
request.postWithoutResponse(
String.format(PATH_AUTH_APPROLE_ROLE, roleName, "/role-id"),
singletonMap("role_id", roleID),
token
);
return true;
}
@ -457,7 +477,13 @@ public class HTTPVaultConnector implements VaultConnector {
public final List<String> listAppRoles() throws VaultConnectorException {
requireAuth();
SecretListResponse secrets = request.get(PATH_AUTH_APPROLE + "role?list=true", new HashMap<>(), token, SecretListResponse.class);
SecretListResponse secrets = request.get(
PATH_AUTH_APPROLE + "role?list=true",
emptyMap(),
token,
SecretListResponse.class
);
return secrets.getKeys();
}
@ -467,7 +493,7 @@ public class HTTPVaultConnector implements VaultConnector {
SecretListResponse secrets = request.get(
String.format(PATH_AUTH_APPROLE_ROLE, roleName, "/secret-id?list=true"),
new HashMap<>(),
emptyMap(),
token,
SecretListResponse.class
);
@ -479,14 +505,14 @@ public class HTTPVaultConnector implements VaultConnector {
public final SecretResponse read(final String key) throws VaultConnectorException {
requireAuth();
/* Issue request and parse secret response */
return request.get(key, new HashMap<>(), token, SecretResponse.class);
return request.get(key, emptyMap(), token, SecretResponse.class);
}
@Override
public final SecretResponse readSecretVersion(final String mount, final String key, final Integer version) throws VaultConnectorException {
requireAuth();
/* Request HTTP response and parse secret metadata */
Map<String, String> args = new HashMap<>();
Map<String, String> args = new HashMap<>(1, 1);
if (version != null) {
args.put("version", version.toString());
}
@ -499,14 +525,14 @@ public class HTTPVaultConnector implements VaultConnector {
requireAuth();
/* Request HTTP response and parse secret metadata */
return request.get(mount + PATH_METADATA + key, new HashMap<>(), token, MetadataResponse.class);
return request.get(mount + PATH_METADATA + key, emptyMap(), token, MetadataResponse.class);
}
@Override
public void updateSecretMetadata(final String mount, final String key, final Integer maxVersions, final boolean casRequired) throws VaultConnectorException {
requireAuth();
Map<String, Object> payload = new HashMap<>();
Map<String, Object> payload = new HashMap<>(2, 1);
if (maxVersions != null) {
payload.put("max_versions", maxVersions);
}
@ -524,12 +550,12 @@ public class HTTPVaultConnector implements VaultConnector {
}
// Add CAS value to options map if present.
Map<String, Object> options = new HashMap<>();
Map<String, Object> options = new HashMap<>(1, 1);
if (cas != null) {
options.put("cas", cas);
}
Map<String, Object> payload = new HashMap<>();
Map<String, Object> payload = new HashMap<>(2, 1);
payload.put("data", data);
payload.put("options", options);
@ -541,7 +567,7 @@ public class HTTPVaultConnector implements VaultConnector {
public final List<String> list(final String path) throws VaultConnectorException {
requireAuth();
SecretListResponse secrets = request.get(path + "/?list=true", new HashMap<>(), token, SecretListResponse.class);
SecretListResponse secrets = request.get(path + "/?list=true", emptyMap(), token, SecretListResponse.class);
return secrets.getKeys();
}
@ -559,7 +585,7 @@ public class HTTPVaultConnector implements VaultConnector {
// If options are given, split payload in two parts.
if (options != null) {
Map<String, Object> payloadMap = new HashMap<>();
Map<String, Object> payloadMap = new HashMap<>(2, 1);
payloadMap.put("data", data);
payloadMap.put("options", options);
payload = payloadMap;
@ -616,8 +642,7 @@ public class HTTPVaultConnector implements VaultConnector {
requireAuth();
/* Request HTTP response and expect empty result */
Map<String, Object> payload = new HashMap<>();
payload.put("versions", versions);
Map<String, Object> payload = singletonMap("versions", versions);
/* Issue request and expect code 204 with empty response */
request.postWithoutResponse(mount + pathPart + key, payload, token);
@ -628,14 +653,14 @@ public class HTTPVaultConnector implements VaultConnector {
requireAuth();
/* Issue request and expect code 204 with empty response */
request.putWithoutResponse(PATH_REVOKE + leaseID, new HashMap<>(), token);
request.putWithoutResponse(PATH_REVOKE + leaseID, emptyMap(), token);
}
@Override
public final SecretResponse renew(final String leaseID, final Integer increment) throws VaultConnectorException {
requireAuth();
Map<String, String> payload = new HashMap<>();
Map<String, String> payload = new HashMap<>(2, 1);
payload.put("lease_id", leaseID);
if (increment != null) {
payload.put("increment", increment.toString());
@ -694,9 +719,12 @@ public class HTTPVaultConnector implements VaultConnector {
requireAuth();
/* Request HTTP response and parse Secret */
Map<String, String> param = new HashMap<>();
param.put("token", token);
return request.get(PATH_TOKEN + PATH_LOOKUP, param, token, TokenResponse.class);
return request.get(
PATH_TOKEN + PATH_LOOKUP,
singletonMap("token", token),
token,
TokenResponse.class
);
}
@Override
@ -720,7 +748,7 @@ public class HTTPVaultConnector implements VaultConnector {
requireAuth();
// Request HTTP response and parse response.
return request.get(PATH_TOKEN + PATH_ROLES + "/" + name, new HashMap<>(), token, TokenRoleResponse.class);
return request.get(PATH_TOKEN + PATH_ROLES + "/" + name, emptyMap(), token, TokenRoleResponse.class);
}
@Override

View File

@ -0,0 +1,299 @@
/*
* Copyright 2016-2021 Stefan Kalscheuer
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package de.stklcode.jvault.connector;
import de.stklcode.jvault.connector.builder.VaultConnectorBuilder;
import de.stklcode.jvault.connector.exception.ConnectionException;
import de.stklcode.jvault.connector.exception.TlsException;
import de.stklcode.jvault.connector.exception.VaultConnectorException;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
/**
* Vault Connector Builder implementation for HTTP Vault connectors.
*
* @author Stefan Kalscheuer
* @since 0.8.0
* @since 0.9.5 Package {@link de.stklcode.jvault.connector}
*/
public class HTTPVaultConnectorBuilder implements VaultConnectorBuilder {
private static final String ENV_VAULT_ADDR = "VAULT_ADDR";
private static final String ENV_VAULT_CACERT = "VAULT_CACERT";
private static final String ENV_VAULT_TOKEN = "VAULT_TOKEN";
private static final String ENV_VAULT_MAX_RETRIES = "VAULT_MAX_RETRIES";
public static final String DEFAULT_HOST = "127.0.0.1";
public static final Integer DEFAULT_PORT = 8200;
public static final boolean DEFAULT_TLS = true;
public static final String DEFAULT_TLS_VERSION = "TLSv1.2";
public static final String DEFAULT_PREFIX = "/v1/";
public static final int DEFAULT_NUMBER_OF_RETRIES = 0;
private String host;
private Integer port;
private boolean tls;
private String tlsVersion;
private String prefix;
private X509Certificate trustedCA;
private int numberOfRetries;
private Integer timeout;
private String token;
/**
* Default empty constructor.
* Initializes factory with default values.
*/
public HTTPVaultConnectorBuilder() {
host = DEFAULT_HOST;
port = DEFAULT_PORT;
tls = DEFAULT_TLS;
tlsVersion = DEFAULT_TLS_VERSION;
prefix = DEFAULT_PREFIX;
numberOfRetries = DEFAULT_NUMBER_OF_RETRIES;
}
/**
* Set hostname (default: 127.0.0.1).
*
* @param host Hostname or IP address
* @return self
*/
public HTTPVaultConnectorBuilder withHost(final String host) {
this.host = host;
return this;
}
/**
* Set port (default: 8200).
*
* @param port Vault TCP port
* @return self
*/
public HTTPVaultConnectorBuilder withPort(final Integer port) {
this.port = port;
return this;
}
/**
* Set TLS usage (default: TRUE).
*
* @param useTLS use TLS or not
* @return self
*/
public HTTPVaultConnectorBuilder withTLS(final boolean useTLS) {
this.tls = useTLS;
return this;
}
/**
* Set TLS usage (default: TRUE).
*
* @param useTLS Use TLS or not.
* @param version Supported TLS version ({@code TLSv1.2}, {@code TLSv1.1}, {@code TLSv1.0}, {@code TLS}).
* @return self
* @since 0.8 Added version parameter (#22).
*/
public HTTPVaultConnectorBuilder withTLS(final boolean useTLS, final String version) {
this.tls = useTLS;
this.tlsVersion = version;
return this;
}
/**
* Convenience Method for TLS usage (enabled by default).
*
* @param version Supported TLS version ({@code TLSv1.2}, {@code TLSv1.1}, {@code TLSv1.0}, {@code TLS}).
* @return self
* @since 0.8 Added version parameter (#22).
*/
public HTTPVaultConnectorBuilder withTLS(final String version) {
return withTLS(true, version);
}
/**
* Convenience Method for TLS usage (enabled by default).
*
* @return self
*/
public HTTPVaultConnectorBuilder withTLS() {
return withTLS(true);
}
/**
* Convenience Method for NOT using TLS.
*
* @return self
*/
public HTTPVaultConnectorBuilder withoutTLS() {
return withTLS(false);
}
/**
* Set API prefix. Default is "/v1/" and changes should not be necessary for current state of development.
*
* @param prefix Vault API prefix (default: "/v1/"
* @return self
*/
public HTTPVaultConnectorBuilder withPrefix(final String prefix) {
this.prefix = prefix;
return this;
}
/**
* Add a trusted CA certificate for HTTPS connections.
*
* @param cert path to certificate file
* @return self
* @throws VaultConnectorException on error
* @since 0.4.0
*/
public HTTPVaultConnectorBuilder withTrustedCA(final Path cert) throws VaultConnectorException {
if (cert != null) {
return withTrustedCA(certificateFromFile(cert));
} else {
this.trustedCA = null;
}
return this;
}
/**
* Add a trusted CA certificate for HTTPS connections.
*
* @param cert path to certificate file
* @return self
* @since 0.8.0
*/
public HTTPVaultConnectorBuilder withTrustedCA(final X509Certificate cert) {
this.trustedCA = cert;
return this;
}
/**
* Set token for automatic authentication, using {@link #buildAndAuth()}.
*
* @param token Vault token
* @return self
* @since 0.6.0
*/
public HTTPVaultConnectorBuilder withToken(final String token) {
this.token = token;
return this;
}
/**
* Build connector based on the {@code }VAULT_ADDR} and {@code VAULT_CACERT} (optional) environment variables.
*
* @return self
* @throws VaultConnectorException if Vault address from environment variables is malformed
* @since 0.6.0
*/
public HTTPVaultConnectorBuilder fromEnv() throws VaultConnectorException {
/* Parse URL from environment variable */
if (System.getenv(ENV_VAULT_ADDR) != null && !System.getenv(ENV_VAULT_ADDR).trim().isEmpty()) {
try {
URL url = new URL(System.getenv(ENV_VAULT_ADDR));
this.host = url.getHost();
this.port = url.getPort();
this.tls = url.getProtocol().equals("https");
} catch (MalformedURLException e) {
throw new ConnectionException("URL provided in environment variable malformed", e);
}
}
/* Read number of retries */
if (System.getenv(ENV_VAULT_MAX_RETRIES) != null) {
try {
numberOfRetries = Integer.parseInt(System.getenv(ENV_VAULT_MAX_RETRIES));
} catch (NumberFormatException ignored) {
/* Ignore malformed values. */
}
}
/* Read token */
token = System.getenv(ENV_VAULT_TOKEN);
/* Parse certificate, if set */
if (System.getenv(ENV_VAULT_CACERT) != null && !System.getenv(ENV_VAULT_CACERT).trim().isEmpty()) {
return withTrustedCA(Paths.get(System.getenv(ENV_VAULT_CACERT)));
}
return this;
}
/**
* Define the number of retries to attempt on 5xx errors.
*
* @param numberOfRetries The number of retries to attempt on 5xx errors (default: 0)
* @return self
* @since 0.6.0
*/
public HTTPVaultConnectorBuilder withNumberOfRetries(final int numberOfRetries) {
this.numberOfRetries = numberOfRetries;
return this;
}
/**
* Define a custom timeout for the HTTP connection.
*
* @param milliseconds Timeout value in milliseconds.
* @return self
* @since 0.6.0
*/
public HTTPVaultConnectorBuilder withTimeout(final int milliseconds) {
this.timeout = milliseconds;
return this;
}
@Override
public HTTPVaultConnector build() {
return new HTTPVaultConnector(host, tls, tlsVersion, port, prefix, trustedCA, numberOfRetries, timeout);
}
@Override
public HTTPVaultConnector buildAndAuth() throws VaultConnectorException {
if (token == null) {
throw new ConnectionException("No vault token provided, unable to authenticate.");
}
HTTPVaultConnector con = build();
con.authToken(token);
return con;
}
/**
* Read given certificate file to X.509 certificate.
*
* @param certFile Path to certificate file
* @return X.509 Certificate object
* @throws TlsException on error
* @since 0.4.0
*/
private X509Certificate certificateFromFile(final Path certFile) throws TlsException {
try (InputStream is = Files.newInputStream(certFile)) {
return (X509Certificate) CertificateFactory.getInstance("X.509").generateCertificate(is);
} catch (IOException | CertificateException e) {
throw new TlsException("Unable to read certificate.", e);
}
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2016-2020 Stefan Kalscheuer
* Copyright 2016-2021 Stefan Kalscheuer
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -22,10 +22,7 @@ import de.stklcode.jvault.connector.model.*;
import de.stklcode.jvault.connector.model.response.*;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.*;
/**
* Vault Connector interface.
@ -404,7 +401,9 @@ public interface VaultConnector extends AutoCloseable, Serializable {
* @param key Secret identifier
* @return Secret response
* @throws VaultConnectorException on error
* @deprecated Convenience method will be removed in 1.0. Use {@link #read(String)} instead with key prefix "secret/".
*/
@Deprecated
default SecretResponse readSecret(final String key) throws VaultConnectorException {
return read(PATH_SECRET + "/" + key);
}
@ -451,7 +450,9 @@ public interface VaultConnector extends AutoCloseable, Serializable {
* @return Metadata for the created/updated secret.
* @throws VaultConnectorException on error
* @since 0.8
* @deprecated Convenience method will be removed in 1.0. Use {@link #writeSecretData(String, String, Map)} instead with mount parameter "secret".
*/
@Deprecated
default SecretVersionResponse writeSecretData(final String key, final Map<String, Object> data) throws VaultConnectorException {
return writeSecretData(PATH_SECRET, key, data, null);
}
@ -500,7 +501,9 @@ public interface VaultConnector extends AutoCloseable, Serializable {
* @return Secret response
* @throws VaultConnectorException on error
* @since 0.8
* @deprecated Convenience method will be removed in 1.0. Use {@link #readSecretVersion(String, String, Integer)} instead with mount parameter "secret".
*/
@Deprecated
default SecretResponse readSecretVersion(final String key, final Integer version) throws VaultConnectorException {
return readSecretVersion(PATH_SECRET, key, version);
}
@ -529,7 +532,9 @@ public interface VaultConnector extends AutoCloseable, Serializable {
* @return Metadata response
* @throws VaultConnectorException on error
* @since 0.8
* @deprecated Convenience method will be removed in 1.0. Use {@link #readSecretMetadata(String, String)} instead with mount parameter "secret".
*/
@Deprecated
default MetadataResponse readSecretMetadata(final String key) throws VaultConnectorException {
return readSecretMetadata(PATH_SECRET, key);
}
@ -545,7 +550,9 @@ public interface VaultConnector extends AutoCloseable, Serializable {
* @param casRequired Specify if Check-And-Set is required for this secret.
* @throws VaultConnectorException on error
* @since 0.8
* @deprecated Convenience method will be removed in 1.0. Use {@link #updateSecretMetadata(String, String, Integer, boolean)} instead with mount parameter "secret".
*/
@Deprecated
default void updateSecretMetadata(final String key, final Integer maxVersions, final boolean casRequired) throws VaultConnectorException {
updateSecretMetadata(PATH_SECRET, key, maxVersions, casRequired);
}
@ -597,7 +604,9 @@ public interface VaultConnector extends AutoCloseable, Serializable {
* @param path Root path to search
* @return List of secret keys
* @throws VaultConnectorException on error
* @deprecated Convenience method will be removed in 1.0. Use {@link #list(String)} instead with key prefix "secret/".
*/
@Deprecated
default List<String> listSecrets(final String path) throws VaultConnectorException {
return list(PATH_SECRET + "/" + path);
}
@ -611,9 +620,7 @@ public interface VaultConnector extends AutoCloseable, Serializable {
* @since 0.5.0
*/
default void write(final String key, final String value) throws VaultConnectorException {
Map<String, Object> param = new HashMap<>();
param.put("value", value);
write(key, param);
write(key, Collections.singletonMap("value", value));
}
/**
@ -647,11 +654,11 @@ public interface VaultConnector extends AutoCloseable, Serializable {
* @param key Secret path
* @param value Secret value
* @throws VaultConnectorException on error
* @deprecated Convenience method will be removed in 1.0. Use {@link #write(String, String)} instead with key prefix "secret/".
*/
@Deprecated
default void writeSecret(final String key, final String value) throws VaultConnectorException {
Map<String, Object> param = new HashMap<>();
param.put("value", value);
writeSecret(key, param);
writeSecret(key, Collections.singletonMap("value", value));
}
/**
@ -663,7 +670,9 @@ public interface VaultConnector extends AutoCloseable, Serializable {
* @param data Secret content. Value must be be JSON serializable.
* @throws VaultConnectorException on error
* @since 0.5.0
* @deprecated Convenience method will be removed in 1.0. Use {@link #write(String, Map)} instead with key prefix "secret/".
*/
@Deprecated
default void writeSecret(final String key, final Map<String, Object> data) throws VaultConnectorException {
if (key == null || key.isEmpty()) {
throw new InvalidRequestException("Secret path must not be empty.");
@ -687,7 +696,9 @@ public interface VaultConnector extends AutoCloseable, Serializable {
*
* @param key Secret path
* @throws VaultConnectorException on error
* @deprecated Convenience method will be removed in 1.0. Use {@link #delete(String)} instead with key prefix "secret/".
*/
@Deprecated
default void deleteSecret(final String key) throws VaultConnectorException {
delete(PATH_SECRET + "/" + key);
}
@ -700,7 +711,9 @@ public interface VaultConnector extends AutoCloseable, Serializable {
* @param key Secret path.
* @throws VaultConnectorException on error
* @since 0.8
* @deprecated Convenience method will be removed in 1.0. Use {@link #deleteLatestSecretVersion(String, String)} instead with mount parameter "secret".
*/
@Deprecated
default void deleteLatestSecretVersion(final String key) throws VaultConnectorException {
deleteLatestSecretVersion(PATH_SECRET, key);
}
@ -726,7 +739,9 @@ public interface VaultConnector extends AutoCloseable, Serializable {
* @param key Secret path.
* @throws VaultConnectorException on error
* @since 0.8
* @deprecated Convenience method will be removed in 1.0. Use {@link #deleteAllSecretVersions(String)} instead with mount parameter "secret".
*/
@Deprecated
default void deleteAllSecretVersions(final String key) throws VaultConnectorException {
deleteAllSecretVersions(PATH_SECRET, key);
}
@ -753,7 +768,9 @@ public interface VaultConnector extends AutoCloseable, Serializable {
* @param versions Versions of the secret to delete.
* @throws VaultConnectorException on error
* @since 0.8
* @deprecated Convenience method will be removed in 1.0. Use {@link #deleteSecretVersions(String, String, int...)} instead with mount parameter "secret".
*/
@Deprecated
default void deleteSecretVersions(final String key, final int... versions) throws VaultConnectorException {
deleteSecretVersions(PATH_SECRET, key, versions);
}
@ -779,7 +796,9 @@ public interface VaultConnector extends AutoCloseable, Serializable {
* @param versions Versions of the secret to undelete.
* @throws VaultConnectorException on error
* @since 0.8
* @deprecated Convenience method will be removed in 1.0. Use {@link #undeleteSecretVersions(String, String, int...)} instead with mount parameter "secret".
*/
@Deprecated
default void undeleteSecretVersions(final String key, final int... versions) throws VaultConnectorException {
undeleteSecretVersions(PATH_SECRET, key, versions);
}
@ -804,7 +823,9 @@ public interface VaultConnector extends AutoCloseable, Serializable {
* @param versions Versions of the secret to destroy.
* @throws VaultConnectorException on error
* @since 0.8
* @deprecated Convenience method will be removed in 1.0. Use {@link #destroySecretVersions(String, String, int...)} instead with mount parameter "secret".
*/
@Deprecated
default void destroySecretVersions(final String key, final int... versions) throws VaultConnectorException {
destroySecretVersions(PATH_SECRET, key, versions);
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2016-2020 Stefan Kalscheuer
* Copyright 2016-2021 Stefan Kalscheuer
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -16,283 +16,17 @@
package de.stklcode.jvault.connector.builder;
import de.stklcode.jvault.connector.HTTPVaultConnector;
import de.stklcode.jvault.connector.exception.ConnectionException;
import de.stklcode.jvault.connector.exception.TlsException;
import de.stklcode.jvault.connector.exception.VaultConnectorException;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
/**
* Vault Connector Builder implementation for HTTP Vault connectors.
*
* @author Stefan Kalscheuer
* @since 0.8.0
* @since 0.9.5 Extends new class for migration purposes only.
* @deprecated Use {@link de.stklcode.jvault.connector.HTTPVaultConnectorBuilder} instead. Will be removed in 1.0
*/
public final class HTTPVaultConnectorBuilder implements VaultConnectorBuilder {
private static final String ENV_VAULT_ADDR = "VAULT_ADDR";
private static final String ENV_VAULT_CACERT = "VAULT_CACERT";
private static final String ENV_VAULT_TOKEN = "VAULT_TOKEN";
private static final String ENV_VAULT_MAX_RETRIES = "VAULT_MAX_RETRIES";
public static final String DEFAULT_HOST = "127.0.0.1";
public static final Integer DEFAULT_PORT = 8200;
public static final boolean DEFAULT_TLS = true;
public static final String DEFAULT_TLS_VERSION = "TLSv1.2";
public static final String DEFAULT_PREFIX = "/v1/";
public static final int DEFAULT_NUMBER_OF_RETRIES = 0;
private String host;
private Integer port;
private boolean tls;
private String tlsVersion;
private String prefix;
private X509Certificate trustedCA;
private int numberOfRetries;
private Integer timeout;
private String token;
/**
* Default empty constructor.
* Initializes factory with default values.
*/
@Deprecated
public class HTTPVaultConnectorBuilder extends de.stklcode.jvault.connector.HTTPVaultConnectorBuilder {
public HTTPVaultConnectorBuilder() {
host = DEFAULT_HOST;
port = DEFAULT_PORT;
tls = DEFAULT_TLS;
tlsVersion = DEFAULT_TLS_VERSION;
prefix = DEFAULT_PREFIX;
numberOfRetries = DEFAULT_NUMBER_OF_RETRIES;
}
/**
* Set hostname (default: 127.0.0.1).
*
* @param host Hostname or IP address
* @return self
*/
public HTTPVaultConnectorBuilder withHost(final String host) {
this.host = host;
return this;
}
/**
* Set port (default: 8200).
*
* @param port Vault TCP port
* @return self
*/
public HTTPVaultConnectorBuilder withPort(final Integer port) {
this.port = port;
return this;
}
/**
* Set TLS usage (default: TRUE).
*
* @param useTLS use TLS or not
* @return self
*/
public HTTPVaultConnectorBuilder withTLS(final boolean useTLS) {
this.tls = useTLS;
return this;
}
/**
* Set TLS usage (default: TRUE).
*
* @param useTLS Use TLS or not.
* @param version Supported TLS version ({@code TLSv1.2}, {@code TLSv1.1}, {@code TLSv1.0}, {@code TLS}).
* @return self
* @since 0.8 Added version parameter (#22).
*/
public HTTPVaultConnectorBuilder withTLS(final boolean useTLS, final String version) {
this.tls = useTLS;
this.tlsVersion = version;
return this;
}
/**
* Convenience Method for TLS usage (enabled by default).
*
* @param version Supported TLS version ({@code TLSv1.2}, {@code TLSv1.1}, {@code TLSv1.0}, {@code TLS}).
* @return self
* @since 0.8 Added version parameter (#22).
*/
public HTTPVaultConnectorBuilder withTLS(final String version) {
return withTLS(true, version);
}
/**
* Convenience Method for TLS usage (enabled by default).
*
* @return self
*/
public HTTPVaultConnectorBuilder withTLS() {
return withTLS(true);
}
/**
* Convenience Method for NOT using TLS.
*
* @return self
*/
public HTTPVaultConnectorBuilder withoutTLS() {
return withTLS(false);
}
/**
* Set API prefix. Default is "/v1/" and changes should not be necessary for current state of development.
*
* @param prefix Vault API prefix (default: "/v1/"
* @return self
*/
public HTTPVaultConnectorBuilder withPrefix(final String prefix) {
this.prefix = prefix;
return this;
}
/**
* Add a trusted CA certificate for HTTPS connections.
*
* @param cert path to certificate file
* @return self
* @throws VaultConnectorException on error
* @since 0.4.0
*/
public HTTPVaultConnectorBuilder withTrustedCA(final Path cert) throws VaultConnectorException {
if (cert != null) {
return withTrustedCA(certificateFromFile(cert));
} else {
this.trustedCA = null;
}
return this;
}
/**
* Add a trusted CA certificate for HTTPS connections.
*
* @param cert path to certificate file
* @return self
* @since 0.8.0
*/
public HTTPVaultConnectorBuilder withTrustedCA(final X509Certificate cert) {
this.trustedCA = cert;
return this;
}
/**
* Set token for automatic authentication, using {@link #buildAndAuth()}.
*
* @param token Vault token
* @return self
* @since 0.6.0
*/
public HTTPVaultConnectorBuilder withToken(final String token) {
this.token = token;
return this;
}
/**
* Build connector based on the {@code }VAULT_ADDR} and {@code VAULT_CACERT} (optional) environment variables.
*
* @return self
* @throws VaultConnectorException if Vault address from environment variables is malformed
* @since 0.6.0
*/
public HTTPVaultConnectorBuilder fromEnv() throws VaultConnectorException {
/* Parse URL from environment variable */
if (System.getenv(ENV_VAULT_ADDR) != null && !System.getenv(ENV_VAULT_ADDR).trim().isEmpty()) {
try {
URL url = new URL(System.getenv(ENV_VAULT_ADDR));
this.host = url.getHost();
this.port = url.getPort();
this.tls = url.getProtocol().equals("https");
} catch (MalformedURLException e) {
throw new ConnectionException("URL provided in environment variable malformed", e);
}
}
/* Read number of retries */
if (System.getenv(ENV_VAULT_MAX_RETRIES) != null) {
try {
numberOfRetries = Integer.parseInt(System.getenv(ENV_VAULT_MAX_RETRIES));
} catch (NumberFormatException ignored) {
/* Ignore malformed values. */
}
}
/* Read token */
token = System.getenv(ENV_VAULT_TOKEN);
/* Parse certificate, if set */
if (System.getenv(ENV_VAULT_CACERT) != null && !System.getenv(ENV_VAULT_CACERT).trim().isEmpty()) {
return withTrustedCA(Paths.get(System.getenv(ENV_VAULT_CACERT)));
}
return this;
}
/**
* Define the number of retries to attempt on 5xx errors.
*
* @param numberOfRetries The number of retries to attempt on 5xx errors (default: 0)
* @return self
* @since 0.6.0
*/
public HTTPVaultConnectorBuilder withNumberOfRetries(final int numberOfRetries) {
this.numberOfRetries = numberOfRetries;
return this;
}
/**
* Define a custom timeout for the HTTP connection.
*
* @param milliseconds Timeout value in milliseconds.
* @return self
* @since 0.6.0
*/
public HTTPVaultConnectorBuilder withTimeout(final int milliseconds) {
this.timeout = milliseconds;
return this;
}
@Override
public HTTPVaultConnector build() {
return new HTTPVaultConnector(host, tls, tlsVersion, port, prefix, trustedCA, numberOfRetries, timeout);
}
@Override
public HTTPVaultConnector buildAndAuth() throws VaultConnectorException {
if (token == null) {
throw new ConnectionException("No vault token provided, unable to authenticate.");
}
HTTPVaultConnector con = build();
con.authToken(token);
return con;
}
/**
* Read given certificate file to X.509 certificate.
*
* @param certFile Path to certificate file
* @return X.509 Certificate object
* @throws TlsException on error
* @since 0.4.0
*/
private X509Certificate certificateFromFile(final Path certFile) throws TlsException {
try (InputStream is = Files.newInputStream(certFile)) {
return (X509Certificate) CertificateFactory.getInstance("X.509").generateCertificate(is);
} catch (IOException | CertificateException e) {
throw new TlsException("Unable to read certificate.", e);
}
super();
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2016-2020 Stefan Kalscheuer
* Copyright 2016-2021 Stefan Kalscheuer
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -16,6 +16,7 @@
package de.stklcode.jvault.connector.builder;
import de.stklcode.jvault.connector.HTTPVaultConnector;
import de.stklcode.jvault.connector.VaultConnector;
import de.stklcode.jvault.connector.exception.VaultConnectorException;
@ -31,7 +32,9 @@ public interface VaultConnectorBuilder {
* Get Factory implementation for HTTP Vault Connector.
*
* @return HTTP Connector Factory
* @deprecated Use {@link HTTPVaultConnector#builder()} instead. This interface will be removed in 1.0
*/
@Deprecated
static HTTPVaultConnectorBuilder http() {
return new HTTPVaultConnectorBuilder();
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2016-2020 Stefan Kalscheuer
* Copyright 2016-2021 Stefan Kalscheuer
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
/*
* Copyright 2016-2020 Stefan Kalscheuer
* Copyright 2016-2021 Stefan Kalscheuer
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
/*
* Copyright 2016-2020 Stefan Kalscheuer
* Copyright 2016-2021 Stefan Kalscheuer
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
/*
* Copyright 2016-2020 Stefan Kalscheuer
* Copyright 2016-2021 Stefan Kalscheuer
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
/*
* Copyright 2016-2020 Stefan Kalscheuer
* Copyright 2016-2021 Stefan Kalscheuer
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
/*
* Copyright 2016-2020 Stefan Kalscheuer
* Copyright 2016-2021 Stefan Kalscheuer
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
/*
* Copyright 2016-2020 Stefan Kalscheuer
* Copyright 2016-2021 Stefan Kalscheuer
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
/*
* Copyright 2016-2020 Stefan Kalscheuer
* Copyright 2016-2021 Stefan Kalscheuer
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -26,7 +26,7 @@ public abstract class VaultConnectorException extends Exception {
/**
* Constructs a new empty exception.
*/
public VaultConnectorException() {
protected VaultConnectorException() {
}
/**
@ -34,7 +34,7 @@ public abstract class VaultConnectorException extends Exception {
*
* @param message the detail message
*/
public VaultConnectorException(final String message) {
protected VaultConnectorException(final String message) {
super(message);
}
@ -43,7 +43,7 @@ public abstract class VaultConnectorException extends Exception {
*
* @param cause the cause
*/
public VaultConnectorException(final Throwable cause) {
protected VaultConnectorException(final Throwable cause) {
super(cause);
}
@ -53,7 +53,7 @@ public abstract class VaultConnectorException extends Exception {
* @param message the detail message
* @param cause the cause
*/
public VaultConnectorException(final String message, final Throwable cause) {
protected VaultConnectorException(final String message, final Throwable cause) {
super(message, cause);
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2016-2020 Stefan Kalscheuer
* Copyright 2016-2021 Stefan Kalscheuer
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
/*
* Copyright 2016-2020 Stefan Kalscheuer
* Copyright 2016-2021 Stefan Kalscheuer
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -17,7 +17,7 @@
package de.stklcode.jvault.connector.factory;
import de.stklcode.jvault.connector.HTTPVaultConnector;
import de.stklcode.jvault.connector.builder.HTTPVaultConnectorBuilder;
import de.stklcode.jvault.connector.HTTPVaultConnectorBuilder;
import de.stklcode.jvault.connector.exception.VaultConnectorException;
import javax.net.ssl.SSLContext;

View File

@ -1,5 +1,5 @@
/*
* Copyright 2016-2020 Stefan Kalscheuer
* Copyright 2016-2021 Stefan Kalscheuer
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
/*
* Copyright 2016-2020 Stefan Kalscheuer
* Copyright 2016-2021 Stefan Kalscheuer
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
/*
* Copyright 2016-2020 Stefan Kalscheuer
* Copyright 2016-2021 Stefan Kalscheuer
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@ -367,18 +367,22 @@ public final class RequestHelper implements Serializable {
*/
private SSLConnectionSocketFactory createSSLSocketFactory() throws TlsException {
try {
// Create Keystore with trusted certificate.
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
keyStore.load(null, null);
keyStore.setCertificateEntry("trustedCert", trustedCaCert);
// Initialize TrustManager.
TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init(keyStore);
// Create context using this TrustManager.
// Create context..
SSLContext context = SSLContext.getInstance(tlsVersion);
context.init(null, tmf.getTrustManagers(), new SecureRandom());
if (trustedCaCert != null) {
// Create Keystore with trusted certificate.
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
keyStore.load(null, null);
keyStore.setCertificateEntry("trustedCert", trustedCaCert);
// Initialize TrustManager.
TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init(keyStore);
context.init(null, tmf.getTrustManagers(), null);
} else {
context.init(null, null, null);
}
return new SSLConnectionSocketFactory(
context,

View File

@ -1,5 +1,5 @@
/*
* Copyright 2016-2020 Stefan Kalscheuer
* Copyright 2016-2021 Stefan Kalscheuer
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -703,21 +703,34 @@ public final class AppRole {
* @return self
* @since 0.9
*/
public Builder wit0hTokenPeriod(final Integer tokenPeriod) {
public Builder withTokenPeriod(final Integer tokenPeriod) {
this.tokenPeriod = tokenPeriod;
return this;
}
/**
* Set renewal period for generated token in seconds.
*
* @param tokenPeriod period in seconds
* @return self
* @since 0.9
* @deprecated Use {@link #withTokenPeriod(Integer)} instead.
*/
@Deprecated
public Builder wit0hTokenPeriod(final Integer tokenPeriod) {
return withTokenPeriod(tokenPeriod);
}
/**
* Set renewal period for generated token in seconds.
*
* @param period period in seconds
* @return self
* @deprecated Use {@link #wit0hTokenPeriod(Integer)} instead.
* @deprecated Use {@link #withTokenPeriod(Integer)} instead.
*/
@Deprecated
public Builder withPeriod(final Integer period) {
return wit0hTokenPeriod(period);
return withTokenPeriod(period);
}
/**

View File

@ -1,5 +1,5 @@
/*
* Copyright 2016-2020 Stefan Kalscheuer
* Copyright 2016-2021 Stefan Kalscheuer
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -308,21 +308,34 @@ public final class AppRoleBuilder {
* @return self
* @since 0.9
*/
public AppRoleBuilder wit0hTokenPeriod(final Integer tokenPeriod) {
public AppRoleBuilder withTokenPeriod(final Integer tokenPeriod) {
this.tokenPeriod = tokenPeriod;
return this;
}
/**
* Set renewal period for generated token in seconds.
*
* @param tokenPeriod period in seconds
* @return self
* @since 0.9
* @deprecated Use {@link #withTokenPeriod(Integer)} instead.
*/
@Deprecated
public AppRoleBuilder wit0hTokenPeriod(final Integer tokenPeriod) {
return withTokenPeriod(tokenPeriod);
}
/**
* Set renewal period for generated token in seconds.
*
* @param period period in seconds
* @return self
* @deprecated Use {@link #wit0hTokenPeriod(Integer)} instead.
* @deprecated Use {@link #withTokenPeriod(Integer)} instead.
*/
@Deprecated
public AppRoleBuilder withPeriod(final Integer period) {
return wit0hTokenPeriod(period);
return withTokenPeriod(period);
}
/**

View File

@ -1,5 +1,5 @@
/*
* Copyright 2016-2020 Stefan Kalscheuer
* Copyright 2016-2021 Stefan Kalscheuer
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
/*
* Copyright 2016-2020 Stefan Kalscheuer
* Copyright 2016-2021 Stefan Kalscheuer
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
/*
* Copyright 2016-2020 Stefan Kalscheuer
* Copyright 2016-2021 Stefan Kalscheuer
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
/*
* Copyright 2016-2020 Stefan Kalscheuer
* Copyright 2016-2021 Stefan Kalscheuer
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
/*
* Copyright 2016-2020 Stefan Kalscheuer
* Copyright 2016-2021 Stefan Kalscheuer
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
/*
* Copyright 2016-2020 Stefan Kalscheuer
* Copyright 2016-2021 Stefan Kalscheuer
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
/*
* Copyright 2016-2020 Stefan Kalscheuer
* Copyright 2016-2021 Stefan Kalscheuer
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -40,7 +40,7 @@ public final class AppRoleResponse extends VaultDataResponse {
ObjectMapper mapper = new ObjectMapper();
try {
/* null empty strings on list objects */
Map<String, Object> filteredData = new HashMap<>();
Map<String, Object> filteredData = new HashMap<>(data.size(), 1);
data.forEach((k, v) -> {
if (!(v instanceof String && ((String) v).isEmpty())) {
filteredData.put(k, v);

View File

@ -1,5 +1,5 @@
/*
* Copyright 2016-2020 Stefan Kalscheuer
* Copyright 2016-2021 Stefan Kalscheuer
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -40,7 +40,7 @@ public final class AppRoleSecretResponse extends VaultDataResponse {
ObjectMapper mapper = new ObjectMapper();
try {
/* null empty strings on list objects */
Map<String, Object> filteredData = new HashMap<>();
Map<String, Object> filteredData = new HashMap<>(data.size(), 1);
data.forEach((k, v) -> {
if (!(v instanceof String && ((String) v).isEmpty())) {
filteredData.put(k, v);

View File

@ -1,5 +1,5 @@
/*
* Copyright 2016-2020 Stefan Kalscheuer
* Copyright 2016-2021 Stefan Kalscheuer
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
/*
* Copyright 2016-2020 Stefan Kalscheuer
* Copyright 2016-2021 Stefan Kalscheuer
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
/*
* Copyright 2016-2020 Stefan Kalscheuer
* Copyright 2016-2021 Stefan Kalscheuer
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
/*
* Copyright 2016-2020 Stefan Kalscheuer
* Copyright 2016-2021 Stefan Kalscheuer
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
/*
* Copyright 2016-2020 Stefan Kalscheuer
* Copyright 2016-2021 Stefan Kalscheuer
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
/*
* Copyright 2016-2020 Stefan Kalscheuer
* Copyright 2016-2021 Stefan Kalscheuer
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
/*
* Copyright 2016-2020 Stefan Kalscheuer
* Copyright 2016-2021 Stefan Kalscheuer
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
/*
* Copyright 2016-2020 Stefan Kalscheuer
* Copyright 2016-2021 Stefan Kalscheuer
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
/*
* Copyright 2016-2020 Stefan Kalscheuer
* Copyright 2016-2021 Stefan Kalscheuer
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
/*
* Copyright 2016-2020 Stefan Kalscheuer
* Copyright 2016-2021 Stefan Kalscheuer
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
/*
* Copyright 2016-2020 Stefan Kalscheuer
* Copyright 2016-2021 Stefan Kalscheuer
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -22,7 +22,7 @@ import de.stklcode.jvault.connector.exception.InvalidResponseException;
import de.stklcode.jvault.connector.model.response.embedded.VersionMetadata;
import java.io.IOException;
import java.util.HashMap;
import java.util.Collections;
import java.util.Map;
/**
@ -66,7 +66,7 @@ public class SecretResponse extends VaultDataResponse {
*/
public final Map<String, Object> getData() {
if (data == null) {
return new HashMap<>();
return Collections.emptyMap();
}
return data;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2016-2020 Stefan Kalscheuer
* Copyright 2016-2021 Stefan Kalscheuer
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
/*
* Copyright 2016-2020 Stefan Kalscheuer
* Copyright 2016-2021 Stefan Kalscheuer
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
/*
* Copyright 2016-2020 Stefan Kalscheuer
* Copyright 2016-2021 Stefan Kalscheuer
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
/*
* Copyright 2016-2020 Stefan Kalscheuer
* Copyright 2016-2021 Stefan Kalscheuer
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
/*
* Copyright 2016-2020 Stefan Kalscheuer
* Copyright 2016-2021 Stefan Kalscheuer
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
/*
* Copyright 2016-2020 Stefan Kalscheuer
* Copyright 2016-2021 Stefan Kalscheuer
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
/*
* Copyright 2016-2020 Stefan Kalscheuer
* Copyright 2016-2021 Stefan Kalscheuer
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
/*
* Copyright 2016-2020 Stefan Kalscheuer
* Copyright 2016-2021 Stefan Kalscheuer
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
/*
* Copyright 2016-2020 Stefan Kalscheuer
* Copyright 2016-2021 Stefan Kalscheuer
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
/*
* Copyright 2016-2020 Stefan Kalscheuer
* Copyright 2016-2021 Stefan Kalscheuer
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
/*
* Copyright 2016-2020 Stefan Kalscheuer
* Copyright 2016-2021 Stefan Kalscheuer
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
/*
* Copyright 2016-2020 Stefan Kalscheuer
* Copyright 2016-2021 Stefan Kalscheuer
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
/*
* Copyright 2016-2020 Stefan Kalscheuer
* Copyright 2016-2021 Stefan Kalscheuer
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@ -1,5 +1,5 @@
/*
* Copyright 2016-2020 Stefan Kalscheuer
* Copyright 2016-2021 Stefan Kalscheuer
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -20,9 +20,6 @@ import de.stklcode.jvault.connector.exception.InvalidRequestException;
import de.stklcode.jvault.connector.exception.InvalidResponseException;
import de.stklcode.jvault.connector.exception.PermissionDeniedException;
import de.stklcode.jvault.connector.exception.VaultConnectorException;
import net.bytebuddy.ByteBuddy;
import net.bytebuddy.agent.ByteBuddyAgent;
import net.bytebuddy.dynamic.loading.ClassReloadingStrategy;
import org.apache.http.ProtocolVersion;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.entity.ContentType;
@ -30,9 +27,9 @@ import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.message.BasicStatusLine;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.*;
import org.junit.jupiter.api.function.Executable;
import org.mockito.MockedStatic;
import java.io.IOException;
import java.io.InputStream;
@ -42,13 +39,12 @@ import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.Collections;
import static net.bytebuddy.implementation.MethodDelegation.to;
import static net.bytebuddy.matcher.ElementMatchers.named;
import static org.hamcrest.CoreMatchers.instanceOf;
import static org.hamcrest.CoreMatchers.nullValue;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.core.Is.is;
import static org.junit.jupiter.api.Assertions.fail;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.*;
@ -59,79 +55,68 @@ import static org.mockito.Mockito.*;
* @author Stefan Kalscheuer
* @since 0.7.0
*/
public class HTTPVaultConnectorOfflineTest {
class HTTPVaultConnectorOfflineTest {
private static final String INVALID_URL = "foo:/\\1nv4l1d_UrL";
private static CloseableHttpClient httpMock = mock(CloseableHttpClient.class);
private CloseableHttpResponse responseMock = mock(CloseableHttpResponse.class);
private static MockedStatic<HttpClientBuilder> hcbMock;
private static CloseableHttpClient httpMock;
private final CloseableHttpResponse responseMock = mock(CloseableHttpResponse.class);
@BeforeAll
public static void initByteBuddy() {
// Install ByteBuddy Agent.
ByteBuddyAgent.install();
static void prepare() {
// Mock the static HTTPClient creation.
hcbMock = mockStatic(HttpClientBuilder.class);
hcbMock.when(HttpClientBuilder::create).thenReturn(new MockedHttpClientBuilder());
}
/**
* Helper method for redefinition of {@link HttpClientBuilder#create()} from {@link #initHttpMock()}.
*
* @return Mocked HTTP client builder.
*/
public static HttpClientBuilder create() {
return new MockedHttpClientBuilder();
}
@AfterAll
static void tearDown() {
hcbMock.close();
}
@BeforeEach
public void initHttpMock() {
// Redefine static method to return Mock on HttpClientBuilder creation.
new ByteBuddy().redefine(HttpClientBuilder.class)
.method(named("create"))
.intercept(to(HTTPVaultConnectorOfflineTest.class))
.make()
.load(HttpClientBuilder.class.getClassLoader(), ClassReloadingStrategy.fromInstalledAgent());
void init() {
// Re-initialize HTTP mock to ensure fresh (empty) results.
httpMock = mock(CloseableHttpClient.class);
}
/**
* Test exceptions thrown during request.
*/
@Test
public void requestExceptionTest() throws IOException {
void requestExceptionTest() throws IOException {
HTTPVaultConnector connector = new HTTPVaultConnector("http://127.0.0.1", null, 0, 250);
// Test invalid response code.
final int responseCode = 400;
mockResponse(responseCode, "", ContentType.APPLICATION_JSON);
try {
connector.getHealth();
fail("Querying health status succeeded on invalid instance");
} catch (Exception e) {
assertThat("Unexpected type of exception", e, instanceOf(InvalidResponseException.class));
assertThat("Unexpected exception message", e.getMessage(), is("Invalid response code"));
assertThat("Unexpected status code in exception", ((InvalidResponseException) e).getStatusCode(), is(responseCode));
assertThat("Response message where none was expected", ((InvalidResponseException) e).getResponse(), is(nullValue()));
}
InvalidResponseException e = assertThrows(
InvalidResponseException.class,
connector::getHealth,
"Querying health status succeeded on invalid instance"
);
assertThat("Unexpected exception message", e.getMessage(), is("Invalid response code"));
assertThat("Unexpected status code in exception", ((InvalidResponseException) e).getStatusCode(), is(responseCode));
assertThat("Response message where none was expected", ((InvalidResponseException) e).getResponse(), is(nullValue()));
// Simulate permission denied response.
mockResponse(responseCode, "{\"errors\":[\"permission denied\"]}", ContentType.APPLICATION_JSON);
try {
connector.getHealth();
fail("Querying health status succeeded on invalid instance");
} catch (Exception e) {
assertThat("Unexpected type of exception", e, instanceOf(PermissionDeniedException.class));
}
assertThrows(
PermissionDeniedException.class,
connector::getHealth,
"Querying health status succeeded on invalid instance"
);
// Test exception thrown during request.
when(httpMock.execute(any())).thenThrow(new IOException("Test Exception"));
try {
connector.getHealth();
fail("Querying health status succeeded on invalid instance");
} catch (Exception e) {
assertThat("Unexpected type of exception", e, instanceOf(InvalidResponseException.class));
assertThat("Unexpected exception message", e.getMessage(), is("Unable to read response"));
assertThat("Unexpected cause", e.getCause(), instanceOf(IOException.class));
}
e = assertThrows(
InvalidResponseException.class,
connector::getHealth,
"Querying health status succeeded on invalid instance"
);
assertThat("Unexpected exception message", e.getMessage(), is("Unable to read response"));
assertThat("Unexpected cause", e.getCause(), instanceOf(IOException.class));
// Now simulate a failing request that succeeds on second try.
connector = new HTTPVaultConnector("https://127.0.0.1", null, 1, 250);
@ -143,18 +128,14 @@ public class HTTPVaultConnectorOfflineTest {
.when(responseMock).getStatusLine();
when(responseMock.getEntity()).thenReturn(new StringEntity("{}", ContentType.APPLICATION_JSON));
try {
connector.getHealth();
} catch (Exception e) {
fail("Request failed unexpectedly: " + e.getMessage());
}
assertDoesNotThrow(connector::getHealth, "Request failed unexpectedly");
}
/**
* Test constructors of the {@link HTTPVaultConnector} class.
*/
@Test
public void constructorTest() throws IOException, CertificateException {
void constructorTest() throws IOException, CertificateException {
final String url = "https://vault.example.net/test/";
final String hostname = "vault.example.com";
final Integer port = 1337;
@ -206,60 +187,53 @@ public class HTTPVaultConnectorOfflineTest {
* This test is designed to test exceptions caught and thrown by seal-methods if Vault is not reachable.
*/
@Test
public void sealExceptionTest() throws IOException {
void sealExceptionTest() {
HTTPVaultConnector connector = new HTTPVaultConnector(INVALID_URL);
try {
connector.sealStatus();
fail("Querying seal status succeeded on invalid URL");
} catch (Exception e) {
assertThat("Unexpected type of exception", e, instanceOf(InvalidRequestException.class));
assertThat("Unexpected exception message", e.getMessage(), is("Invalid URI format"));
}
connector = new HTTPVaultConnector("https://127.0.0.1", null, 0, 250);
VaultConnectorException e = assertThrows(
InvalidRequestException.class,
connector::sealStatus,
"Querying seal status succeeded on invalid URL"
);
assertThat("Unexpected exception message", e.getMessage(), is("Invalid URI format"));
// Simulate NULL response (mock not supplied with data).
try {
connector.sealStatus();
fail("Querying seal status succeeded on invalid instance");
} catch (Exception e) {
assertThat("Unexpected type of exception", e, instanceOf(InvalidResponseException.class));
assertThat("Unexpected exception message", e.getMessage(), is("Response unavailable"));
}
connector = new HTTPVaultConnector("https://127.0.0.1", null, 0, 250);
e = assertThrows(
InvalidResponseException.class,
connector::sealStatus,
"Querying seal status succeeded on invalid instance"
);
assertThat("Unexpected exception message", e.getMessage(), is("Response unavailable"));
}
/**
* This test is designed to test exceptions caught and thrown by seal-methods if Vault is not reachable.
*/
@Test
public void healthExceptionTest() throws IOException {
void healthExceptionTest() {
HTTPVaultConnector connector = new HTTPVaultConnector(INVALID_URL);
try {
connector.getHealth();
fail("Querying health status succeeded on invalid URL");
} catch (Exception e) {
assertThat("Unexpected type of exception", e, instanceOf(InvalidRequestException.class));
assertThat("Unexpected exception message", e.getMessage(), is("Invalid URI format"));
}
connector = new HTTPVaultConnector("https://127.0.0.1", null, 0, 250);
VaultConnectorException e = assertThrows(
InvalidRequestException.class,
connector::getHealth,
"Querying health status succeeded on invalid URL"
);
assertThat("Unexpected exception message", e.getMessage(), is("Invalid URI format"));
// Simulate NULL response (mock not supplied with data).
try {
connector.getHealth();
fail("Querying health status succeeded on invalid instance");
} catch (Exception e) {
assertThat("Unexpected type of exception", e, instanceOf(InvalidResponseException.class));
assertThat("Unexpected exception message", e.getMessage(), is("Response unavailable"));
}
connector = new HTTPVaultConnector("https://127.0.0.1", null, 0, 250);
e = assertThrows(
InvalidResponseException.class,
connector::getHealth,
"Querying health status succeeded on invalid instance"
);
assertThat("Unexpected exception message", e.getMessage(), is("Response unavailable"));
}
/**
* Test behavior on unparsable responses.
*/
@Test
public void parseExceptionTest() throws IOException {
void parseExceptionTest() throws IOException {
HTTPVaultConnector connector = new HTTPVaultConnector("https://127.0.0.1", null, 0, 250);
// Mock authorization.
setPrivate(connector, "authorized", true);
@ -267,114 +241,25 @@ public class HTTPVaultConnectorOfflineTest {
mockResponse(200, "invalid", ContentType.APPLICATION_JSON);
// Now test the methods.
try {
connector.sealStatus();
fail("sealStatus() succeeded on invalid instance");
} catch (Exception e) {
assertParseError(e);
}
try {
connector.unseal("key");
fail("unseal() succeeded on invalid instance");
} catch (Exception e) {
assertParseError(e);
}
try {
connector.getHealth();
fail("getHealth() succeeded on invalid instance");
} catch (Exception e) {
assertParseError(e);
}
try {
connector.getAuthBackends();
fail("getAuthBackends() succeeded on invalid instance");
} catch (Exception e) {
assertParseError(e);
}
try {
connector.authToken("token");
fail("authToken() succeeded on invalid instance");
} catch (Exception e) {
assertParseError(e);
}
try {
connector.lookupAppRole("roleName");
fail("lookupAppRole() succeeded on invalid instance");
} catch (Exception e) {
assertParseError(e);
}
try {
connector.getAppRoleID("roleName");
fail("getAppRoleID() succeeded on invalid instance");
} catch (Exception e) {
assertParseError(e);
}
try {
connector.createAppRoleSecret("roleName");
fail("createAppRoleSecret() succeeded on invalid instance");
} catch (Exception e) {
assertParseError(e);
}
try {
connector.lookupAppRoleSecret("roleName", "secretID");
fail("lookupAppRoleSecret() succeeded on invalid instance");
} catch (Exception e) {
assertParseError(e);
}
try {
connector.listAppRoles();
fail("listAppRoles() succeeded on invalid instance");
} catch (Exception e) {
assertParseError(e);
}
try {
connector.listAppRoleSecrets("roleName");
fail("listAppRoleSecrets() succeeded on invalid instance");
} catch (Exception e) {
assertParseError(e);
}
try {
connector.read("key");
fail("read() succeeded on invalid instance");
} catch (Exception e) {
assertParseError(e);
}
try {
connector.list("path");
fail("list() succeeded on invalid instance");
} catch (Exception e) {
assertParseError(e);
}
try {
connector.renew("leaseID");
fail("renew() succeeded on invalid instance");
} catch (Exception e) {
assertParseError(e);
}
try {
connector.lookupToken("token");
fail("lookupToken() succeeded on invalid instance");
} catch (Exception e) {
assertParseError(e);
}
assertParseError(connector::sealStatus, "sealStatus() succeeded on invalid instance");
assertParseError(() -> connector.unseal("key"), "unseal() succeeded on invalid instance");
assertParseError(connector::getHealth, "getHealth() succeeded on invalid instance");
assertParseError(connector::getAuthBackends, "getAuthBackends() succeeded on invalid instance");
assertParseError(() -> connector.authToken("token"), "authToken() succeeded on invalid instance");
assertParseError(() -> connector.lookupAppRole("roleName"), "lookupAppRole() succeeded on invalid instance");
assertParseError(() -> connector.getAppRoleID("roleName"), "getAppRoleID() succeeded on invalid instance");
assertParseError(() -> connector.createAppRoleSecret("roleName"), "createAppRoleSecret() succeeded on invalid instance");
assertParseError(() -> connector.lookupAppRoleSecret("roleName", "secretID"), "lookupAppRoleSecret() succeeded on invalid instance");
assertParseError(connector::listAppRoles, "listAppRoles() succeeded on invalid instance");
assertParseError(() -> connector.listAppRoleSecrets("roleName"), "listAppRoleSecrets() succeeded on invalid instance");
assertParseError(() -> connector.read("key"), "read() succeeded on invalid instance");
assertParseError(() -> connector.list("path"), "list() succeeded on invalid instance");
assertParseError(() -> connector.renew("leaseID"), "renew() succeeded on invalid instance");
assertParseError(() -> connector.lookupToken("token"), "lookupToken() succeeded on invalid instance");
}
private void assertParseError(Exception e) {
assertThat("Unexpected type of exception", e, instanceOf(InvalidResponseException.class));
private void assertParseError(Executable executable, String message) {
InvalidResponseException e = assertThrows(InvalidResponseException.class, executable, message);
assertThat("Unexpected exception message", e.getMessage(), is("Unable to parse response"));
}
@ -382,7 +267,7 @@ public class HTTPVaultConnectorOfflineTest {
* Test requests that expect an empty response with code 204, but receive a 200 body.
*/
@Test
public void nonEmpty204ResponseTest() throws IOException {
void nonEmpty204ResponseTest() throws IOException {
HTTPVaultConnector connector = new HTTPVaultConnector("https://127.0.0.1", null, 0, 250);
// Mock authorization.
setPrivate(connector, "authorized", true);
@ -390,71 +275,62 @@ public class HTTPVaultConnectorOfflineTest {
mockResponse(200, "{}", ContentType.APPLICATION_JSON);
// Now test the methods expecting a 204.
try {
connector.registerAppId("appID", "policy", "displayName");
fail("registerAppId() with 200 response succeeded");
} catch (VaultConnectorException e) {
assertThat("Unexpected exception type", e, instanceOf(InvalidResponseException.class));
}
assertThrows(
InvalidResponseException.class,
() -> connector.registerAppId("appID", "policy", "displayName"),
"registerAppId() with 200 response succeeded"
);
try {
connector.registerUserId("appID", "userID");
fail("registerUserId() with 200 response succeeded");
} catch (VaultConnectorException e) {
assertThat("Unexpected exception type", e, instanceOf(InvalidResponseException.class));
}
assertThrows(
InvalidResponseException.class,
() -> connector.registerUserId("appID", "userID"),
"registerUserId() with 200 response succeeded"
);
try {
connector.createAppRole("appID", Collections.singletonList("policy"));
fail("createAppRole() with 200 response succeeded");
} catch (VaultConnectorException e) {
assertThat("Unexpected exception type", e, instanceOf(InvalidResponseException.class));
}
assertThrows(
InvalidResponseException.class,
() -> connector.createAppRole("appID", Collections.singletonList("policy")),
"createAppRole() with 200 response succeeded"
);
try {
connector.deleteAppRole("roleName");
fail("deleteAppRole() with 200 response succeeded");
} catch (VaultConnectorException e) {
assertThat("Unexpected exception type", e, instanceOf(InvalidResponseException.class));
}
assertThrows(
InvalidResponseException.class,
() -> connector.deleteAppRole("roleName"),
"deleteAppRole() with 200 response succeeded"
);
try {
connector.setAppRoleID("roleName", "roleID");
fail("setAppRoleID() with 200 response succeeded");
} catch (VaultConnectorException e) {
assertThat("Unexpected exception type", e, instanceOf(InvalidResponseException.class));
}
assertThrows(
InvalidResponseException.class,
() -> connector.setAppRoleID("roleName", "roleID"),
"setAppRoleID() with 200 response succeeded"
);
try {
connector.destroyAppRoleSecret("roleName", "secretID");
fail("destroyAppRoleSecret() with 200 response succeeded");
} catch (VaultConnectorException e) {
assertThat("Unexpected exception type", e, instanceOf(InvalidResponseException.class));
}
assertThrows(
InvalidResponseException.class,
() -> connector.destroyAppRoleSecret("roleName", "secretID"),
"destroyAppRoleSecret() with 200 response succeeded"
);
try {
connector.destroyAppRoleSecret("roleName", "secretUD");
fail("destroyAppRoleSecret() with 200 response succeeded");
} catch (VaultConnectorException e) {
assertThat("Unexpected exception type", e, instanceOf(InvalidResponseException.class));
}
assertThrows(
InvalidResponseException.class,
() -> connector.destroyAppRoleSecret("roleName", "secretUD"),
"destroyAppRoleSecret() with 200 response succeeded"
);
try {
connector.delete("key");
fail("delete() with 200 response succeeded");
} catch (VaultConnectorException e) {
assertThat("Unexpected exception type", e, instanceOf(InvalidResponseException.class));
}
assertThrows(
InvalidResponseException.class,
() -> connector.delete("key"),
"delete() with 200 response succeeded"
);
try {
connector.revoke("leaseID");
fail("destroyAppRoleSecret() with 200 response succeeded");
} catch (VaultConnectorException e) {
assertThat("Unexpected exception type", e, instanceOf(InvalidResponseException.class));
}
assertThrows(
InvalidResponseException.class,
() -> connector.revoke("leaseID"),
"destroyAppRoleSecret() with 200 response succeeded"
);
}
private Object getRequestHelperPrivate(HTTPVaultConnector connector, String fieldName) {
private Object getRequestHelperPrivate(HTTPVaultConnector connector, String fieldName) {
try {
return getPrivate(getPrivate(connector, "request"), fieldName);
} catch (NoSuchFieldException | IllegalAccessException e) {

View File

@ -1,5 +1,5 @@
/*
* Copyright 2016-2020 Stefan Kalscheuer
* Copyright 2016-2021 Stefan Kalscheuer
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -16,21 +16,22 @@
package de.stklcode.jvault.connector.builder;
import com.github.stefanbirkner.systemlambda.SystemLambda;
import de.stklcode.jvault.connector.HTTPVaultConnector;
import de.stklcode.jvault.connector.HTTPVaultConnectorBuilder;
import de.stklcode.jvault.connector.exception.TlsException;
import de.stklcode.jvault.connector.exception.VaultConnectorException;
import de.stklcode.jvault.connector.test.EnvironmentMock;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Field;
import java.nio.file.NoSuchFileException;
import static com.github.stefanbirkner.systemlambda.SystemLambda.withEnvironmentVariable;
import static org.hamcrest.CoreMatchers.*;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.jupiter.api.Assertions.fail;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertThrows;
/**
* JUnit test for HTTP Vault connector factory
@ -38,7 +39,7 @@ import static org.junit.jupiter.api.Assertions.fail;
* @author Stefan Kalscheuer
* @since 0.8.0
*/
public class HTTPVaultConnectorBuilderTest {
class HTTPVaultConnectorBuilderTest {
private static final String VAULT_ADDR = "https://localhost:8201";
private static final Integer VAULT_MAX_RETRIES = 13;
private static final String VAULT_TOKEN = "00001111-2222-3333-4444-555566667777";
@ -50,66 +51,68 @@ public class HTTPVaultConnectorBuilderTest {
* Test building from environment variables
*/
@Test
void testFromEnv() throws NoSuchFieldException, IllegalAccessException, IOException {
void testFromEnv() throws Exception {
/* Provide address only should be enough */
setenv(VAULT_ADDR, null, null, null);
withVaultEnv(VAULT_ADDR, null, null, null).execute(() -> {
HTTPVaultConnectorBuilder builder = assertDoesNotThrow(
() -> HTTPVaultConnector.builder().fromEnv(),
"Factory creation from minimal environment failed"
);
HTTPVaultConnector connector = builder.build();
HTTPVaultConnectorBuilder factory = null;
HTTPVaultConnector connector;
try {
factory = VaultConnectorBuilder.http().fromEnv();
} catch (VaultConnectorException e) {
fail("Factory creation from minimal environment failed");
}
connector = factory.build();
assertThat("URL nor set correctly", getRequestHelperPrivate(connector, "baseURL"), is(equalTo(VAULT_ADDR + "/v1/")));
assertThat("Trusted CA cert set when no cert provided", getRequestHelperPrivate(connector, "trustedCaCert"), is(nullValue()));
assertThat("Non-default number of retries, when none set", getRequestHelperPrivate(connector, "retries"), is(0));
assertThat("URL nor set correctly", getRequestHelperPrivate(connector, "baseURL"), is(equalTo(VAULT_ADDR + "/v1/")));
assertThat("Trusted CA cert set when no cert provided", getRequestHelperPrivate(connector, "trustedCaCert"), is(nullValue()));
assertThat("Non-default number of retries, when none set", getRequestHelperPrivate(connector, "retries"), is(0));
return null;
});
/* Provide address and number of retries */
setenv(VAULT_ADDR, null, VAULT_MAX_RETRIES.toString(), null);
withVaultEnv(VAULT_ADDR, null, VAULT_MAX_RETRIES.toString(), null).execute(() -> {
HTTPVaultConnectorBuilder builder = assertDoesNotThrow(
() -> HTTPVaultConnector.builder().fromEnv(),
"Factory creation from environment failed"
);
HTTPVaultConnector connector = builder.build();
try {
factory = VaultConnectorBuilder.http().fromEnv();
} catch (VaultConnectorException e) {
fail("Factory creation from environment failed");
}
connector = factory.build();
assertThat("URL nor set correctly", getRequestHelperPrivate(connector, "baseURL"), is(equalTo(VAULT_ADDR + "/v1/")));
assertThat("Trusted CA cert set when no cert provided", getRequestHelperPrivate(connector, "trustedCaCert"), is(nullValue()));
assertThat("Number of retries not set correctly", getRequestHelperPrivate(connector, "retries"), is(VAULT_MAX_RETRIES));
assertThat("URL nor set correctly", getRequestHelperPrivate(connector, "baseURL"), is(equalTo(VAULT_ADDR + "/v1/")));
assertThat("Trusted CA cert set when no cert provided", getRequestHelperPrivate(connector, "trustedCaCert"), is(nullValue()));
assertThat("Number of retries not set correctly", getRequestHelperPrivate(connector, "retries"), is(VAULT_MAX_RETRIES));
return null;
});
/* Provide CA certificate */
String VAULT_CACERT = tempDir.toString() + "/doesnotexist";
setenv(VAULT_ADDR, VAULT_CACERT, VAULT_MAX_RETRIES.toString(), null);
try {
VaultConnectorBuilder.http().fromEnv();
fail("Creation with unknown cert path failed.");
} catch (VaultConnectorException e) {
assertThat(e, is(instanceOf(TlsException.class)));
withVaultEnv(VAULT_ADDR, VAULT_CACERT, VAULT_MAX_RETRIES.toString(), null).execute(() -> {
TlsException e = assertThrows(
TlsException.class,
() -> HTTPVaultConnector.builder().fromEnv(),
"Creation with unknown cert path failed."
);
assertThat(e.getCause(), is(instanceOf(NoSuchFileException.class)));
assertThat(((NoSuchFileException) e.getCause()).getFile(), is(VAULT_CACERT));
}
return null;
});
/* Automatic authentication */
setenv(VAULT_ADDR, null, VAULT_MAX_RETRIES.toString(), VAULT_TOKEN);
withVaultEnv(VAULT_ADDR, null, VAULT_MAX_RETRIES.toString(), VAULT_TOKEN).execute(() -> {
HTTPVaultConnectorBuilder builder = assertDoesNotThrow(
() -> HTTPVaultConnector.builder().fromEnv(),
"Factory creation from minimal environment failed"
);
assertThat("Token nor set correctly", getPrivate(builder, "token"), is(equalTo(VAULT_TOKEN)));
try {
factory = VaultConnectorBuilder.http().fromEnv();
} catch (VaultConnectorException e) {
fail("Factory creation from minimal environment failed");
}
assertThat("Token nor set correctly", getPrivate(factory, "token"), is(equalTo(VAULT_TOKEN)));
return null;
});
}
private void setenv(String vault_addr, String vault_cacert, String vault_max_retries, String vault_token) {
EnvironmentMock.setenv("VAULT_ADDR", vault_addr);
EnvironmentMock.setenv("VAULT_CACERT", vault_cacert);
EnvironmentMock.setenv("VAULT_MAX_RETRIES", vault_max_retries);
EnvironmentMock.setenv("VAULT_TOKEN", vault_token);
private SystemLambda.WithEnvironmentVariables withVaultEnv(String vault_addr, String vault_cacert, String vault_max_retries, String vault_token) {
return withEnvironmentVariable("VAULT_ADDR", vault_addr)
.and("VAULT_CACERT", vault_cacert)
.and("VAULT_MAX_RETRIES", vault_max_retries)
.and("VAULT_TOKEN", vault_token);
}
private Object getRequestHelperPrivate(HTTPVaultConnector connector, String fieldName) throws NoSuchFieldException, IllegalAccessException {

View File

@ -1,5 +1,5 @@
/*
* Copyright 2016-2020 Stefan Kalscheuer
* Copyright 2016-2021 Stefan Kalscheuer
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -29,19 +29,19 @@ import static org.hamcrest.core.Is.is;
* @author Stefan Kalscheuer
* @since 0.6.2
*/
public class VaultConnectorExceptionTest {
class VaultConnectorExceptionTest {
private static final String MSG = "This is a test exception!";
private static final Throwable CAUSE = new Exception("Test-Cause");
private static final Integer STATUS_CODE = 1337;
private static final String RESPONSE = "Dummy response";
@Test
public void authorizationRequiredExceptionTest() {
void authorizationRequiredExceptionTest() {
assertEmptyConstructor(new AuthorizationRequiredException());
}
@Test
public void connectionExceptionTest() {
void connectionExceptionTest() {
assertEmptyConstructor(new ConnectionException());
assertMsgConstructor(new ConnectionException(MSG));
assertCauseConstructor(new ConnectionException(CAUSE));
@ -49,7 +49,7 @@ public class VaultConnectorExceptionTest {
}
@Test
public void invalidRequestExceptionTest() {
void invalidRequestExceptionTest() {
assertEmptyConstructor(new InvalidRequestException());
assertMsgConstructor(new InvalidRequestException(MSG));
assertCauseConstructor(new InvalidRequestException(CAUSE));
@ -57,7 +57,7 @@ public class VaultConnectorExceptionTest {
}
@Test
public void invalidResponseExceptionTest() {
void invalidResponseExceptionTest() {
assertEmptyConstructor(new InvalidResponseException());
assertMsgConstructor(new InvalidResponseException(MSG));
assertCauseConstructor(new InvalidResponseException(CAUSE));
@ -93,7 +93,7 @@ public class VaultConnectorExceptionTest {
}
@Test
public void permissionDeniedExceptionTest() {
void permissionDeniedExceptionTest() {
// Default message overwritten.
PermissionDeniedException e = new PermissionDeniedException();
assertThat(e, is(instanceOf(VaultConnectorException.class)));
@ -108,7 +108,7 @@ public class VaultConnectorExceptionTest {
}
@Test
public void tlsExceptionTest() {
void tlsExceptionTest() {
assertEmptyConstructor(new TlsException());
assertMsgConstructor(new TlsException(MSG));
assertCauseConstructor(new TlsException(CAUSE));

View File

@ -1,5 +1,5 @@
/*
* Copyright 2016-2020 Stefan Kalscheuer
* Copyright 2016-2021 Stefan Kalscheuer
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -16,21 +16,21 @@
package de.stklcode.jvault.connector.factory;
import com.github.stefanbirkner.systemlambda.SystemLambda;
import de.stklcode.jvault.connector.HTTPVaultConnector;
import de.stklcode.jvault.connector.exception.TlsException;
import de.stklcode.jvault.connector.exception.VaultConnectorException;
import de.stklcode.jvault.connector.test.EnvironmentMock;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Field;
import java.nio.file.NoSuchFileException;
import static com.github.stefanbirkner.systemlambda.SystemLambda.withEnvironmentVariable;
import static org.hamcrest.CoreMatchers.*;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.jupiter.api.Assertions.fail;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertThrows;
/**
* JUnit test for HTTP Vault connector factory
@ -38,7 +38,7 @@ import static org.junit.jupiter.api.Assertions.fail;
* @author Stefan Kalscheuer
* @since 0.6.0
*/
public class HTTPVaultConnectorFactoryTest {
class HTTPVaultConnectorFactoryTest {
private static String VAULT_ADDR = "https://localhost:8201";
private static Integer VAULT_MAX_RETRIES = 13;
private static String VAULT_TOKEN = "00001111-2222-3333-4444-555566667777";
@ -50,66 +50,68 @@ public class HTTPVaultConnectorFactoryTest {
* Test building from environment variables
*/
@Test
public void testFromEnv() throws NoSuchFieldException, IllegalAccessException, IOException {
void testFromEnv() throws Exception {
/* Provide address only should be enough */
setenv(VAULT_ADDR, null, null, null);
withVaultEnv(VAULT_ADDR, null, null, null).execute(() -> {
HTTPVaultConnectorFactory factory = assertDoesNotThrow(
() -> VaultConnectorFactory.httpFactory().fromEnv(),
"Factory creation from minimal environment failed"
);
HTTPVaultConnector connector = factory.build();
HTTPVaultConnectorFactory factory = null;
HTTPVaultConnector connector;
try {
factory = VaultConnectorFactory.httpFactory().fromEnv();
} catch (VaultConnectorException e) {
fail("Factory creation from minimal environment failed");
}
connector = factory.build();
assertThat("URL nor set correctly", getRequestHelperPrivate(connector, "baseURL"), is(equalTo(VAULT_ADDR + "/v1/")));
assertThat("Trusted CA cert set when no cert provided", getRequestHelperPrivate(connector, "trustedCaCert"), is(nullValue()));
assertThat("Non-default number of retries, when none set", getRequestHelperPrivate(connector, "retries"), is(0));
assertThat("URL nor set correctly", getRequestHelperPrivate(connector, "baseURL"), is(equalTo(VAULT_ADDR + "/v1/")));
assertThat("Trusted CA cert set when no cert provided", getRequestHelperPrivate(connector, "trustedCaCert"), is(nullValue()));
assertThat("Non-default number of retries, when none set", getRequestHelperPrivate(connector, "retries"), is(0));
return null;
});
/* Provide address and number of retries */
setenv(VAULT_ADDR, null, VAULT_MAX_RETRIES.toString(), null);
withVaultEnv(VAULT_ADDR, null, VAULT_MAX_RETRIES.toString(), null).execute(() -> {
HTTPVaultConnectorFactory factory = assertDoesNotThrow(
() -> VaultConnectorFactory.httpFactory().fromEnv(),
"Factory creation from environment failed"
);
HTTPVaultConnector connector = factory.build();
try {
factory = VaultConnectorFactory.httpFactory().fromEnv();
} catch (VaultConnectorException e) {
fail("Factory creation from environment failed");
}
connector = factory.build();
assertThat("URL nor set correctly", getRequestHelperPrivate(connector, "baseURL"), is(equalTo(VAULT_ADDR + "/v1/")));
assertThat("Trusted CA cert set when no cert provided", getRequestHelperPrivate(connector, "trustedCaCert"), is(nullValue()));
assertThat("Number of retries not set correctly", getRequestHelperPrivate(connector, "retries"), is(VAULT_MAX_RETRIES));
assertThat("URL nor set correctly", getRequestHelperPrivate(connector, "baseURL"), is(equalTo(VAULT_ADDR + "/v1/")));
assertThat("Trusted CA cert set when no cert provided", getRequestHelperPrivate(connector, "trustedCaCert"), is(nullValue()));
assertThat("Number of retries not set correctly", getRequestHelperPrivate(connector, "retries"), is(VAULT_MAX_RETRIES));
return null;
});
/* Provide CA certificate */
String VAULT_CACERT = tempDir.toString() + "/doesnotexist";
setenv(VAULT_ADDR, VAULT_CACERT, VAULT_MAX_RETRIES.toString(), null);
try {
VaultConnectorFactory.httpFactory().fromEnv();
fail("Creation with unknown cert path failed.");
} catch (VaultConnectorException e) {
assertThat(e, is(instanceOf(TlsException.class)));
withVaultEnv(VAULT_ADDR, VAULT_CACERT, VAULT_MAX_RETRIES.toString(), null).execute(() -> {
TlsException e = assertThrows(
TlsException.class,
() -> VaultConnectorFactory.httpFactory().fromEnv(),
"Creation with unknown cert path failed."
);
assertThat(e.getCause(), is(instanceOf(NoSuchFileException.class)));
assertThat(((NoSuchFileException) e.getCause()).getFile(), is(VAULT_CACERT));
}
return null;
});
/* Automatic authentication */
setenv(VAULT_ADDR, null, VAULT_MAX_RETRIES.toString(), VAULT_TOKEN);
withVaultEnv(VAULT_ADDR, null, VAULT_MAX_RETRIES.toString(), VAULT_TOKEN).execute(() -> {
HTTPVaultConnectorFactory factory = assertDoesNotThrow(
() -> VaultConnectorFactory.httpFactory().fromEnv(),
"Factory creation from minimal environment failed"
);
assertThat("Token nor set correctly", getPrivate(getPrivate(factory, "delegate"), "token"), is(equalTo(VAULT_TOKEN)));
try {
factory = VaultConnectorFactory.httpFactory().fromEnv();
} catch (VaultConnectorException e) {
fail("Factory creation from minimal environment failed");
}
assertThat("Token nor set correctly", getPrivate(getPrivate(factory, "delegate"), "token"), is(equalTo(VAULT_TOKEN)));
return null;
});
}
private void setenv(String vault_addr, String vault_cacert, String vault_max_retries, String vault_token) {
EnvironmentMock.setenv("VAULT_ADDR", vault_addr);
EnvironmentMock.setenv("VAULT_CACERT", vault_cacert);
EnvironmentMock.setenv("VAULT_MAX_RETRIES", vault_max_retries);
EnvironmentMock.setenv("VAULT_TOKEN", vault_token);
private SystemLambda.WithEnvironmentVariables withVaultEnv(String vault_addr, String vault_cacert, String vault_max_retries, String vault_token) {
return withEnvironmentVariable("VAULT_ADDR", vault_addr)
.and("VAULT_CACERT", vault_cacert)
.and("VAULT_MAX_RETRIES", vault_max_retries)
.and("VAULT_TOKEN", vault_token);
}
private Object getRequestHelperPrivate(HTTPVaultConnector connector, String fieldName) throws NoSuchFieldException, IllegalAccessException {

View File

@ -1,5 +1,5 @@
/*
* Copyright 2016-2020 Stefan Kalscheuer
* Copyright 2016-2021 Stefan Kalscheuer
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -33,7 +33,7 @@ import static org.hamcrest.Matchers.*;
* @author Stefan Kalscheuer
* @since 0.4.0
*/
public class AppRoleBuilderTest {
class AppRoleBuilderTest {
private static final String NAME = "TestRole";
private static final String ID = "test-id";
private static final Boolean BIND_SECRET_ID = true;
@ -58,7 +58,7 @@ public class AppRoleBuilderTest {
NAME, ID, BIND_SECRET_ID, CIDR_1, SECRET_ID_NUM_USES, SECRET_ID_TTL, ENABLE_LOCAL_SECRET_IDS, TOKEN_TTL, TOKEN_MAX_TTL, POLICY, CIDR_1, TOKEN_EXPLICIT_MAX_TTL, TOKEN_NO_DEFAULT_POLICY, TOKEN_NUM_USES, TOKEN_PERIOD, TOKEN_TYPE.value());
@BeforeAll
public static void init() {
static void init() {
BOUND_CIDR_LIST.add(CIDR_1);
POLICIES.add(POLICY);
}
@ -67,7 +67,7 @@ public class AppRoleBuilderTest {
* Build role with only a name.
*/
@Test
public void buildDefaultTest() throws JsonProcessingException {
void buildDefaultTest() throws JsonProcessingException {
AppRole role = AppRole.builder(NAME).build();
assertThat(role.getId(), is(nullValue()));
assertThat(role.getBindSecretId(), is(nullValue()));
@ -95,7 +95,7 @@ public class AppRoleBuilderTest {
* Build role with only a name.
*/
@Test
public void legacyBuildDefaultTest() throws JsonProcessingException {
void legacyBuildDefaultTest() throws JsonProcessingException {
AppRole role = new AppRoleBuilder(NAME).build();
assertThat(role.getId(), is(nullValue()));
assertThat(role.getBindSecretId(), is(nullValue()));
@ -123,7 +123,7 @@ public class AppRoleBuilderTest {
* Build token without all parameters set.
*/
@Test
public void buildFullTest() throws JsonProcessingException {
void buildFullTest() throws JsonProcessingException {
AppRole role = AppRole.builder(NAME)
.withId(ID)
.withBindSecretID(BIND_SECRET_ID)
@ -138,7 +138,7 @@ public class AppRoleBuilderTest {
.withTokenExplicitMaxTtl(TOKEN_EXPLICIT_MAX_TTL)
.withTokenNoDefaultPolicy(TOKEN_NO_DEFAULT_POLICY)
.withTokenNumUses(TOKEN_NUM_USES)
.wit0hTokenPeriod(TOKEN_PERIOD)
.withTokenPeriod(TOKEN_PERIOD)
.withTokenType(TOKEN_TYPE)
.build();
assertThat(role.getName(), is(NAME));
@ -168,7 +168,7 @@ public class AppRoleBuilderTest {
* Build token without all parameters set.
*/
@Test
public void legacyBuildFullTest() throws JsonProcessingException {
void legacyBuildFullTest() throws JsonProcessingException {
AppRole role = new AppRoleBuilder(NAME)
.withId(ID)
.withBindSecretID(BIND_SECRET_ID)
@ -183,7 +183,7 @@ public class AppRoleBuilderTest {
.withTokenExplicitMaxTtl(TOKEN_EXPLICIT_MAX_TTL)
.withTokenNoDefaultPolicy(TOKEN_NO_DEFAULT_POLICY)
.withTokenNumUses(TOKEN_NUM_USES)
.wit0hTokenPeriod(TOKEN_PERIOD)
.withTokenPeriod(TOKEN_PERIOD)
.withTokenType(TOKEN_TYPE)
.build();
assertThat(role.getName(), is(NAME));
@ -213,7 +213,7 @@ public class AppRoleBuilderTest {
* Test convenience methods
*/
@Test
public void convenienceMethodsTest() {
void convenienceMethodsTest() {
/* bind_secret_id */
AppRole role = AppRole.builder(NAME).build();
assertThat(role.getBindSecretId(), is(nullValue()));
@ -257,7 +257,7 @@ public class AppRoleBuilderTest {
* Test convenience methods
*/
@Test
public void legacyConvenienceMethodsTest() {
void legacyConvenienceMethodsTest() {
/* bind_secret_id */
AppRole role = new AppRoleBuilder(NAME).build();
assertThat(role.getBindSecretId(), is(nullValue()));

View File

@ -1,5 +1,5 @@
/*
* Copyright 2016-2020 Stefan Kalscheuer
* Copyright 2016-2021 Stefan Kalscheuer
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -16,11 +16,9 @@
package de.stklcode.jvault.connector.model;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.jupiter.api.Test;
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.HashMap;
@ -29,7 +27,7 @@ import java.util.Map;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*;
import static org.junit.jupiter.api.Assertions.fail;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assumptions.assumeTrue;
@ -39,7 +37,7 @@ import static org.junit.jupiter.api.Assumptions.assumeTrue;
* @author Stefan Kalscheuer
* @since 0.5.0
*/
public class AppRoleSecretTest {
class AppRoleSecretTest {
private static final String TEST_ID = "abc123";
private static final Map<String, Object> TEST_META = new HashMap<>();
@ -54,7 +52,7 @@ public class AppRoleSecretTest {
* Test constructors.
*/
@Test
public void constructorTest() {
void constructorTest() {
/* Empty constructor */
AppRoleSecret secret = new AppRoleSecret();
assertThat(secret.getId(), is(nullValue()));
@ -99,7 +97,7 @@ public class AppRoleSecretTest {
* Test setter.
*/
@Test
public void setterTest() {
void setterTest() {
AppRoleSecret secret = new AppRoleSecret(TEST_ID);
assertThat(secret.getCidrList(), is(nullValue()));
assertThat(secret.getCidrListString(), is(emptyString()));
@ -115,31 +113,22 @@ public class AppRoleSecretTest {
* Test JSON (de)serialization.
*/
@Test
public void jsonTest() throws NoSuchFieldException, IllegalAccessException {
void jsonTest() throws NoSuchFieldException, IllegalAccessException {
ObjectMapper mapper = new ObjectMapper();
/* A simple roundtrip first. All set fields should be present afterwards. */
AppRoleSecret secret = new AppRoleSecret(TEST_ID, TEST_META, TEST_CIDR);
String secretJson = "";
try {
secretJson = mapper.writeValueAsString(secret);
} catch (JsonProcessingException e) {
e.printStackTrace();
fail("Serialization failed");
}
String secretJson = assertDoesNotThrow(() -> mapper.writeValueAsString(secret), "Serialization failed");
/* CIDR list is comma-separated when used as input, but List otherwise, hence convert string to list */
secretJson = commaSeparatedToList(secretJson);
String secretJson2 = commaSeparatedToList(secretJson);
AppRoleSecret secret2;
try {
secret2 = mapper.readValue(secretJson, AppRoleSecret.class);
assertThat(secret.getId(), is(secret2.getId()));
assertThat(secret.getMetadata(), is(secret2.getMetadata()));
assertThat(secret.getCidrList(), is(secret2.getCidrList()));
} catch (IOException e) {
e.printStackTrace();
fail("Deserialization failed");
}
AppRoleSecret secret2 = assertDoesNotThrow(
() -> mapper.readValue(secretJson2, AppRoleSecret.class),
"Deserialization failed"
);
assertThat(secret.getId(), is(secret2.getId()));
assertThat(secret.getMetadata(), is(secret2.getMetadata()));
assertThat(secret.getCidrList(), is(secret2.getCidrList()));
/* Test fields, that should not be written to JSON */
setPrivateField(secret, "accessor", "TEST_ACCESSOR");
@ -154,45 +143,33 @@ public class AppRoleSecretTest {
assumeTrue(secret.getNumUses() == 678);
setPrivateField(secret, "ttl", 12345);
assumeTrue(secret.getTtl() == 12345);
try {
secretJson = mapper.writeValueAsString(secret);
} catch (JsonProcessingException e) {
e.printStackTrace();
fail("Serialization failed");
}
try {
secret2 = mapper.readValue(commaSeparatedToList(secretJson), AppRoleSecret.class);
assertThat(secret.getId(), is(secret2.getId()));
assertThat(secret.getMetadata(), is(secret2.getMetadata()));
assertThat(secret.getCidrList(), is(secret2.getCidrList()));
assertThat(secret2.getAccessor(), is(nullValue()));
assertThat(secret2.getCreationTime(), is(nullValue()));
assertThat(secret2.getExpirationTime(), is(nullValue()));
assertThat(secret2.getLastUpdatedTime(), is(nullValue()));
assertThat(secret2.getNumUses(), is(nullValue()));
assertThat(secret2.getTtl(), is(nullValue()));
} catch (IOException e) {
e.printStackTrace();
fail("Deserialization failed");
}
String secretJson3 = assertDoesNotThrow(() -> mapper.writeValueAsString(secret), "Serialization failed");
secret2 = assertDoesNotThrow(
() -> mapper.readValue(commaSeparatedToList(secretJson3), AppRoleSecret.class),
"Deserialization failed"
);
assertThat(secret.getId(), is(secret2.getId()));
assertThat(secret.getMetadata(), is(secret2.getMetadata()));
assertThat(secret.getCidrList(), is(secret2.getCidrList()));
assertThat(secret2.getAccessor(), is(nullValue()));
assertThat(secret2.getCreationTime(), is(nullValue()));
assertThat(secret2.getExpirationTime(), is(nullValue()));
assertThat(secret2.getLastUpdatedTime(), is(nullValue()));
assertThat(secret2.getNumUses(), is(nullValue()));
assertThat(secret2.getTtl(), is(nullValue()));
/* Those fields should be deserialized from JSON though */
secretJson = "{\"secret_id\":\"abc123\",\"metadata\":{\"number\":1337,\"foo\":\"bar\"}," +
String secretJson4 = "{\"secret_id\":\"abc123\",\"metadata\":{\"number\":1337,\"foo\":\"bar\"}," +
"\"cidr_list\":[\"203.0.113.0/24\",\"198.51.100.0/24\"],\"secret_id_accessor\":\"TEST_ACCESSOR\"," +
"\"creation_time\":\"TEST_CREATION\",\"expiration_time\":\"TEST_EXPIRATION\"," +
"\"last_updated_time\":\"TEST_LASTUPDATE\",\"secret_id_num_uses\":678,\"secret_id_ttl\":12345}";
try {
secret2 = mapper.readValue(secretJson, AppRoleSecret.class);
assertThat(secret2.getAccessor(), is("TEST_ACCESSOR"));
assertThat(secret2.getCreationTime(), is("TEST_CREATION"));
assertThat(secret2.getExpirationTime(), is("TEST_EXPIRATION"));
assertThat(secret2.getLastUpdatedTime(), is("TEST_LASTUPDATE"));
assertThat(secret2.getNumUses(), is(678));
assertThat(secret2.getTtl(), is(12345));
} catch (IOException e) {
e.printStackTrace();
fail("Deserialization failed");
}
secret2 = assertDoesNotThrow(() -> mapper.readValue(secretJson4, AppRoleSecret.class), "Deserialization failed");
assertThat(secret2.getAccessor(), is("TEST_ACCESSOR"));
assertThat(secret2.getCreationTime(), is("TEST_CREATION"));
assertThat(secret2.getExpirationTime(), is("TEST_EXPIRATION"));
assertThat(secret2.getLastUpdatedTime(), is("TEST_LASTUPDATE"));
assertThat(secret2.getNumUses(), is(678));
assertThat(secret2.getTtl(), is(12345));
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2016-2020 Stefan Kalscheuer
* Copyright 2016-2021 Stefan Kalscheuer
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -27,13 +27,13 @@ import static org.hamcrest.Matchers.is;
* @author Stefan Kalscheuer
* @since 0.4.0
*/
public class AuthBackendTest {
class AuthBackendTest {
/**
* Test forType() method.
*/
@Test
public void forTypeTest() {
void forTypeTest() {
assertThat(AuthBackend.forType("token"), is(AuthBackend.TOKEN));
assertThat(AuthBackend.forType("app-id"), is(AuthBackend.APPID));
assertThat(AuthBackend.forType("userpass"), is(AuthBackend.USERPASS));

View File

@ -1,5 +1,5 @@
/*
* Copyright 2016-2020 Stefan Kalscheuer
* Copyright 2016-2021 Stefan Kalscheuer
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -35,7 +35,7 @@ import static org.hamcrest.Matchers.*;
* @author Stefan Kalscheuer
* @since 0.4.0
*/
public class TokenBuilderTest {
class TokenBuilderTest {
private static final String ID = "test-id";
private static final String DISPLAY_NAME = "display-name";
private static final Boolean NO_PARENT = false;
@ -59,7 +59,7 @@ public class TokenBuilderTest {
private static final String JSON_FULL = "{\"id\":\"test-id\",\"type\":\"service\",\"display_name\":\"display-name\",\"no_parent\":false,\"no_default_policy\":false,\"ttl\":123,\"explicit_max_ttl\":456,\"num_uses\":4,\"policies\":[\"policy\"],\"meta\":{\"key\":\"value\"},\"renewable\":true,\"period\":3600,\"entity_alias\":\"alias-value\"}";
@BeforeAll
public static void init() {
static void init() {
POLICIES.add(POLICY);
META.put(META_KEY, META_VALUE);
}
@ -68,7 +68,7 @@ public class TokenBuilderTest {
* Build token without any parameters.
*/
@Test
public void buildDefaultTest() throws JsonProcessingException {
void buildDefaultTest() throws JsonProcessingException {
Token token = Token.builder().build();
assertThat(token.getId(), is(nullValue()));
assertThat(token.getType(), is(nullValue()));
@ -92,7 +92,7 @@ public class TokenBuilderTest {
* Build token without any parameters.
*/
@Test
public void legacyBuildDefaultTest() throws JsonProcessingException {
void legacyBuildDefaultTest() throws JsonProcessingException {
Token token = new TokenBuilder().build();
assertThat(token.getId(), is(nullValue()));
assertThat(token.getType(), is(nullValue()));
@ -113,7 +113,7 @@ public class TokenBuilderTest {
* Build token without all parameters set.
*/
@Test
public void buildFullTest() throws JsonProcessingException {
void buildFullTest() throws JsonProcessingException {
Token token = Token.builder()
.withId(ID)
.withType(Token.Type.SERVICE)
@ -150,7 +150,7 @@ public class TokenBuilderTest {
* Build token without all parameters set.
*/
@Test
public void legacyBuildFullTest() throws JsonProcessingException {
void legacyBuildFullTest() throws JsonProcessingException {
Token token = new TokenBuilder()
.withId(ID)
.withType(Token.Type.SERVICE)
@ -182,7 +182,7 @@ public class TokenBuilderTest {
* Test convenience methods
*/
@Test
public void convenienceMethodsTest() {
void convenienceMethodsTest() {
/* Parent */
Token token = Token.builder().asOrphan().build();
assertThat(token.getNoParent(), is(true));
@ -230,7 +230,7 @@ public class TokenBuilderTest {
* Test convenience methods
*/
@Test
public void legacyConvenienceMethodsTest() {
void legacyConvenienceMethodsTest() {
/* Parent */
Token token = new TokenBuilder().asOrphan().build();
assertThat(token.getNoParent(), is(true));

View File

@ -1,5 +1,5 @@
/*
* Copyright 2016-2020 Stefan Kalscheuer
* Copyright 2016-2021 Stefan Kalscheuer
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -32,7 +32,7 @@ import static org.hamcrest.Matchers.*;
* @author Stefan Kalscheuer
* @since 0.9
*/
public class TokenRoleBuilderTest {
class TokenRoleBuilderTest {
private static final String NAME = "test-role";
private static final String ALLOWED_POLICY_1 = "apol-1";
private static final String ALLOWED_POLICY_2 = "apol-2";
@ -78,7 +78,7 @@ public class TokenRoleBuilderTest {
* Build token without any parameters.
*/
@Test
public void buildDefaultTest() throws JsonProcessingException {
void buildDefaultTest() throws JsonProcessingException {
TokenRole role = TokenRole.builder().build();
assertThat(role.getAllowedPolicies(), is(nullValue()));
assertThat(role.getDisallowedPolicies(), is(nullValue()));
@ -100,7 +100,7 @@ public class TokenRoleBuilderTest {
* Build token without all parameters NULL.
*/
@Test
public void buildNullTest() throws JsonProcessingException {
void buildNullTest() throws JsonProcessingException {
TokenRole role = TokenRole.builder()
.forName(null)
.withAllowedPolicies(null)
@ -141,7 +141,7 @@ public class TokenRoleBuilderTest {
* Build token without all parameters set.
*/
@Test
public void buildFullTest() throws JsonProcessingException {
void buildFullTest() throws JsonProcessingException {
TokenRole role = TokenRole.builder()
.forName(NAME)
.withAllowedPolicies(ALLOWED_POLICIES)

View File

@ -1,5 +1,5 @@
/*
* Copyright 2016-2020 Stefan Kalscheuer
* Copyright 2016-2021 Stefan Kalscheuer
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -21,13 +21,13 @@ import de.stklcode.jvault.connector.exception.InvalidResponseException;
import de.stklcode.jvault.connector.model.AppRole;
import org.junit.jupiter.api.Test;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*;
import static org.junit.jupiter.api.Assertions.fail;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertThrows;
/**
* JUnit Test for {@link AppRoleResponse} model.
@ -35,7 +35,7 @@ import static org.junit.jupiter.api.Assertions.fail;
* @author Stefan Kalscheuer
* @since 0.6.2
*/
public class AppRoleResponseTest {
class AppRoleResponseTest {
private static final Integer ROLE_TOKEN_TTL = 1200;
private static final Integer ROLE_TOKEN_MAX_TTL = 1800;
private static final Integer ROLE_SECRET_TTL = 600;
@ -75,46 +75,44 @@ public class AppRoleResponseTest {
* Test getter, setter and get-methods for response data.
*/
@Test
public void getDataRoundtrip() {
void getDataRoundtrip() {
// Create empty Object.
AppRoleResponse res = new AppRoleResponse();
assertThat("Initial data should be empty", res.getRole(), is(nullValue()));
// Parsing invalid auth data map should fail.
try {
res.setData(INVALID_DATA);
fail("Parsing invalid data succeeded");
} catch (Exception e) {
assertThat(e, is(instanceOf(InvalidResponseException.class)));
}
assertThrows(
InvalidResponseException.class,
() -> res.setData(INVALID_DATA),
"Parsing invalid data succeeded"
);
}
/**
* Test creation from JSON value as returned by Vault (JSON example copied from Vault documentation).
*/
@Test
public void jsonRoundtrip() {
try {
AppRoleResponse res = new ObjectMapper().readValue(RES_JSON, AppRoleResponse.class);
assertThat("Parsed response is NULL", res, is(notNullValue()));
// Extract role data.
AppRole role = res.getRole();
assertThat("Role data is NULL", role, is(notNullValue()));
assertThat("Incorrect token TTL", role.getTokenTtl(), is(ROLE_TOKEN_TTL));
assertThat("Incorrect token max TTL", role.getTokenMaxTtl(), is(ROLE_TOKEN_MAX_TTL));
assertThat("Incorrect secret ID TTL", role.getSecretIdTtl(), is(ROLE_SECRET_TTL));
assertThat("Incorrect secret ID umber of uses", role.getSecretIdNumUses(), is(ROLE_SECRET_NUM_USES));
assertThat("Incorrect number of policies", role.getTokenPolicies(), hasSize(1));
assertThat("Incorrect role policies", role.getTokenPolicies(), contains(ROLE_POLICY));
assertThat("Incorrect number of policies", role.getPolicies(), hasSize(1));
assertThat("Incorrect role policies", role.getPolicies(), contains(ROLE_POLICY));
assertThat("Incorrect role period", role.getTokenPeriod(), is(ROLE_PERIOD));
assertThat("Incorrect role period", role.getPeriod(), is(ROLE_PERIOD));
assertThat("Incorrect role bind secret ID flag", role.getBindSecretId(), is(ROLE_BIND_SECRET));
assertThat("Incorrect bound CIDR list", role.getTokenBoundCidrs(), is(nullValue()));
assertThat("Incorrect bound CIDR list string", role.getTokenBoundCidrsString(), is(emptyString()));
} catch (IOException e) {
fail("AuthResponse deserialization failed: " + e.getMessage());
}
void jsonRoundtrip() {
AppRoleResponse res = assertDoesNotThrow(
() -> new ObjectMapper().readValue(RES_JSON, AppRoleResponse.class),
"AuthResponse deserialization failed."
);
assertThat("Parsed response is NULL", res, is(notNullValue()));
// Extract role data.
AppRole role = res.getRole();
assertThat("Role data is NULL", role, is(notNullValue()));
assertThat("Incorrect token TTL", role.getTokenTtl(), is(ROLE_TOKEN_TTL));
assertThat("Incorrect token max TTL", role.getTokenMaxTtl(), is(ROLE_TOKEN_MAX_TTL));
assertThat("Incorrect secret ID TTL", role.getSecretIdTtl(), is(ROLE_SECRET_TTL));
assertThat("Incorrect secret ID umber of uses", role.getSecretIdNumUses(), is(ROLE_SECRET_NUM_USES));
assertThat("Incorrect number of policies", role.getTokenPolicies(), hasSize(1));
assertThat("Incorrect role policies", role.getTokenPolicies(), contains(ROLE_POLICY));
assertThat("Incorrect number of policies", role.getPolicies(), hasSize(1));
assertThat("Incorrect role policies", role.getPolicies(), contains(ROLE_POLICY));
assertThat("Incorrect role period", role.getTokenPeriod(), is(ROLE_PERIOD));
assertThat("Incorrect role period", role.getPeriod(), is(ROLE_PERIOD));
assertThat("Incorrect role bind secret ID flag", role.getBindSecretId(), is(ROLE_BIND_SECRET));
assertThat("Incorrect bound CIDR list", role.getTokenBoundCidrs(), is(nullValue()));
assertThat("Incorrect bound CIDR list string", role.getTokenBoundCidrsString(), is(emptyString()));
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2016-2020 Stefan Kalscheuer
* Copyright 2016-2021 Stefan Kalscheuer
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -22,13 +22,13 @@ import de.stklcode.jvault.connector.model.AuthBackend;
import de.stklcode.jvault.connector.model.response.embedded.AuthMethod;
import org.junit.jupiter.api.Test;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*;
import static org.junit.jupiter.api.Assertions.fail;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertThrows;
/**
* JUnit Test for {@link AuthMethodsResponse} model.
@ -36,7 +36,7 @@ import static org.junit.jupiter.api.Assertions.fail;
* @author Stefan Kalscheuer
* @since 0.6.2
*/
public class AuthMethodsResponseTest {
class AuthMethodsResponseTest {
private static final String GH_PATH = "github/";
private static final String GH_TYPE = "github";
private static final String GH_DESCR = "GitHub auth";
@ -73,53 +73,51 @@ public class AuthMethodsResponseTest {
* Test getter, setter and get-methods for response data.
*/
@Test
public void getDataRoundtrip() {
void getDataRoundtrip() {
// Create empty Object.
AuthMethodsResponse res = new AuthMethodsResponse();
assertThat("Initial method map should be empty", res.getSupportedMethods(), is(anEmptyMap()));
// Parsing invalid data map should fail.
try {
res.setData(INVALID_DATA);
fail("Parsing invalid data succeeded");
} catch (Exception e) {
assertThat(e, is(instanceOf(InvalidResponseException.class)));
}
assertThrows(
InvalidResponseException.class,
() -> res.setData(INVALID_DATA),
"Parsing invalid data succeeded"
);
}
/**
* Test creation from JSON value as returned by Vault (JSON example copied from Vault documentation).
*/
@Test
public void jsonRoundtrip() {
try {
AuthMethodsResponse res = new ObjectMapper().readValue(RES_JSON, AuthMethodsResponse.class);
assertThat("Parsed response is NULL", res, is(notNullValue()));
// Extract auth data.
Map<String, AuthMethod> supported = res.getSupportedMethods();
assertThat("Auth data is NULL", supported, is(notNullValue()));
assertThat("Incorrect number of supported methods", supported.entrySet(), hasSize(2));
assertThat("Incorrect method paths", supported.keySet(), containsInAnyOrder(GH_PATH, TK_PATH));
void jsonRoundtrip() {
AuthMethodsResponse res = assertDoesNotThrow(
() -> new ObjectMapper().readValue(RES_JSON, AuthMethodsResponse.class),
"AuthResponse deserialization failed"
);
assertThat("Parsed response is NULL", res, is(notNullValue()));
// Extract auth data.
Map<String, AuthMethod> supported = res.getSupportedMethods();
assertThat("Auth data is NULL", supported, is(notNullValue()));
assertThat("Incorrect number of supported methods", supported.entrySet(), hasSize(2));
assertThat("Incorrect method paths", supported.keySet(), containsInAnyOrder(GH_PATH, TK_PATH));
// Verify first method.
AuthMethod method = supported.get(GH_PATH);
assertThat("Incorrect raw type for GitHub", method.getRawType(), is(GH_TYPE));
assertThat("Incorrect parsed type for GitHub", method.getType(), is(AuthBackend.GITHUB));
assertThat("Incorrect description for GitHub", method.getDescription(), is(GH_DESCR));
assertThat("Unexpected config for GitHub", method.getConfig(), is(nullValue()));
// Verify first method.
AuthMethod method = supported.get(GH_PATH);
assertThat("Incorrect raw type for GitHub", method.getRawType(), is(GH_TYPE));
assertThat("Incorrect parsed type for GitHub", method.getType(), is(AuthBackend.GITHUB));
assertThat("Incorrect description for GitHub", method.getDescription(), is(GH_DESCR));
assertThat("Unexpected config for GitHub", method.getConfig(), is(nullValue()));
// Verify first method.
method = supported.get(TK_PATH);
assertThat("Incorrect raw type for Token", method.getRawType(), is(TK_TYPE));
assertThat("Incorrect parsed type for Token", method.getType(), is(AuthBackend.TOKEN));
assertThat("Incorrect description for Token", method.getDescription(), is(TK_DESCR));
assertThat("Missing config for Token", method.getConfig(), is(notNullValue()));
assertThat("Unexpected config size for Token", method.getConfig().keySet(), hasSize(2));
assertThat("Incorrect lease TTL config", method.getConfig().get("default_lease_ttl"), is(TK_LEASE_TTL.toString()));
assertThat("Incorrect max lease TTL config", method.getConfig().get("max_lease_ttl"), is(TK_MAX_LEASE_TTL.toString()));
} catch (IOException e) {
fail("AuthResponse deserialization failed: " + e.getMessage());
}
// Verify first method.
method = supported.get(TK_PATH);
assertThat("Incorrect raw type for Token", method.getRawType(), is(TK_TYPE));
assertThat("Incorrect parsed type for Token", method.getType(), is(AuthBackend.TOKEN));
assertThat("Incorrect description for Token", method.getDescription(), is(TK_DESCR));
assertThat("Missing config for Token", method.getConfig(), is(notNullValue()));
assertThat("Unexpected config size for Token", method.getConfig().keySet(), hasSize(2));
assertThat("Incorrect lease TTL config", method.getConfig().get("default_lease_ttl"), is(TK_LEASE_TTL.toString()));
assertThat("Incorrect max lease TTL config", method.getConfig().get("max_lease_ttl"), is(TK_MAX_LEASE_TTL.toString()));
}
private static class Dummy {

View File

@ -1,5 +1,5 @@
/*
* Copyright 2016-2020 Stefan Kalscheuer
* Copyright 2016-2021 Stefan Kalscheuer
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -21,13 +21,13 @@ import de.stklcode.jvault.connector.exception.InvalidResponseException;
import de.stklcode.jvault.connector.model.response.embedded.AuthData;
import org.junit.jupiter.api.Test;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*;
import static org.junit.jupiter.api.Assertions.fail;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertThrows;
/**
* JUnit Test for {@link AuthResponse} model.
@ -35,7 +35,7 @@ import static org.junit.jupiter.api.Assertions.fail;
* @author Stefan Kalscheuer
* @since 0.6.2
*/
public class AuthResponseTest {
class AuthResponseTest {
private static final String AUTH_ACCESSOR = "2c84f488-2133-4ced-87b0-570f93a76830";
private static final String AUTH_CLIENT_TOKEN = "ABCD";
private static final String AUTH_POLICY_1 = "web";
@ -81,18 +81,17 @@ public class AuthResponseTest {
* Test getter, setter and get-methods for response data.
*/
@Test
public void getDataRoundtrip() {
void getDataRoundtrip() {
// Create empty Object.
AuthResponse res = new AuthResponse();
assertThat("Initial data should be empty", res.getData(), is(nullValue()));
// Parsing invalid auth data map should fail.
try {
res.setAuth(INVALID_AUTH_DATA);
fail("Parsing invalid auth data succeeded");
} catch (Exception e) {
assertThat(e, is(instanceOf(InvalidResponseException.class)));
}
assertThrows(
InvalidResponseException.class,
() -> res.setAuth(INVALID_AUTH_DATA),
"Parsing invalid auth data succeeded"
);
// Data method should be agnostic.
res.setData(INVALID_AUTH_DATA);
@ -103,9 +102,11 @@ public class AuthResponseTest {
* Test creation from JSON value as returned by Vault (JSON example copied from Vault documentation).
*/
@Test
public void jsonRoundtrip() {
try {
AuthResponse res = new ObjectMapper().readValue(RES_JSON, AuthResponse.class);
void jsonRoundtrip() {
AuthResponse res = assertDoesNotThrow(
() -> new ObjectMapper().readValue(RES_JSON, AuthResponse.class),
"AuthResponse deserialization failed."
);
assertThat("Parsed response is NULL", res, is(notNullValue()));
// Extract auth data.
AuthData data = res.getAuth();
@ -123,9 +124,5 @@ public class AuthResponseTest {
assertThat("Incorrect token policies", data.getTokenPolicies(), containsInRelativeOrder(AUTH_POLICY_2, AUTH_POLICY_1));
assertThat("Incorrect auth metadata size", data.getMetadata().entrySet(), hasSize(1));
assertThat("Incorrect auth metadata", data.getMetadata().get(AUTH_META_KEY), is(AUTH_META_VALUE));
} catch (IOException e) {
fail("AuthResponse deserialization failed: " + e.getMessage());
}
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2016-2020 Stefan Kalscheuer
* Copyright 2016-2021 Stefan Kalscheuer
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -35,7 +35,7 @@ import static org.junit.jupiter.api.Assertions.fail;
* @author Stefan Kalscheuer
* @since 0.8
*/
public class CredentialsResponseTest {
class CredentialsResponseTest {
private static final Map<String, Object> DATA = new HashMap<>();
private static final String VAL_USER = "testUserName";
private static final String VAL_PASS = "5up3r5ecr3tP455";
@ -52,7 +52,7 @@ public class CredentialsResponseTest {
*/
@Test
@SuppressWarnings("unchecked")
public void getCredentialsTest() throws InvalidResponseException {
void getCredentialsTest() throws InvalidResponseException {
// Create empty Object.
CredentialsResponse res = new CredentialsResponse();
assertThat("Username not present in data map should not return anything", res.getUsername(), is(nullValue()));

View File

@ -1,5 +1,5 @@
/*
* Copyright 2016-2020 Stefan Kalscheuer
* Copyright 2016-2021 Stefan Kalscheuer
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -19,12 +19,10 @@ package de.stklcode.jvault.connector.model.response;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.jupiter.api.Test;
import java.io.IOException;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.notNullValue;
import static org.junit.jupiter.api.Assertions.fail;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
/**
* JUnit Test for {@link AuthResponse} model.
@ -32,7 +30,7 @@ import static org.junit.jupiter.api.Assertions.fail;
* @author Stefan Kalscheuer
* @since 0.7.0
*/
public class HealthResponseTest {
class HealthResponseTest {
private static final String CLUSTER_ID = "c9abceea-4f46-4dab-a688-5ce55f89e228";
private static final String CLUSTER_NAME = "vault-cluster-5515c810";
private static final String VERSION = "0.9.2";
@ -56,26 +54,26 @@ public class HealthResponseTest {
" \"replication_dr_mode\": \"" + REPL_DR_MODE + "\",\n" +
" \"performance_standby\": " + PERF_STANDBY + "\n" +
"}";
/**
* Test creation from JSON value as returned by Vault (JSON example copied from Vault documentation).
*/
@Test
public void jsonRoundtrip() {
try {
HealthResponse res = new ObjectMapper().readValue(RES_JSON, HealthResponse.class);
assertThat("Parsed response is NULL", res, is(notNullValue()));
assertThat("Incorrect cluster ID", res.getClusterID(), is(CLUSTER_ID));
assertThat("Incorrect cluster name", res.getClusterName(), is(CLUSTER_NAME));
assertThat("Incorrect version", res.getVersion(), is(VERSION));
assertThat("Incorrect server time", res.getServerTimeUTC(), is(SERVER_TIME_UTC));
assertThat("Incorrect standby state", res.isStandby(), is(STANDBY));
assertThat("Incorrect seal state", res.isSealed(), is(SEALED));
assertThat("Incorrect initialization state", res.isInitialized(), is(INITIALIZED));
assertThat("Incorrect performance standby state", res.isPerformanceStandby(), is(PERF_STANDBY));
assertThat("Incorrect replication perf mode", res.getReplicationPerfMode(), is(REPL_PERF_MODE));
assertThat("Incorrect replication DR mode", res.getReplicationDrMode(), is(REPL_DR_MODE));
} catch (IOException e) {
fail("Health deserialization failed: " + e.getMessage());
}
void jsonRoundtrip() {
HealthResponse res = assertDoesNotThrow(
() -> new ObjectMapper().readValue(RES_JSON, HealthResponse.class),
"Health deserialization failed."
);
assertThat("Parsed response is NULL", res, is(notNullValue()));
assertThat("Incorrect cluster ID", res.getClusterID(), is(CLUSTER_ID));
assertThat("Incorrect cluster name", res.getClusterName(), is(CLUSTER_NAME));
assertThat("Incorrect version", res.getVersion(), is(VERSION));
assertThat("Incorrect server time", res.getServerTimeUTC(), is(SERVER_TIME_UTC));
assertThat("Incorrect standby state", res.isStandby(), is(STANDBY));
assertThat("Incorrect seal state", res.isSealed(), is(SEALED));
assertThat("Incorrect initialization state", res.isInitialized(), is(INITIALIZED));
assertThat("Incorrect performance standby state", res.isPerformanceStandby(), is(PERF_STANDBY));
assertThat("Incorrect replication perf mode", res.getReplicationPerfMode(), is(REPL_PERF_MODE));
assertThat("Incorrect replication DR mode", res.getReplicationDrMode(), is(REPL_DR_MODE));
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2016-2020 Stefan Kalscheuer
* Copyright 2016-2021 Stefan Kalscheuer
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -17,16 +17,12 @@
package de.stklcode.jvault.connector.model.response;
import com.fasterxml.jackson.databind.ObjectMapper;
import de.stklcode.jvault.connector.exception.InvalidResponseException;
import org.junit.jupiter.api.Test;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*;
import static org.junit.jupiter.api.Assertions.fail;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.notNullValue;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
/**
* JUnit Test for {@link MetadataResponse} model.
@ -34,7 +30,7 @@ import static org.junit.jupiter.api.Assertions.fail;
* @author Stefan Kalscheuer
* @since 0.8
*/
public class MetadataResponseTest {
class MetadataResponseTest {
private static final String V1_TIME = "2018-03-22T02:24:06.945319214Z";
private static final String V3_TIME = "2018-03-22T02:36:43.986212308Z";
private static final String V2_TIME = "2018-03-22T02:36:33.954880664Z";
@ -73,28 +69,26 @@ public class MetadataResponseTest {
* Test creation from JSON value as returned by Vault (JSON example copied from Vault documentation).
*/
@Test
public void jsonRoundtrip() {
try {
MetadataResponse res = new ObjectMapper().readValue(META_JSON, MetadataResponse.class);
assertThat("Parsed response is NULL", res, is(notNullValue()));
assertThat("Parsed metadata is NULL", res.getMetadata(), is(notNullValue()));
assertThat("Incorrect created time", res.getMetadata().getCreatedTimeString(), is(V1_TIME));
assertThat("Parting created time failed", res.getMetadata().getCreatedTime(), is(notNullValue()));
assertThat("Incorrect current version", res.getMetadata().getCurrentVersion(), is(CURRENT_VERSION));
assertThat("Incorrect max versions", res.getMetadata().getMaxVersions(), is(MAX_VERSIONS));
assertThat("Incorrect oldest version", res.getMetadata().getOldestVersion(), is(OLDEST_VERSION));
assertThat("Incorrect updated time", res.getMetadata().getUpdatedTimeString(), is(V3_TIME));
assertThat("Parting updated time failed", res.getMetadata().getUpdatedTime(), is(notNullValue()));
assertThat("Incorrect number of versions", res.getMetadata().getVersions().size(), is(3));
assertThat("Incorrect version 1 delete time", res.getMetadata().getVersions().get(1).getDeletionTimeString(), is(V2_TIME));
assertThat("Parsing version delete time failed", res.getMetadata().getVersions().get(1).getDeletionTime(), is(notNullValue()));
assertThat("Incorrect version 1 destroyed state", res.getMetadata().getVersions().get(1).isDestroyed(), is(true));
assertThat("Incorrect version 2 created time", res.getMetadata().getVersions().get(2).getCreatedTimeString(), is(V2_TIME));
assertThat("Parsing version created failed", res.getMetadata().getVersions().get(2).getCreatedTime(), is(notNullValue()));
assertThat("Incorrect version 3 destroyed state", res.getMetadata().getVersions().get(3).isDestroyed(), is(false));
} catch (IOException e) {
fail("MetadataResponse deserialization failed: " + e.getMessage());
}
void jsonRoundtrip() {
MetadataResponse res = assertDoesNotThrow(
() -> new ObjectMapper().readValue(META_JSON, MetadataResponse.class),
"MetadataResponse deserialization failed."
);
assertThat("Parsed response is NULL", res, is(notNullValue()));
assertThat("Parsed metadata is NULL", res.getMetadata(), is(notNullValue()));
assertThat("Incorrect created time", res.getMetadata().getCreatedTimeString(), is(V1_TIME));
assertThat("Parting created time failed", res.getMetadata().getCreatedTime(), is(notNullValue()));
assertThat("Incorrect current version", res.getMetadata().getCurrentVersion(), is(CURRENT_VERSION));
assertThat("Incorrect max versions", res.getMetadata().getMaxVersions(), is(MAX_VERSIONS));
assertThat("Incorrect oldest version", res.getMetadata().getOldestVersion(), is(OLDEST_VERSION));
assertThat("Incorrect updated time", res.getMetadata().getUpdatedTimeString(), is(V3_TIME));
assertThat("Parting updated time failed", res.getMetadata().getUpdatedTime(), is(notNullValue()));
assertThat("Incorrect number of versions", res.getMetadata().getVersions().size(), is(3));
assertThat("Incorrect version 1 delete time", res.getMetadata().getVersions().get(1).getDeletionTimeString(), is(V2_TIME));
assertThat("Parsing version delete time failed", res.getMetadata().getVersions().get(1).getDeletionTime(), is(notNullValue()));
assertThat("Incorrect version 1 destroyed state", res.getMetadata().getVersions().get(1).isDestroyed(), is(true));
assertThat("Incorrect version 2 created time", res.getMetadata().getVersions().get(2).getCreatedTimeString(), is(V2_TIME));
assertThat("Parsing version created failed", res.getMetadata().getVersions().get(2).getCreatedTime(), is(notNullValue()));
assertThat("Incorrect version 3 destroyed state", res.getMetadata().getVersions().get(3).isDestroyed(), is(false));
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2016-2020 Stefan Kalscheuer
* Copyright 2016-2021 Stefan Kalscheuer
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -19,11 +19,9 @@ package de.stklcode.jvault.connector.model.response;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.jupiter.api.Test;
import java.io.IOException;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*;
import static org.junit.jupiter.api.Assertions.fail;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
/**
* JUnit Test for {@link SealResponse} model.
@ -31,7 +29,7 @@ import static org.junit.jupiter.api.Assertions.fail;
* @author Stefan Kalscheuer
* @since 0.8
*/
public class SealResponseTest {
class SealResponseTest {
private static final String TYPE = "shamir";
private static final Integer THRESHOLD = 3;
private static final Integer SHARES = 5;
@ -70,43 +68,41 @@ public class SealResponseTest {
* Test creation from JSON value as returned by Vault when sealed (JSON example close to Vault documentation).
*/
@Test
public void jsonRoundtripSealed() {
void jsonRoundtripSealed() {
// First test sealed Vault's response.
try {
SealResponse res = new ObjectMapper().readValue(RES_SEALED, SealResponse.class);
assertThat("Parsed response is NULL", res, is(notNullValue()));
assertThat("Incorrect seal type", res.getType(), is(TYPE));
assertThat("Incorrect seal status", res.isSealed(), is(true));
assertThat("Incorrect initialization status", res.isInitialized(), is(true));
assertThat("Incorrect threshold", res.getThreshold(), is(THRESHOLD));
assertThat("Incorrect number of shares", res.getNumberOfShares(), is(SHARES));
assertThat("Incorrect progress", res.getProgress(), is(PROGRESS_SEALED));
assertThat("Nonce not empty", res.getNonce(), is(""));
assertThat("Incorrect version", res.getVersion(), is(VERSION));
// And the fields, that should not be filled.
assertThat("Cluster name should not be populated", res.getClusterName(), is(nullValue()));
assertThat("Cluster ID should not be populated", res.getClusterId(), is(nullValue()));
} catch (IOException e) {
fail("TokenResponse deserialization failed: " + e.getMessage());
}
SealResponse res = assertDoesNotThrow(
() -> new ObjectMapper().readValue(RES_SEALED, SealResponse.class),
"TokenResponse deserialization failed."
);
assertThat("Parsed response is NULL", res, is(notNullValue()));
assertThat("Incorrect seal type", res.getType(), is(TYPE));
assertThat("Incorrect seal status", res.isSealed(), is(true));
assertThat("Incorrect initialization status", res.isInitialized(), is(true));
assertThat("Incorrect threshold", res.getThreshold(), is(THRESHOLD));
assertThat("Incorrect number of shares", res.getNumberOfShares(), is(SHARES));
assertThat("Incorrect progress", res.getProgress(), is(PROGRESS_SEALED));
assertThat("Nonce not empty", res.getNonce(), is(""));
assertThat("Incorrect version", res.getVersion(), is(VERSION));
// And the fields, that should not be filled.
assertThat("Cluster name should not be populated", res.getClusterName(), is(nullValue()));
assertThat("Cluster ID should not be populated", res.getClusterId(), is(nullValue()));
// Not test unsealed Vault's response.
try {
SealResponse res = new ObjectMapper().readValue(RES_UNSEALED, SealResponse.class);
assertThat("Parsed response is NULL", res, is(notNullValue()));
assertThat("Incorrect seal type", res.getType(), is(TYPE));
assertThat("Incorrect seal status", res.isSealed(), is(false));
assertThat("Incorrect initialization status", res.isInitialized(), is(true));
assertThat("Incorrect threshold", res.getThreshold(), is(THRESHOLD));
assertThat("Incorrect number of shares", res.getNumberOfShares(), is(SHARES));
assertThat("Incorrect progress", res.getProgress(), is(PROGRESS_UNSEALED));
assertThat("Incorrect nonce", res.getNonce(), is(NONCE));
assertThat("Incorrect version", res.getVersion(), is(VERSION));
assertThat("Incorrect cluster name", res.getClusterName(), is(CLUSTER_NAME));
assertThat("Incorrect cluster ID", res.getClusterId(), is(CLUSTER_ID));
} catch (IOException e) {
fail("TokenResponse deserialization failed: " + e.getMessage());
}
res = assertDoesNotThrow(
() -> new ObjectMapper().readValue(RES_UNSEALED, SealResponse.class),
"TokenResponse deserialization failed."
);
assertThat("Parsed response is NULL", res, is(notNullValue()));
assertThat("Incorrect seal type", res.getType(), is(TYPE));
assertThat("Incorrect seal status", res.isSealed(), is(false));
assertThat("Incorrect initialization status", res.isInitialized(), is(true));
assertThat("Incorrect threshold", res.getThreshold(), is(THRESHOLD));
assertThat("Incorrect number of shares", res.getNumberOfShares(), is(SHARES));
assertThat("Incorrect progress", res.getProgress(), is(PROGRESS_UNSEALED));
assertThat("Incorrect nonce", res.getNonce(), is(NONCE));
assertThat("Incorrect version", res.getVersion(), is(VERSION));
assertThat("Incorrect cluster name", res.getClusterName(), is(CLUSTER_NAME));
assertThat("Incorrect cluster ID", res.getClusterId(), is(CLUSTER_ID));
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2016-2020 Stefan Kalscheuer
* Copyright 2016-2021 Stefan Kalscheuer
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -26,7 +26,7 @@ import java.util.Map;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*;
import static org.junit.jupiter.api.Assertions.fail;
import static org.junit.jupiter.api.Assertions.assertThrows;
/**
* JUnit Test for {@link SecretListResponse} model.
@ -34,7 +34,7 @@ import static org.junit.jupiter.api.Assertions.fail;
* @author Stefan Kalscheuer
* @since 0.8
*/
public class SecretListResponseTest {
class SecretListResponseTest {
private static final Map<String, Object> DATA = new HashMap<>();
private static final String KEY1 = "key1";
private static final String KEY2 = "key-2";
@ -50,20 +50,19 @@ public class SecretListResponseTest {
* @throws InvalidResponseException Should not occur
*/
@Test
public void getKeysTest() throws InvalidResponseException {
void getKeysTest() throws InvalidResponseException {
// Create empty Object.
SecretListResponse res = new SecretListResponse();
assertThat("Keys should be null without initialization", res.getKeys(), is(nullValue()));
// Provoke internal ClassCastException.
try {
Map<String, Object> invalidData = new HashMap<>();
invalidData.put("keys", "some string");
res.setData(invalidData);
fail("Setting incorrect class succeeded");
} catch (Exception e) {
assertThat("Unexpected exception type", e, instanceOf(InvalidResponseException.class));
}
Map<String, Object> invalidData = new HashMap<>();
invalidData.put("keys", "some string");
assertThrows(
InvalidResponseException.class,
() -> res.setData(invalidData),
"Setting incorrect class succeeded"
);
// Fill correct data.
res.setData(DATA);

View File

@ -1,5 +1,5 @@
/*
* Copyright 2016-2020 Stefan Kalscheuer
* Copyright 2016-2021 Stefan Kalscheuer
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -20,14 +20,14 @@ import com.fasterxml.jackson.databind.ObjectMapper;
import de.stklcode.jvault.connector.exception.InvalidResponseException;
import org.junit.jupiter.api.Test;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*;
import static org.junit.jupiter.api.Assertions.fail;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertThrows;
/**
* JUnit Test for {@link SecretResponse} model.
@ -35,7 +35,7 @@ import static org.junit.jupiter.api.Assertions.fail;
* @author Stefan Kalscheuer
* @since 0.6.2
*/
public class SecretResponseTest {
class SecretResponseTest {
private static final Map<String, Object> DATA = new HashMap<>();
private static final String KEY_UNKNOWN = "unknown";
private static final String KEY_STRING = "test1";
@ -120,7 +120,7 @@ public class SecretResponseTest {
*/
@Test
@SuppressWarnings("unchecked")
public void getDataRoundtrip() throws InvalidResponseException {
void getDataRoundtrip() throws InvalidResponseException {
// Create empty Object.
SecretResponse res = new SecretResponse();
assertThat("Initial data should be Map", res.getData(), is(instanceOf(Map.class)));
@ -137,61 +137,58 @@ public class SecretResponseTest {
assertThat("Non-Null returned on unknown key", res.get(KEY_UNKNOWN), is(nullValue()));
// Try explicit JSON conversion.
final List list = res.get(KEY_LIST, List.class);
final List<?> list = res.get(KEY_LIST, List.class);
assertThat("JSON parsing of list failed", list, is(notNullValue()));
assertThat("JSON parsing of list returned incorrect size", list.size(), is(2));
assertThat("JSON parsing of list returned incorrect elements", (List<Object>)list, contains("first", "second"));
assertThat("JSON parsing of list returned incorrect elements", list, contains("first", "second"));
assertThat("Non-Null returned on unknown key", res.get(KEY_UNKNOWN, Object.class), is(nullValue()));
// Requesting invalid class should result in Exception.
try {
res.get(KEY_LIST, Double.class);
fail("JSON parsing to incorrect type succeeded.");
} catch (Exception e) {
assertThat(e, is(instanceOf(InvalidResponseException.class)));
}
assertThrows(
InvalidResponseException.class,
() -> res.get(KEY_LIST, Double.class),
"JSON parsing to incorrect type succeeded."
);
}
/**
* Test creation from JSON value as returned by Vault (JSON example copied from Vault documentation).
*/
@Test
public void jsonRoundtrip() {
try {
assertSecretData(new ObjectMapper().readValue(SECRET_JSON, SecretResponse.class));
} catch (IOException e) {
fail("SecretResponse deserialization failed: " + e.getMessage());
}
void jsonRoundtrip() {
SecretResponse res = assertDoesNotThrow(
() -> new ObjectMapper().readValue(SECRET_JSON, SecretResponse.class),
"SecretResponse deserialization failed."
);
assertSecretData(res);
// KV v2 secret.
try {
SecretResponse res = new ObjectMapper().readValue(SECRET_JSON_V2, SecretResponse.class);
assertSecretData(res);
assertThat("SecretResponse does not contain metadata", res.getMetadata(), is(notNullValue()));
assertThat("Incorrect creation date string", res.getMetadata().getCreatedTimeString(), is(SECRET_META_CREATED));
assertThat("Creation date parsing failed", res.getMetadata().getCreatedTime(), is(notNullValue()));
assertThat("Incorrect deletion date string", res.getMetadata().getDeletionTimeString(), is(emptyString()));
assertThat("Incorrect deletion date", res.getMetadata().getDeletionTime(), is(nullValue()));
assertThat("Secret destroyed when not expected", res.getMetadata().isDestroyed(), is(false));
assertThat("Incorrect secret version", res.getMetadata().getVersion(), is(1));
} catch (IOException e) {
fail("SecretResponse deserialization failed: " + e.getMessage());
}
res = assertDoesNotThrow(
() -> new ObjectMapper().readValue(SECRET_JSON_V2, SecretResponse.class),
"SecretResponse deserialization failed."
);
assertSecretData(res);
assertThat("SecretResponse does not contain metadata", res.getMetadata(), is(notNullValue()));
assertThat("Incorrect creation date string", res.getMetadata().getCreatedTimeString(), is(SECRET_META_CREATED));
assertThat("Creation date parsing failed", res.getMetadata().getCreatedTime(), is(notNullValue()));
assertThat("Incorrect deletion date string", res.getMetadata().getDeletionTimeString(), is(emptyString()));
assertThat("Incorrect deletion date", res.getMetadata().getDeletionTime(), is(nullValue()));
assertThat("Secret destroyed when not expected", res.getMetadata().isDestroyed(), is(false));
assertThat("Incorrect secret version", res.getMetadata().getVersion(), is(1));
// Deleted KV v2 secret.
try {
SecretResponse res = new ObjectMapper().readValue(SECRET_JSON_V2_2, SecretResponse.class);
assertSecretData(res);
assertThat("SecretResponse does not contain metadata", res.getMetadata(), is(notNullValue()));
assertThat("Incorrect creation date string", res.getMetadata().getCreatedTimeString(), is(SECRET_META_CREATED));
assertThat("Creation date parsing failed", res.getMetadata().getCreatedTime(), is(notNullValue()));
assertThat("Incorrect deletion date string", res.getMetadata().getDeletionTimeString(), is(SECRET_META_DELETED));
assertThat("Incorrect deletion date", res.getMetadata().getDeletionTime(), is(notNullValue()));
assertThat("Secret destroyed when not expected", res.getMetadata().isDestroyed(), is(true));
assertThat("Incorrect secret version", res.getMetadata().getVersion(), is(2));
} catch (IOException e) {
fail("SecretResponse deserialization failed: " + e.getMessage());
}
res = assertDoesNotThrow(
() -> new ObjectMapper().readValue(SECRET_JSON_V2_2, SecretResponse.class),
"SecretResponse deserialization failed."
);
assertSecretData(res);
assertThat("SecretResponse does not contain metadata", res.getMetadata(), is(notNullValue()));
assertThat("Incorrect creation date string", res.getMetadata().getCreatedTimeString(), is(SECRET_META_CREATED));
assertThat("Creation date parsing failed", res.getMetadata().getCreatedTime(), is(notNullValue()));
assertThat("Incorrect deletion date string", res.getMetadata().getDeletionTimeString(), is(SECRET_META_DELETED));
assertThat("Incorrect deletion date", res.getMetadata().getDeletionTime(), is(notNullValue()));
assertThat("Secret destroyed when not expected", res.getMetadata().isDestroyed(), is(true));
assertThat("Incorrect secret version", res.getMetadata().getVersion(), is(2));
}
private void assertSecretData(SecretResponse res) {

View File

@ -1,5 +1,5 @@
/*
* Copyright 2016-2020 Stefan Kalscheuer
* Copyright 2016-2021 Stefan Kalscheuer
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -19,12 +19,10 @@ package de.stklcode.jvault.connector.model.response;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.jupiter.api.Test;
import java.io.IOException;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.notNullValue;
import static org.junit.jupiter.api.Assertions.fail;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
/**
* JUnit Test for {@link SecretVersionResponse} model.
@ -32,7 +30,7 @@ import static org.junit.jupiter.api.Assertions.fail;
* @author Stefan Kalscheuer
* @since 0.8
*/
public class SecretVersionResponseTest {
class SecretVersionResponseTest {
private static final String CREATION_TIME = "2018-03-22T02:24:06.945319214Z";
private static final String DELETION_TIME = "2018-03-22T02:36:43.986212308Z";
private static final Integer VERSION = 42;
@ -50,17 +48,16 @@ public class SecretVersionResponseTest {
* Test creation from JSON value as returned by Vault (JSON example copied from Vault documentation).
*/
@Test
public void jsonRoundtrip() {
try {
SecretVersionResponse res = new ObjectMapper().readValue(META_JSON, SecretVersionResponse.class);
assertThat("Parsed response is NULL", res, is(notNullValue()));
assertThat("Parsed metadata is NULL", res.getMetadata(), is(notNullValue()));
assertThat("Incorrect created time", res.getMetadata().getCreatedTimeString(), is(CREATION_TIME));
assertThat("Incorrect deletion time", res.getMetadata().getDeletionTimeString(), is(DELETION_TIME));
assertThat("Incorrect destroyed state", res.getMetadata().isDestroyed(), is(false));
assertThat("Incorrect version", res.getMetadata().getVersion(), is(VERSION));
} catch (IOException e) {
fail("SecretVersionResponse deserialization failed: " + e.getMessage());
}
void jsonRoundtrip() {
SecretVersionResponse res = assertDoesNotThrow(
() -> new ObjectMapper().readValue(META_JSON, SecretVersionResponse.class),
"SecretVersionResponse deserialization failed"
);
assertThat("Parsed response is NULL", res, is(notNullValue()));
assertThat("Parsed metadata is NULL", res.getMetadata(), is(notNullValue()));
assertThat("Incorrect created time", res.getMetadata().getCreatedTimeString(), is(CREATION_TIME));
assertThat("Incorrect deletion time", res.getMetadata().getDeletionTimeString(), is(DELETION_TIME));
assertThat("Incorrect destroyed state", res.getMetadata().isDestroyed(), is(false));
assertThat("Incorrect version", res.getMetadata().getVersion(), is(VERSION));
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2016-2020 Stefan Kalscheuer
* Copyright 2016-2021 Stefan Kalscheuer
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -21,14 +21,14 @@ import de.stklcode.jvault.connector.exception.InvalidResponseException;
import de.stklcode.jvault.connector.model.response.embedded.TokenData;
import org.junit.jupiter.api.Test;
import java.io.IOException;
import java.time.ZonedDateTime;
import java.util.HashMap;
import java.util.Map;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*;
import static org.junit.jupiter.api.Assertions.fail;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertThrows;
/**
* JUnit Test for {@link TokenResponse} model.
@ -36,7 +36,7 @@ import static org.junit.jupiter.api.Assertions.fail;
* @author Stefan Kalscheuer
* @since 0.6.2
*/
public class TokenResponseTest {
class TokenResponseTest {
private static final Integer TOKEN_CREATION_TIME = 1457533232;
private static final Integer TOKEN_TTL = 2764800;
private static final Integer TOKEN_EXPLICIT_MAX_TTL = 0;
@ -101,57 +101,55 @@ public class TokenResponseTest {
* Test getter, setter and get-methods for response data.
*/
@Test
public void getDataRoundtrip() {
void getDataRoundtrip() {
// Create empty Object.
TokenResponse res = new TokenResponse();
assertThat("Initial data should be empty", res.getData(), is(nullValue()));
// Parsing invalid data map should fail.
try {
res.setData(INVALID_TOKEN_DATA);
fail("Parsing invalid token data succeeded");
} catch (Exception e) {
assertThat(e, is(instanceOf(InvalidResponseException.class)));
}
assertThrows(
InvalidResponseException.class,
() -> res.setData(INVALID_TOKEN_DATA),
"Parsing invalid token data succeeded"
);
}
/**
* Test creation from JSON value as returned by Vault (JSON example copied from Vault documentation).
*/
@Test
public void jsonRoundtrip() {
try {
TokenResponse res = new ObjectMapper().readValue(RES_JSON, TokenResponse.class);
assertThat("Parsed response is NULL", res, is(notNullValue()));
assertThat("Incorrect lease duration", res.getLeaseDuration(), is(RES_LEASE_DURATION));
assertThat("Incorrect response renewable flag", res.isRenewable(), is(RES_RENEWABLE));
assertThat("Incorrect response lease duration", res.getLeaseDuration(), is(RES_LEASE_DURATION));
// Extract token data.
TokenData data = res.getData();
assertThat("Token data is NULL", data, is(notNullValue()));
assertThat("Incorrect token accessor", data.getAccessor(), is(TOKEN_ACCESSOR));
assertThat("Incorrect token creation time", data.getCreationTime(), is(TOKEN_CREATION_TIME));
assertThat("Incorrect token creation TTL", data.getCreationTtl(), is(TOKEN_TTL));
assertThat("Incorrect token display name", data.getName(), is(TOKEN_DISPLAY_NAME));
assertThat("Incorrect token entity ID", data.getEntityId(), is(TOKEN_ENTITY_ID));
assertThat("Incorrect token expire time", data.getExpireTimeString(), is(TOKEN_EXPIRE_TIME));
assertThat("Incorrect parsed token expire time", data.getExpireTime(), is(ZonedDateTime.parse(TOKEN_EXPIRE_TIME)));
assertThat("Incorrect token explicit max TTL", data.getExplicitMaxTtl(), is(TOKEN_EXPLICIT_MAX_TTL));
assertThat("Incorrect token ID", data.getId(), is(TOKEN_ID));
assertThat("Incorrect token issue time", data.getIssueTimeString(), is(TOKEN_ISSUE_TIME));
assertThat("Incorrect parsed token issue time", data.getIssueTime(), is(ZonedDateTime.parse(TOKEN_ISSUE_TIME)));
assertThat("Incorrect token metadata size", data.getMeta().entrySet(), hasSize(1));
assertThat("Incorrect token metadata", data.getMeta().get(TOKEN_META_KEY), is(TOKEN_META_VALUE));
assertThat("Incorrect token number of uses", data.getNumUses(), is(TOKEN_NUM_USES));
assertThat("Incorrect token orphan flag", data.isOrphan(), is(TOKEN_ORPHAN));
assertThat("Incorrect token path", data.getPath(), is(TOKEN_PATH));
assertThat("Incorrect number of token policies", data.getPolicies(), hasSize(2));
assertThat("Incorrect token policies", data.getPolicies(), contains(TOKEN_POLICY_1, TOKEN_POLICY_2));
assertThat("Incorrect token renewable flag", data.isRenewable(), is(TOKEN_RENEWABLE));
assertThat("Incorrect token TTL", data.getTtl(), is(RES_TTL));
assertThat("Incorrect token type", data.getType(), is(TOKEN_TYPE));
} catch (IOException e) {
fail("TokenResponse deserialization failed: " + e.getMessage());
}
void jsonRoundtrip() {
TokenResponse res = assertDoesNotThrow(
() -> new ObjectMapper().readValue(RES_JSON, TokenResponse.class),
"TokenResponse deserialization failed."
);
assertThat("Parsed response is NULL", res, is(notNullValue()));
assertThat("Incorrect lease duration", res.getLeaseDuration(), is(RES_LEASE_DURATION));
assertThat("Incorrect response renewable flag", res.isRenewable(), is(RES_RENEWABLE));
assertThat("Incorrect response lease duration", res.getLeaseDuration(), is(RES_LEASE_DURATION));
// Extract token data.
TokenData data = res.getData();
assertThat("Token data is NULL", data, is(notNullValue()));
assertThat("Incorrect token accessor", data.getAccessor(), is(TOKEN_ACCESSOR));
assertThat("Incorrect token creation time", data.getCreationTime(), is(TOKEN_CREATION_TIME));
assertThat("Incorrect token creation TTL", data.getCreationTtl(), is(TOKEN_TTL));
assertThat("Incorrect token display name", data.getName(), is(TOKEN_DISPLAY_NAME));
assertThat("Incorrect token entity ID", data.getEntityId(), is(TOKEN_ENTITY_ID));
assertThat("Incorrect token expire time", data.getExpireTimeString(), is(TOKEN_EXPIRE_TIME));
assertThat("Incorrect parsed token expire time", data.getExpireTime(), is(ZonedDateTime.parse(TOKEN_EXPIRE_TIME)));
assertThat("Incorrect token explicit max TTL", data.getExplicitMaxTtl(), is(TOKEN_EXPLICIT_MAX_TTL));
assertThat("Incorrect token ID", data.getId(), is(TOKEN_ID));
assertThat("Incorrect token issue time", data.getIssueTimeString(), is(TOKEN_ISSUE_TIME));
assertThat("Incorrect parsed token issue time", data.getIssueTime(), is(ZonedDateTime.parse(TOKEN_ISSUE_TIME)));
assertThat("Incorrect token metadata size", data.getMeta().entrySet(), hasSize(1));
assertThat("Incorrect token metadata", data.getMeta().get(TOKEN_META_KEY), is(TOKEN_META_VALUE));
assertThat("Incorrect token number of uses", data.getNumUses(), is(TOKEN_NUM_USES));
assertThat("Incorrect token orphan flag", data.isOrphan(), is(TOKEN_ORPHAN));
assertThat("Incorrect token path", data.getPath(), is(TOKEN_PATH));
assertThat("Incorrect number of token policies", data.getPolicies(), hasSize(2));
assertThat("Incorrect token policies", data.getPolicies(), contains(TOKEN_POLICY_1, TOKEN_POLICY_2));
assertThat("Incorrect token renewable flag", data.isRenewable(), is(TOKEN_RENEWABLE));
assertThat("Incorrect token TTL", data.getTtl(), is(RES_TTL));
assertThat("Incorrect token type", data.getType(), is(TOKEN_TYPE));
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2016-2020 Stefan Kalscheuer
* Copyright 2016-2021 Stefan Kalscheuer
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@ -1,51 +0,0 @@
/*
* Copyright 2016-2020 Stefan Kalscheuer
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package de.stklcode.jvault.connector.test;
import java.lang.reflect.Field;
import java.util.Map;
import static org.junit.jupiter.api.Assertions.fail;
/**
* Test helper to modify system environment.
*
* @author Stefan Kalscheuer
*/
@SuppressWarnings("unchecked")
public class EnvironmentMock {
private static Map<String, String> environment;
static {
try {
Map<String, String> originalEnv = System.getenv();
Field mapField = originalEnv.getClass().getDeclaredField("m");
mapField.setAccessible(true);
environment = (Map<String, String>) mapField.get(originalEnv);
} catch (NoSuchFieldException | IllegalAccessException | ClassCastException e) {
fail("Failed to intercept unmodifiable system environment");
}
}
public static void setenv(String key, String value) {
if (value != null) {
environment.put(key, value);
} else {
environment.remove(key);
}
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2016-2020 Stefan Kalscheuer
* Copyright 2016-2021 Stefan Kalscheuer
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.