Compare commits
77 Commits
v1.3.1
...
feat/split
Author | SHA1 | Date | |
---|---|---|---|
1072e9b4a9
|
|||
e96ece3385
|
|||
41eeae6687
|
|||
bac06c5d19
|
|||
e30a3bd93a
|
|||
8447b572b4
|
|||
a95b05ba0e
|
|||
29517b9d78
|
|||
1536c23cf0
|
|||
a7a435b420
|
|||
d1b8b12ffe
|
|||
27c94870d3
|
|||
12aee10741
|
|||
1803728256
|
|||
9e7d8f50d3
|
|||
08886a0c7c
|
|||
eebe3f0ef6
|
|||
5b9f1392d3
|
|||
da4fffc823
|
|||
91276e1615
|
|||
6d2313289c
|
|||
bcbb3a0926
|
|||
f03c05bd5b
|
|||
afdad92ae6
|
|||
9fa360393d
|
|||
d28c189ec2
|
|||
46fffcc711
|
|||
31d8f9b0aa
|
|||
505b360343
|
|||
51ab19cd8a
|
|||
|
c8f396a5df
|
||
4bd6039827
|
|||
80abbda46f
|
|||
a8e85b88d1
|
|||
91baed4fe5
|
|||
2ea261d36a
|
|||
43da0f5109
|
|||
cc5ca13aeb
|
|||
71842eb758
|
|||
e9aeda9a55
|
|||
d51af06e29
|
|||
7b2b137d53
|
|||
ee2543e3ad
|
|||
dad35023eb
|
|||
0127cf30be
|
|||
90f8bb7f20
|
|||
ff6d2140cf
|
|||
076cd8b607
|
|||
2e0d092cae
|
|||
d329af2c67
|
|||
f50f5c5de7
|
|||
c8a6015f3f
|
|||
835372eb3b
|
|||
11ece9974f
|
|||
0d0fbb5461
|
|||
6c9a1fc10e
|
|||
7e05f4937d
|
|||
fd9045d7cd
|
|||
e938f81954
|
|||
e5dd207c8c
|
|||
92d5750c1d
|
|||
2011a83fd9
|
|||
d3da00372c
|
|||
d90dfc8ba7
|
|||
8bf0f9c45f
|
|||
4fcfa6938e
|
|||
26cfceb581
|
|||
ccf820d524
|
|||
5a9d6d9183
|
|||
a1dd2b20fb
|
|||
b0c6ea2d19
|
|||
9b6aa91e52
|
|||
01812bf492
|
|||
e6ef19f1a1
|
|||
d4066c1829
|
|||
498e46d94d
|
|||
658f005433
|
49
.drone.yml
49
.drone.yml
@@ -1,49 +0,0 @@
|
||||
kind: pipeline
|
||||
name: default
|
||||
|
||||
steps:
|
||||
- name: compile
|
||||
image: maven:3-eclipse-temurin-21
|
||||
commands:
|
||||
- mvn -B clean compile
|
||||
when:
|
||||
branch:
|
||||
- main
|
||||
- develop
|
||||
- feature/*
|
||||
- fix/*
|
||||
- release/*
|
||||
- name: unit-tests
|
||||
image: maven:3-eclipse-temurin-21
|
||||
commands:
|
||||
- mvn -B test
|
||||
when:
|
||||
branch:
|
||||
- develop
|
||||
- feature/*
|
||||
- fix/*
|
||||
- name: setup-vault
|
||||
image: alpine:latest
|
||||
environment:
|
||||
VAULT_VERSION: 1.17.6
|
||||
commands:
|
||||
- wget -q -O vault_$${VAULT_VERSION}_linux_amd64.zip 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
|
||||
- mkdir -p .bin
|
||||
- unzip vault_$${VAULT_VERSION}_linux_amd64.zip -d .bin
|
||||
- rm vault_$${VAULT_VERSION}_linux_amd64.zip
|
||||
when:
|
||||
branch:
|
||||
- main
|
||||
- release/*
|
||||
- name: unit-integration-tests
|
||||
image: maven:3-eclipse-temurin-21
|
||||
environment:
|
||||
VAULT_VERSION: 1.17.6
|
||||
commands:
|
||||
- export PATH=$${DRONE_WORKSPACE}/.bin:$${PATH}
|
||||
- mvn -B -P integration-test verify
|
||||
when:
|
||||
branch:
|
||||
- main
|
||||
- release/*
|
56
.github/workflows/ci-it.yml
vendored
Normal file
56
.github/workflows/ci-it.yml
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
name: CI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- 'main'
|
||||
pull_request:
|
||||
branches:
|
||||
- 'main'
|
||||
|
||||
jobs:
|
||||
build-with-it:
|
||||
if: github.ref_name == 'main' || github.base_ref == 'main' || startsWith(github.ref_name, 'release/')
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
jdk: [ 11, 17, 21 ]
|
||||
vault: [ '1.2.0', '1.20.0' ]
|
||||
include:
|
||||
- jdk: 21
|
||||
vault: '1.20.0'
|
||||
analysis: true
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Set up Java
|
||||
uses: actions/setup-java@v5
|
||||
with:
|
||||
java-version: ${{ matrix.jdk }}
|
||||
distribution: 'temurin'
|
||||
- name: Compile
|
||||
run: ./mvnw -B clean compile
|
||||
- name: Set up Vault
|
||||
run: |
|
||||
wget -q "https://releases.hashicorp.com/vault/${{ matrix.vault }}/vault_${{ matrix.vault }}_linux_amd64.zip"
|
||||
wget -q -O - "https://releases.hashicorp.com/vault/${{ matrix.vault }}/vault_${{ matrix.vault }}_SHA256SUMS" | grep linux_amd64 | sha256sum -c
|
||||
tmp="$(mktemp -d)"
|
||||
unzip "vault_${{ matrix.vault }}_linux_amd64.zip" -d "$tmp"
|
||||
rm "vault_${{ matrix.vault }}_linux_amd64.zip"
|
||||
sudo mv "$tmp/vault" /usr/bin/vault
|
||||
rm -rf "$tmp"
|
||||
- name: Test (Unit & Integration)
|
||||
env:
|
||||
VAULT_VERSION: ${{ matrix.vault }}
|
||||
run: ./mvnw -B -P coverage -P integration-test verify
|
||||
- name: Analysis
|
||||
if: matrix.analysis && env.SONAR_TOKEN != ''
|
||||
run: >
|
||||
./mvnw -B sonar:sonar
|
||||
-Dsonar.host.url=https://sonarcloud.io
|
||||
-Dsonar.organization=stklcode-github
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
|
42
.github/workflows/ci.yml
vendored
42
.github/workflows/ci.yml
vendored
@@ -1,50 +1,42 @@
|
||||
name: CI
|
||||
on: [ push, pull_request ]
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- '**'
|
||||
- '!main'
|
||||
pull_request:
|
||||
branches:
|
||||
- '**'
|
||||
- '!main'
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
jdk: [ 11, 17, 21 ]
|
||||
vault: [ '1.2.0', '1.11.12', '1.17.6' ]
|
||||
include:
|
||||
- jdk: 21
|
||||
vault: '1.11.12'
|
||||
analysis: true
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Set up Java
|
||||
uses: actions/setup-java@v4
|
||||
uses: actions/setup-java@v5
|
||||
with:
|
||||
java-version: ${{ matrix.jdk }}
|
||||
distribution: 'temurin'
|
||||
- name: Compile
|
||||
run: mvn -B clean compile
|
||||
- name: Set up Vault
|
||||
if: github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/heads/release/')
|
||||
run: |
|
||||
wget -q "https://releases.hashicorp.com/vault/${{ matrix.vault }}/vault_${{ matrix.vault }}_linux_amd64.zip"
|
||||
wget -q -O - "https://releases.hashicorp.com/vault/${{ matrix.vault }}/vault_${{ matrix.vault }}_SHA256SUMS" | grep linux_amd64 | sha256sum -c
|
||||
tmp="$(mktemp -d)"
|
||||
unzip "vault_${{ matrix.vault }}_linux_amd64.zip" -d "$tmp"
|
||||
rm "vault_${{ matrix.vault }}_linux_amd64.zip"
|
||||
sudo mv "$tmp/vault" /usr/bin/vault
|
||||
rm -rf "$tmp"
|
||||
- name: Test (Unit & Integration)
|
||||
if: github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/heads/release/')
|
||||
env:
|
||||
VAULT_VERSION: ${{ matrix.vault }}
|
||||
run: mvn -B -P coverage -P integration-test verify
|
||||
run: ./mvnw -B clean compile
|
||||
- name: Test (Unit)
|
||||
if: github.ref != 'refs/heads/main' && !startsWith(github.ref, 'refs/heads/release/')
|
||||
run: mvn -B -P coverage verify
|
||||
run: ./mvnw -B -P coverage verify
|
||||
- name: Analysis
|
||||
if: matrix.analysis
|
||||
if: matrix.analysis && env.SONAR_TOKEN != ''
|
||||
run: >
|
||||
mvn -B sonar:sonar
|
||||
./mvnw -B sonar:sonar
|
||||
-Dsonar.host.url=https://sonarcloud.io
|
||||
-Dsonar.organization=stklcode-github
|
||||
env:
|
||||
|
1
.gitignore
vendored
1
.gitignore
vendored
@@ -7,6 +7,7 @@ release.properties
|
||||
dependency-reduced-pom.xml
|
||||
buildNumber.properties
|
||||
.mvn/timing.properties
|
||||
.mvn/wrapper/maven-wrapper.jar
|
||||
|
||||
.idea
|
||||
*.iml
|
||||
|
2
.mvn/wrapper/maven-wrapper.properties
vendored
Normal file
2
.mvn/wrapper/maven-wrapper.properties
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
distributionType=only-script
|
||||
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.11/apache-maven-3.9.11-bin.zip
|
70
CHANGELOG.md
70
CHANGELOG.md
@@ -1,3 +1,73 @@
|
||||
## unreleased
|
||||
|
||||
### Dependencies
|
||||
* Updated Jackson to 2.20.0 (#106)
|
||||
|
||||
### Improvements
|
||||
* Extract API paths into a utility class (#108)
|
||||
|
||||
### Fix
|
||||
* Prevent potential off-by-1 error in internal `mapOf()` helper (#107)
|
||||
|
||||
## 1.5.2 (2025-07-16)
|
||||
|
||||
### Dependencies
|
||||
* Updated Jackson to 2.19.1 (#101)
|
||||
|
||||
### Fix
|
||||
* Use `Long` for numeric TTL fields (#103) (#104)
|
||||
|
||||
### Test
|
||||
* Tested against Vault 1.2 to 1.20 (#102)
|
||||
|
||||
|
||||
## 1.5.1 (2025-06-02)
|
||||
|
||||
### Improvements
|
||||
* Use `lookup-self` for token check instead of `lookup` (#98) (#99)
|
||||
|
||||
### Dependencies
|
||||
* Updated Jackson to 2.19.0 (#97)
|
||||
|
||||
|
||||
## 1.5.0 (2025-04-13)
|
||||
|
||||
### Deprecations
|
||||
* `read...Credentials()` methods for specific database mounts (#92)
|
||||
|
||||
### Features
|
||||
* Support Vault transit API (#89)
|
||||
* Support PEM certificate string from `VAULT_CACERT` environment variable (#93)
|
||||
|
||||
### Improvements
|
||||
* Replace deprecated `java.net.URL` usage with `java.net.URI` (#94)
|
||||
|
||||
### Fix
|
||||
* Fix initialization from environment without explicit port
|
||||
|
||||
### Dependencies
|
||||
* Updated Jackson to 2.18.3 (#90)
|
||||
|
||||
### Test
|
||||
* Tested against Vault 1.2 to 1.19
|
||||
|
||||
|
||||
## 1.4.0 (2024-12-07)
|
||||
|
||||
### Removal
|
||||
* Remove deprecated `get...TimeString()` on model classes (#77)
|
||||
* Drop support for deprecated `App-ID` auth backend (#61) (#78)
|
||||
|
||||
### Fix
|
||||
* Add jackson-annotations requirement to module-info (#84)
|
||||
|
||||
### Dependencies
|
||||
* Updated Jackson to 2.18.2 (#85)
|
||||
|
||||
### Test
|
||||
* Tested against Vault 1.2 to 1.18
|
||||
|
||||
|
||||
## 1.3.1 (2024-10-03)
|
||||
|
||||
### Dependencies
|
||||
|
16
README.md
16
README.md
@@ -5,7 +5,7 @@
|
||||
[](https://github.com/stklcode/jvaultconnector/blob/main/LICENSE.txt)
|
||||
[](https://central.sonatype.com/artifact/de.stklcode.jvault/jvault-connector)
|
||||
|
||||

|
||||

|
||||
|
||||
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.
|
||||
|
||||
@@ -18,7 +18,6 @@ Java Vault Connector is a connector library for [Vault](https://www.vaultproject
|
||||
* Token
|
||||
* Username/Password
|
||||
* AppRole (register and authenticate)
|
||||
* AppID (register and authenticate) [_deprecated_]
|
||||
* Tokens
|
||||
* Creation and lookup of tokens and token roles
|
||||
* TokenBuilder for speaking creation of complex configurations
|
||||
@@ -29,10 +28,11 @@ Java Vault Connector is a connector library for [Vault](https://www.vaultproject
|
||||
* Delete secrets
|
||||
* Renew/revoke leases
|
||||
* Raw secret content or JSON decoding
|
||||
* SQL secret handling
|
||||
* KV v1 and v2 support
|
||||
* Database secret handling
|
||||
* Transit API support
|
||||
* Connector Factory with builder pattern
|
||||
* Tested against Vault 1.2 to 1.17
|
||||
* Tested against Vault 1.2 to 1.20
|
||||
|
||||
|
||||
## 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>1.3.1</version>
|
||||
<version>1.5.2</version>
|
||||
</dependency>
|
||||
```
|
||||
|
||||
@@ -109,11 +109,11 @@ Token token = Token.builder()
|
||||
.withDisplayName("new test token")
|
||||
.withPolicies("pol1", "pol2")
|
||||
.build();
|
||||
vault.createToken(token);
|
||||
vault.token().create(token);
|
||||
|
||||
// Create AppRole credentials
|
||||
vault.createAppRole("testrole", policyList);
|
||||
AppRoleSecretResponse secret = vault.createAppRoleSecret("testrole");
|
||||
vault.appRole().create("testrole", policyList);
|
||||
AppRoleSecretResponse secret = vault.appRole().createSecret("testrole");
|
||||
```
|
||||
|
||||
## Links
|
||||
|
295
mvnw
vendored
Executable file
295
mvnw
vendored
Executable file
@@ -0,0 +1,295 @@
|
||||
#!/bin/sh
|
||||
# ----------------------------------------------------------------------------
|
||||
# Licensed to the Apache Software Foundation (ASF) under one
|
||||
# or more contributor license agreements. See the NOTICE file
|
||||
# distributed with this work for additional information
|
||||
# regarding copyright ownership. The ASF licenses this file
|
||||
# to you 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.
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# Apache Maven Wrapper startup batch script, version 3.3.3
|
||||
#
|
||||
# Optional ENV vars
|
||||
# -----------------
|
||||
# JAVA_HOME - location of a JDK home dir, required when download maven via java source
|
||||
# MVNW_REPOURL - repo url base for downloading maven distribution
|
||||
# MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven
|
||||
# MVNW_VERBOSE - true: enable verbose log; debug: trace the mvnw script; others: silence the output
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
set -euf
|
||||
[ "${MVNW_VERBOSE-}" != debug ] || set -x
|
||||
|
||||
# OS specific support.
|
||||
native_path() { printf %s\\n "$1"; }
|
||||
case "$(uname)" in
|
||||
CYGWIN* | MINGW*)
|
||||
[ -z "${JAVA_HOME-}" ] || JAVA_HOME="$(cygpath --unix "$JAVA_HOME")"
|
||||
native_path() { cygpath --path --windows "$1"; }
|
||||
;;
|
||||
esac
|
||||
|
||||
# set JAVACMD and JAVACCMD
|
||||
set_java_home() {
|
||||
# For Cygwin and MinGW, ensure paths are in Unix format before anything is touched
|
||||
if [ -n "${JAVA_HOME-}" ]; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ]; then
|
||||
# IBM's JDK on AIX uses strange locations for the executables
|
||||
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||
JAVACCMD="$JAVA_HOME/jre/sh/javac"
|
||||
else
|
||||
JAVACMD="$JAVA_HOME/bin/java"
|
||||
JAVACCMD="$JAVA_HOME/bin/javac"
|
||||
|
||||
if [ ! -x "$JAVACMD" ] || [ ! -x "$JAVACCMD" ]; then
|
||||
echo "The JAVA_HOME environment variable is not defined correctly, so mvnw cannot run." >&2
|
||||
echo "JAVA_HOME is set to \"$JAVA_HOME\", but \"\$JAVA_HOME/bin/java\" or \"\$JAVA_HOME/bin/javac\" does not exist." >&2
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
else
|
||||
JAVACMD="$(
|
||||
'set' +e
|
||||
'unset' -f command 2>/dev/null
|
||||
'command' -v java
|
||||
)" || :
|
||||
JAVACCMD="$(
|
||||
'set' +e
|
||||
'unset' -f command 2>/dev/null
|
||||
'command' -v javac
|
||||
)" || :
|
||||
|
||||
if [ ! -x "${JAVACMD-}" ] || [ ! -x "${JAVACCMD-}" ]; then
|
||||
echo "The java/javac command does not exist in PATH nor is JAVA_HOME set, so mvnw cannot run." >&2
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# hash string like Java String::hashCode
|
||||
hash_string() {
|
||||
str="${1:-}" h=0
|
||||
while [ -n "$str" ]; do
|
||||
char="${str%"${str#?}"}"
|
||||
h=$(((h * 31 + $(LC_CTYPE=C printf %d "'$char")) % 4294967296))
|
||||
str="${str#?}"
|
||||
done
|
||||
printf %x\\n $h
|
||||
}
|
||||
|
||||
verbose() { :; }
|
||||
[ "${MVNW_VERBOSE-}" != true ] || verbose() { printf %s\\n "${1-}"; }
|
||||
|
||||
die() {
|
||||
printf %s\\n "$1" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
trim() {
|
||||
# MWRAPPER-139:
|
||||
# Trims trailing and leading whitespace, carriage returns, tabs, and linefeeds.
|
||||
# Needed for removing poorly interpreted newline sequences when running in more
|
||||
# exotic environments such as mingw bash on Windows.
|
||||
printf "%s" "${1}" | tr -d '[:space:]'
|
||||
}
|
||||
|
||||
scriptDir="$(dirname "$0")"
|
||||
scriptName="$(basename "$0")"
|
||||
|
||||
# parse distributionUrl and optional distributionSha256Sum, requires .mvn/wrapper/maven-wrapper.properties
|
||||
while IFS="=" read -r key value; do
|
||||
case "${key-}" in
|
||||
distributionUrl) distributionUrl=$(trim "${value-}") ;;
|
||||
distributionSha256Sum) distributionSha256Sum=$(trim "${value-}") ;;
|
||||
esac
|
||||
done <"$scriptDir/.mvn/wrapper/maven-wrapper.properties"
|
||||
[ -n "${distributionUrl-}" ] || die "cannot read distributionUrl property in $scriptDir/.mvn/wrapper/maven-wrapper.properties"
|
||||
|
||||
case "${distributionUrl##*/}" in
|
||||
maven-mvnd-*bin.*)
|
||||
MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/
|
||||
case "${PROCESSOR_ARCHITECTURE-}${PROCESSOR_ARCHITEW6432-}:$(uname -a)" in
|
||||
*AMD64:CYGWIN* | *AMD64:MINGW*) distributionPlatform=windows-amd64 ;;
|
||||
:Darwin*x86_64) distributionPlatform=darwin-amd64 ;;
|
||||
:Darwin*arm64) distributionPlatform=darwin-aarch64 ;;
|
||||
:Linux*x86_64*) distributionPlatform=linux-amd64 ;;
|
||||
*)
|
||||
echo "Cannot detect native platform for mvnd on $(uname)-$(uname -m), use pure java version" >&2
|
||||
distributionPlatform=linux-amd64
|
||||
;;
|
||||
esac
|
||||
distributionUrl="${distributionUrl%-bin.*}-$distributionPlatform.zip"
|
||||
;;
|
||||
maven-mvnd-*) MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/ ;;
|
||||
*) MVN_CMD="mvn${scriptName#mvnw}" _MVNW_REPO_PATTERN=/org/apache/maven/ ;;
|
||||
esac
|
||||
|
||||
# apply MVNW_REPOURL and calculate MAVEN_HOME
|
||||
# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-<version>,maven-mvnd-<version>-<platform>}/<hash>
|
||||
[ -z "${MVNW_REPOURL-}" ] || distributionUrl="$MVNW_REPOURL$_MVNW_REPO_PATTERN${distributionUrl#*"$_MVNW_REPO_PATTERN"}"
|
||||
distributionUrlName="${distributionUrl##*/}"
|
||||
distributionUrlNameMain="${distributionUrlName%.*}"
|
||||
distributionUrlNameMain="${distributionUrlNameMain%-bin}"
|
||||
MAVEN_USER_HOME="${MAVEN_USER_HOME:-${HOME}/.m2}"
|
||||
MAVEN_HOME="${MAVEN_USER_HOME}/wrapper/dists/${distributionUrlNameMain-}/$(hash_string "$distributionUrl")"
|
||||
|
||||
exec_maven() {
|
||||
unset MVNW_VERBOSE MVNW_USERNAME MVNW_PASSWORD MVNW_REPOURL || :
|
||||
exec "$MAVEN_HOME/bin/$MVN_CMD" "$@" || die "cannot exec $MAVEN_HOME/bin/$MVN_CMD"
|
||||
}
|
||||
|
||||
if [ -d "$MAVEN_HOME" ]; then
|
||||
verbose "found existing MAVEN_HOME at $MAVEN_HOME"
|
||||
exec_maven "$@"
|
||||
fi
|
||||
|
||||
case "${distributionUrl-}" in
|
||||
*?-bin.zip | *?maven-mvnd-?*-?*.zip) ;;
|
||||
*) die "distributionUrl is not valid, must match *-bin.zip or maven-mvnd-*.zip, but found '${distributionUrl-}'" ;;
|
||||
esac
|
||||
|
||||
# prepare tmp dir
|
||||
if TMP_DOWNLOAD_DIR="$(mktemp -d)" && [ -d "$TMP_DOWNLOAD_DIR" ]; then
|
||||
clean() { rm -rf -- "$TMP_DOWNLOAD_DIR"; }
|
||||
trap clean HUP INT TERM EXIT
|
||||
else
|
||||
die "cannot create temp dir"
|
||||
fi
|
||||
|
||||
mkdir -p -- "${MAVEN_HOME%/*}"
|
||||
|
||||
# Download and Install Apache Maven
|
||||
verbose "Couldn't find MAVEN_HOME, downloading and installing it ..."
|
||||
verbose "Downloading from: $distributionUrl"
|
||||
verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName"
|
||||
|
||||
# select .zip or .tar.gz
|
||||
if ! command -v unzip >/dev/null; then
|
||||
distributionUrl="${distributionUrl%.zip}.tar.gz"
|
||||
distributionUrlName="${distributionUrl##*/}"
|
||||
fi
|
||||
|
||||
# verbose opt
|
||||
__MVNW_QUIET_WGET=--quiet __MVNW_QUIET_CURL=--silent __MVNW_QUIET_UNZIP=-q __MVNW_QUIET_TAR=''
|
||||
[ "${MVNW_VERBOSE-}" != true ] || __MVNW_QUIET_WGET='' __MVNW_QUIET_CURL='' __MVNW_QUIET_UNZIP='' __MVNW_QUIET_TAR=v
|
||||
|
||||
# normalize http auth
|
||||
case "${MVNW_PASSWORD:+has-password}" in
|
||||
'') MVNW_USERNAME='' MVNW_PASSWORD='' ;;
|
||||
has-password) [ -n "${MVNW_USERNAME-}" ] || MVNW_USERNAME='' MVNW_PASSWORD='' ;;
|
||||
esac
|
||||
|
||||
if [ -z "${MVNW_USERNAME-}" ] && command -v wget >/dev/null; then
|
||||
verbose "Found wget ... using wget"
|
||||
wget ${__MVNW_QUIET_WGET:+"$__MVNW_QUIET_WGET"} "$distributionUrl" -O "$TMP_DOWNLOAD_DIR/$distributionUrlName" || die "wget: Failed to fetch $distributionUrl"
|
||||
elif [ -z "${MVNW_USERNAME-}" ] && command -v curl >/dev/null; then
|
||||
verbose "Found curl ... using curl"
|
||||
curl ${__MVNW_QUIET_CURL:+"$__MVNW_QUIET_CURL"} -f -L -o "$TMP_DOWNLOAD_DIR/$distributionUrlName" "$distributionUrl" || die "curl: Failed to fetch $distributionUrl"
|
||||
elif set_java_home; then
|
||||
verbose "Falling back to use Java to download"
|
||||
javaSource="$TMP_DOWNLOAD_DIR/Downloader.java"
|
||||
targetZip="$TMP_DOWNLOAD_DIR/$distributionUrlName"
|
||||
cat >"$javaSource" <<-END
|
||||
public class Downloader extends java.net.Authenticator
|
||||
{
|
||||
protected java.net.PasswordAuthentication getPasswordAuthentication()
|
||||
{
|
||||
return new java.net.PasswordAuthentication( System.getenv( "MVNW_USERNAME" ), System.getenv( "MVNW_PASSWORD" ).toCharArray() );
|
||||
}
|
||||
public static void main( String[] args ) throws Exception
|
||||
{
|
||||
setDefault( new Downloader() );
|
||||
java.nio.file.Files.copy( java.net.URI.create( args[0] ).toURL().openStream(), java.nio.file.Paths.get( args[1] ).toAbsolutePath().normalize() );
|
||||
}
|
||||
}
|
||||
END
|
||||
# For Cygwin/MinGW, switch paths to Windows format before running javac and java
|
||||
verbose " - Compiling Downloader.java ..."
|
||||
"$(native_path "$JAVACCMD")" "$(native_path "$javaSource")" || die "Failed to compile Downloader.java"
|
||||
verbose " - Running Downloader.java ..."
|
||||
"$(native_path "$JAVACMD")" -cp "$(native_path "$TMP_DOWNLOAD_DIR")" Downloader "$distributionUrl" "$(native_path "$targetZip")"
|
||||
fi
|
||||
|
||||
# If specified, validate the SHA-256 sum of the Maven distribution zip file
|
||||
if [ -n "${distributionSha256Sum-}" ]; then
|
||||
distributionSha256Result=false
|
||||
if [ "$MVN_CMD" = mvnd.sh ]; then
|
||||
echo "Checksum validation is not supported for maven-mvnd." >&2
|
||||
echo "Please disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2
|
||||
exit 1
|
||||
elif command -v sha256sum >/dev/null; then
|
||||
if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | sha256sum -c - >/dev/null 2>&1; then
|
||||
distributionSha256Result=true
|
||||
fi
|
||||
elif command -v shasum >/dev/null; then
|
||||
if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | shasum -a 256 -c >/dev/null 2>&1; then
|
||||
distributionSha256Result=true
|
||||
fi
|
||||
else
|
||||
echo "Checksum validation was requested but neither 'sha256sum' or 'shasum' are available." >&2
|
||||
echo "Please install either command, or disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2
|
||||
exit 1
|
||||
fi
|
||||
if [ $distributionSha256Result = false ]; then
|
||||
echo "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised." >&2
|
||||
echo "If you updated your Maven version, you need to update the specified distributionSha256Sum property." >&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# unzip and move
|
||||
if command -v unzip >/dev/null; then
|
||||
unzip ${__MVNW_QUIET_UNZIP:+"$__MVNW_QUIET_UNZIP"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -d "$TMP_DOWNLOAD_DIR" || die "failed to unzip"
|
||||
else
|
||||
tar xzf${__MVNW_QUIET_TAR:+"$__MVNW_QUIET_TAR"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -C "$TMP_DOWNLOAD_DIR" || die "failed to untar"
|
||||
fi
|
||||
|
||||
# Find the actual extracted directory name (handles snapshots where filename != directory name)
|
||||
actualDistributionDir=""
|
||||
|
||||
# First try the expected directory name (for regular distributions)
|
||||
if [ -d "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" ]; then
|
||||
if [ -f "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain/bin/$MVN_CMD" ]; then
|
||||
actualDistributionDir="$distributionUrlNameMain"
|
||||
fi
|
||||
fi
|
||||
|
||||
# If not found, search for any directory with the Maven executable (for snapshots)
|
||||
if [ -z "$actualDistributionDir" ]; then
|
||||
# enable globbing to iterate over items
|
||||
set +f
|
||||
for dir in "$TMP_DOWNLOAD_DIR"/*; do
|
||||
if [ -d "$dir" ]; then
|
||||
if [ -f "$dir/bin/$MVN_CMD" ]; then
|
||||
actualDistributionDir="$(basename "$dir")"
|
||||
break
|
||||
fi
|
||||
fi
|
||||
done
|
||||
set -f
|
||||
fi
|
||||
|
||||
if [ -z "$actualDistributionDir" ]; then
|
||||
verbose "Contents of $TMP_DOWNLOAD_DIR:"
|
||||
verbose "$(ls -la "$TMP_DOWNLOAD_DIR")"
|
||||
die "Could not find Maven distribution directory in extracted archive"
|
||||
fi
|
||||
|
||||
verbose "Found extracted Maven distribution directory: $actualDistributionDir"
|
||||
printf %s\\n "$distributionUrl" >"$TMP_DOWNLOAD_DIR/$actualDistributionDir/mvnw.url"
|
||||
mv -- "$TMP_DOWNLOAD_DIR/$actualDistributionDir" "$MAVEN_HOME" || [ -d "$MAVEN_HOME" ] || die "fail to move MAVEN_HOME"
|
||||
|
||||
clean || :
|
||||
exec_maven "$@"
|
189
mvnw.cmd
vendored
Normal file
189
mvnw.cmd
vendored
Normal file
@@ -0,0 +1,189 @@
|
||||
<# : batch portion
|
||||
@REM ----------------------------------------------------------------------------
|
||||
@REM Licensed to the Apache Software Foundation (ASF) under one
|
||||
@REM or more contributor license agreements. See the NOTICE file
|
||||
@REM distributed with this work for additional information
|
||||
@REM regarding copyright ownership. The ASF licenses this file
|
||||
@REM to you under the Apache License, Version 2.0 (the
|
||||
@REM "License"); you may not use this file except in compliance
|
||||
@REM with the License. You may obtain a copy of the License at
|
||||
@REM
|
||||
@REM http://www.apache.org/licenses/LICENSE-2.0
|
||||
@REM
|
||||
@REM Unless required by applicable law or agreed to in writing,
|
||||
@REM software distributed under the License is distributed on an
|
||||
@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
@REM KIND, either express or implied. See the License for the
|
||||
@REM specific language governing permissions and limitations
|
||||
@REM under the License.
|
||||
@REM ----------------------------------------------------------------------------
|
||||
|
||||
@REM ----------------------------------------------------------------------------
|
||||
@REM Apache Maven Wrapper startup batch script, version 3.3.3
|
||||
@REM
|
||||
@REM Optional ENV vars
|
||||
@REM MVNW_REPOURL - repo url base for downloading maven distribution
|
||||
@REM MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven
|
||||
@REM MVNW_VERBOSE - true: enable verbose log; others: silence the output
|
||||
@REM ----------------------------------------------------------------------------
|
||||
|
||||
@IF "%__MVNW_ARG0_NAME__%"=="" (SET __MVNW_ARG0_NAME__=%~nx0)
|
||||
@SET __MVNW_CMD__=
|
||||
@SET __MVNW_ERROR__=
|
||||
@SET __MVNW_PSMODULEP_SAVE=%PSModulePath%
|
||||
@SET PSModulePath=
|
||||
@FOR /F "usebackq tokens=1* delims==" %%A IN (`powershell -noprofile "& {$scriptDir='%~dp0'; $script='%__MVNW_ARG0_NAME__%'; icm -ScriptBlock ([Scriptblock]::Create((Get-Content -Raw '%~f0'))) -NoNewScope}"`) DO @(
|
||||
IF "%%A"=="MVN_CMD" (set __MVNW_CMD__=%%B) ELSE IF "%%B"=="" (echo %%A) ELSE (echo %%A=%%B)
|
||||
)
|
||||
@SET PSModulePath=%__MVNW_PSMODULEP_SAVE%
|
||||
@SET __MVNW_PSMODULEP_SAVE=
|
||||
@SET __MVNW_ARG0_NAME__=
|
||||
@SET MVNW_USERNAME=
|
||||
@SET MVNW_PASSWORD=
|
||||
@IF NOT "%__MVNW_CMD__%"=="" ("%__MVNW_CMD__%" %*)
|
||||
@echo Cannot start maven from wrapper >&2 && exit /b 1
|
||||
@GOTO :EOF
|
||||
: end batch / begin powershell #>
|
||||
|
||||
$ErrorActionPreference = "Stop"
|
||||
if ($env:MVNW_VERBOSE -eq "true") {
|
||||
$VerbosePreference = "Continue"
|
||||
}
|
||||
|
||||
# calculate distributionUrl, requires .mvn/wrapper/maven-wrapper.properties
|
||||
$distributionUrl = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionUrl
|
||||
if (!$distributionUrl) {
|
||||
Write-Error "cannot read distributionUrl property in $scriptDir/.mvn/wrapper/maven-wrapper.properties"
|
||||
}
|
||||
|
||||
switch -wildcard -casesensitive ( $($distributionUrl -replace '^.*/','') ) {
|
||||
"maven-mvnd-*" {
|
||||
$USE_MVND = $true
|
||||
$distributionUrl = $distributionUrl -replace '-bin\.[^.]*$',"-windows-amd64.zip"
|
||||
$MVN_CMD = "mvnd.cmd"
|
||||
break
|
||||
}
|
||||
default {
|
||||
$USE_MVND = $false
|
||||
$MVN_CMD = $script -replace '^mvnw','mvn'
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
# apply MVNW_REPOURL and calculate MAVEN_HOME
|
||||
# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-<version>,maven-mvnd-<version>-<platform>}/<hash>
|
||||
if ($env:MVNW_REPOURL) {
|
||||
$MVNW_REPO_PATTERN = if ($USE_MVND -eq $False) { "/org/apache/maven/" } else { "/maven/mvnd/" }
|
||||
$distributionUrl = "$env:MVNW_REPOURL$MVNW_REPO_PATTERN$($distributionUrl -replace "^.*$MVNW_REPO_PATTERN",'')"
|
||||
}
|
||||
$distributionUrlName = $distributionUrl -replace '^.*/',''
|
||||
$distributionUrlNameMain = $distributionUrlName -replace '\.[^.]*$','' -replace '-bin$',''
|
||||
|
||||
$MAVEN_M2_PATH = "$HOME/.m2"
|
||||
if ($env:MAVEN_USER_HOME) {
|
||||
$MAVEN_M2_PATH = "$env:MAVEN_USER_HOME"
|
||||
}
|
||||
|
||||
if (-not (Test-Path -Path $MAVEN_M2_PATH)) {
|
||||
New-Item -Path $MAVEN_M2_PATH -ItemType Directory | Out-Null
|
||||
}
|
||||
|
||||
$MAVEN_WRAPPER_DISTS = $null
|
||||
if ((Get-Item $MAVEN_M2_PATH).Target[0] -eq $null) {
|
||||
$MAVEN_WRAPPER_DISTS = "$MAVEN_M2_PATH/wrapper/dists"
|
||||
} else {
|
||||
$MAVEN_WRAPPER_DISTS = (Get-Item $MAVEN_M2_PATH).Target[0] + "/wrapper/dists"
|
||||
}
|
||||
|
||||
$MAVEN_HOME_PARENT = "$MAVEN_WRAPPER_DISTS/$distributionUrlNameMain"
|
||||
$MAVEN_HOME_NAME = ([System.Security.Cryptography.SHA256]::Create().ComputeHash([byte[]][char[]]$distributionUrl) | ForEach-Object {$_.ToString("x2")}) -join ''
|
||||
$MAVEN_HOME = "$MAVEN_HOME_PARENT/$MAVEN_HOME_NAME"
|
||||
|
||||
if (Test-Path -Path "$MAVEN_HOME" -PathType Container) {
|
||||
Write-Verbose "found existing MAVEN_HOME at $MAVEN_HOME"
|
||||
Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD"
|
||||
exit $?
|
||||
}
|
||||
|
||||
if (! $distributionUrlNameMain -or ($distributionUrlName -eq $distributionUrlNameMain)) {
|
||||
Write-Error "distributionUrl is not valid, must end with *-bin.zip, but found $distributionUrl"
|
||||
}
|
||||
|
||||
# prepare tmp dir
|
||||
$TMP_DOWNLOAD_DIR_HOLDER = New-TemporaryFile
|
||||
$TMP_DOWNLOAD_DIR = New-Item -Itemtype Directory -Path "$TMP_DOWNLOAD_DIR_HOLDER.dir"
|
||||
$TMP_DOWNLOAD_DIR_HOLDER.Delete() | Out-Null
|
||||
trap {
|
||||
if ($TMP_DOWNLOAD_DIR.Exists) {
|
||||
try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null }
|
||||
catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" }
|
||||
}
|
||||
}
|
||||
|
||||
New-Item -Itemtype Directory -Path "$MAVEN_HOME_PARENT" -Force | Out-Null
|
||||
|
||||
# Download and Install Apache Maven
|
||||
Write-Verbose "Couldn't find MAVEN_HOME, downloading and installing it ..."
|
||||
Write-Verbose "Downloading from: $distributionUrl"
|
||||
Write-Verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName"
|
||||
|
||||
$webclient = New-Object System.Net.WebClient
|
||||
if ($env:MVNW_USERNAME -and $env:MVNW_PASSWORD) {
|
||||
$webclient.Credentials = New-Object System.Net.NetworkCredential($env:MVNW_USERNAME, $env:MVNW_PASSWORD)
|
||||
}
|
||||
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
|
||||
$webclient.DownloadFile($distributionUrl, "$TMP_DOWNLOAD_DIR/$distributionUrlName") | Out-Null
|
||||
|
||||
# If specified, validate the SHA-256 sum of the Maven distribution zip file
|
||||
$distributionSha256Sum = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionSha256Sum
|
||||
if ($distributionSha256Sum) {
|
||||
if ($USE_MVND) {
|
||||
Write-Error "Checksum validation is not supported for maven-mvnd. `nPlease disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties."
|
||||
}
|
||||
Import-Module $PSHOME\Modules\Microsoft.PowerShell.Utility -Function Get-FileHash
|
||||
if ((Get-FileHash "$TMP_DOWNLOAD_DIR/$distributionUrlName" -Algorithm SHA256).Hash.ToLower() -ne $distributionSha256Sum) {
|
||||
Write-Error "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised. If you updated your Maven version, you need to update the specified distributionSha256Sum property."
|
||||
}
|
||||
}
|
||||
|
||||
# unzip and move
|
||||
Expand-Archive "$TMP_DOWNLOAD_DIR/$distributionUrlName" -DestinationPath "$TMP_DOWNLOAD_DIR" | Out-Null
|
||||
|
||||
# Find the actual extracted directory name (handles snapshots where filename != directory name)
|
||||
$actualDistributionDir = ""
|
||||
|
||||
# First try the expected directory name (for regular distributions)
|
||||
$expectedPath = Join-Path "$TMP_DOWNLOAD_DIR" "$distributionUrlNameMain"
|
||||
$expectedMvnPath = Join-Path "$expectedPath" "bin/$MVN_CMD"
|
||||
if ((Test-Path -Path $expectedPath -PathType Container) -and (Test-Path -Path $expectedMvnPath -PathType Leaf)) {
|
||||
$actualDistributionDir = $distributionUrlNameMain
|
||||
}
|
||||
|
||||
# If not found, search for any directory with the Maven executable (for snapshots)
|
||||
if (!$actualDistributionDir) {
|
||||
Get-ChildItem -Path "$TMP_DOWNLOAD_DIR" -Directory | ForEach-Object {
|
||||
$testPath = Join-Path $_.FullName "bin/$MVN_CMD"
|
||||
if (Test-Path -Path $testPath -PathType Leaf) {
|
||||
$actualDistributionDir = $_.Name
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!$actualDistributionDir) {
|
||||
Write-Error "Could not find Maven distribution directory in extracted archive"
|
||||
}
|
||||
|
||||
Write-Verbose "Found extracted Maven distribution directory: $actualDistributionDir"
|
||||
Rename-Item -Path "$TMP_DOWNLOAD_DIR/$actualDistributionDir" -NewName $MAVEN_HOME_NAME | Out-Null
|
||||
try {
|
||||
Move-Item -Path "$TMP_DOWNLOAD_DIR/$MAVEN_HOME_NAME" -Destination $MAVEN_HOME_PARENT | Out-Null
|
||||
} catch {
|
||||
if (! (Test-Path -Path "$MAVEN_HOME" -PathType Container)) {
|
||||
Write-Error "fail to move MAVEN_HOME"
|
||||
}
|
||||
} finally {
|
||||
try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null }
|
||||
catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" }
|
||||
}
|
||||
|
||||
Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD"
|
115
pom.xml
115
pom.xml
@@ -1,10 +1,9 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>de.stklcode.jvault</groupId>
|
||||
<artifactId>jvault-connector</artifactId>
|
||||
<version>1.3.1</version>
|
||||
<version>2.0.0-SNAPSHOT</version>
|
||||
|
||||
<packaging>jar</packaging>
|
||||
|
||||
@@ -33,6 +32,7 @@
|
||||
<connection>scm:git:git://github.com/stklcode/jvaultconnector.git</connection>
|
||||
<developerConnection>scm:git:git@github.com:stklcode/jvaultconnector.git</developerConnection>
|
||||
<url>https://github.com/stklcode/jvaultconnector</url>
|
||||
<tag>HEAD</tag>
|
||||
</scm>
|
||||
|
||||
<issueManagement>
|
||||
@@ -42,31 +42,31 @@
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<argLine></argLine>
|
||||
<argLine />
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-databind</artifactId>
|
||||
<version>2.18.0</version>
|
||||
<version>2.20.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.datatype</groupId>
|
||||
<artifactId>jackson-datatype-jsr310</artifactId>
|
||||
<version>2.18.0</version>
|
||||
<version>2.20.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter</artifactId>
|
||||
<version>5.11.1</version>
|
||||
<version>5.13.3</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-core</artifactId>
|
||||
<version>5.14.1</version>
|
||||
<version>5.19.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@@ -78,25 +78,25 @@
|
||||
<dependency>
|
||||
<groupId>org.wiremock</groupId>
|
||||
<artifactId>wiremock</artifactId>
|
||||
<version>3.9.1</version>
|
||||
<version>3.13.1</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-io</groupId>
|
||||
<artifactId>commons-io</artifactId>
|
||||
<version>2.17.0</version>
|
||||
<version>2.20.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>nl.jqno.equalsverifier</groupId>
|
||||
<artifactId>equalsverifier</artifactId>
|
||||
<version>3.17.1</version>
|
||||
<version>3.19.4</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.awaitility</groupId>
|
||||
<artifactId>awaitility</artifactId>
|
||||
<version>4.2.2</version>
|
||||
<version>4.3.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
@@ -107,37 +107,37 @@
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.13.0</version>
|
||||
<version>3.14.0</version>
|
||||
<configuration>
|
||||
<source>11</source>
|
||||
<target>11</target>
|
||||
<release>11</release>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-clean-plugin</artifactId>
|
||||
<version>3.4.0</version>
|
||||
<version>3.5.0</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-deploy-plugin</artifactId>
|
||||
<version>3.1.3</version>
|
||||
<version>3.1.4</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-failsafe-plugin</artifactId>
|
||||
<version>3.5.0</version>
|
||||
<version>3.5.3</version>
|
||||
<configuration>
|
||||
<argLine>
|
||||
@{argLine}
|
||||
--add-opens de.stklcode.jvault.connector/de.stklcode.jvault.connector.test=com.fasterxml.jackson.databind
|
||||
--add-opens
|
||||
de.stklcode.jvault.connector/de.stklcode.jvault.connector.test=com.fasterxml.jackson.databind
|
||||
</argLine>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-install-plugin</artifactId>
|
||||
<version>3.1.3</version>
|
||||
<version>3.1.4</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
@@ -157,38 +157,57 @@
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<version>3.5.0</version>
|
||||
<version>3.5.3</version>
|
||||
<configuration>
|
||||
<argLine>
|
||||
@{argLine}
|
||||
--add-opens java.base/java.util=ALL-UNNAMED
|
||||
--add-opens de.stklcode.jvault.connector/de.stklcode.jvault.connector=ALL-UNNAMED
|
||||
--add-opens de.stklcode.jvault.connector/de.stklcode.jvault.connector.exception=ALL-UNNAMED
|
||||
--add-opens de.stklcode.jvault.connector/de.stklcode.jvault.connector.model=ALL-UNNAMED
|
||||
--add-opens de.stklcode.jvault.connector/de.stklcode.jvault.connector.model.response=ALL-UNNAMED
|
||||
--add-opens de.stklcode.jvault.connector/de.stklcode.jvault.connector.model.response.embedded=ALL-UNNAMED
|
||||
--add-opens de.stklcode.jvault.connector/de.stklcode.jvault.connector.test=com.fasterxml.jackson.databind
|
||||
--add-opens de.stklcode.jvault.connector/de.stklcode.jvault.connector.test=com.fasterxml.jackson.datatype.jsr310
|
||||
</argLine>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.cyclonedx</groupId>
|
||||
<artifactId>cyclonedx-maven-plugin</artifactId>
|
||||
<version>2.8.2</version>
|
||||
<version>2.9.1</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.jacoco</groupId>
|
||||
<artifactId>jacoco-maven-plugin</artifactId>
|
||||
<version>0.8.12</version>
|
||||
<version>0.8.13</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.sonarsource.scanner.maven</groupId>
|
||||
<artifactId>sonar-maven-plugin</artifactId>
|
||||
<version>4.0.0.4121</version>
|
||||
<version> 5.2.0.4988</version>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</pluginManagement>
|
||||
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-enforcer-plugin</artifactId>
|
||||
<version>3.6.1</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>enforce-versions</id>
|
||||
<goals>
|
||||
<goal>enforce</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<rules>
|
||||
<requireMavenVersion>
|
||||
<version>[3.6.3,)</version>
|
||||
</requireMavenVersion>
|
||||
<requireJavaVersion>
|
||||
<version>[11,)</version>
|
||||
</requireJavaVersion>
|
||||
</rules>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<profiles>
|
||||
@@ -225,7 +244,7 @@
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-javadoc-plugin</artifactId>
|
||||
<version>3.10.0</version>
|
||||
<version>3.11.3</version>
|
||||
<configuration>
|
||||
<source>11</source>
|
||||
</configuration>
|
||||
@@ -255,6 +274,9 @@
|
||||
<goals>
|
||||
<goal>makeBom</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<skipNotDeployed>false</skipNotDeployed>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
@@ -269,7 +291,7 @@
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-gpg-plugin</artifactId>
|
||||
<version>3.2.7</version>
|
||||
<version>3.2.8</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>sign-artifacts</id>
|
||||
@@ -340,7 +362,7 @@
|
||||
<plugin>
|
||||
<groupId>org.owasp</groupId>
|
||||
<artifactId>dependency-check-maven</artifactId>
|
||||
<version>10.0.4</version>
|
||||
<version>12.1.3</version>
|
||||
<configuration>
|
||||
<nvdApiKey>${env.NVD_API_KEY}</nvdApiKey>
|
||||
<nvdDatafeedUrl>${env.NVD_DATAFEED_URL}</nvdDatafeedUrl>
|
||||
@@ -358,17 +380,20 @@
|
||||
</profile>
|
||||
|
||||
<profile>
|
||||
<id>sonatype</id>
|
||||
<distributionManagement>
|
||||
<repository>
|
||||
<id>ossrh</id>
|
||||
<url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
|
||||
</repository>
|
||||
<snapshotRepository>
|
||||
<id>ossrh</id>
|
||||
<url>https://oss.sonatype.org/content/repositories/snapshots</url>
|
||||
</snapshotRepository>
|
||||
</distributionManagement>
|
||||
<id>central</id>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.sonatype.central</groupId>
|
||||
<artifactId>central-publishing-maven-plugin</artifactId>
|
||||
<version>0.8.0</version>
|
||||
<extensions>true</extensions>
|
||||
<configuration>
|
||||
<publishingServerId>central</publishingServerId>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
|
||||
<profile>
|
||||
|
217
src/main/java/de/stklcode/jvault/connector/AppRoleClient.java
Normal file
217
src/main/java/de/stklcode/jvault/connector/AppRoleClient.java
Normal file
@@ -0,0 +1,217 @@
|
||||
/*
|
||||
* Copyright 2016-2025 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.exception.VaultConnectorException;
|
||||
import de.stklcode.jvault.connector.model.AppRole;
|
||||
import de.stklcode.jvault.connector.model.AppRoleSecret;
|
||||
import de.stklcode.jvault.connector.model.Token;
|
||||
import de.stklcode.jvault.connector.model.TokenRole;
|
||||
import de.stklcode.jvault.connector.model.response.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* AppRole client interface.
|
||||
* Provides methods to interact with Vault's AppRole API.
|
||||
*
|
||||
* @since 2.0.0 extracted from {@link VaultConnector}
|
||||
*/
|
||||
public interface AppRoleClient {
|
||||
|
||||
/**
|
||||
* Register a new AppRole role from given metamodel.
|
||||
*
|
||||
* @param role The role
|
||||
* @return {@code true} on success
|
||||
* @throws VaultConnectorException on error
|
||||
* @since 0.4.0
|
||||
*/
|
||||
boolean create(final AppRole role) throws VaultConnectorException;
|
||||
|
||||
/**
|
||||
* Register new AppRole role with default policy.
|
||||
*
|
||||
* @param roleName The role name
|
||||
* @return {@code true} on success
|
||||
* @throws VaultConnectorException on error
|
||||
* @since 0.4.0
|
||||
*/
|
||||
default boolean create(final String roleName) throws VaultConnectorException {
|
||||
return create(roleName, new ArrayList<>());
|
||||
}
|
||||
|
||||
/**
|
||||
* Register new AppRole role with policies.
|
||||
*
|
||||
* @param roleName The role name
|
||||
* @param policies The policies to associate with
|
||||
* @return {@code true} on success
|
||||
* @throws VaultConnectorException on error
|
||||
* @since 0.4.0
|
||||
*/
|
||||
default boolean create(final String roleName, final List<String> policies) throws VaultConnectorException {
|
||||
return create(roleName, policies, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register new AppRole role with default policy and custom ID.
|
||||
*
|
||||
* @param roleName The role name
|
||||
* @param roleID A custom role ID
|
||||
* @return {@code true} on success
|
||||
* @throws VaultConnectorException on error
|
||||
* @since 0.4.0
|
||||
*/
|
||||
default boolean create(final String roleName, final String roleID) throws VaultConnectorException {
|
||||
return create(roleName, new ArrayList<>(), roleID);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register new AppRole role with policies and custom ID.
|
||||
*
|
||||
* @param roleName The role name
|
||||
* @param policies The policies to associate with
|
||||
* @param roleID A custom role ID
|
||||
* @return {@code true} on success
|
||||
* @throws VaultConnectorException on error
|
||||
* @since 0.4.0
|
||||
*/
|
||||
default boolean create(final String roleName, final List<String> policies, final String roleID)
|
||||
throws VaultConnectorException {
|
||||
return create(AppRole.builder(roleName).withTokenPolicies(policies).withId(roleID).build());
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete AppRole role from Vault.
|
||||
*
|
||||
* @param roleName The role name
|
||||
* @return {@code true} on success
|
||||
* @throws VaultConnectorException on error
|
||||
*/
|
||||
boolean delete(final String roleName) throws VaultConnectorException;
|
||||
|
||||
/**
|
||||
* Lookup an AppRole role.
|
||||
*
|
||||
* @param roleName The role name
|
||||
* @return Result of the lookup
|
||||
* @throws VaultConnectorException on error
|
||||
* @since 0.4.0
|
||||
*/
|
||||
AppRoleResponse lookup(final String roleName) throws VaultConnectorException;
|
||||
|
||||
/**
|
||||
* Retrieve ID for an AppRole role.
|
||||
*
|
||||
* @param roleName The role name
|
||||
* @return The role ID
|
||||
* @throws VaultConnectorException on error
|
||||
* @since 0.4.0
|
||||
*/
|
||||
String getRoleID(final String roleName) throws VaultConnectorException;
|
||||
|
||||
/**
|
||||
* Set custom ID for an AppRole role.
|
||||
*
|
||||
* @param roleName The role name
|
||||
* @param roleID The role ID
|
||||
* @return {@code true} on success
|
||||
* @throws VaultConnectorException on error
|
||||
* @since 0.4.0
|
||||
*/
|
||||
boolean setRoleID(final String roleName, final String roleID) throws VaultConnectorException;
|
||||
|
||||
/**
|
||||
* Register new random generated AppRole secret.
|
||||
*
|
||||
* @param roleName The role name
|
||||
* @return The secret ID
|
||||
* @throws VaultConnectorException on error
|
||||
* @since 0.4.0
|
||||
*/
|
||||
default AppRoleSecretResponse createSecret(final String roleName) throws VaultConnectorException {
|
||||
return createSecret(roleName, new AppRoleSecret());
|
||||
}
|
||||
|
||||
/**
|
||||
* Register new AppRole secret with custom ID.
|
||||
*
|
||||
* @param roleName The role name
|
||||
* @param secretID A custom secret ID
|
||||
* @return The secret ID
|
||||
* @throws VaultConnectorException on error
|
||||
* @since 0.4.0
|
||||
*/
|
||||
default AppRoleSecretResponse createSecret(final String roleName, final String secretID)
|
||||
throws VaultConnectorException {
|
||||
return createSecret(roleName, new AppRoleSecret(secretID));
|
||||
}
|
||||
|
||||
/**
|
||||
* Register new AppRole secret with custom ID.
|
||||
*
|
||||
* @param roleName The role name
|
||||
* @param secret The secret meta object
|
||||
* @return The secret ID
|
||||
* @throws VaultConnectorException on error
|
||||
* @since 0.4.0
|
||||
*/
|
||||
AppRoleSecretResponse createSecret(final String roleName, final AppRoleSecret secret)
|
||||
throws VaultConnectorException;
|
||||
|
||||
/**
|
||||
* Lookup an AppRole secret.
|
||||
*
|
||||
* @param roleName The role name
|
||||
* @param secretID The secret ID
|
||||
* @return Result of the lookup
|
||||
* @throws VaultConnectorException on error
|
||||
* @since 0.4.0
|
||||
*/
|
||||
AppRoleSecretResponse lookupSecret(final String roleName, final String secretID)
|
||||
throws VaultConnectorException;
|
||||
|
||||
/**
|
||||
* Destroy an AppRole secret.
|
||||
*
|
||||
* @param roleName The role name
|
||||
* @param secretID The secret meta object
|
||||
* @return The secret ID
|
||||
* @throws VaultConnectorException on error
|
||||
* @since 0.4.0
|
||||
*/
|
||||
boolean destroySecret(final String roleName, final String secretID) throws VaultConnectorException;
|
||||
|
||||
/**
|
||||
* List existing (accessible) AppRole roles.
|
||||
*
|
||||
* @return List of roles
|
||||
* @throws VaultConnectorException on error
|
||||
*/
|
||||
List<String> listRoles() throws VaultConnectorException;
|
||||
|
||||
/**
|
||||
* List existing (accessible) secret IDs for AppRole role.
|
||||
*
|
||||
* @param roleName The role name
|
||||
* @return List of roles
|
||||
* @throws VaultConnectorException on error
|
||||
*/
|
||||
List<String> listSecrets(final String roleName) throws VaultConnectorException;
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016-2024 Stefan Kalscheuer
|
||||
* Copyright 2016-2025 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,18 +20,17 @@ import de.stklcode.jvault.connector.exception.ConnectionException;
|
||||
import de.stklcode.jvault.connector.exception.TlsException;
|
||||
import de.stklcode.jvault.connector.exception.VaultConnectorException;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
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;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Vault Connector Builder implementation for HTTP Vault connectors.
|
||||
@@ -96,10 +95,14 @@ public final class HTTPVaultConnectorBuilder {
|
||||
* @since 1.0
|
||||
*/
|
||||
public HTTPVaultConnectorBuilder withBaseURL(final URI baseURL) {
|
||||
return withTLS(!("http".equalsIgnoreCase(Objects.requireNonNullElse(baseURL.getScheme(), ""))))
|
||||
.withHost(baseURL.getHost())
|
||||
.withPort(baseURL.getPort())
|
||||
.withPrefix(baseURL.getPath());
|
||||
String path = baseURL.getPath();
|
||||
if (path == null || path.isBlank()) {
|
||||
path = DEFAULT_PREFIX;
|
||||
}
|
||||
return withTLS(!("http".equalsIgnoreCase(baseURL.getScheme())))
|
||||
.withHost(baseURL.getHost())
|
||||
.withPort(baseURL.getPort())
|
||||
.withPrefix(path);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -301,13 +304,10 @@ public final class HTTPVaultConnectorBuilder {
|
||||
*/
|
||||
public HTTPVaultConnectorBuilder fromEnv() throws VaultConnectorException {
|
||||
/* Parse URL from environment variable */
|
||||
if (System.getenv(ENV_VAULT_ADDR) != null && !System.getenv(ENV_VAULT_ADDR).trim().isEmpty()) {
|
||||
if (System.getenv(ENV_VAULT_ADDR) != null && !System.getenv(ENV_VAULT_ADDR).isBlank()) {
|
||||
try {
|
||||
var 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) {
|
||||
withBaseURL(System.getenv(ENV_VAULT_ADDR));
|
||||
} catch (URISyntaxException e) {
|
||||
throw new ConnectionException("URL provided in environment variable malformed", e);
|
||||
}
|
||||
}
|
||||
@@ -315,7 +315,7 @@ public final class HTTPVaultConnectorBuilder {
|
||||
/* Read number of retries */
|
||||
if (System.getenv(ENV_VAULT_MAX_RETRIES) != null) {
|
||||
try {
|
||||
numberOfRetries = Integer.parseInt(System.getenv(ENV_VAULT_MAX_RETRIES));
|
||||
withNumberOfRetries(Integer.parseInt(System.getenv(ENV_VAULT_MAX_RETRIES)));
|
||||
} catch (NumberFormatException ignored) {
|
||||
/* Ignore malformed values. */
|
||||
}
|
||||
@@ -325,8 +325,12 @@ public final class HTTPVaultConnectorBuilder {
|
||||
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)));
|
||||
if (System.getenv(ENV_VAULT_CACERT) != null && !System.getenv(ENV_VAULT_CACERT).isBlank()) {
|
||||
X509Certificate cert = certificateFromString(System.getenv(ENV_VAULT_CACERT));
|
||||
if (cert == null) {
|
||||
cert = certificateFromFile(Paths.get(System.getenv(ENV_VAULT_CACERT)));
|
||||
}
|
||||
return withTrustedCA(cert);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
@@ -398,6 +402,28 @@ public final class HTTPVaultConnectorBuilder {
|
||||
return con;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read given certificate file to X.509 certificate.
|
||||
*
|
||||
* @param cert Certificate string (optionally PEM)
|
||||
* @return X.509 Certificate object if parseable, else {@code null}
|
||||
* @throws TlsException on error
|
||||
* @since 1.5.0
|
||||
*/
|
||||
private X509Certificate certificateFromString(final String cert) throws TlsException {
|
||||
// Check if PEM header is present in given string
|
||||
if (cert.contains("-BEGIN ") && cert.contains("-END")) {
|
||||
try (var is = new ByteArrayInputStream(cert.getBytes(StandardCharsets.UTF_8))) {
|
||||
return (X509Certificate) CertificateFactory.getInstance("X.509").generateCertificate(is);
|
||||
} catch (IOException | CertificateException e) {
|
||||
throw new TlsException("Unable to read certificate.", e);
|
||||
}
|
||||
}
|
||||
|
||||
// Not am PEM string, skip
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read given certificate file to X.509 certificate.
|
||||
*
|
||||
|
200
src/main/java/de/stklcode/jvault/connector/KV2Client.java
Normal file
200
src/main/java/de/stklcode/jvault/connector/KV2Client.java
Normal file
@@ -0,0 +1,200 @@
|
||||
/*
|
||||
* Copyright 2016-2025 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.exception.VaultConnectorException;
|
||||
import de.stklcode.jvault.connector.model.response.MetadataResponse;
|
||||
import de.stklcode.jvault.connector.model.response.SecretResponse;
|
||||
import de.stklcode.jvault.connector.model.response.SecretVersionResponse;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* KV v2 client interface.
|
||||
* Provides methods to interact with Vault's KV v2 API.
|
||||
*
|
||||
* @since 2.0.0 extracted from {@link VaultConnector}
|
||||
*/
|
||||
public interface KV2Client {
|
||||
|
||||
/**
|
||||
* Retrieve the latest secret data for specific version from Vault.
|
||||
* <br>
|
||||
* Path {@code <mount>/data/<key>} is read here.
|
||||
* Only available for KV v2 secrets.
|
||||
*
|
||||
* @param mount Secret store mount point (without leading or trailing slash).
|
||||
* @param key Secret identifier
|
||||
* @return Secret response
|
||||
* @throws VaultConnectorException on error
|
||||
* @since 0.8
|
||||
*/
|
||||
default SecretResponse readData(final String mount, final String key) throws VaultConnectorException {
|
||||
return readVersion(mount, key, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write secret to Vault.
|
||||
* <br>
|
||||
* Path {@code <mount>/data/<key>} is written here.
|
||||
* Only available for KV v2 secrets.
|
||||
*
|
||||
* @param mount Secret store mount point (without leading or trailing slash).
|
||||
* @param key Secret identifier
|
||||
* @param data Secret content. Value must be be JSON serializable.
|
||||
* @return Metadata for the created/updated secret.
|
||||
* @throws VaultConnectorException on error
|
||||
* @since 0.8
|
||||
*/
|
||||
default SecretVersionResponse writeData(final String mount,
|
||||
final String key,
|
||||
final Map<String, Object> data) throws VaultConnectorException {
|
||||
return writeData(mount, key, data, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write secret to Vault.
|
||||
* <br>
|
||||
* Path {@code <mount>/data/<key>} is written here.
|
||||
* Only available for KV v2 secrets.
|
||||
*
|
||||
* @param mount Secret store mount point (without leading or trailing slash).
|
||||
* @param key Secret identifier
|
||||
* @param data Secret content. Value must be be JSON serializable.
|
||||
* @param cas Use Check-And-Set operation, i.e. only allow writing if current version matches this value.
|
||||
* @return Metadata for the created/updated secret.
|
||||
* @throws VaultConnectorException on error
|
||||
* @since 0.8
|
||||
*/
|
||||
SecretVersionResponse writeData(final String mount,
|
||||
final String key,
|
||||
final Map<String, Object> data,
|
||||
final Integer cas) throws VaultConnectorException;
|
||||
|
||||
/**
|
||||
* Retrieve secret data from Vault.
|
||||
* <br>
|
||||
* Path {@code <mount>/data/<key>} is read here.
|
||||
* Only available for KV v2 secrets.
|
||||
*
|
||||
* @param mount Secret store mount point (without leading or trailing slash).
|
||||
* @param key Secret identifier
|
||||
* @param version Version to read. If {@code null} or zero, the latest version will be returned.
|
||||
* @return Secret response.
|
||||
* @throws VaultConnectorException on error
|
||||
* @since 0.8
|
||||
*/
|
||||
SecretResponse readVersion(final String mount, final String key, final Integer version)
|
||||
throws VaultConnectorException;
|
||||
|
||||
/**
|
||||
* Retrieve secret metadata from Vault.
|
||||
* <br>
|
||||
* Path {@code <mount>/metadata/<key>} is read here.
|
||||
* Only available for KV v2 secrets.
|
||||
*
|
||||
* @param mount Secret store mount point (without leading or trailing slash).
|
||||
* @param key Secret identifier
|
||||
* @return Metadata response
|
||||
* @throws VaultConnectorException on error
|
||||
* @since 0.8
|
||||
*/
|
||||
MetadataResponse readMetadata(final String mount, final String key) throws VaultConnectorException;
|
||||
|
||||
/**
|
||||
* Update secret metadata.
|
||||
* <br>
|
||||
* Path {@code <mount>/metadata/<key>} is written here.
|
||||
* Only available for KV v2 secrets.
|
||||
*
|
||||
* @param mount Secret store mount point (without leading or trailing slash).
|
||||
* @param key Secret identifier
|
||||
* @param maxVersions Maximum number of versions (fallback to backend default if {@code null})
|
||||
* @param casRequired Specify if Check-And-Set is required for this secret.
|
||||
* @throws VaultConnectorException on error
|
||||
* @since 0.8
|
||||
*/
|
||||
void updateMetadata(final String mount,
|
||||
final String key,
|
||||
final Integer maxVersions,
|
||||
final boolean casRequired) throws VaultConnectorException;
|
||||
|
||||
/**
|
||||
* Delete latest version of a secret from Vault.
|
||||
* <br>
|
||||
* Only available for KV v2 stores.
|
||||
*
|
||||
* @param mount Secret store mount point (without leading or trailing slash).
|
||||
* @param key Secret path.
|
||||
* @throws VaultConnectorException on error
|
||||
* @since 0.8
|
||||
*/
|
||||
void deleteLatestVersion(final String mount, final String key) throws VaultConnectorException;
|
||||
|
||||
/**
|
||||
* Delete latest version of a secret from Vault.
|
||||
* <br>
|
||||
* Prefix {@code secret/} is automatically added to path.
|
||||
* Only available for KV v2 stores.
|
||||
*
|
||||
* @param mount Secret store mount point (without leading or trailing slash).
|
||||
* @param key Secret path.
|
||||
* @throws VaultConnectorException on error
|
||||
* @since 0.8
|
||||
*/
|
||||
void deleteAllVersions(final String mount, final String key) throws VaultConnectorException;
|
||||
|
||||
/**
|
||||
* Delete secret versions from Vault.
|
||||
* <br>
|
||||
* Only available for KV v2 stores.
|
||||
*
|
||||
* @param mount Secret store mount point (without leading or trailing slash).
|
||||
* @param key Secret path.
|
||||
* @param versions Versions of the secret to delete.
|
||||
* @throws VaultConnectorException on error
|
||||
* @since 0.8
|
||||
*/
|
||||
void deleteVersions(final String mount, final String key, final int... versions)
|
||||
throws VaultConnectorException;
|
||||
|
||||
/**
|
||||
* Undelete (restore) secret versions from Vault.
|
||||
* Only available for KV v2 stores.
|
||||
*
|
||||
* @param mount Secret store mount point (without leading or trailing slash).
|
||||
* @param key Secret path.
|
||||
* @param versions Versions of the secret to undelete.
|
||||
* @throws VaultConnectorException on error
|
||||
* @since 0.8
|
||||
*/
|
||||
void undeleteVersions(final String mount, final String key, final int... versions)
|
||||
throws VaultConnectorException;
|
||||
|
||||
/**
|
||||
* Destroy secret versions from Vault.
|
||||
* Only available for KV v2 stores.
|
||||
*
|
||||
* @param mount Secret store mount point (without leading or trailing slash).
|
||||
* @param key Secret path.
|
||||
* @param versions Versions of the secret to destroy.
|
||||
* @throws VaultConnectorException on error
|
||||
* @since 0.8
|
||||
*/
|
||||
void destroyVersions(final String mount, final String key, final int... versions)
|
||||
throws VaultConnectorException;
|
||||
}
|
88
src/main/java/de/stklcode/jvault/connector/SysClient.java
Normal file
88
src/main/java/de/stklcode/jvault/connector/SysClient.java
Normal file
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copyright 2016-2025 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.exception.VaultConnectorException;
|
||||
import de.stklcode.jvault.connector.model.AuthBackend;
|
||||
import de.stklcode.jvault.connector.model.Token;
|
||||
import de.stklcode.jvault.connector.model.TokenRole;
|
||||
import de.stklcode.jvault.connector.model.response.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Sys client interface.
|
||||
* Provides methods to interact with Vault's system API.
|
||||
*
|
||||
* @since 2.0.0 extracted from {@link VaultConnector}
|
||||
*/
|
||||
public interface SysClient {
|
||||
|
||||
/**
|
||||
* Retrieve status of vault seal.
|
||||
*
|
||||
* @return Seal status
|
||||
* @throws VaultConnectorException on error
|
||||
*/
|
||||
SealResponse sealStatus() throws VaultConnectorException;
|
||||
|
||||
/**
|
||||
* Seal vault.
|
||||
*
|
||||
* @throws VaultConnectorException on error
|
||||
*/
|
||||
void seal() throws VaultConnectorException;
|
||||
|
||||
/**
|
||||
* Unseal vault.
|
||||
*
|
||||
* @param key A single master share key
|
||||
* @param reset Discard previously provided keys (optional)
|
||||
* @return Response with seal status
|
||||
* @throws VaultConnectorException on error
|
||||
*/
|
||||
SealResponse unseal(final String key, final Boolean reset) throws VaultConnectorException;
|
||||
|
||||
/**
|
||||
* Unseal vault.
|
||||
*
|
||||
* @param key A single master share key
|
||||
* @return Response with seal status
|
||||
* @throws VaultConnectorException on error
|
||||
*/
|
||||
default SealResponse unseal(final String key) throws VaultConnectorException {
|
||||
return unseal(key, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Query server health information.
|
||||
*
|
||||
* @return Health information.
|
||||
* @throws VaultConnectorException on error
|
||||
* @since 0.7.0
|
||||
*/
|
||||
HealthResponse getHealth() throws VaultConnectorException;
|
||||
|
||||
/**
|
||||
* Get all available authentication backends.
|
||||
*
|
||||
* @return List of backends
|
||||
* @throws VaultConnectorException on error
|
||||
*/
|
||||
List<AuthBackend> getAuthBackends() throws VaultConnectorException;
|
||||
|
||||
}
|
125
src/main/java/de/stklcode/jvault/connector/TokenClient.java
Normal file
125
src/main/java/de/stklcode/jvault/connector/TokenClient.java
Normal file
@@ -0,0 +1,125 @@
|
||||
/*
|
||||
* Copyright 2016-2025 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.exception.VaultConnectorException;
|
||||
import de.stklcode.jvault.connector.model.Token;
|
||||
import de.stklcode.jvault.connector.model.TokenRole;
|
||||
import de.stklcode.jvault.connector.model.response.AuthResponse;
|
||||
import de.stklcode.jvault.connector.model.response.TokenResponse;
|
||||
import de.stklcode.jvault.connector.model.response.TokenRoleResponse;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Token client interface.
|
||||
* Provides methods to interact with Vault's token API.
|
||||
*
|
||||
* @since 2.0.0 extracted from {@link VaultConnector}
|
||||
*/
|
||||
public interface TokenClient {
|
||||
|
||||
/**
|
||||
* Create a new token.
|
||||
*
|
||||
* @param token the token
|
||||
* @return the result response
|
||||
* @throws VaultConnectorException on error
|
||||
*/
|
||||
AuthResponse create(final Token token) throws VaultConnectorException;
|
||||
|
||||
/**
|
||||
* Create a new token.
|
||||
*
|
||||
* @param token the token
|
||||
* @param orphan create orphan token
|
||||
* @return the result response
|
||||
* @throws VaultConnectorException on error
|
||||
*/
|
||||
AuthResponse create(final Token token, boolean orphan) throws VaultConnectorException;
|
||||
|
||||
/**
|
||||
* Create a new token for specific role.
|
||||
*
|
||||
* @param token the token
|
||||
* @param role the role name
|
||||
* @return the result response
|
||||
* @throws VaultConnectorException on error
|
||||
*/
|
||||
AuthResponse create(final Token token, final String role) throws VaultConnectorException;
|
||||
|
||||
/**
|
||||
* Lookup token information.
|
||||
*
|
||||
* @param token the token
|
||||
* @return the result response
|
||||
* @throws VaultConnectorException on error
|
||||
*/
|
||||
TokenResponse lookup(final String token) throws VaultConnectorException;
|
||||
|
||||
/**
|
||||
* Create a new or update an existing token role.
|
||||
*
|
||||
* @param role the role entity (name must be set)
|
||||
* @return {@code true} on success
|
||||
* @throws VaultConnectorException on error
|
||||
* @since 0.9
|
||||
*/
|
||||
default boolean createOrUpdateRole(final TokenRole role) throws VaultConnectorException {
|
||||
return createOrUpdateRole(role.getName(), role);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new or update an existing token role.
|
||||
*
|
||||
* @param name the role name (overrides name possibly set in role entity)
|
||||
* @param role the role entity
|
||||
* @return {@code true} on success
|
||||
* @throws VaultConnectorException on error
|
||||
* @since 0.9
|
||||
*/
|
||||
boolean createOrUpdateRole(final String name, final TokenRole role) throws VaultConnectorException;
|
||||
|
||||
/**
|
||||
* Lookup token information.
|
||||
*
|
||||
* @param name the role name
|
||||
* @return the result response
|
||||
* @throws VaultConnectorException on error
|
||||
* @since 0.9
|
||||
*/
|
||||
TokenRoleResponse readRole(final String name) throws VaultConnectorException;
|
||||
|
||||
/**
|
||||
* List available token roles from Vault.
|
||||
*
|
||||
* @return List of token roles
|
||||
* @throws VaultConnectorException on error
|
||||
* @since 0.9
|
||||
*/
|
||||
List<String> listRoles() throws VaultConnectorException;
|
||||
|
||||
/**
|
||||
* Delete a token role.
|
||||
*
|
||||
* @param name the role name to delete
|
||||
* @return {@code true} on success
|
||||
* @throws VaultConnectorException on error
|
||||
* @since 0.9
|
||||
*/
|
||||
boolean deleteRole(final String name) throws VaultConnectorException;
|
||||
}
|
107
src/main/java/de/stklcode/jvault/connector/TransitClient.java
Normal file
107
src/main/java/de/stklcode/jvault/connector/TransitClient.java
Normal file
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
* Copyright 2016-2025 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.exception.VaultConnectorException;
|
||||
import de.stklcode.jvault.connector.model.response.TransitResponse;
|
||||
|
||||
import java.util.Base64;
|
||||
|
||||
/**
|
||||
* Transit client interface.
|
||||
* Provides methods to interact with Vault's transit API.
|
||||
*
|
||||
* @since 2.0.0 extracted from {@link VaultConnector}
|
||||
*/
|
||||
public interface TransitClient {
|
||||
|
||||
/**
|
||||
* Encrypt plaintext via transit engine from Vault.
|
||||
*
|
||||
* @param keyName Transit key name
|
||||
* @param plaintext Text to encrypt (Base64 encoded)
|
||||
* @return Transit response
|
||||
* @throws VaultConnectorException on error
|
||||
* @since 1.5.0
|
||||
*/
|
||||
TransitResponse encrypt(final String keyName, final String plaintext) throws VaultConnectorException;
|
||||
|
||||
/**
|
||||
* Encrypt plaintext via transit engine from Vault.
|
||||
*
|
||||
* @param keyName Transit key name
|
||||
* @param plaintext Binary data to encrypt
|
||||
* @return Transit response
|
||||
* @throws VaultConnectorException on error
|
||||
* @since 1.5.0
|
||||
*/
|
||||
default TransitResponse encrypt(final String keyName, final byte[] plaintext)
|
||||
throws VaultConnectorException {
|
||||
return encrypt(keyName, Base64.getEncoder().encodeToString(plaintext));
|
||||
}
|
||||
|
||||
/**
|
||||
* Decrypt ciphertext via transit engine from Vault.
|
||||
*
|
||||
* @param keyName Transit key name
|
||||
* @param ciphertext Text to decrypt
|
||||
* @return Transit response
|
||||
* @throws VaultConnectorException on error
|
||||
* @since 1.5.0
|
||||
*/
|
||||
TransitResponse decrypt(final String keyName, final String ciphertext) throws VaultConnectorException;
|
||||
|
||||
/**
|
||||
* Hash data in hex format via transit engine from Vault.
|
||||
*
|
||||
* @param algorithm Specifies the hash algorithm to use
|
||||
* @param input Data to hash
|
||||
* @return Transit response
|
||||
* @throws VaultConnectorException on error
|
||||
* @since 1.5.0
|
||||
*/
|
||||
default TransitResponse hash(final String algorithm, final String input) throws VaultConnectorException {
|
||||
return hash(algorithm, input, "hex");
|
||||
}
|
||||
|
||||
/**
|
||||
* Hash data via transit engine from Vault.
|
||||
*
|
||||
* @param algorithm Specifies the hash algorithm to use
|
||||
* @param input Data to hash (Base64 encoded)
|
||||
* @param format Specifies the output encoding (hex/base64)
|
||||
* @return Transit response
|
||||
* @throws VaultConnectorException on error
|
||||
* @since 1.5.0
|
||||
*/
|
||||
TransitResponse hash(final String algorithm, final String input, final String format)
|
||||
throws VaultConnectorException;
|
||||
|
||||
/**
|
||||
* Hash data via transit engine from Vault.
|
||||
*
|
||||
* @param algorithm Specifies the hash algorithm to use
|
||||
* @param input Data to hash
|
||||
* @return Transit response
|
||||
* @throws VaultConnectorException on error
|
||||
* @since 1.5.0
|
||||
*/
|
||||
default TransitResponse hash(final String algorithm, final byte[] input, final String format)
|
||||
throws VaultConnectorException {
|
||||
return hash(algorithm, Base64.getEncoder().encodeToString(input), format);
|
||||
}
|
||||
}
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016-2024 Stefan Kalscheuer
|
||||
* Copyright 2016-2025 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,10 +21,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.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Vault Connector interface.
|
||||
@@ -40,59 +37,6 @@ public interface VaultConnector extends AutoCloseable, Serializable {
|
||||
*/
|
||||
void resetAuth();
|
||||
|
||||
/**
|
||||
* Retrieve status of vault seal.
|
||||
*
|
||||
* @return Seal status
|
||||
* @throws VaultConnectorException on error
|
||||
*/
|
||||
SealResponse sealStatus() throws VaultConnectorException;
|
||||
|
||||
/**
|
||||
* Seal vault.
|
||||
*
|
||||
* @throws VaultConnectorException on error
|
||||
*/
|
||||
void seal() throws VaultConnectorException;
|
||||
|
||||
/**
|
||||
* Unseal vault.
|
||||
*
|
||||
* @param key A single master share key
|
||||
* @param reset Discard previously provided keys (optional)
|
||||
* @return Response with seal status
|
||||
* @throws VaultConnectorException on error
|
||||
*/
|
||||
SealResponse unseal(final String key, final Boolean reset) throws VaultConnectorException;
|
||||
|
||||
/**
|
||||
* Unseal vault.
|
||||
*
|
||||
* @param key A single master share key
|
||||
* @return Response with seal status
|
||||
* @throws VaultConnectorException on error
|
||||
*/
|
||||
default SealResponse unseal(final String key) throws VaultConnectorException {
|
||||
return unseal(key, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Query server health information.
|
||||
*
|
||||
* @return Health information.
|
||||
* @throws VaultConnectorException on error
|
||||
* @since 0.7.0
|
||||
*/
|
||||
HealthResponse getHealth() throws VaultConnectorException;
|
||||
|
||||
/**
|
||||
* Get all available authentication backends.
|
||||
*
|
||||
* @return List of backends
|
||||
* @throws VaultConnectorException on error
|
||||
*/
|
||||
List<AuthBackend> getAuthBackends() throws VaultConnectorException;
|
||||
|
||||
/**
|
||||
* Authorize to Vault using token.
|
||||
*
|
||||
@@ -112,19 +56,6 @@ public interface VaultConnector extends AutoCloseable, Serializable {
|
||||
*/
|
||||
AuthResponse authUserPass(final String username, final String password) throws VaultConnectorException;
|
||||
|
||||
/**
|
||||
* Authorize to Vault using AppID method.
|
||||
*
|
||||
* @param appID The App ID
|
||||
* @param userID The User ID
|
||||
* @return The {@link AuthResponse}
|
||||
* @throws VaultConnectorException on error
|
||||
* @deprecated As of Vault 0.6.1 App-ID is superseded by AppRole. App-ID was removed in Vault 1.12.
|
||||
* Consider using {@link #authAppRole} instead.
|
||||
*/
|
||||
@Deprecated(since = "0.4", forRemoval = true)
|
||||
AuthResponse authAppId(final String appID, final String userID) throws VaultConnectorException;
|
||||
|
||||
/**
|
||||
* Authorize to Vault using AppRole method without secret ID.
|
||||
*
|
||||
@@ -148,234 +79,6 @@ public interface VaultConnector extends AutoCloseable, Serializable {
|
||||
*/
|
||||
AuthResponse authAppRole(final String roleID, final String secretID) throws VaultConnectorException;
|
||||
|
||||
/**
|
||||
* Register new App-ID with policy.
|
||||
*
|
||||
* @param appID The unique App-ID
|
||||
* @param policy The policy to associate with
|
||||
* @param displayName Arbitrary name to display
|
||||
* @return {@code true} on success
|
||||
* @throws VaultConnectorException on error
|
||||
* @deprecated As of Vault 0.6.1 App-ID is superseded by AppRole. App-ID was removed in Vault 1.12.
|
||||
* Consider using {@link #createAppRole} instead.
|
||||
*/
|
||||
@Deprecated(since = "0.4", forRemoval = true)
|
||||
boolean registerAppId(final String appID, final String policy, final String displayName)
|
||||
throws VaultConnectorException;
|
||||
|
||||
/**
|
||||
* Register a new AppRole role from given metamodel.
|
||||
*
|
||||
* @param role The role
|
||||
* @return {@code true} on success
|
||||
* @throws VaultConnectorException on error
|
||||
* @since 0.4.0
|
||||
*/
|
||||
boolean createAppRole(final AppRole role) throws VaultConnectorException;
|
||||
|
||||
/**
|
||||
* Register new AppRole role with default policy.
|
||||
*
|
||||
* @param roleName The role name
|
||||
* @return {@code true} on success
|
||||
* @throws VaultConnectorException on error
|
||||
* @since 0.4.0
|
||||
*/
|
||||
default boolean createAppRole(final String roleName) throws VaultConnectorException {
|
||||
return createAppRole(roleName, new ArrayList<>());
|
||||
}
|
||||
|
||||
/**
|
||||
* Register new AppRole role with policies.
|
||||
*
|
||||
* @param roleName The role name
|
||||
* @param policies The policies to associate with
|
||||
* @return {@code true} on success
|
||||
* @throws VaultConnectorException on error
|
||||
* @since 0.4.0
|
||||
*/
|
||||
default boolean createAppRole(final String roleName, final List<String> policies) throws VaultConnectorException {
|
||||
return createAppRole(roleName, policies, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register new AppRole role with default policy and custom ID.
|
||||
*
|
||||
* @param roleName The role name
|
||||
* @param roleID A custom role ID
|
||||
* @return {@code true} on success
|
||||
* @throws VaultConnectorException on error
|
||||
* @since 0.4.0
|
||||
*/
|
||||
default boolean createAppRole(final String roleName, final String roleID) throws VaultConnectorException {
|
||||
return createAppRole(roleName, new ArrayList<>(), roleID);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register new AppRole role with policies and custom ID.
|
||||
*
|
||||
* @param roleName The role name
|
||||
* @param policies The policies to associate with
|
||||
* @param roleID A custom role ID
|
||||
* @return {@code true} on success
|
||||
* @throws VaultConnectorException on error
|
||||
* @since 0.4.0
|
||||
*/
|
||||
default boolean createAppRole(final String roleName, final List<String> policies, final String roleID)
|
||||
throws VaultConnectorException {
|
||||
return createAppRole(AppRole.builder(roleName).withTokenPolicies(policies).withId(roleID).build());
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete AppRole role from Vault.
|
||||
*
|
||||
* @param roleName The role name
|
||||
* @return {@code true} on success
|
||||
* @throws VaultConnectorException on error
|
||||
*/
|
||||
boolean deleteAppRole(final String roleName) throws VaultConnectorException;
|
||||
|
||||
/**
|
||||
* Lookup an AppRole role.
|
||||
*
|
||||
* @param roleName The role name
|
||||
* @return Result of the lookup
|
||||
* @throws VaultConnectorException on error
|
||||
* @since 0.4.0
|
||||
*/
|
||||
AppRoleResponse lookupAppRole(final String roleName) throws VaultConnectorException;
|
||||
|
||||
/**
|
||||
* Retrieve ID for an AppRole role.
|
||||
*
|
||||
* @param roleName The role name
|
||||
* @return The role ID
|
||||
* @throws VaultConnectorException on error
|
||||
* @since 0.4.0
|
||||
*/
|
||||
String getAppRoleID(final String roleName) throws VaultConnectorException;
|
||||
|
||||
/**
|
||||
* Set custom ID for an AppRole role.
|
||||
*
|
||||
* @param roleName The role name
|
||||
* @param roleID The role ID
|
||||
* @return {@code true} on success
|
||||
* @throws VaultConnectorException on error
|
||||
* @since 0.4.0
|
||||
*/
|
||||
boolean setAppRoleID(final String roleName, final String roleID) throws VaultConnectorException;
|
||||
|
||||
/**
|
||||
* Register new random generated AppRole secret.
|
||||
*
|
||||
* @param roleName The role name
|
||||
* @return The secret ID
|
||||
* @throws VaultConnectorException on error
|
||||
* @since 0.4.0
|
||||
*/
|
||||
default AppRoleSecretResponse createAppRoleSecret(final String roleName) throws VaultConnectorException {
|
||||
return createAppRoleSecret(roleName, new AppRoleSecret());
|
||||
}
|
||||
|
||||
/**
|
||||
* Register new AppRole secret with custom ID.
|
||||
*
|
||||
* @param roleName The role name
|
||||
* @param secretID A custom secret ID
|
||||
* @return The secret ID
|
||||
* @throws VaultConnectorException on error
|
||||
* @since 0.4.0
|
||||
*/
|
||||
default AppRoleSecretResponse createAppRoleSecret(final String roleName, final String secretID)
|
||||
throws VaultConnectorException {
|
||||
return createAppRoleSecret(roleName, new AppRoleSecret(secretID));
|
||||
}
|
||||
|
||||
/**
|
||||
* Register new AppRole secret with custom ID.
|
||||
*
|
||||
* @param roleName The role name
|
||||
* @param secret The secret meta object
|
||||
* @return The secret ID
|
||||
* @throws VaultConnectorException on error
|
||||
* @since 0.4.0
|
||||
*/
|
||||
AppRoleSecretResponse createAppRoleSecret(final String roleName, final AppRoleSecret secret)
|
||||
throws VaultConnectorException;
|
||||
|
||||
/**
|
||||
* Lookup an AppRole secret.
|
||||
*
|
||||
* @param roleName The role name
|
||||
* @param secretID The secret ID
|
||||
* @return Result of the lookup
|
||||
* @throws VaultConnectorException on error
|
||||
* @since 0.4.0
|
||||
*/
|
||||
AppRoleSecretResponse lookupAppRoleSecret(final String roleName, final String secretID)
|
||||
throws VaultConnectorException;
|
||||
|
||||
/**
|
||||
* Destroy an AppRole secret.
|
||||
*
|
||||
* @param roleName The role name
|
||||
* @param secretID The secret meta object
|
||||
* @return The secret ID
|
||||
* @throws VaultConnectorException on error
|
||||
* @since 0.4.0
|
||||
*/
|
||||
boolean destroyAppRoleSecret(final String roleName, final String secretID) throws VaultConnectorException;
|
||||
|
||||
/**
|
||||
* List existing (accessible) AppRole roles.
|
||||
*
|
||||
* @return List of roles
|
||||
* @throws VaultConnectorException on error
|
||||
*/
|
||||
List<String> listAppRoles() throws VaultConnectorException;
|
||||
|
||||
/**
|
||||
* List existing (accessible) secret IDs for AppRole role.
|
||||
*
|
||||
* @param roleName The role name
|
||||
* @return List of roles
|
||||
* @throws VaultConnectorException on error
|
||||
*/
|
||||
List<String> listAppRoleSecrets(final String roleName) throws VaultConnectorException;
|
||||
|
||||
/**
|
||||
* Register User-ID with App-ID.
|
||||
*
|
||||
* @param appID The App-ID
|
||||
* @param userID The User-ID
|
||||
* @return {@code true} on success
|
||||
* @throws VaultConnectorException on error
|
||||
* @deprecated As of Vault 0.6.1 App-ID is superseded by AppRole. App-ID was removed in Vault 1.12.
|
||||
* Consider using {@link #createAppRoleSecret} instead.
|
||||
*/
|
||||
@Deprecated(since = "0.4", forRemoval = true)
|
||||
boolean registerUserId(final String appID, final String userID) throws VaultConnectorException;
|
||||
|
||||
/**
|
||||
* Register new App-ID and User-ID at once.
|
||||
*
|
||||
* @param appID The App-ID
|
||||
* @param policy The policy to associate with
|
||||
* @param displayName Arbitrary name to display
|
||||
* @param userID The User-ID
|
||||
* @return {@code true} on success
|
||||
* @throws VaultConnectorException on error
|
||||
* @deprecated As of Vault 0.6.1 App-ID is superseded by AppRole. App-ID was removed in Vault 1.12.
|
||||
*/
|
||||
@Deprecated(since = "0.4", forRemoval = true)
|
||||
default boolean registerAppUserId(final String appID,
|
||||
final String policy,
|
||||
final String displayName,
|
||||
final String userID) throws VaultConnectorException {
|
||||
return registerAppId(appID, policy, userID) && registerUserId(appID, userID);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get authorization status.
|
||||
*
|
||||
@@ -393,108 +96,6 @@ public interface VaultConnector extends AutoCloseable, Serializable {
|
||||
*/
|
||||
SecretResponse read(final String key) throws VaultConnectorException;
|
||||
|
||||
/**
|
||||
* Retrieve the latest secret data for specific version from Vault.
|
||||
* <br>
|
||||
* Path {@code <mount>/data/<key>} is read here.
|
||||
* Only available for KV v2 secrets.
|
||||
*
|
||||
* @param mount Secret store mount point (without leading or trailing slash).
|
||||
* @param key Secret identifier
|
||||
* @return Secret response
|
||||
* @throws VaultConnectorException on error
|
||||
* @since 0.8
|
||||
*/
|
||||
default SecretResponse readSecretData(final String mount, final String key) throws VaultConnectorException {
|
||||
return readSecretVersion(mount, key, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write secret to Vault.
|
||||
* <br>
|
||||
* Path {@code <mount>/data/<key>} is written here.
|
||||
* Only available for KV v2 secrets.
|
||||
*
|
||||
* @param mount Secret store mount point (without leading or trailing slash).
|
||||
* @param key Secret identifier
|
||||
* @param data Secret content. Value must be be JSON serializable.
|
||||
* @return Metadata for the created/updated secret.
|
||||
* @throws VaultConnectorException on error
|
||||
* @since 0.8
|
||||
*/
|
||||
default SecretVersionResponse writeSecretData(final String mount,
|
||||
final String key,
|
||||
final Map<String, Object> data) throws VaultConnectorException {
|
||||
return writeSecretData(mount, key, data, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write secret to Vault.
|
||||
* <br>
|
||||
* Path {@code <mount>/data/<key>} is written here.
|
||||
* Only available for KV v2 secrets.
|
||||
*
|
||||
* @param mount Secret store mount point (without leading or trailing slash).
|
||||
* @param key Secret identifier
|
||||
* @param data Secret content. Value must be be JSON serializable.
|
||||
* @param cas Use Check-And-Set operation, i.e. only allow writing if current version matches this value.
|
||||
* @return Metadata for the created/updated secret.
|
||||
* @throws VaultConnectorException on error
|
||||
* @since 0.8
|
||||
*/
|
||||
SecretVersionResponse writeSecretData(final String mount,
|
||||
final String key,
|
||||
final Map<String, Object> data,
|
||||
final Integer cas) throws VaultConnectorException;
|
||||
|
||||
/**
|
||||
* Retrieve secret data from Vault.
|
||||
* <br>
|
||||
* Path {@code <mount>/data/<key>} is read here.
|
||||
* Only available for KV v2 secrets.
|
||||
*
|
||||
* @param mount Secret store mount point (without leading or trailing slash).
|
||||
* @param key Secret identifier
|
||||
* @param version Version to read. If {@code null} or zero, the latest version will be returned.
|
||||
* @return Secret response.
|
||||
* @throws VaultConnectorException on error
|
||||
* @since 0.8
|
||||
*/
|
||||
SecretResponse readSecretVersion(final String mount, final String key, final Integer version)
|
||||
throws VaultConnectorException;
|
||||
|
||||
/**
|
||||
* Retrieve secret metadata from Vault.
|
||||
* <br>
|
||||
* Path {@code <mount>/metadata/<key>} is read here.
|
||||
* Only available for KV v2 secrets.
|
||||
*
|
||||
* @param mount Secret store mount point (without leading or trailing slash).
|
||||
* @param key Secret identifier
|
||||
* @return Metadata response
|
||||
* @throws VaultConnectorException on error
|
||||
* @since 0.8
|
||||
*/
|
||||
MetadataResponse readSecretMetadata(final String mount, final String key) throws VaultConnectorException;
|
||||
|
||||
/**
|
||||
* Update secret metadata.
|
||||
* <br>
|
||||
* Path {@code <mount>/metadata/<key>} is written here.
|
||||
* Only available for KV v2 secrets.
|
||||
*
|
||||
* @param mount Secret store mount point (without leading or trailing slash).
|
||||
* @param key Secret identifier
|
||||
* @param maxVersions Maximum number of versions (fallback to backend default if {@code null})
|
||||
* @param casRequired Specify if Check-And-Set is required for this secret.
|
||||
* @throws VaultConnectorException on error
|
||||
* @since 0.8
|
||||
*/
|
||||
void updateSecretMetadata(final String mount,
|
||||
final String key,
|
||||
final Integer maxVersions,
|
||||
final boolean casRequired) throws VaultConnectorException;
|
||||
|
||||
/**
|
||||
* List available nodes from Vault.
|
||||
*
|
||||
@@ -539,7 +140,7 @@ public interface VaultConnector extends AutoCloseable, Serializable {
|
||||
* @since 0.8 {@code options} parameter added
|
||||
*/
|
||||
void write(final String key, final Map<String, Object> data, final Map<String, Object> options)
|
||||
throws VaultConnectorException;
|
||||
throws VaultConnectorException;
|
||||
|
||||
/**
|
||||
* Delete key from Vault.
|
||||
@@ -550,71 +151,6 @@ public interface VaultConnector extends AutoCloseable, Serializable {
|
||||
*/
|
||||
void delete(final String key) throws VaultConnectorException;
|
||||
|
||||
/**
|
||||
* Delete latest version of a secret from Vault.
|
||||
* <br>
|
||||
* Only available for KV v2 stores.
|
||||
*
|
||||
* @param mount Secret store mount point (without leading or trailing slash).
|
||||
* @param key Secret path.
|
||||
* @throws VaultConnectorException on error
|
||||
* @since 0.8
|
||||
*/
|
||||
void deleteLatestSecretVersion(final String mount, final String key) throws VaultConnectorException;
|
||||
|
||||
/**
|
||||
* Delete latest version of a secret from Vault.
|
||||
* <br>
|
||||
* Prefix {@code secret/} is automatically added to path.
|
||||
* Only available for KV v2 stores.
|
||||
*
|
||||
* @param mount Secret store mount point (without leading or trailing slash).
|
||||
* @param key Secret path.
|
||||
* @throws VaultConnectorException on error
|
||||
* @since 0.8
|
||||
*/
|
||||
void deleteAllSecretVersions(final String mount, final String key) throws VaultConnectorException;
|
||||
|
||||
/**
|
||||
* Delete secret versions from Vault.
|
||||
* <br>
|
||||
* Only available for KV v2 stores.
|
||||
*
|
||||
* @param mount Secret store mount point (without leading or trailing slash).
|
||||
* @param key Secret path.
|
||||
* @param versions Versions of the secret to delete.
|
||||
* @throws VaultConnectorException on error
|
||||
* @since 0.8
|
||||
*/
|
||||
void deleteSecretVersions(final String mount, final String key, final int... versions)
|
||||
throws VaultConnectorException;
|
||||
|
||||
/**
|
||||
* Undelete (restore) secret versions from Vault.
|
||||
* Only available for KV v2 stores.
|
||||
*
|
||||
* @param mount Secret store mount point (without leading or trailing slash).
|
||||
* @param key Secret path.
|
||||
* @param versions Versions of the secret to undelete.
|
||||
* @throws VaultConnectorException on error
|
||||
* @since 0.8
|
||||
*/
|
||||
void undeleteSecretVersions(final String mount, final String key, final int... versions)
|
||||
throws VaultConnectorException;
|
||||
|
||||
/**
|
||||
* Destroy secret versions from Vault.
|
||||
* Only available for KV v2 stores.
|
||||
*
|
||||
* @param mount Secret store mount point (without leading or trailing slash).
|
||||
* @param key Secret path.
|
||||
* @param versions Versions of the secret to destroy.
|
||||
* @throws VaultConnectorException on error
|
||||
* @since 0.8
|
||||
*/
|
||||
void destroySecretVersions(final String mount, final String key, final int... versions)
|
||||
throws VaultConnectorException;
|
||||
|
||||
/**
|
||||
* Revoke given lease immediately.
|
||||
*
|
||||
@@ -645,94 +181,44 @@ public interface VaultConnector extends AutoCloseable, Serializable {
|
||||
SecretResponse renew(final String leaseID, final Integer increment) throws VaultConnectorException;
|
||||
|
||||
/**
|
||||
* Create a new token.
|
||||
* Get client for KV v2 API.
|
||||
*
|
||||
* @param token the token
|
||||
* @return the result response
|
||||
* @throws VaultConnectorException on error
|
||||
* @return KV v2 client
|
||||
* @since 2.0.0
|
||||
*/
|
||||
AuthResponse createToken(final Token token) throws VaultConnectorException;
|
||||
KV2Client kv2();
|
||||
|
||||
/**
|
||||
* Create a new token.
|
||||
* Get client for token API.
|
||||
*
|
||||
* @param token the token
|
||||
* @param orphan create orphan token
|
||||
* @return the result response
|
||||
* @throws VaultConnectorException on error
|
||||
* @return Token client
|
||||
* @since 2.0.0
|
||||
*/
|
||||
AuthResponse createToken(final Token token, boolean orphan) throws VaultConnectorException;
|
||||
TokenClient token();
|
||||
|
||||
/**
|
||||
* Create a new token for specific role.
|
||||
* Get client for AppRole API.
|
||||
*
|
||||
* @param token the token
|
||||
* @param role the role name
|
||||
* @return the result response
|
||||
* @throws VaultConnectorException on error
|
||||
* @return AppRole client
|
||||
* @since 2.0.0
|
||||
*/
|
||||
AuthResponse createToken(final Token token, final String role) throws VaultConnectorException;
|
||||
AppRoleClient appRole();
|
||||
|
||||
/**
|
||||
* Lookup token information.
|
||||
* Get client for transit API.
|
||||
*
|
||||
* @param token the token
|
||||
* @return the result response
|
||||
* @throws VaultConnectorException on error
|
||||
* @return Transit client
|
||||
* @since 2.0.0
|
||||
*/
|
||||
TokenResponse lookupToken(final String token) throws VaultConnectorException;
|
||||
TransitClient transit();
|
||||
|
||||
/**
|
||||
* Create a new or update an existing token role.
|
||||
* Get client for system API.
|
||||
*
|
||||
* @param role the role entity (name must be set)
|
||||
* @return {@code true} on success
|
||||
* @throws VaultConnectorException on error
|
||||
* @since 0.9
|
||||
* @return System client
|
||||
* @since 2.0.0
|
||||
*/
|
||||
default boolean createOrUpdateTokenRole(final TokenRole role) throws VaultConnectorException {
|
||||
return createOrUpdateTokenRole(role.getName(), role);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new or update an existing token role.
|
||||
*
|
||||
* @param name the role name (overrides name possibly set in role entity)
|
||||
* @param role the role entity
|
||||
* @return {@code true} on success
|
||||
* @throws VaultConnectorException on error
|
||||
* @since 0.9
|
||||
*/
|
||||
boolean createOrUpdateTokenRole(final String name, final TokenRole role) throws VaultConnectorException;
|
||||
|
||||
/**
|
||||
* Lookup token information.
|
||||
*
|
||||
* @param name the role name
|
||||
* @return the result response
|
||||
* @throws VaultConnectorException on error
|
||||
* @since 0.9
|
||||
*/
|
||||
TokenRoleResponse readTokenRole(final String name) throws VaultConnectorException;
|
||||
|
||||
/**
|
||||
* List available token roles from Vault.
|
||||
*
|
||||
* @return List of token roles
|
||||
* @throws VaultConnectorException on error
|
||||
* @since 0.9
|
||||
*/
|
||||
List<String> listTokenRoles() throws VaultConnectorException;
|
||||
|
||||
/**
|
||||
* Delete a token role.
|
||||
*
|
||||
* @param name the role name to delete
|
||||
* @return {@code true} on success
|
||||
* @throws VaultConnectorException on error
|
||||
* @since 0.9
|
||||
*/
|
||||
boolean deleteTokenRole(final String name) throws VaultConnectorException;
|
||||
SysClient sys();
|
||||
|
||||
/**
|
||||
* Read credentials for MySQL backend at default mount point.
|
||||
@@ -741,7 +227,9 @@ public interface VaultConnector extends AutoCloseable, Serializable {
|
||||
* @return the credentials response
|
||||
* @throws VaultConnectorException on error
|
||||
* @since 0.5.0
|
||||
* @deprecated use {@link #readDbCredentials(String, String)} your MySQL mountpoint
|
||||
*/
|
||||
@Deprecated(since = "1.5.0", forRemoval = true)
|
||||
default CredentialsResponse readMySqlCredentials(final String role) throws VaultConnectorException {
|
||||
return readDbCredentials(role, "mysql");
|
||||
}
|
||||
@@ -753,7 +241,9 @@ public interface VaultConnector extends AutoCloseable, Serializable {
|
||||
* @return the credentials response
|
||||
* @throws VaultConnectorException on error
|
||||
* @since 0.5.0
|
||||
* @deprecated use {@link #readDbCredentials(String, String)} your PostgreSQL mountpoint
|
||||
*/
|
||||
@Deprecated(since = "1.5.0", forRemoval = true)
|
||||
default CredentialsResponse readPostgreSqlCredentials(final String role) throws VaultConnectorException {
|
||||
return readDbCredentials(role, "postgresql");
|
||||
}
|
||||
@@ -765,34 +255,39 @@ public interface VaultConnector extends AutoCloseable, Serializable {
|
||||
* @return the credentials response
|
||||
* @throws VaultConnectorException on error
|
||||
* @since 0.5.0
|
||||
* @deprecated use {@link #readDbCredentials(String, String)} your MSSQL mountpoint
|
||||
*/
|
||||
@Deprecated(since = "1.5.0", forRemoval = true)
|
||||
default CredentialsResponse readMsSqlCredentials(final String role) throws VaultConnectorException {
|
||||
return readDbCredentials(role, "mssql");
|
||||
}
|
||||
|
||||
/**
|
||||
* Read credentials for MSSQL backend at default mount point.
|
||||
* Read credentials for MongoDB backend at default mount point.
|
||||
*
|
||||
* @param role the role name
|
||||
* @return the credentials response
|
||||
* @throws VaultConnectorException on error
|
||||
* @since 0.5.0
|
||||
* @deprecated use {@link #readDbCredentials(String, String)} your MongoDB mountpoint
|
||||
*/
|
||||
@Deprecated(since = "1.5.0", forRemoval = true)
|
||||
default CredentialsResponse readMongoDbCredentials(final String role) throws VaultConnectorException {
|
||||
return readDbCredentials(role, "mongodb");
|
||||
}
|
||||
|
||||
/**
|
||||
* Read credentials for SQL backends.
|
||||
* Read credentials for database backends.
|
||||
*
|
||||
* @param role the role name
|
||||
* @param mount mount point of the SQL backend
|
||||
* @param mount mount point of the database backend
|
||||
* @return the credentials response
|
||||
* @throws VaultConnectorException on error
|
||||
* @since 0.5.0
|
||||
*/
|
||||
default CredentialsResponse readDbCredentials(final String role, final String mount)
|
||||
throws VaultConnectorException {
|
||||
throws VaultConnectorException {
|
||||
return (CredentialsResponse) read(mount + "/creds/" + role);
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016-2024 Stefan Kalscheuer
|
||||
* Copyright 2016-2025 Stefan Kalscheuer
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016-2024 Stefan Kalscheuer
|
||||
* Copyright 2016-2025 Stefan Kalscheuer
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016-2024 Stefan Kalscheuer
|
||||
* Copyright 2016-2025 Stefan Kalscheuer
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016-2024 Stefan Kalscheuer
|
||||
* Copyright 2016-2025 Stefan Kalscheuer
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016-2024 Stefan Kalscheuer
|
||||
* Copyright 2016-2025 Stefan Kalscheuer
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016-2024 Stefan Kalscheuer
|
||||
* Copyright 2016-2025 Stefan Kalscheuer
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016-2024 Stefan Kalscheuer
|
||||
* Copyright 2016-2025 Stefan Kalscheuer
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016-2024 Stefan Kalscheuer
|
||||
* Copyright 2016-2025 Stefan Kalscheuer
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016-2024 Stefan Kalscheuer
|
||||
* Copyright 2016-2025 Stefan Kalscheuer
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@@ -2,8 +2,8 @@ package de.stklcode.jvault.connector.internal;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.DeserializationFeature;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.SerializationFeature;
|
||||
import com.fasterxml.jackson.databind.json.JsonMapper;
|
||||
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
|
||||
import de.stklcode.jvault.connector.exception.*;
|
||||
import de.stklcode.jvault.connector.model.response.ErrorResponse;
|
||||
@@ -44,7 +44,7 @@ public final class RequestHelper implements Serializable {
|
||||
private final int retries; // Number of retries on 5xx errors.
|
||||
private final String tlsVersion; // TLS version (#22).
|
||||
private final X509Certificate trustedCaCert; // Trusted CA certificate.
|
||||
private final ObjectMapper jsonMapper;
|
||||
private final JsonMapper jsonMapper;
|
||||
|
||||
/**
|
||||
* Constructor of the request helper.
|
||||
@@ -65,10 +65,11 @@ public final class RequestHelper implements Serializable {
|
||||
this.timeout = timeout;
|
||||
this.tlsVersion = tlsVersion;
|
||||
this.trustedCaCert = trustedCaCert;
|
||||
this.jsonMapper = new ObjectMapper()
|
||||
.registerModule(new JavaTimeModule())
|
||||
.enable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
|
||||
.disable(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE);
|
||||
this.jsonMapper = JsonMapper.builder()
|
||||
.addModule(new JavaTimeModule())
|
||||
.enable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
|
||||
.disable(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE)
|
||||
.build();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -115,7 +116,7 @@ public final class RequestHelper implements Serializable {
|
||||
* @since 0.8
|
||||
*/
|
||||
public <T> T post(final String path, final Object payload, final String token, final Class<T> target)
|
||||
throws VaultConnectorException {
|
||||
throws VaultConnectorException {
|
||||
try {
|
||||
String response = post(path, payload, token);
|
||||
return jsonMapper.readValue(response, target);
|
||||
@@ -134,7 +135,7 @@ public final class RequestHelper implements Serializable {
|
||||
* @since 0.8
|
||||
*/
|
||||
public void postWithoutResponse(final String path, final Object payload, final String token)
|
||||
throws VaultConnectorException {
|
||||
throws VaultConnectorException {
|
||||
if (!post(path, payload, token).isEmpty()) {
|
||||
throw new InvalidResponseException(Error.UNEXPECTED_RESPONSE);
|
||||
}
|
||||
@@ -151,7 +152,7 @@ public final class RequestHelper implements Serializable {
|
||||
* @since 0.8 Added {@code token} parameter.
|
||||
*/
|
||||
public String put(final String path, final Map<String, String> payload, final String token)
|
||||
throws VaultConnectorException {
|
||||
throws VaultConnectorException {
|
||||
// Initialize PUT.
|
||||
var req = HttpRequest.newBuilder(URI.create(baseURL + path));
|
||||
|
||||
@@ -185,7 +186,7 @@ public final class RequestHelper implements Serializable {
|
||||
* @since 0.8
|
||||
*/
|
||||
public <T> T put(final String path, final Map<String, String> payload, final String token, final Class<T> target)
|
||||
throws VaultConnectorException {
|
||||
throws VaultConnectorException {
|
||||
try {
|
||||
String response = put(path, payload, token);
|
||||
return jsonMapper.readValue(response, target);
|
||||
@@ -204,7 +205,7 @@ public final class RequestHelper implements Serializable {
|
||||
* @since 0.8
|
||||
*/
|
||||
public void putWithoutResponse(final String path, final Map<String, String> payload, final String token)
|
||||
throws VaultConnectorException {
|
||||
throws VaultConnectorException {
|
||||
if (!put(path, payload, token).isEmpty()) {
|
||||
throw new InvalidResponseException(Error.UNEXPECTED_RESPONSE);
|
||||
}
|
||||
@@ -256,15 +257,15 @@ public final class RequestHelper implements Serializable {
|
||||
* @since 0.8 Added {@code token} parameter.
|
||||
*/
|
||||
public String get(final String path, final Map<String, String> payload, final String token)
|
||||
throws VaultConnectorException {
|
||||
throws VaultConnectorException {
|
||||
// Add parameters to URI.
|
||||
var uriBuilder = new StringBuilder(baseURL + path);
|
||||
|
||||
if (!payload.isEmpty()) {
|
||||
uriBuilder.append("?").append(
|
||||
payload.entrySet().stream().map(par ->
|
||||
URLEncoder.encode(par.getKey(), UTF_8) + "=" + URLEncoder.encode(par.getValue(), UTF_8)
|
||||
).collect(Collectors.joining("&"))
|
||||
payload.entrySet().stream().map(par ->
|
||||
URLEncoder.encode(par.getKey(), UTF_8) + "=" + URLEncoder.encode(par.getValue(), UTF_8)
|
||||
).collect(Collectors.joining("&"))
|
||||
);
|
||||
}
|
||||
|
||||
@@ -297,7 +298,7 @@ public final class RequestHelper implements Serializable {
|
||||
* @since 0.8
|
||||
*/
|
||||
public <T> T get(final String path, final Map<String, String> payload, final String token, final Class<T> target)
|
||||
throws VaultConnectorException {
|
||||
throws VaultConnectorException {
|
||||
try {
|
||||
String response = get(path, payload, token);
|
||||
return jsonMapper.readValue(response, target);
|
||||
@@ -333,8 +334,8 @@ public final class RequestHelper implements Serializable {
|
||||
// Execute request.
|
||||
try {
|
||||
HttpResponse<InputStream> response = client.sendAsync(
|
||||
requestBuilder.build(),
|
||||
HttpResponse.BodyHandlers.ofInputStream()
|
||||
requestBuilder.build(),
|
||||
HttpResponse.BodyHandlers.ofInputStream()
|
||||
).join();
|
||||
|
||||
/* Check if response is valid */
|
||||
|
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright 2016-2025 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.internal;
|
||||
|
||||
/**
|
||||
* Vault API path constants.
|
||||
*
|
||||
* @author Stefan Kalscheuer
|
||||
* @since 1.5.3
|
||||
*/
|
||||
public final class VaultApiPath {
|
||||
// Base paths
|
||||
private static final String SYS = "sys";
|
||||
private static final String AUTH = "auth";
|
||||
private static final String TRANSIT = "transit";
|
||||
|
||||
// System paths
|
||||
public static final String SYS_AUTH = SYS + "/auth";
|
||||
public static final String SYS_LEASES_RENEW = SYS + "/leases/renew";
|
||||
public static final String SYS_LEASES_REVOKE = SYS + "/leases/revoke/";
|
||||
public static final String SYS_HEALTH = SYS + "/health";
|
||||
public static final String SYS_SEAL = SYS + "/seal";
|
||||
public static final String SYS_SEAL_STATUS = SYS + "/seal-status";
|
||||
public static final String SYS_UNSEAL = SYS + "/unseal";
|
||||
|
||||
// Auth paths
|
||||
public static final String AUTH_TOKEN = AUTH + "/token";
|
||||
public static final String AUTH_USERPASS_LOGIN = AUTH + "/userpass/login/";
|
||||
public static final String AUTH_APPROLE = AUTH + "/approle";
|
||||
public static final String AUTH_APPROLE_ROLE = AUTH_APPROLE + "/role/%s%s";
|
||||
|
||||
// Token operations
|
||||
public static final String TOKEN_LOOKUP = "/lookup";
|
||||
public static final String TOKEN_LOOKUP_SELF = "/lookup-self";
|
||||
public static final String TOKEN_CREATE = "/create";
|
||||
public static final String TOKEN_CREATE_ORPHAN = "/create-orphan";
|
||||
public static final String TOKEN_ROLES = "/roles";
|
||||
|
||||
// Secret engine paths
|
||||
public static final String SECRET_DATA = "/data/";
|
||||
public static final String SECRET_METADATA = "/metadata/";
|
||||
public static final String SECRET_DELETE = "/delete/";
|
||||
public static final String SECRET_UNDELETE = "/undelete/";
|
||||
public static final String SECRET_DESTROY = "/destroy/";
|
||||
|
||||
// Generic paths
|
||||
public static final String LOGIN = "/login";
|
||||
|
||||
// Transit engine paths
|
||||
public static final String TRANSIT_ENCRYPT = TRANSIT + "/encrypt/";
|
||||
public static final String TRANSIT_DECRYPT = TRANSIT + "/decrypt/";
|
||||
public static final String TRANSIT_HASH = TRANSIT + "/hash/";
|
||||
|
||||
/**
|
||||
* Private constructor to prevent instantiation.
|
||||
*/
|
||||
private VaultApiPath() {
|
||||
// Utility class
|
||||
}
|
||||
}
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016-2024 Stefan Kalscheuer
|
||||
* Copyright 2016-2025 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 java.util.Objects;
|
||||
*/
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public final class AppRole implements Serializable {
|
||||
private static final long serialVersionUID = 693228837510483448L;
|
||||
private static final long serialVersionUID = 1546673231280751679L;
|
||||
|
||||
@JsonProperty("role_name")
|
||||
private String name;
|
||||
@@ -53,7 +53,7 @@ public final class AppRole implements Serializable {
|
||||
|
||||
@JsonProperty("secret_id_ttl")
|
||||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||
private Integer secretIdTtl;
|
||||
private Long secretIdTtl;
|
||||
|
||||
@JsonProperty("local_secret_ids")
|
||||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||
@@ -61,11 +61,11 @@ public final class AppRole implements Serializable {
|
||||
|
||||
@JsonProperty("token_ttl")
|
||||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||
private Integer tokenTtl;
|
||||
private Long tokenTtl;
|
||||
|
||||
@JsonProperty("token_max_ttl")
|
||||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||
private Integer tokenMaxTtl;
|
||||
private Long tokenMaxTtl;
|
||||
|
||||
private List<String> tokenPolicies;
|
||||
|
||||
@@ -75,7 +75,7 @@ public final class AppRole implements Serializable {
|
||||
|
||||
@JsonProperty("token_explicit_max_ttl")
|
||||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||
private Integer tokenExplicitMaxTtl;
|
||||
private Long tokenExplicitMaxTtl;
|
||||
|
||||
@JsonProperty("token_no_default_policy")
|
||||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||
@@ -255,7 +255,7 @@ public final class AppRole implements Serializable {
|
||||
/**
|
||||
* @return maximum TTL in seconds for secrets
|
||||
*/
|
||||
public Integer getSecretIdTtl() {
|
||||
public Long getSecretIdTtl() {
|
||||
return secretIdTtl;
|
||||
}
|
||||
|
||||
@@ -271,14 +271,14 @@ public final class AppRole implements Serializable {
|
||||
/**
|
||||
* @return token TTL in seconds
|
||||
*/
|
||||
public Integer getTokenTtl() {
|
||||
public Long getTokenTtl() {
|
||||
return tokenTtl;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return maximum token TTL in seconds, including renewals
|
||||
*/
|
||||
public Integer getTokenMaxTtl() {
|
||||
public Long getTokenMaxTtl() {
|
||||
return tokenMaxTtl;
|
||||
}
|
||||
|
||||
@@ -286,7 +286,7 @@ public final class AppRole implements Serializable {
|
||||
* @return explicit maximum token TTL in seconds, including renewals
|
||||
* @since 0.9
|
||||
*/
|
||||
public Integer getTokenExplicitMaxTtl() {
|
||||
public Long getTokenExplicitMaxTtl() {
|
||||
return tokenExplicitMaxTtl;
|
||||
}
|
||||
|
||||
@@ -331,28 +331,28 @@ public final class AppRole implements Serializable {
|
||||
}
|
||||
AppRole appRole = (AppRole) o;
|
||||
return Objects.equals(name, appRole.name) &&
|
||||
Objects.equals(id, appRole.id) &&
|
||||
Objects.equals(bindSecretId, appRole.bindSecretId) &&
|
||||
Objects.equals(secretIdBoundCidrs, appRole.secretIdBoundCidrs) &&
|
||||
Objects.equals(secretIdNumUses, appRole.secretIdNumUses) &&
|
||||
Objects.equals(secretIdTtl, appRole.secretIdTtl) &&
|
||||
Objects.equals(localSecretIds, appRole.localSecretIds) &&
|
||||
Objects.equals(tokenTtl, appRole.tokenTtl) &&
|
||||
Objects.equals(tokenMaxTtl, appRole.tokenMaxTtl) &&
|
||||
Objects.equals(tokenPolicies, appRole.tokenPolicies) &&
|
||||
Objects.equals(tokenBoundCidrs, appRole.tokenBoundCidrs) &&
|
||||
Objects.equals(tokenExplicitMaxTtl, appRole.tokenExplicitMaxTtl) &&
|
||||
Objects.equals(tokenNoDefaultPolicy, appRole.tokenNoDefaultPolicy) &&
|
||||
Objects.equals(tokenNumUses, appRole.tokenNumUses) &&
|
||||
Objects.equals(tokenPeriod, appRole.tokenPeriod) &&
|
||||
Objects.equals(tokenType, appRole.tokenType);
|
||||
Objects.equals(id, appRole.id) &&
|
||||
Objects.equals(bindSecretId, appRole.bindSecretId) &&
|
||||
Objects.equals(secretIdBoundCidrs, appRole.secretIdBoundCidrs) &&
|
||||
Objects.equals(secretIdNumUses, appRole.secretIdNumUses) &&
|
||||
Objects.equals(secretIdTtl, appRole.secretIdTtl) &&
|
||||
Objects.equals(localSecretIds, appRole.localSecretIds) &&
|
||||
Objects.equals(tokenTtl, appRole.tokenTtl) &&
|
||||
Objects.equals(tokenMaxTtl, appRole.tokenMaxTtl) &&
|
||||
Objects.equals(tokenPolicies, appRole.tokenPolicies) &&
|
||||
Objects.equals(tokenBoundCidrs, appRole.tokenBoundCidrs) &&
|
||||
Objects.equals(tokenExplicitMaxTtl, appRole.tokenExplicitMaxTtl) &&
|
||||
Objects.equals(tokenNoDefaultPolicy, appRole.tokenNoDefaultPolicy) &&
|
||||
Objects.equals(tokenNumUses, appRole.tokenNumUses) &&
|
||||
Objects.equals(tokenPeriod, appRole.tokenPeriod) &&
|
||||
Objects.equals(tokenType, appRole.tokenType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(name, id, bindSecretId, secretIdBoundCidrs, secretIdNumUses, secretIdTtl,
|
||||
localSecretIds, tokenTtl, tokenMaxTtl, tokenPolicies, tokenBoundCidrs, tokenExplicitMaxTtl,
|
||||
tokenNoDefaultPolicy, tokenNumUses, tokenPeriod, tokenType);
|
||||
localSecretIds, tokenTtl, tokenMaxTtl, tokenPolicies, tokenBoundCidrs, tokenExplicitMaxTtl,
|
||||
tokenNoDefaultPolicy, tokenNumUses, tokenPeriod, tokenType);
|
||||
}
|
||||
|
||||
|
||||
@@ -370,12 +370,12 @@ public final class AppRole implements Serializable {
|
||||
private List<String> secretIdBoundCidrs;
|
||||
private List<String> tokenPolicies;
|
||||
private Integer secretIdNumUses;
|
||||
private Integer secretIdTtl;
|
||||
private Long secretIdTtl;
|
||||
private Boolean localSecretIds;
|
||||
private Integer tokenTtl;
|
||||
private Integer tokenMaxTtl;
|
||||
private Long tokenTtl;
|
||||
private Long tokenMaxTtl;
|
||||
private List<String> tokenBoundCidrs;
|
||||
private Integer tokenExplicitMaxTtl;
|
||||
private Long tokenExplicitMaxTtl;
|
||||
private Boolean tokenNoDefaultPolicy;
|
||||
private Integer tokenNumUses;
|
||||
private Integer tokenPeriod;
|
||||
@@ -520,7 +520,7 @@ public final class AppRole implements Serializable {
|
||||
* @param secretIdTtl the TTL
|
||||
* @return self
|
||||
*/
|
||||
public Builder withSecretIdTtl(final Integer secretIdTtl) {
|
||||
public Builder withSecretIdTtl(final Long secretIdTtl) {
|
||||
this.secretIdTtl = secretIdTtl;
|
||||
return this;
|
||||
}
|
||||
@@ -544,7 +544,7 @@ public final class AppRole implements Serializable {
|
||||
* @param tokenTtl the TTL
|
||||
* @return self
|
||||
*/
|
||||
public Builder withTokenTtl(final Integer tokenTtl) {
|
||||
public Builder withTokenTtl(final Long tokenTtl) {
|
||||
this.tokenTtl = tokenTtl;
|
||||
return this;
|
||||
}
|
||||
@@ -555,7 +555,7 @@ public final class AppRole implements Serializable {
|
||||
* @param tokenMaxTtl the TTL
|
||||
* @return self
|
||||
*/
|
||||
public Builder withTokenMaxTtl(final Integer tokenMaxTtl) {
|
||||
public Builder withTokenMaxTtl(final Long tokenMaxTtl) {
|
||||
this.tokenMaxTtl = tokenMaxTtl;
|
||||
return this;
|
||||
}
|
||||
@@ -596,7 +596,7 @@ public final class AppRole implements Serializable {
|
||||
* @param tokenExplicitMaxTtl the TTL
|
||||
* @return self
|
||||
*/
|
||||
public Builder withTokenExplicitMaxTtl(final Integer tokenExplicitMaxTtl) {
|
||||
public Builder withTokenExplicitMaxTtl(final Long tokenExplicitMaxTtl) {
|
||||
this.tokenExplicitMaxTtl = tokenExplicitMaxTtl;
|
||||
return this;
|
||||
}
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016-2024 Stefan Kalscheuer
|
||||
* Copyright 2016-2025 Stefan Kalscheuer
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -181,19 +181,19 @@ public final class AppRoleSecret implements Serializable {
|
||||
}
|
||||
AppRoleSecret that = (AppRoleSecret) o;
|
||||
return Objects.equals(id, that.id) &&
|
||||
Objects.equals(accessor, that.accessor) &&
|
||||
Objects.equals(metadata, that.metadata) &&
|
||||
Objects.equals(cidrList, that.cidrList) &&
|
||||
Objects.equals(creationTime, that.creationTime) &&
|
||||
Objects.equals(expirationTime, that.expirationTime) &&
|
||||
Objects.equals(lastUpdatedTime, that.lastUpdatedTime) &&
|
||||
Objects.equals(numUses, that.numUses) &&
|
||||
Objects.equals(ttl, that.ttl);
|
||||
Objects.equals(accessor, that.accessor) &&
|
||||
Objects.equals(metadata, that.metadata) &&
|
||||
Objects.equals(cidrList, that.cidrList) &&
|
||||
Objects.equals(creationTime, that.creationTime) &&
|
||||
Objects.equals(expirationTime, that.expirationTime) &&
|
||||
Objects.equals(lastUpdatedTime, that.lastUpdatedTime) &&
|
||||
Objects.equals(numUses, that.numUses) &&
|
||||
Objects.equals(ttl, that.ttl);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(id, accessor, metadata, cidrList, creationTime, expirationTime, lastUpdatedTime, numUses,
|
||||
ttl);
|
||||
ttl);
|
||||
}
|
||||
}
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016-2024 Stefan Kalscheuer
|
||||
* Copyright 2016-2025 Stefan Kalscheuer
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -24,8 +24,6 @@ package de.stklcode.jvault.connector.model;
|
||||
*/
|
||||
public enum AuthBackend {
|
||||
TOKEN("token"),
|
||||
@Deprecated(since = "1.1.3", forRemoval = true)
|
||||
APPID("app-id"),
|
||||
APPROLE("approle"),
|
||||
USERPASS("userpass"),
|
||||
GITHUB("github"), // Not supported yet.
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016-2024 Stefan Kalscheuer
|
||||
* Copyright 2016-2025 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 java.util.*;
|
||||
*/
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public final class Token implements Serializable {
|
||||
private static final long serialVersionUID = 5208508683665365287L;
|
||||
private static final long serialVersionUID = 7003016071684507115L;
|
||||
|
||||
@JsonProperty("id")
|
||||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||
@@ -56,11 +56,11 @@ public final class Token implements Serializable {
|
||||
|
||||
@JsonProperty("ttl")
|
||||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||
private Integer ttl;
|
||||
private Long ttl;
|
||||
|
||||
@JsonProperty("explicit_max_ttl")
|
||||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||
private Integer explicitMaxTtl;
|
||||
private Long explicitMaxTtl;
|
||||
|
||||
@JsonProperty("num_uses")
|
||||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||
@@ -162,7 +162,7 @@ public final class Token implements Serializable {
|
||||
/**
|
||||
* @return Time-to-live in seconds
|
||||
*/
|
||||
public Integer getTtl() {
|
||||
public Long getTtl() {
|
||||
return ttl;
|
||||
}
|
||||
|
||||
@@ -170,7 +170,7 @@ public final class Token implements Serializable {
|
||||
* @return Explicit maximum time-to-live in seconds
|
||||
* @since 0.9
|
||||
*/
|
||||
public Integer getExplicitMaxTtl() {
|
||||
public Long getExplicitMaxTtl() {
|
||||
return explicitMaxTtl;
|
||||
}
|
||||
|
||||
@@ -227,24 +227,24 @@ public final class Token implements Serializable {
|
||||
}
|
||||
Token token = (Token) o;
|
||||
return Objects.equals(id, token.id) &&
|
||||
Objects.equals(type, token.type) &&
|
||||
Objects.equals(displayName, token.displayName) &&
|
||||
Objects.equals(noParent, token.noParent) &&
|
||||
Objects.equals(noDefaultPolicy, token.noDefaultPolicy) &&
|
||||
Objects.equals(ttl, token.ttl) &&
|
||||
Objects.equals(explicitMaxTtl, token.explicitMaxTtl) &&
|
||||
Objects.equals(numUses, token.numUses) &&
|
||||
Objects.equals(policies, token.policies) &&
|
||||
Objects.equals(meta, token.meta) &&
|
||||
Objects.equals(renewable, token.renewable) &&
|
||||
Objects.equals(period, token.period) &&
|
||||
Objects.equals(entityAlias, token.entityAlias);
|
||||
Objects.equals(type, token.type) &&
|
||||
Objects.equals(displayName, token.displayName) &&
|
||||
Objects.equals(noParent, token.noParent) &&
|
||||
Objects.equals(noDefaultPolicy, token.noDefaultPolicy) &&
|
||||
Objects.equals(ttl, token.ttl) &&
|
||||
Objects.equals(explicitMaxTtl, token.explicitMaxTtl) &&
|
||||
Objects.equals(numUses, token.numUses) &&
|
||||
Objects.equals(policies, token.policies) &&
|
||||
Objects.equals(meta, token.meta) &&
|
||||
Objects.equals(renewable, token.renewable) &&
|
||||
Objects.equals(period, token.period) &&
|
||||
Objects.equals(entityAlias, token.entityAlias);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(id, type, displayName, noParent, noDefaultPolicy, ttl, explicitMaxTtl, numUses, policies,
|
||||
meta, renewable, period, entityAlias);
|
||||
meta, renewable, period, entityAlias);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -282,8 +282,8 @@ public final class Token implements Serializable {
|
||||
private String displayName;
|
||||
private Boolean noParent;
|
||||
private Boolean noDefaultPolicy;
|
||||
private Integer ttl;
|
||||
private Integer explicitMaxTtl;
|
||||
private Long ttl;
|
||||
private Long explicitMaxTtl;
|
||||
private Integer numUses;
|
||||
private List<String> policies;
|
||||
private Map<String, String> meta;
|
||||
@@ -331,7 +331,7 @@ public final class Token implements Serializable {
|
||||
* @param ttl the ttl
|
||||
* @return self
|
||||
*/
|
||||
public Builder withTtl(final Integer ttl) {
|
||||
public Builder withTtl(final Long ttl) {
|
||||
this.ttl = ttl;
|
||||
return this;
|
||||
}
|
||||
@@ -342,7 +342,7 @@ public final class Token implements Serializable {
|
||||
* @param explicitMaxTtl the explicit max. TTL
|
||||
* @return self
|
||||
*/
|
||||
public Builder withExplicitMaxTtl(final Integer explicitMaxTtl) {
|
||||
public Builder withExplicitMaxTtl(final Long explicitMaxTtl) {
|
||||
this.explicitMaxTtl = explicitMaxTtl;
|
||||
return this;
|
||||
}
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016-2024 Stefan Kalscheuer
|
||||
* Copyright 2016-2025 Stefan Kalscheuer
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -34,7 +34,7 @@ import java.util.Objects;
|
||||
*/
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public final class TokenRole implements Serializable {
|
||||
private static final long serialVersionUID = -3505215215838576321L;
|
||||
private static final long serialVersionUID = -4856948364869438439L;
|
||||
|
||||
@JsonProperty("name")
|
||||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||
@@ -78,7 +78,7 @@ public final class TokenRole implements Serializable {
|
||||
|
||||
@JsonProperty("token_explicit_max_ttl")
|
||||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||
private Integer tokenExplicitMaxTtl;
|
||||
private Long tokenExplicitMaxTtl;
|
||||
|
||||
@JsonProperty("token_no_default_policy")
|
||||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||
@@ -204,7 +204,7 @@ public final class TokenRole implements Serializable {
|
||||
/**
|
||||
* @return Token explicit maximum TTL
|
||||
*/
|
||||
public Integer getTokenExplicitMaxTtl() {
|
||||
public Long getTokenExplicitMaxTtl() {
|
||||
return tokenExplicitMaxTtl;
|
||||
}
|
||||
|
||||
@@ -245,27 +245,27 @@ public final class TokenRole implements Serializable {
|
||||
}
|
||||
TokenRole tokenRole = (TokenRole) o;
|
||||
return Objects.equals(name, tokenRole.name) &&
|
||||
Objects.equals(allowedPolicies, tokenRole.allowedPolicies) &&
|
||||
Objects.equals(allowedPoliciesGlob, tokenRole.allowedPoliciesGlob) &&
|
||||
Objects.equals(disallowedPolicies, tokenRole.disallowedPolicies) &&
|
||||
Objects.equals(disallowedPoliciesGlob, tokenRole.disallowedPoliciesGlob) &&
|
||||
Objects.equals(orphan, tokenRole.orphan) &&
|
||||
Objects.equals(renewable, tokenRole.renewable) &&
|
||||
Objects.equals(pathSuffix, tokenRole.pathSuffix) &&
|
||||
Objects.equals(allowedEntityAliases, tokenRole.allowedEntityAliases) &&
|
||||
Objects.equals(tokenBoundCidrs, tokenRole.tokenBoundCidrs) &&
|
||||
Objects.equals(tokenExplicitMaxTtl, tokenRole.tokenExplicitMaxTtl) &&
|
||||
Objects.equals(tokenNoDefaultPolicy, tokenRole.tokenNoDefaultPolicy) &&
|
||||
Objects.equals(tokenNumUses, tokenRole.tokenNumUses) &&
|
||||
Objects.equals(tokenPeriod, tokenRole.tokenPeriod) &&
|
||||
Objects.equals(tokenType, tokenRole.tokenType);
|
||||
Objects.equals(allowedPolicies, tokenRole.allowedPolicies) &&
|
||||
Objects.equals(allowedPoliciesGlob, tokenRole.allowedPoliciesGlob) &&
|
||||
Objects.equals(disallowedPolicies, tokenRole.disallowedPolicies) &&
|
||||
Objects.equals(disallowedPoliciesGlob, tokenRole.disallowedPoliciesGlob) &&
|
||||
Objects.equals(orphan, tokenRole.orphan) &&
|
||||
Objects.equals(renewable, tokenRole.renewable) &&
|
||||
Objects.equals(pathSuffix, tokenRole.pathSuffix) &&
|
||||
Objects.equals(allowedEntityAliases, tokenRole.allowedEntityAliases) &&
|
||||
Objects.equals(tokenBoundCidrs, tokenRole.tokenBoundCidrs) &&
|
||||
Objects.equals(tokenExplicitMaxTtl, tokenRole.tokenExplicitMaxTtl) &&
|
||||
Objects.equals(tokenNoDefaultPolicy, tokenRole.tokenNoDefaultPolicy) &&
|
||||
Objects.equals(tokenNumUses, tokenRole.tokenNumUses) &&
|
||||
Objects.equals(tokenPeriod, tokenRole.tokenPeriod) &&
|
||||
Objects.equals(tokenType, tokenRole.tokenType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(name, allowedPolicies, allowedPoliciesGlob, disallowedPolicies, disallowedPoliciesGlob,
|
||||
orphan, renewable, pathSuffix, allowedEntityAliases, tokenBoundCidrs, tokenExplicitMaxTtl,
|
||||
tokenNoDefaultPolicy, tokenNumUses, tokenPeriod, tokenType);
|
||||
orphan, renewable, pathSuffix, allowedEntityAliases, tokenBoundCidrs, tokenExplicitMaxTtl,
|
||||
tokenNoDefaultPolicy, tokenNumUses, tokenPeriod, tokenType);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -285,7 +285,7 @@ public final class TokenRole implements Serializable {
|
||||
private String pathSuffix;
|
||||
private List<String> allowedEntityAliases;
|
||||
private List<String> tokenBoundCidrs;
|
||||
private Integer tokenExplicitMaxTtl;
|
||||
private Long tokenExplicitMaxTtl;
|
||||
private Boolean tokenNoDefaultPolicy;
|
||||
private Integer tokenNumUses;
|
||||
private Integer tokenPeriod;
|
||||
@@ -537,7 +537,7 @@ public final class TokenRole implements Serializable {
|
||||
* @param tokenExplicitMaxTtl explicit maximum TTL
|
||||
* @return self
|
||||
*/
|
||||
public Builder withTokenExplicitMaxTtl(final Integer tokenExplicitMaxTtl) {
|
||||
public Builder withTokenExplicitMaxTtl(final Long tokenExplicitMaxTtl) {
|
||||
this.tokenExplicitMaxTtl = tokenExplicitMaxTtl;
|
||||
return this;
|
||||
}
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016-2024 Stefan Kalscheuer
|
||||
* Copyright 2016-2025 Stefan Kalscheuer
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016-2024 Stefan Kalscheuer
|
||||
* Copyright 2016-2025 Stefan Kalscheuer
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016-2024 Stefan Kalscheuer
|
||||
* Copyright 2016-2025 Stefan Kalscheuer
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016-2024 Stefan Kalscheuer
|
||||
* Copyright 2016-2025 Stefan Kalscheuer
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016-2024 Stefan Kalscheuer
|
||||
* Copyright 2016-2025 Stefan Kalscheuer
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016-2024 Stefan Kalscheuer
|
||||
* Copyright 2016-2025 Stefan Kalscheuer
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016-2024 Stefan Kalscheuer
|
||||
* Copyright 2016-2025 Stefan Kalscheuer
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016-2024 Stefan Kalscheuer
|
||||
* Copyright 2016-2025 Stefan Kalscheuer
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -187,19 +187,19 @@ public final class HealthResponse implements VaultResponse {
|
||||
}
|
||||
HealthResponse that = (HealthResponse) o;
|
||||
return Objects.equals(clusterID, that.clusterID) &&
|
||||
Objects.equals(clusterName, that.clusterName) &&
|
||||
Objects.equals(version, that.version) &&
|
||||
Objects.equals(serverTimeUTC, that.serverTimeUTC) &&
|
||||
Objects.equals(standby, that.standby) &&
|
||||
Objects.equals(sealed, that.sealed) &&
|
||||
Objects.equals(initialized, that.initialized) &&
|
||||
Objects.equals(replicationPerfMode, that.replicationPerfMode) &&
|
||||
Objects.equals(replicationDrMode, that.replicationDrMode) &&
|
||||
Objects.equals(performanceStandby, that.performanceStandby) &&
|
||||
Objects.equals(echoDurationMs, that.echoDurationMs) &&
|
||||
Objects.equals(clockSkewMs, that.clockSkewMs) &&
|
||||
Objects.equals(replicationPrimaryCanaryAgeMs, that.replicationPrimaryCanaryAgeMs) &&
|
||||
Objects.equals(enterprise, that.enterprise);
|
||||
Objects.equals(clusterName, that.clusterName) &&
|
||||
Objects.equals(version, that.version) &&
|
||||
Objects.equals(serverTimeUTC, that.serverTimeUTC) &&
|
||||
Objects.equals(standby, that.standby) &&
|
||||
Objects.equals(sealed, that.sealed) &&
|
||||
Objects.equals(initialized, that.initialized) &&
|
||||
Objects.equals(replicationPerfMode, that.replicationPerfMode) &&
|
||||
Objects.equals(replicationDrMode, that.replicationDrMode) &&
|
||||
Objects.equals(performanceStandby, that.performanceStandby) &&
|
||||
Objects.equals(echoDurationMs, that.echoDurationMs) &&
|
||||
Objects.equals(clockSkewMs, that.clockSkewMs) &&
|
||||
Objects.equals(replicationPrimaryCanaryAgeMs, that.replicationPrimaryCanaryAgeMs) &&
|
||||
Objects.equals(enterprise, that.enterprise);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016-2024 Stefan Kalscheuer
|
||||
* Copyright 2016-2025 Stefan Kalscheuer
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016-2021 Stefan Kalscheuer
|
||||
* Copyright 2016-2025 Stefan Kalscheuer
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016-2024 Stefan Kalscheuer
|
||||
* Copyright 2016-2025 Stefan Kalscheuer
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016-2021 Stefan Kalscheuer
|
||||
* Copyright 2016-2025 Stefan Kalscheuer
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016-2024 Stefan Kalscheuer
|
||||
* Copyright 2016-2025 Stefan Kalscheuer
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016-2024 Stefan Kalscheuer
|
||||
* Copyright 2016-2025 Stefan Kalscheuer
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -191,24 +191,24 @@ public final class SealResponse implements VaultResponse {
|
||||
}
|
||||
SealResponse that = (SealResponse) o;
|
||||
return sealed == that.sealed &&
|
||||
initialized == that.initialized &&
|
||||
Objects.equals(type, that.type) &&
|
||||
Objects.equals(threshold, that.threshold) &&
|
||||
Objects.equals(numberOfShares, that.numberOfShares) &&
|
||||
Objects.equals(progress, that.progress) &&
|
||||
Objects.equals(version, that.version) &&
|
||||
Objects.equals(buildDate, that.buildDate) &&
|
||||
Objects.equals(nonce, that.nonce) &&
|
||||
Objects.equals(clusterName, that.clusterName) &&
|
||||
Objects.equals(clusterId, that.clusterId) &&
|
||||
Objects.equals(migration, that.migration) &&
|
||||
Objects.equals(recoverySeal, that.recoverySeal) &&
|
||||
Objects.equals(storageType, that.storageType);
|
||||
initialized == that.initialized &&
|
||||
Objects.equals(type, that.type) &&
|
||||
Objects.equals(threshold, that.threshold) &&
|
||||
Objects.equals(numberOfShares, that.numberOfShares) &&
|
||||
Objects.equals(progress, that.progress) &&
|
||||
Objects.equals(version, that.version) &&
|
||||
Objects.equals(buildDate, that.buildDate) &&
|
||||
Objects.equals(nonce, that.nonce) &&
|
||||
Objects.equals(clusterName, that.clusterName) &&
|
||||
Objects.equals(clusterId, that.clusterId) &&
|
||||
Objects.equals(migration, that.migration) &&
|
||||
Objects.equals(recoverySeal, that.recoverySeal) &&
|
||||
Objects.equals(storageType, that.storageType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(type, sealed, initialized, threshold, numberOfShares, progress, version, buildDate, nonce,
|
||||
clusterName, clusterId, migration, recoverySeal, storageType);
|
||||
clusterName, clusterId, migration, recoverySeal, storageType);
|
||||
}
|
||||
}
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016-2024 Stefan Kalscheuer
|
||||
* Copyright 2016-2025 Stefan Kalscheuer
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016-2024 Stefan Kalscheuer
|
||||
* Copyright 2016-2025 Stefan Kalscheuer
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -18,8 +18,8 @@ package de.stklcode.jvault.connector.model.response;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.databind.DeserializationFeature;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.SerializationFeature;
|
||||
import com.fasterxml.jackson.databind.json.JsonMapper;
|
||||
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
|
||||
import de.stklcode.jvault.connector.exception.InvalidResponseException;
|
||||
import de.stklcode.jvault.connector.model.response.embedded.VersionMetadata;
|
||||
@@ -85,10 +85,11 @@ public abstract class SecretResponse extends VaultDataResponse {
|
||||
} else if (type.isInstance(rawValue)) {
|
||||
return type.cast(rawValue);
|
||||
} else {
|
||||
var om = new ObjectMapper()
|
||||
.registerModule(new JavaTimeModule())
|
||||
.enable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
|
||||
.disable(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE);
|
||||
var om = JsonMapper.builder()
|
||||
.addModule(new JavaTimeModule())
|
||||
.enable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
|
||||
.disable(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE)
|
||||
.build();
|
||||
|
||||
if (rawValue instanceof String) {
|
||||
return om.readValue((String) rawValue, type);
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016-2024 Stefan Kalscheuer
|
||||
* Copyright 2016-2025 Stefan Kalscheuer
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016-2024 Stefan Kalscheuer
|
||||
* Copyright 2016-2025 Stefan Kalscheuer
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016-2024 Stefan Kalscheuer
|
||||
* Copyright 2016-2025 Stefan Kalscheuer
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* Copyright 2016-2025 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.model.response;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonSetter;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Response entity for transit operations.
|
||||
*
|
||||
* @author Stefan Kalscheuer
|
||||
* @since 1.5.0
|
||||
*/
|
||||
public class TransitResponse extends VaultDataResponse {
|
||||
|
||||
private static final long serialVersionUID = 6873804240772242771L;
|
||||
|
||||
private String ciphertext;
|
||||
private String plaintext;
|
||||
private String sum;
|
||||
|
||||
@JsonSetter("data")
|
||||
private void setData(Map<String, String> data) {
|
||||
ciphertext = data.get("ciphertext");
|
||||
plaintext = data.get("plaintext");
|
||||
sum = data.get("sum");
|
||||
}
|
||||
|
||||
/**
|
||||
* Get ciphertext.
|
||||
* Populated after encryption.
|
||||
*
|
||||
* @return Ciphertext
|
||||
*/
|
||||
public String getCiphertext() {
|
||||
return ciphertext;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get plaintext.
|
||||
* Base64 encoded, populated after decryption.
|
||||
*
|
||||
* @return Plaintext
|
||||
*/
|
||||
public String getPlaintext() {
|
||||
return plaintext;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get hash sum.
|
||||
* Hex or Base64 string. Populated after hashing.
|
||||
*
|
||||
* @return Hash sum
|
||||
*/
|
||||
public String getSum() {
|
||||
return sum;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
} else if (o == null || getClass() != o.getClass() || !super.equals(o)) {
|
||||
return false;
|
||||
}
|
||||
TransitResponse that = (TransitResponse) o;
|
||||
return Objects.equals(ciphertext, that.ciphertext) &&
|
||||
Objects.equals(plaintext, that.plaintext) &&
|
||||
Objects.equals(sum, that.sum);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(super.hashCode(), ciphertext, plaintext, sum);
|
||||
}
|
||||
}
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016-2024 Stefan Kalscheuer
|
||||
* Copyright 2016-2025 Stefan Kalscheuer
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -115,6 +115,7 @@ public abstract class VaultDataResponse implements VaultResponse {
|
||||
public final String getMountType() {
|
||||
return mountType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
@@ -124,13 +125,13 @@ public abstract class VaultDataResponse implements VaultResponse {
|
||||
}
|
||||
VaultDataResponse that = (VaultDataResponse) o;
|
||||
return renewable == that.renewable &&
|
||||
Objects.equals(requestId, that.requestId) &&
|
||||
Objects.equals(leaseId, that.leaseId) &&
|
||||
Objects.equals(leaseDuration, that.leaseDuration) &&
|
||||
Objects.equals(warnings, that.warnings) &&
|
||||
Objects.equals(wrapInfo, that.wrapInfo) &&
|
||||
Objects.equals(auth, that.auth) &&
|
||||
Objects.equals(mountType, that.mountType);
|
||||
Objects.equals(requestId, that.requestId) &&
|
||||
Objects.equals(leaseId, that.leaseId) &&
|
||||
Objects.equals(leaseDuration, that.leaseDuration) &&
|
||||
Objects.equals(warnings, that.warnings) &&
|
||||
Objects.equals(wrapInfo, that.wrapInfo) &&
|
||||
Objects.equals(auth, that.auth) &&
|
||||
Objects.equals(mountType, that.mountType);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016-2024 Stefan Kalscheuer
|
||||
* Copyright 2016-2025 Stefan Kalscheuer
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016-2024 Stefan Kalscheuer
|
||||
* Copyright 2016-2025 Stefan Kalscheuer
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -171,22 +171,22 @@ public final class AuthData implements Serializable {
|
||||
}
|
||||
AuthData authData = (AuthData) o;
|
||||
return renewable == authData.renewable &&
|
||||
orphan == authData.orphan &&
|
||||
Objects.equals(clientToken, authData.clientToken) &&
|
||||
Objects.equals(accessor, authData.accessor) &&
|
||||
Objects.equals(policies, authData.policies) &&
|
||||
Objects.equals(tokenPolicies, authData.tokenPolicies) &&
|
||||
Objects.equals(metadata, authData.metadata) &&
|
||||
Objects.equals(leaseDuration, authData.leaseDuration) &&
|
||||
Objects.equals(entityId, authData.entityId) &&
|
||||
Objects.equals(tokenType, authData.tokenType) &&
|
||||
Objects.equals(numUses, authData.numUses) &&
|
||||
Objects.equals(mfaRequirement, authData.mfaRequirement);
|
||||
orphan == authData.orphan &&
|
||||
Objects.equals(clientToken, authData.clientToken) &&
|
||||
Objects.equals(accessor, authData.accessor) &&
|
||||
Objects.equals(policies, authData.policies) &&
|
||||
Objects.equals(tokenPolicies, authData.tokenPolicies) &&
|
||||
Objects.equals(metadata, authData.metadata) &&
|
||||
Objects.equals(leaseDuration, authData.leaseDuration) &&
|
||||
Objects.equals(entityId, authData.entityId) &&
|
||||
Objects.equals(tokenType, authData.tokenType) &&
|
||||
Objects.equals(numUses, authData.numUses) &&
|
||||
Objects.equals(mfaRequirement, authData.mfaRequirement);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(clientToken, accessor, policies, tokenPolicies, metadata, leaseDuration, renewable,
|
||||
entityId, tokenType, orphan, numUses, mfaRequirement);
|
||||
entityId, tokenType, orphan, numUses, mfaRequirement);
|
||||
}
|
||||
}
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016-2024 Stefan Kalscheuer
|
||||
* Copyright 2016-2025 Stefan Kalscheuer
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -202,19 +202,19 @@ public final class AuthMethod implements Serializable {
|
||||
}
|
||||
AuthMethod that = (AuthMethod) o;
|
||||
return local == that.local &&
|
||||
type == that.type &&
|
||||
externalEntropyAccess == that.externalEntropyAccess &&
|
||||
sealWrap == that.sealWrap &&
|
||||
Objects.equals(rawType, that.rawType) &&
|
||||
Objects.equals(accessor, that.accessor) &&
|
||||
Objects.equals(deprecationStatus, that.deprecationStatus) &&
|
||||
Objects.equals(description, that.description) &&
|
||||
Objects.equals(config, that.config) &&
|
||||
Objects.equals(options, that.options) &&
|
||||
Objects.equals(pluginVersion, that.pluginVersion) &&
|
||||
Objects.equals(runningPluginVersion, that.runningPluginVersion) &&
|
||||
Objects.equals(runningSha256, that.runningSha256) &&
|
||||
Objects.equals(uuid, that.uuid);
|
||||
type == that.type &&
|
||||
externalEntropyAccess == that.externalEntropyAccess &&
|
||||
sealWrap == that.sealWrap &&
|
||||
Objects.equals(rawType, that.rawType) &&
|
||||
Objects.equals(accessor, that.accessor) &&
|
||||
Objects.equals(deprecationStatus, that.deprecationStatus) &&
|
||||
Objects.equals(description, that.description) &&
|
||||
Objects.equals(config, that.config) &&
|
||||
Objects.equals(options, that.options) &&
|
||||
Objects.equals(pluginVersion, that.pluginVersion) &&
|
||||
Objects.equals(runningPluginVersion, that.runningPluginVersion) &&
|
||||
Objects.equals(runningSha256, that.runningSha256) &&
|
||||
Objects.equals(uuid, that.uuid);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016-2024 Stefan Kalscheuer
|
||||
* Copyright 2016-2025 Stefan Kalscheuer
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016-2024 Stefan Kalscheuer
|
||||
* Copyright 2016-2025 Stefan Kalscheuer
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016-2024 Stefan Kalscheuer
|
||||
* Copyright 2016-2025 Stefan Kalscheuer
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@@ -15,13 +15,13 @@ import java.util.Objects;
|
||||
*/
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class MountConfig implements Serializable {
|
||||
private static final long serialVersionUID = -8653909672663717792L;
|
||||
private static final long serialVersionUID = 7241631159224756605L;
|
||||
|
||||
@JsonProperty("default_lease_ttl")
|
||||
private Integer defaultLeaseTtl;
|
||||
private Long defaultLeaseTtl;
|
||||
|
||||
@JsonProperty("max_lease_ttl")
|
||||
private Integer maxLeaseTtl;
|
||||
private Long maxLeaseTtl;
|
||||
|
||||
@JsonProperty("force_no_cache")
|
||||
private Boolean forceNoCache;
|
||||
@@ -56,14 +56,14 @@ public class MountConfig implements Serializable {
|
||||
/**
|
||||
* @return Default lease TTL
|
||||
*/
|
||||
public Integer getDefaultLeaseTtl() {
|
||||
public Long getDefaultLeaseTtl() {
|
||||
return defaultLeaseTtl;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Maximum lease TTL
|
||||
*/
|
||||
public Integer getMaxLeaseTtl() {
|
||||
public Long getMaxLeaseTtl() {
|
||||
return maxLeaseTtl;
|
||||
}
|
||||
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016-2024 Stefan Kalscheuer
|
||||
* Copyright 2016-2025 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,7 +21,6 @@ import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
@@ -37,9 +36,6 @@ import java.util.Objects;
|
||||
public final class SecretMetadata implements Serializable {
|
||||
private static final long serialVersionUID = -905059942871916214L;
|
||||
|
||||
private static final DateTimeFormatter TIME_FORMAT =
|
||||
DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSSSSSSSXXX");
|
||||
|
||||
@JsonProperty("created_time")
|
||||
private ZonedDateTime createdTime;
|
||||
|
||||
@@ -67,19 +63,6 @@ public final class SecretMetadata implements Serializable {
|
||||
@JsonProperty("delete_version_after")
|
||||
private String deleteVersionAfter;
|
||||
|
||||
/**
|
||||
* @return Time of secret creation as raw string representation.
|
||||
* @deprecated Method left for backwards compatibility only. Use {@link #getCreatedTime()} instead.
|
||||
*/
|
||||
@Deprecated(since = "1.2", forRemoval = true)
|
||||
public String getCreatedTimeString() {
|
||||
if (createdTime != null) {
|
||||
return TIME_FORMAT.format(createdTime);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Time of secret creation.
|
||||
*/
|
||||
@@ -108,19 +91,6 @@ public final class SecretMetadata implements Serializable {
|
||||
return oldestVersion;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Time of secret update as raw string representation.
|
||||
* @deprecated Method left for backwards compatibility only. Use {@link #getUpdatedTime()} instead.
|
||||
*/
|
||||
@Deprecated(since = "1.2", forRemoval = true)
|
||||
public String getUpdatedTimeString() {
|
||||
if (updatedTime != null) {
|
||||
return TIME_FORMAT.format(updatedTime);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Time of secret update.
|
||||
*/
|
||||
@@ -168,14 +138,14 @@ public final class SecretMetadata implements Serializable {
|
||||
}
|
||||
SecretMetadata that = (SecretMetadata) o;
|
||||
return Objects.equals(createdTime, that.createdTime) &&
|
||||
Objects.equals(currentVersion, that.currentVersion) &&
|
||||
Objects.equals(maxVersions, that.maxVersions) &&
|
||||
Objects.equals(oldestVersion, that.oldestVersion) &&
|
||||
Objects.equals(updatedTime, that.updatedTime) &&
|
||||
Objects.equals(versions, that.versions) &&
|
||||
Objects.equals(casRequired, that.casRequired) &&
|
||||
Objects.equals(customMetadata, that.customMetadata) &&
|
||||
Objects.equals(deleteVersionAfter, that.deleteVersionAfter);
|
||||
Objects.equals(currentVersion, that.currentVersion) &&
|
||||
Objects.equals(maxVersions, that.maxVersions) &&
|
||||
Objects.equals(oldestVersion, that.oldestVersion) &&
|
||||
Objects.equals(updatedTime, that.updatedTime) &&
|
||||
Objects.equals(versions, that.versions) &&
|
||||
Objects.equals(casRequired, that.casRequired) &&
|
||||
Objects.equals(customMetadata, that.customMetadata) &&
|
||||
Objects.equals(deleteVersionAfter, that.deleteVersionAfter);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016-2024 Stefan Kalscheuer
|
||||
* Copyright 2016-2025 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,7 +21,6 @@ import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
@@ -35,10 +34,7 @@ import java.util.Objects;
|
||||
*/
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public final class TokenData implements Serializable {
|
||||
private static final long serialVersionUID = -5749716740973138916L;
|
||||
|
||||
private static final DateTimeFormatter TIME_FORMAT =
|
||||
DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSSSSSSSXXX");
|
||||
private static final long serialVersionUID = -4168046151053509784L;
|
||||
|
||||
@JsonProperty("accessor")
|
||||
private String accessor;
|
||||
@@ -47,7 +43,7 @@ public final class TokenData implements Serializable {
|
||||
private Integer creationTime;
|
||||
|
||||
@JsonProperty("creation_ttl")
|
||||
private Integer creationTtl;
|
||||
private Long creationTtl;
|
||||
|
||||
@JsonProperty("display_name")
|
||||
private String name;
|
||||
@@ -59,7 +55,7 @@ public final class TokenData implements Serializable {
|
||||
private ZonedDateTime expireTime;
|
||||
|
||||
@JsonProperty("explicit_max_ttl")
|
||||
private Integer explicitMaxTtl;
|
||||
private Long explicitMaxTtl;
|
||||
|
||||
@JsonProperty("id")
|
||||
private String id;
|
||||
@@ -86,7 +82,7 @@ public final class TokenData implements Serializable {
|
||||
private boolean renewable;
|
||||
|
||||
@JsonProperty("ttl")
|
||||
private Integer ttl;
|
||||
private Long ttl;
|
||||
|
||||
@JsonProperty("type")
|
||||
private String type;
|
||||
@@ -108,7 +104,7 @@ public final class TokenData implements Serializable {
|
||||
/**
|
||||
* @return Creation TTL (in seconds)
|
||||
*/
|
||||
public Integer getCreationTtl() {
|
||||
public Long getCreationTtl() {
|
||||
return creationTtl;
|
||||
}
|
||||
|
||||
@@ -127,20 +123,6 @@ public final class TokenData implements Serializable {
|
||||
return entityId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Expire time as raw string value
|
||||
* @since 0.9
|
||||
* @deprecated Method left for backwards compatibility only. Use {@link #getExpireTime()} instead.
|
||||
*/
|
||||
@Deprecated(since = "1.2", forRemoval = true)
|
||||
public String getExpireTimeString() {
|
||||
if (expireTime != null) {
|
||||
return TIME_FORMAT.format(expireTime);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Expire time (parsed)
|
||||
* @since 0.9
|
||||
@@ -153,7 +135,7 @@ public final class TokenData implements Serializable {
|
||||
* @return Explicit maximum TTL
|
||||
* @since 0.9
|
||||
*/
|
||||
public Integer getExplicitMaxTtl() {
|
||||
public Long getExplicitMaxTtl() {
|
||||
return explicitMaxTtl;
|
||||
}
|
||||
|
||||
@@ -164,20 +146,6 @@ public final class TokenData implements Serializable {
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Issue time as raw string value
|
||||
* @since 0.9
|
||||
* @deprecated Method left for backwards compatibility only. Use {@link #getIssueTime()} instead.
|
||||
*/
|
||||
@Deprecated(since = "1.2", forRemoval = true)
|
||||
public String getIssueTimeString() {
|
||||
if (issueTime != null) {
|
||||
return TIME_FORMAT.format(issueTime);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Expire time (parsed)
|
||||
* @since 0.9
|
||||
@@ -234,7 +202,7 @@ public final class TokenData implements Serializable {
|
||||
/**
|
||||
* @return Token TTL (in seconds)
|
||||
*/
|
||||
public Integer getTtl() {
|
||||
public Long getTtl() {
|
||||
return ttl;
|
||||
}
|
||||
|
||||
@@ -254,27 +222,27 @@ public final class TokenData implements Serializable {
|
||||
}
|
||||
TokenData tokenData = (TokenData) o;
|
||||
return orphan == tokenData.orphan &&
|
||||
renewable == tokenData.renewable &&
|
||||
Objects.equals(accessor, tokenData.accessor) &&
|
||||
Objects.equals(creationTime, tokenData.creationTime) &&
|
||||
Objects.equals(creationTtl, tokenData.creationTtl) &&
|
||||
Objects.equals(name, tokenData.name) &&
|
||||
Objects.equals(entityId, tokenData.entityId) &&
|
||||
Objects.equals(expireTime, tokenData.expireTime) &&
|
||||
Objects.equals(explicitMaxTtl, tokenData.explicitMaxTtl) &&
|
||||
Objects.equals(id, tokenData.id) &&
|
||||
Objects.equals(issueTime, tokenData.issueTime) &&
|
||||
Objects.equals(meta, tokenData.meta) &&
|
||||
Objects.equals(numUses, tokenData.numUses) &&
|
||||
Objects.equals(path, tokenData.path) &&
|
||||
Objects.equals(policies, tokenData.policies) &&
|
||||
Objects.equals(ttl, tokenData.ttl) &&
|
||||
Objects.equals(type, tokenData.type);
|
||||
renewable == tokenData.renewable &&
|
||||
Objects.equals(accessor, tokenData.accessor) &&
|
||||
Objects.equals(creationTime, tokenData.creationTime) &&
|
||||
Objects.equals(creationTtl, tokenData.creationTtl) &&
|
||||
Objects.equals(name, tokenData.name) &&
|
||||
Objects.equals(entityId, tokenData.entityId) &&
|
||||
Objects.equals(expireTime, tokenData.expireTime) &&
|
||||
Objects.equals(explicitMaxTtl, tokenData.explicitMaxTtl) &&
|
||||
Objects.equals(id, tokenData.id) &&
|
||||
Objects.equals(issueTime, tokenData.issueTime) &&
|
||||
Objects.equals(meta, tokenData.meta) &&
|
||||
Objects.equals(numUses, tokenData.numUses) &&
|
||||
Objects.equals(path, tokenData.path) &&
|
||||
Objects.equals(policies, tokenData.policies) &&
|
||||
Objects.equals(ttl, tokenData.ttl) &&
|
||||
Objects.equals(type, tokenData.type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(accessor, creationTime, creationTtl, name, entityId, expireTime, explicitMaxTtl, id,
|
||||
issueTime, meta, numUses, orphan, path, policies, renewable, ttl, type);
|
||||
issueTime, meta, numUses, orphan, path, policies, renewable, ttl, type);
|
||||
}
|
||||
}
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016-2024 Stefan Kalscheuer
|
||||
* Copyright 2016-2025 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,7 +21,6 @@ import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
@@ -37,9 +36,6 @@ import java.util.Objects;
|
||||
public final class VersionMetadata implements Serializable {
|
||||
private static final long serialVersionUID = 8495687554714216478L;
|
||||
|
||||
private static final DateTimeFormatter TIME_FORMAT =
|
||||
DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSSSSSSSXXX");
|
||||
|
||||
@JsonProperty("created_time")
|
||||
private ZonedDateTime createdTime;
|
||||
|
||||
@@ -55,19 +51,6 @@ public final class VersionMetadata implements Serializable {
|
||||
@JsonProperty("custom_metadata")
|
||||
private HashMap<String, String> customMetadata;
|
||||
|
||||
/**
|
||||
* @return Time of secret creation as raw string representation.
|
||||
* @deprecated Method left for backwards compatibility only. Use {@link #getCreatedTime()} instead.
|
||||
*/
|
||||
@Deprecated(since = "1.2", forRemoval = true)
|
||||
public String getCreatedTimeString() {
|
||||
if (createdTime != null) {
|
||||
return TIME_FORMAT.format(createdTime);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Time of secret creation.
|
||||
*/
|
||||
@@ -75,19 +58,6 @@ public final class VersionMetadata implements Serializable {
|
||||
return createdTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Time for secret deletion as raw string representation.
|
||||
* @deprecated Method left for backwards compatibility only. Use {@link #getDeletionTime()} instead.
|
||||
*/
|
||||
@Deprecated(since = "1.2", forRemoval = true)
|
||||
public String getDeletionTimeString() {
|
||||
if (deletionTime != null) {
|
||||
return TIME_FORMAT.format(deletionTime);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Time for secret deletion.
|
||||
*/
|
||||
@@ -126,10 +96,10 @@ public final class VersionMetadata implements Serializable {
|
||||
}
|
||||
VersionMetadata that = (VersionMetadata) o;
|
||||
return destroyed == that.destroyed &&
|
||||
Objects.equals(createdTime, that.createdTime) &&
|
||||
Objects.equals(deletionTime, that.deletionTime) &&
|
||||
Objects.equals(version, that.version) &&
|
||||
Objects.equals(customMetadata, that.customMetadata);
|
||||
Objects.equals(createdTime, that.createdTime) &&
|
||||
Objects.equals(deletionTime, that.deletionTime) &&
|
||||
Objects.equals(version, that.version) &&
|
||||
Objects.equals(customMetadata, that.customMetadata);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016-2024 Stefan Kalscheuer
|
||||
* Copyright 2016-2025 Stefan Kalscheuer
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -80,9 +80,9 @@ public class WrapInfo implements Serializable {
|
||||
}
|
||||
WrapInfo that = (WrapInfo) o;
|
||||
return Objects.equals(token, that.token) &&
|
||||
Objects.equals(ttl, that.ttl) &&
|
||||
Objects.equals(creationTime, that.creationTime) &&
|
||||
Objects.equals(creationPath, that.creationPath);
|
||||
Objects.equals(ttl, that.ttl) &&
|
||||
Objects.equals(creationTime, that.creationTime) &&
|
||||
Objects.equals(creationPath, that.creationPath);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016-2024 Stefan Kalscheuer
|
||||
* Copyright 2016-2025 Stefan Kalscheuer
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016-2024 Stefan Kalscheuer
|
||||
* Copyright 2016-2025 Stefan Kalscheuer
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016-2024 Stefan Kalscheuer
|
||||
* Copyright 2016-2025 Stefan Kalscheuer
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016-2024 Stefan Kalscheuer
|
||||
* Copyright 2016-2025 Stefan Kalscheuer
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -31,6 +31,7 @@ module de.stklcode.jvault.connector {
|
||||
opens de.stklcode.jvault.connector.model.response.embedded to com.fasterxml.jackson.databind;
|
||||
|
||||
requires java.net.http;
|
||||
requires com.fasterxml.jackson.annotation;
|
||||
requires com.fasterxml.jackson.databind;
|
||||
requires com.fasterxml.jackson.datatype.jsr310;
|
||||
}
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016-2024 Stefan Kalscheuer
|
||||
* Copyright 2016-2025 Stefan Kalscheuer
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -25,7 +25,10 @@ import org.junit.jupiter.api.io.TempDir;
|
||||
import java.io.File;
|
||||
import java.lang.reflect.Field;
|
||||
import java.net.URISyntaxException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.NoSuchFileException;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import static com.github.stefanbirkner.systemlambda.SystemLambda.withEnvironmentVariable;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
@@ -38,6 +41,8 @@ import static org.junit.jupiter.api.Assertions.*;
|
||||
*/
|
||||
class HTTPVaultConnectorBuilderTest {
|
||||
private static final String VAULT_ADDR = "https://localhost:8201";
|
||||
private static final String VAULT_ADDR_2 = "http://localhost";
|
||||
private static final String VAULT_ADDR_3 = "https://localhost/vault/";
|
||||
private static final Integer VAULT_MAX_RETRIES = 13;
|
||||
private static final String VAULT_TOKEN = "00001111-2222-3333-4444-555566667777";
|
||||
|
||||
@@ -58,12 +63,12 @@ class HTTPVaultConnectorBuilderTest {
|
||||
|
||||
// Specify all options.
|
||||
HTTPVaultConnectorBuilder builder = HTTPVaultConnector.builder()
|
||||
.withHost("vault2.example.com")
|
||||
.withoutTLS()
|
||||
.withPort(1234)
|
||||
.withPrefix("/foo/")
|
||||
.withTimeout(5678)
|
||||
.withNumberOfRetries(9);
|
||||
.withHost("vault2.example.com")
|
||||
.withoutTLS()
|
||||
.withPort(1234)
|
||||
.withPrefix("/foo/")
|
||||
.withTimeout(5678)
|
||||
.withNumberOfRetries(9);
|
||||
connector = builder.build();
|
||||
|
||||
assertEquals("http://vault2.example.com:1234/foo/", getRequestHelperPrivate(connector, "baseURL"), "URL not set correctly");
|
||||
@@ -74,13 +79,13 @@ class HTTPVaultConnectorBuilderTest {
|
||||
|
||||
// Initialization from URL.
|
||||
assertThrows(
|
||||
URISyntaxException.class,
|
||||
() -> HTTPVaultConnector.builder().withBaseURL("foo:/\\1nv4l1d_UrL"),
|
||||
"Initialization from invalid URL should fail"
|
||||
URISyntaxException.class,
|
||||
() -> HTTPVaultConnector.builder().withBaseURL("foo:/\\1nv4l1d_UrL"),
|
||||
"Initialization from invalid URL should fail"
|
||||
);
|
||||
connector = assertDoesNotThrow(
|
||||
() -> HTTPVaultConnector.builder().withBaseURL("https://vault3.example.com:5678/bar/").build(),
|
||||
"Initialization from valid URL should not fail"
|
||||
() -> HTTPVaultConnector.builder().withBaseURL("https://vault3.example.com:5678/bar/").build(),
|
||||
"Initialization from valid URL should not fail"
|
||||
);
|
||||
assertEquals("https://vault3.example.com:5678/bar/", getRequestHelperPrivate(connector, "baseURL"), "URL not set correctly");
|
||||
|
||||
@@ -101,8 +106,8 @@ class HTTPVaultConnectorBuilderTest {
|
||||
// Provide address only should be enough.
|
||||
withVaultEnv(VAULT_ADDR, null, null, null).execute(() -> {
|
||||
HTTPVaultConnectorBuilder builder = assertDoesNotThrow(
|
||||
() -> HTTPVaultConnector.builder().fromEnv(),
|
||||
"Factory creation from minimal environment failed"
|
||||
() -> HTTPVaultConnector.builder().fromEnv(),
|
||||
"Factory creation from minimal environment failed"
|
||||
);
|
||||
HTTPVaultConnector connector = builder.build();
|
||||
|
||||
@@ -112,12 +117,28 @@ class HTTPVaultConnectorBuilderTest {
|
||||
|
||||
return null;
|
||||
});
|
||||
withVaultEnv(VAULT_ADDR_2, null, null, null).execute(() -> {
|
||||
HTTPVaultConnectorBuilder builder = assertDoesNotThrow(
|
||||
() -> HTTPVaultConnector.builder().fromEnv(),
|
||||
"Factory creation from minimal environment failed"
|
||||
);
|
||||
assertEquals(VAULT_ADDR_2 + "/v1/", getRequestHelperPrivate(builder.build(), "baseURL"), "URL without port not set correctly");
|
||||
return null;
|
||||
});
|
||||
withVaultEnv(VAULT_ADDR_3, null, null, null).execute(() -> {
|
||||
HTTPVaultConnectorBuilder builder = assertDoesNotThrow(
|
||||
() -> HTTPVaultConnector.builder().fromEnv(),
|
||||
"Factory creation from minimal environment failed"
|
||||
);
|
||||
assertEquals(VAULT_ADDR_3, getRequestHelperPrivate(builder.build(), "baseURL"), "URL with custom path not set correctly");
|
||||
return null;
|
||||
});
|
||||
|
||||
// Provide address and number of retries.
|
||||
withVaultEnv(VAULT_ADDR, null, VAULT_MAX_RETRIES.toString(), null).execute(() -> {
|
||||
HTTPVaultConnectorBuilder builder = assertDoesNotThrow(
|
||||
() -> HTTPVaultConnector.builder().fromEnv(),
|
||||
"Factory creation from environment failed"
|
||||
() -> HTTPVaultConnector.builder().fromEnv(),
|
||||
"Factory creation from environment failed"
|
||||
);
|
||||
HTTPVaultConnector connector = builder.build();
|
||||
|
||||
@@ -128,24 +149,11 @@ class HTTPVaultConnectorBuilderTest {
|
||||
return null;
|
||||
});
|
||||
|
||||
// Provide CA certificate.
|
||||
String vaultCacert = tempDir.toString() + "/doesnotexist";
|
||||
withVaultEnv(VAULT_ADDR, vaultCacert, VAULT_MAX_RETRIES.toString(), null).execute(() -> {
|
||||
TlsException e = assertThrows(
|
||||
TlsException.class,
|
||||
() -> HTTPVaultConnector.builder().fromEnv(),
|
||||
"Creation with unknown cert path failed"
|
||||
);
|
||||
assertEquals(vaultCacert, assertInstanceOf(NoSuchFileException.class, e.getCause()).getFile());
|
||||
|
||||
return null;
|
||||
});
|
||||
|
||||
// Automatic authentication.
|
||||
withVaultEnv(VAULT_ADDR, null, VAULT_MAX_RETRIES.toString(), VAULT_TOKEN).execute(() -> {
|
||||
HTTPVaultConnectorBuilder builder = assertDoesNotThrow(
|
||||
() -> HTTPVaultConnector.builder().fromEnv(),
|
||||
"Factory creation from minimal environment failed"
|
||||
() -> HTTPVaultConnector.builder().fromEnv(),
|
||||
"Factory creation from minimal environment failed"
|
||||
);
|
||||
assertEquals(VAULT_TOKEN, getPrivate(builder, "token"), "Token not set correctly");
|
||||
|
||||
@@ -155,20 +163,73 @@ class HTTPVaultConnectorBuilderTest {
|
||||
// Invalid URL.
|
||||
withVaultEnv("This is not a valid URL!", null, VAULT_MAX_RETRIES.toString(), VAULT_TOKEN).execute(() -> {
|
||||
assertThrows(
|
||||
ConnectionException.class,
|
||||
() -> HTTPVaultConnector.builder().fromEnv(),
|
||||
"Invalid URL from environment should raise an exception"
|
||||
ConnectionException.class,
|
||||
() -> HTTPVaultConnector.builder().fromEnv(),
|
||||
"Invalid URL from environment should raise an exception"
|
||||
);
|
||||
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Test CA certificate handling from environment variables
|
||||
*/
|
||||
@Test
|
||||
void testCertificateFromEnv() throws Exception {
|
||||
// From direct PEM content
|
||||
String pem = Files.readString(Paths.get(getClass().getResource("/tls/ca.pem").toURI()));
|
||||
AtomicReference<Object> certFromPem = new AtomicReference<>();
|
||||
withVaultEnv(VAULT_ADDR, pem, null, null).execute(() -> {
|
||||
HTTPVaultConnectorBuilder builder = assertDoesNotThrow(
|
||||
() -> HTTPVaultConnector.builder().fromEnv(),
|
||||
"Builder with PEM certificate from environment failed"
|
||||
);
|
||||
HTTPVaultConnector connector = builder.build();
|
||||
|
||||
certFromPem.set(getRequestHelperPrivate(connector, "trustedCaCert"));
|
||||
assertNotNull(certFromPem.get(), "Trusted CA cert from PEM not set");
|
||||
|
||||
return null;
|
||||
});
|
||||
|
||||
// From file path
|
||||
String file = Paths.get(getClass().getResource("/tls/ca.pem").toURI()).toString();
|
||||
AtomicReference<Object> certFromFile = new AtomicReference<>();
|
||||
withVaultEnv(VAULT_ADDR, file, null, null).execute(() -> {
|
||||
HTTPVaultConnectorBuilder builder = assertDoesNotThrow(
|
||||
() -> HTTPVaultConnector.builder().fromEnv(),
|
||||
"Builder with certificate path from environment failed"
|
||||
);
|
||||
HTTPVaultConnector connector = builder.build();
|
||||
|
||||
certFromFile.set(getRequestHelperPrivate(connector, "trustedCaCert"));
|
||||
assertNotNull(certFromFile.get(), "Trusted CA cert from file not set");
|
||||
|
||||
return null;
|
||||
});
|
||||
|
||||
assertEquals(certFromPem.get(), certFromFile.get(), "Certificates from PEM and file should be equal");
|
||||
|
||||
// Non-existing path CA certificate path
|
||||
String doesNotExist = tempDir.toString() + "/doesnotexist";
|
||||
withVaultEnv(VAULT_ADDR, doesNotExist, VAULT_MAX_RETRIES.toString(), null).execute(() -> {
|
||||
TlsException e = assertThrows(
|
||||
TlsException.class,
|
||||
() -> HTTPVaultConnector.builder().fromEnv(),
|
||||
"Creation with unknown cert path failed"
|
||||
);
|
||||
assertEquals(doesNotExist, assertInstanceOf(NoSuchFileException.class, e.getCause()).getFile());
|
||||
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
private SystemLambda.WithEnvironmentVariables withVaultEnv(String vaultAddr, String vaultCacert, String vaultMaxRetries, String vaultToken) {
|
||||
return withEnvironmentVariable("VAULT_ADDR", vaultAddr)
|
||||
.and("VAULT_CACERT", vaultCacert)
|
||||
.and("VAULT_MAX_RETRIES", vaultMaxRetries)
|
||||
.and("VAULT_TOKEN", vaultToken);
|
||||
.and("VAULT_CACERT", vaultCacert)
|
||||
.and("VAULT_MAX_RETRIES", vaultMaxRetries)
|
||||
.and("VAULT_TOKEN", vaultToken);
|
||||
}
|
||||
|
||||
private Object getRequestHelperPrivate(HTTPVaultConnector connector, String fieldName) throws NoSuchFieldException, IllegalAccessException {
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016-2024 Stefan Kalscheuer
|
||||
* Copyright 2016-2025 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,13 +17,13 @@
|
||||
package de.stklcode.jvault.connector;
|
||||
|
||||
import com.github.tomakehurst.wiremock.client.WireMock;
|
||||
import com.github.tomakehurst.wiremock.junit5.WireMockExtension;
|
||||
import com.github.tomakehurst.wiremock.junit5.WireMockRuntimeInfo;
|
||||
import com.github.tomakehurst.wiremock.junit5.WireMockTest;
|
||||
import de.stklcode.jvault.connector.exception.ConnectionException;
|
||||
import de.stklcode.jvault.connector.exception.InvalidResponseException;
|
||||
import de.stklcode.jvault.connector.exception.PermissionDeniedException;
|
||||
import de.stklcode.jvault.connector.exception.VaultConnectorException;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.RegisterExtension;
|
||||
import org.junit.jupiter.api.function.Executable;
|
||||
|
||||
import java.io.IOException;
|
||||
@@ -36,9 +36,7 @@ import java.security.cert.CertificateFactory;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.util.Collections;
|
||||
|
||||
import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
|
||||
import static com.github.tomakehurst.wiremock.client.WireMock.anyUrl;
|
||||
import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig;
|
||||
import static com.github.tomakehurst.wiremock.client.WireMock.*;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
/**
|
||||
@@ -48,62 +46,59 @@ import static org.junit.jupiter.api.Assertions.*;
|
||||
* @author Stefan Kalscheuer
|
||||
* @since 0.7.0
|
||||
*/
|
||||
@WireMockTest
|
||||
class HTTPVaultConnectorTest {
|
||||
@RegisterExtension
|
||||
static WireMockExtension wireMock = WireMockExtension.newInstance()
|
||||
.options(wireMockConfig().dynamicPort())
|
||||
.build();
|
||||
|
||||
/**
|
||||
* Test exceptions thrown during request.
|
||||
*/
|
||||
@Test
|
||||
void requestExceptionTest() throws IOException, URISyntaxException {
|
||||
HTTPVaultConnector connector = HTTPVaultConnector.builder(wireMock.url("/")).withTimeout(250).build();
|
||||
|
||||
// Test invalid response code.
|
||||
final int responseCode = 400;
|
||||
mockHttpResponse(responseCode, "", "application/json");
|
||||
VaultConnectorException e = assertThrows(
|
||||
void requestExceptionTest(WireMockRuntimeInfo wireMock) throws IOException, URISyntaxException {
|
||||
try (var connector = HTTPVaultConnector.builder(wireMock.getHttpBaseUrl()).withTimeout(250).build()) {
|
||||
// Test invalid response code.
|
||||
final int responseCode = 400;
|
||||
mockHttpResponse(responseCode, "", "application/json");
|
||||
VaultConnectorException e = assertThrows(
|
||||
InvalidResponseException.class,
|
||||
connector::getHealth,
|
||||
() -> connector.sys().getHealth(),
|
||||
"Querying health status succeeded on invalid instance"
|
||||
);
|
||||
assertEquals("Invalid response code", e.getMessage(), "Unexpected exception message");
|
||||
assertEquals(responseCode, ((InvalidResponseException) e).getStatusCode(), "Unexpected status code in exception");
|
||||
assertNull(((InvalidResponseException) e).getResponse(), "Response message where none was expected");
|
||||
);
|
||||
assertEquals("Invalid response code", e.getMessage(), "Unexpected exception message");
|
||||
assertEquals(responseCode, ((InvalidResponseException) e).getStatusCode(), "Unexpected status code in exception");
|
||||
assertNull(((InvalidResponseException) e).getResponse(), "Response message where none was expected");
|
||||
|
||||
// Simulate permission denied response.
|
||||
mockHttpResponse(responseCode, "{\"errors\":[\"permission denied\"]}", "application/json");
|
||||
assertThrows(
|
||||
// Simulate permission denied response.
|
||||
mockHttpResponse(responseCode, "{\"errors\":[\"permission denied\"]}", "application/json");
|
||||
assertThrows(
|
||||
PermissionDeniedException.class,
|
||||
connector::getHealth,
|
||||
() -> connector.sys().getHealth(),
|
||||
"Querying health status succeeded on invalid instance"
|
||||
);
|
||||
);
|
||||
}
|
||||
|
||||
// Test exception thrown during request.
|
||||
try (ServerSocket s = new ServerSocket(0)) {
|
||||
connector = HTTPVaultConnector.builder("http://localst:" + s.getLocalPort() + "/").withTimeout(250).build();
|
||||
}
|
||||
e = assertThrows(
|
||||
try (ServerSocket s = new ServerSocket(0);
|
||||
var connector = HTTPVaultConnector.builder("http://localst:" + s.getLocalPort() + "/").withTimeout(250).build()) {
|
||||
var e = assertThrows(
|
||||
ConnectionException.class,
|
||||
connector::getHealth,
|
||||
() -> connector.sys().getHealth(),
|
||||
"Querying health status succeeded on invalid instance"
|
||||
);
|
||||
assertEquals("Unable to connect to Vault server", e.getMessage(), "Unexpected exception message");
|
||||
assertInstanceOf(IOException.class, e.getCause(), "Unexpected cause");
|
||||
);
|
||||
assertEquals("Unable to connect to Vault server", e.getMessage(), "Unexpected exception message");
|
||||
assertInstanceOf(IOException.class, e.getCause(), "Unexpected cause");
|
||||
}
|
||||
|
||||
// Now simulate a failing request that succeeds on second try.
|
||||
connector = HTTPVaultConnector.builder(wireMock.url("/")).withNumberOfRetries(1).withTimeout(250).build();
|
||||
|
||||
wireMock.stubFor(
|
||||
try (var connector3 = HTTPVaultConnector.builder(wireMock.getHttpBaseUrl()).withNumberOfRetries(1).withTimeout(250).build()) {
|
||||
stubFor(
|
||||
WireMock.any(anyUrl())
|
||||
.willReturn(aResponse().withStatus(500))
|
||||
.willReturn(aResponse().withStatus(500))
|
||||
.willReturn(aResponse().withStatus(500))
|
||||
.willReturn(aResponse().withStatus(200).withBody("{}").withHeader("Content-Type", "application/json"))
|
||||
);
|
||||
assertDoesNotThrow(connector::getHealth, "Request failed unexpectedly");
|
||||
.willReturn(aResponse().withStatus(500))
|
||||
.willReturn(aResponse().withStatus(500))
|
||||
.willReturn(aResponse().withStatus(500))
|
||||
.willReturn(aResponse().withStatus(200).withBody("{}").withHeader("Content-Type", "application/json"))
|
||||
);
|
||||
assertDoesNotThrow(() -> connector3.sys().getHealth(), "Request failed unexpectedly");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -164,9 +159,9 @@ class HTTPVaultConnectorTest {
|
||||
connector = HTTPVaultConnector.builder("http://localst:" + s.getLocalPort()).withTimeout(250).build();
|
||||
}
|
||||
ConnectionException e = assertThrows(
|
||||
ConnectionException.class,
|
||||
connector::sealStatus,
|
||||
"Querying seal status succeeded on invalid instance"
|
||||
ConnectionException.class,
|
||||
() -> connector.sys().sealStatus(),
|
||||
"Querying seal status succeeded on invalid instance"
|
||||
);
|
||||
assertEquals("Unable to connect to Vault server", e.getMessage(), "Unexpected exception message");
|
||||
}
|
||||
@@ -182,9 +177,9 @@ class HTTPVaultConnectorTest {
|
||||
connector = HTTPVaultConnector.builder("http://localhost:" + s.getLocalPort() + "/").withTimeout(250).build();
|
||||
}
|
||||
ConnectionException e = assertThrows(
|
||||
ConnectionException.class,
|
||||
connector::getHealth,
|
||||
"Querying health status succeeded on invalid instance"
|
||||
ConnectionException.class,
|
||||
() -> connector.sys().getHealth(),
|
||||
"Querying health status succeeded on invalid instance"
|
||||
);
|
||||
assertEquals("Unable to connect to Vault server", e.getMessage(), "Unexpected exception message");
|
||||
}
|
||||
@@ -193,29 +188,29 @@ class HTTPVaultConnectorTest {
|
||||
* Test behavior on unparsable responses.
|
||||
*/
|
||||
@Test
|
||||
void parseExceptionTest() throws URISyntaxException {
|
||||
HTTPVaultConnector connector = HTTPVaultConnector.builder(wireMock.url("/")).withTimeout(250).build();
|
||||
void parseExceptionTest(WireMockRuntimeInfo wireMock) throws URISyntaxException {
|
||||
HTTPVaultConnector connector = HTTPVaultConnector.builder(wireMock.getHttpBaseUrl()).withTimeout(250).build();
|
||||
// Mock authorization.
|
||||
setPrivate(connector, "authorized", true);
|
||||
// Mock response.
|
||||
mockHttpResponse(200, "invalid", "application/json");
|
||||
|
||||
// Now test the methods.
|
||||
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.sys().sealStatus(), "sys().sealStatus() succeeded on invalid instance");
|
||||
assertParseError(() -> connector.sys().unseal("key"), "sys().unseal() succeeded on invalid instance");
|
||||
assertParseError(() -> connector.sys().getHealth(), "sys().getHealth() succeeded on invalid instance");
|
||||
assertParseError(() -> connector.sys().getAuthBackends(), "sys().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.appRole().lookup("roleName"), "appRole().lookup() succeeded on invalid instance");
|
||||
assertParseError(() -> connector.appRole().getRoleID("roleName"), "appRole().getRoleID() succeeded on invalid instance");
|
||||
assertParseError(() -> connector.appRole().createSecret("roleName"), "appRole().createSecret() succeeded on invalid instance");
|
||||
assertParseError(() -> connector.appRole().lookupSecret("roleName", "secretID"), "appRole().lookupSecret() succeeded on invalid instance");
|
||||
assertParseError(() -> connector.appRole().listRoles(), "appRole().listRoles() succeeded on invalid instance");
|
||||
assertParseError(() -> connector.appRole().listSecrets("roleName"), "appRole().listSecrets() 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");
|
||||
assertParseError(() -> connector.token().lookup("token"), "token().lookup() succeeded on invalid instance");
|
||||
}
|
||||
|
||||
private void assertParseError(Executable executable, String message) {
|
||||
@@ -227,8 +222,8 @@ class HTTPVaultConnectorTest {
|
||||
* Test requests that expect an empty response with code 204, but receive a 200 body.
|
||||
*/
|
||||
@Test
|
||||
void nonEmpty204ResponseTest() throws URISyntaxException {
|
||||
HTTPVaultConnector connector = HTTPVaultConnector.builder(wireMock.url("/")).withTimeout(250).build();
|
||||
void nonEmpty204ResponseTest(WireMockRuntimeInfo wireMock) throws URISyntaxException {
|
||||
HTTPVaultConnector connector = HTTPVaultConnector.builder(wireMock.getHttpBaseUrl()).withTimeout(250).build();
|
||||
// Mock authorization.
|
||||
setPrivate(connector, "authorized", true);
|
||||
// Mock response.
|
||||
@@ -236,57 +231,45 @@ class HTTPVaultConnectorTest {
|
||||
|
||||
// Now test the methods expecting a 204.
|
||||
assertThrows(
|
||||
InvalidResponseException.class,
|
||||
() -> connector.registerAppId("appID", "policy", "displayName"),
|
||||
"registerAppId() with 200 response succeeded"
|
||||
InvalidResponseException.class,
|
||||
() -> connector.appRole().create("appID", Collections.singletonList("policy")),
|
||||
"appRole().create() with 200 response succeeded"
|
||||
);
|
||||
|
||||
assertThrows(
|
||||
InvalidResponseException.class,
|
||||
() -> connector.registerUserId("appID", "userID"),
|
||||
"registerUserId() with 200 response succeeded"
|
||||
InvalidResponseException.class,
|
||||
() -> connector.delete("roleName"),
|
||||
"appRole().delete() with 200 response succeeded"
|
||||
);
|
||||
|
||||
assertThrows(
|
||||
InvalidResponseException.class,
|
||||
() -> connector.createAppRole("appID", Collections.singletonList("policy")),
|
||||
"createAppRole() with 200 response succeeded"
|
||||
InvalidResponseException.class,
|
||||
() -> connector.appRole().setRoleID("roleName", "roleID"),
|
||||
"appRole().setRoleID() with 200 response succeeded"
|
||||
);
|
||||
|
||||
assertThrows(
|
||||
InvalidResponseException.class,
|
||||
() -> connector.deleteAppRole("roleName"),
|
||||
"deleteAppRole() with 200 response succeeded"
|
||||
InvalidResponseException.class,
|
||||
() -> connector.appRole().destroySecret("roleName", "secretID"),
|
||||
"appRole().destroySecret() with 200 response succeeded"
|
||||
);
|
||||
|
||||
assertThrows(
|
||||
InvalidResponseException.class,
|
||||
() -> connector.setAppRoleID("roleName", "roleID"),
|
||||
"setAppRoleID() with 200 response succeeded"
|
||||
InvalidResponseException.class,
|
||||
() -> connector.appRole().destroySecret("roleName", "secretUD"),
|
||||
"appRole().destroySecret() with 200 response succeeded"
|
||||
);
|
||||
|
||||
assertThrows(
|
||||
InvalidResponseException.class,
|
||||
() -> connector.destroyAppRoleSecret("roleName", "secretID"),
|
||||
"destroyAppRoleSecret() with 200 response succeeded"
|
||||
InvalidResponseException.class,
|
||||
() -> connector.delete("key"),
|
||||
"delete() with 200 response succeeded"
|
||||
);
|
||||
|
||||
assertThrows(
|
||||
InvalidResponseException.class,
|
||||
() -> connector.destroyAppRoleSecret("roleName", "secretUD"),
|
||||
"destroyAppRoleSecret() with 200 response succeeded"
|
||||
);
|
||||
|
||||
assertThrows(
|
||||
InvalidResponseException.class,
|
||||
() -> connector.delete("key"),
|
||||
"delete() with 200 response succeeded"
|
||||
);
|
||||
|
||||
assertThrows(
|
||||
InvalidResponseException.class,
|
||||
() -> connector.revoke("leaseID"),
|
||||
"destroyAppRoleSecret() with 200 response succeeded"
|
||||
InvalidResponseException.class,
|
||||
() -> connector.revoke("leaseID"),
|
||||
"destroyAppRoleSecret() with 200 response succeeded"
|
||||
);
|
||||
}
|
||||
|
||||
@@ -322,10 +305,10 @@ class HTTPVaultConnectorTest {
|
||||
}
|
||||
|
||||
private void mockHttpResponse(int status, String body, String contentType) {
|
||||
wireMock.stubFor(
|
||||
WireMock.any(anyUrl()).willReturn(
|
||||
aResponse().withStatus(status).withBody(body).withHeader("Content-Type", contentType)
|
||||
)
|
||||
stubFor(
|
||||
WireMock.any(anyUrl()).willReturn(
|
||||
aResponse().withStatus(status).withBody(body).withHeader("Content-Type", contentType)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016-2024 Stefan Kalscheuer
|
||||
* Copyright 2016-2025 Stefan Kalscheuer
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@@ -3,6 +3,7 @@ package de.stklcode.jvault.connector.model;
|
||||
import com.fasterxml.jackson.databind.DeserializationFeature;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.SerializationFeature;
|
||||
import com.fasterxml.jackson.databind.json.JsonMapper;
|
||||
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
|
||||
import nl.jqno.equalsverifier.EqualsVerifier;
|
||||
import org.junit.jupiter.api.Test;
|
||||
@@ -29,10 +30,11 @@ public abstract class AbstractModelTest<T> {
|
||||
*/
|
||||
protected AbstractModelTest(Class<T> modelClass) {
|
||||
this.modelClass = modelClass;
|
||||
this.objectMapper = new ObjectMapper()
|
||||
.registerModule(new JavaTimeModule())
|
||||
.enable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
|
||||
.disable(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE);
|
||||
this.objectMapper = JsonMapper.builder()
|
||||
.addModule(new JavaTimeModule())
|
||||
.enable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
|
||||
.disable(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE)
|
||||
.build();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016-2024 Stefan Kalscheuer
|
||||
* Copyright 2016-2025 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,8 +35,8 @@ import static org.junit.jupiter.api.Assumptions.assumeTrue;
|
||||
class AppRoleSecretTest extends AbstractModelTest<AppRoleSecret> {
|
||||
private static final String TEST_ID = "abc123";
|
||||
private static final Map<String, Object> TEST_META = Map.of(
|
||||
"foo", "bar",
|
||||
"number", 1337
|
||||
"foo", "bar",
|
||||
"number", 1337
|
||||
);
|
||||
private static final List<String> TEST_CIDR = List.of("203.0.113.0/24", "198.51.100.0/24");
|
||||
|
||||
@@ -122,8 +122,8 @@ class AppRoleSecretTest extends AbstractModelTest<AppRoleSecret> {
|
||||
String secretJson2 = commaSeparatedToList(secretJson);
|
||||
|
||||
AppRoleSecret secret2 = assertDoesNotThrow(
|
||||
() -> objectMapper.readValue(secretJson2, AppRoleSecret.class),
|
||||
"Deserialization failed"
|
||||
() -> objectMapper.readValue(secretJson2, AppRoleSecret.class),
|
||||
"Deserialization failed"
|
||||
);
|
||||
assertEquals(secret2.getId(), secret.getId());
|
||||
assertEquals(secret2.getMetadata(), secret.getMetadata());
|
||||
@@ -144,8 +144,8 @@ class AppRoleSecretTest extends AbstractModelTest<AppRoleSecret> {
|
||||
assumeTrue(secret.getTtl() == 12345);
|
||||
String secretJson3 = assertDoesNotThrow(() -> objectMapper.writeValueAsString(secret), "Serialization failed");
|
||||
secret2 = assertDoesNotThrow(
|
||||
() -> objectMapper.readValue(commaSeparatedToList(secretJson3), AppRoleSecret.class),
|
||||
"Deserialization failed"
|
||||
() -> objectMapper.readValue(commaSeparatedToList(secretJson3), AppRoleSecret.class),
|
||||
"Deserialization failed"
|
||||
);
|
||||
assertEquals(secret2.getId(), secret.getId());
|
||||
assertEquals(secret2.getMetadata(), secret.getMetadata());
|
||||
@@ -159,9 +159,9 @@ class AppRoleSecretTest extends AbstractModelTest<AppRoleSecret> {
|
||||
|
||||
// Those fields should be deserialized from JSON though.
|
||||
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}";
|
||||
"\"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}";
|
||||
secret2 = assertDoesNotThrow(() -> objectMapper.readValue(secretJson4, AppRoleSecret.class), "Deserialization failed");
|
||||
assertEquals("TEST_ACCESSOR", secret2.getAccessor());
|
||||
assertEquals("TEST_CREATION", secret2.getCreationTime());
|
||||
@@ -181,6 +181,6 @@ class AppRoleSecretTest extends AbstractModelTest<AppRoleSecret> {
|
||||
|
||||
private static String commaSeparatedToList(String json) {
|
||||
return json.replaceAll("\"cidr_list\":\"([^\"]*)\"", "\"cidr_list\":[$1]")
|
||||
.replaceAll("(\\d+\\.\\d+\\.\\d+\\.\\d+/\\d+)", "\"$1\"");
|
||||
.replaceAll("(\\d+\\.\\d+\\.\\d+\\.\\d+/\\d+)", "\"$1\"");
|
||||
}
|
||||
}
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016-2024 Stefan Kalscheuer
|
||||
* Copyright 2016-2025 Stefan Kalscheuer
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -42,18 +42,18 @@ class AppRoleTest extends AbstractModelTest<AppRole> {
|
||||
private static final String POLICY = "policy";
|
||||
private static final String POLICY_2 = "policy2";
|
||||
private static final Integer SECRET_ID_NUM_USES = 10;
|
||||
private static final Integer SECRET_ID_TTL = 7200;
|
||||
private static final Long SECRET_ID_TTL = 7200L;
|
||||
private static final Boolean LOCAL_SECRET_IDS = false;
|
||||
private static final Integer TOKEN_TTL = 4800;
|
||||
private static final Integer TOKEN_MAX_TTL = 9600;
|
||||
private static final Integer TOKEN_EXPLICIT_MAX_TTL = 14400;
|
||||
private static final Long TOKEN_TTL = 4800L;
|
||||
private static final Long TOKEN_MAX_TTL = 9600L;
|
||||
private static final Long TOKEN_EXPLICIT_MAX_TTL = 14400L;
|
||||
private static final Boolean TOKEN_NO_DEFAULT_POLICY = false;
|
||||
private static final Integer TOKEN_NUM_USES = 42;
|
||||
private static final Integer TOKEN_PERIOD = 1234;
|
||||
private static final Token.Type TOKEN_TYPE = Token.Type.DEFAULT_SERVICE;
|
||||
private static final String JSON_MIN = "{\"role_name\":\"" + NAME + "\"}";
|
||||
private static final String JSON_FULL = String.format("{\"role_name\":\"%s\",\"role_id\":\"%s\",\"bind_secret_id\":%s,\"secret_id_bound_cidrs\":\"%s\",\"secret_id_num_uses\":%d,\"secret_id_ttl\":%d,\"local_secret_ids\":%s,\"token_ttl\":%d,\"token_max_ttl\":%d,\"token_policies\":\"%s\",\"token_bound_cidrs\":\"%s\",\"token_explicit_max_ttl\":%d,\"token_no_default_policy\":%s,\"token_num_uses\":%d,\"token_period\":%d,\"token_type\":\"%s\"}",
|
||||
NAME, ID, BIND_SECRET_ID, CIDR_1, SECRET_ID_NUM_USES, SECRET_ID_TTL, 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());
|
||||
NAME, ID, BIND_SECRET_ID, CIDR_1, SECRET_ID_NUM_USES, SECRET_ID_TTL, 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());
|
||||
|
||||
AppRoleTest() {
|
||||
super(AppRole.class);
|
||||
@@ -62,22 +62,22 @@ class AppRoleTest extends AbstractModelTest<AppRole> {
|
||||
@Override
|
||||
protected AppRole createFull() {
|
||||
return AppRole.builder(NAME)
|
||||
.withId(ID)
|
||||
.withBindSecretID(BIND_SECRET_ID)
|
||||
.withSecretIdBoundCidrs(BOUND_CIDR_LIST)
|
||||
.withTokenPolicies(POLICIES)
|
||||
.withSecretIdNumUses(SECRET_ID_NUM_USES)
|
||||
.withSecretIdTtl(SECRET_ID_TTL)
|
||||
.withLocalSecretIds(LOCAL_SECRET_IDS)
|
||||
.withTokenTtl(TOKEN_TTL)
|
||||
.withTokenMaxTtl(TOKEN_MAX_TTL)
|
||||
.withTokenBoundCidrs(BOUND_CIDR_LIST)
|
||||
.withTokenExplicitMaxTtl(TOKEN_EXPLICIT_MAX_TTL)
|
||||
.withTokenNoDefaultPolicy(TOKEN_NO_DEFAULT_POLICY)
|
||||
.withTokenNumUses(TOKEN_NUM_USES)
|
||||
.withTokenPeriod(TOKEN_PERIOD)
|
||||
.withTokenType(TOKEN_TYPE)
|
||||
.build();
|
||||
.withId(ID)
|
||||
.withBindSecretID(BIND_SECRET_ID)
|
||||
.withSecretIdBoundCidrs(BOUND_CIDR_LIST)
|
||||
.withTokenPolicies(POLICIES)
|
||||
.withSecretIdNumUses(SECRET_ID_NUM_USES)
|
||||
.withSecretIdTtl(SECRET_ID_TTL)
|
||||
.withLocalSecretIds(LOCAL_SECRET_IDS)
|
||||
.withTokenTtl(TOKEN_TTL)
|
||||
.withTokenMaxTtl(TOKEN_MAX_TTL)
|
||||
.withTokenBoundCidrs(BOUND_CIDR_LIST)
|
||||
.withTokenExplicitMaxTtl(TOKEN_EXPLICIT_MAX_TTL)
|
||||
.withTokenNoDefaultPolicy(TOKEN_NO_DEFAULT_POLICY)
|
||||
.withTokenNumUses(TOKEN_NUM_USES)
|
||||
.withTokenPeriod(TOKEN_PERIOD)
|
||||
.withTokenType(TOKEN_TYPE)
|
||||
.build();
|
||||
}
|
||||
|
||||
@BeforeAll
|
||||
@@ -159,11 +159,11 @@ class AppRoleTest extends AbstractModelTest<AppRole> {
|
||||
assertEquals(1, role.getTokenBoundCidrs().size());
|
||||
assertEquals(CIDR_2, role.getTokenBoundCidrs().get(0));
|
||||
role = AppRole.builder(NAME)
|
||||
.withSecretIdBoundCidrs(BOUND_CIDR_LIST)
|
||||
.withSecretBoundCidr(CIDR_2)
|
||||
.withTokenBoundCidrs(BOUND_CIDR_LIST)
|
||||
.withTokenBoundCidr(CIDR_2)
|
||||
.build();
|
||||
.withSecretIdBoundCidrs(BOUND_CIDR_LIST)
|
||||
.withSecretBoundCidr(CIDR_2)
|
||||
.withTokenBoundCidrs(BOUND_CIDR_LIST)
|
||||
.withTokenBoundCidr(CIDR_2)
|
||||
.build();
|
||||
assertEquals(2, role.getSecretIdBoundCidrs().size());
|
||||
assertTrue(role.getSecretIdBoundCidrs().containsAll(List.of(CIDR_1, CIDR_2)));
|
||||
assertEquals(2, role.getTokenBoundCidrs().size());
|
||||
@@ -174,9 +174,9 @@ class AppRoleTest extends AbstractModelTest<AppRole> {
|
||||
assertEquals(1, role.getTokenPolicies().size());
|
||||
assertEquals(POLICY_2, role.getTokenPolicies().get(0));
|
||||
role = AppRole.builder(NAME)
|
||||
.withTokenPolicies(POLICIES)
|
||||
.withTokenPolicy(POLICY_2)
|
||||
.build();
|
||||
.withTokenPolicies(POLICIES)
|
||||
.withTokenPolicy(POLICY_2)
|
||||
.build();
|
||||
assertEquals(2, role.getTokenPolicies().size());
|
||||
assertTrue(role.getTokenPolicies().containsAll(List.of(POLICY, POLICY_2)));
|
||||
}
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016-2024 Stefan Kalscheuer
|
||||
* Copyright 2016-2025 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,10 +33,8 @@ class AuthBackendTest {
|
||||
* Test forType() method.
|
||||
*/
|
||||
@Test
|
||||
@SuppressWarnings("deprecation")
|
||||
void forTypeTest() {
|
||||
assertEquals(AuthBackend.TOKEN, AuthBackend.forType("token"));
|
||||
assertEquals(AuthBackend.APPID, AuthBackend.forType("app-id"));
|
||||
assertEquals(AuthBackend.USERPASS, AuthBackend.forType("userpass"));
|
||||
assertEquals(AuthBackend.GITHUB, AuthBackend.forType("github"));
|
||||
assertEquals(AuthBackend.UNKNOWN, AuthBackend.forType(""));
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016-2024 Stefan Kalscheuer
|
||||
* Copyright 2016-2025 Stefan Kalscheuer
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -59,28 +59,28 @@ class TokenRoleTest extends AbstractModelTest<TokenRole> {
|
||||
private static final String TOKEN_BOUND_CIDR_2 = "198.51.100.0/24";
|
||||
private static final String TOKEN_BOUND_CIDR_3 = "203.0.113.0/24";
|
||||
private static final List<String> TOKEN_BOUND_CIDRS = Arrays.asList(TOKEN_BOUND_CIDR_2, TOKEN_BOUND_CIDR_1);
|
||||
private static final Integer TOKEN_EXPLICIT_MAX_TTL = 1234;
|
||||
private static final Long TOKEN_EXPLICIT_MAX_TTL = 1234L;
|
||||
private static final Boolean TOKEN_NO_DEFAULT_POLICY = false;
|
||||
private static final Integer TOKEN_NUM_USES = 5;
|
||||
private static final Integer TOKEN_PERIOD = 2345;
|
||||
private static final Token.Type TOKEN_TYPE = Token.Type.SERVICE;
|
||||
|
||||
private static final String JSON_FULL = "{" +
|
||||
"\"name\":\"" + NAME + "\"," +
|
||||
"\"allowed_policies\":[\"" + ALLOWED_POLICY_1 + "\",\"" + ALLOWED_POLICY_2 + "\",\"" + ALLOWED_POLICY_3 + "\"]," +
|
||||
"\"allowed_policies_glob\":[\"" + ALLOWED_POLICY_GLOB_1 + "\",\"" + ALLOWED_POLICY_GLOB_2 + "\",\"" + ALLOWED_POLICY_GLOB_3 + "\"]," +
|
||||
"\"disallowed_policies\":[\"" + DISALLOWED_POLICY_1 + "\",\"" + DISALLOWED_POLICY_2 + "\",\"" + DISALLOWED_POLICY_3 + "\"]," +
|
||||
"\"disallowed_policies_glob\":[\"" + DISALLOWED_POLICY_GLOB_1 + "\",\"" + DISALLOWED_POLICY_GLOB_2 + "\",\"" + DISALLOWED_POLICY_GLOB_3 + "\"]," +
|
||||
"\"orphan\":" + ORPHAN + "," +
|
||||
"\"renewable\":" + RENEWABLE + "," +
|
||||
"\"path_suffix\":\"" + PATH_SUFFIX + "\"," +
|
||||
"\"allowed_entity_aliases\":[\"" + ALLOWED_ENTITY_ALIAS_1 + "\",\"" + ALLOWED_ENTITY_ALIAS_3 + "\",\"" + ALLOWED_ENTITY_ALIAS_2 + "\"]," +
|
||||
"\"token_bound_cidrs\":[\"" + TOKEN_BOUND_CIDR_3 + "\",\"" + TOKEN_BOUND_CIDR_2 + "\",\"" + TOKEN_BOUND_CIDR_1 + "\"]," +
|
||||
"\"token_explicit_max_ttl\":" + TOKEN_EXPLICIT_MAX_TTL + "," +
|
||||
"\"token_no_default_policy\":" + TOKEN_NO_DEFAULT_POLICY + "," +
|
||||
"\"token_num_uses\":" + TOKEN_NUM_USES + "," +
|
||||
"\"token_period\":" + TOKEN_PERIOD + "," +
|
||||
"\"token_type\":\"" + TOKEN_TYPE.value() + "\"}";
|
||||
"\"name\":\"" + NAME + "\"," +
|
||||
"\"allowed_policies\":[\"" + ALLOWED_POLICY_1 + "\",\"" + ALLOWED_POLICY_2 + "\",\"" + ALLOWED_POLICY_3 + "\"]," +
|
||||
"\"allowed_policies_glob\":[\"" + ALLOWED_POLICY_GLOB_1 + "\",\"" + ALLOWED_POLICY_GLOB_2 + "\",\"" + ALLOWED_POLICY_GLOB_3 + "\"]," +
|
||||
"\"disallowed_policies\":[\"" + DISALLOWED_POLICY_1 + "\",\"" + DISALLOWED_POLICY_2 + "\",\"" + DISALLOWED_POLICY_3 + "\"]," +
|
||||
"\"disallowed_policies_glob\":[\"" + DISALLOWED_POLICY_GLOB_1 + "\",\"" + DISALLOWED_POLICY_GLOB_2 + "\",\"" + DISALLOWED_POLICY_GLOB_3 + "\"]," +
|
||||
"\"orphan\":" + ORPHAN + "," +
|
||||
"\"renewable\":" + RENEWABLE + "," +
|
||||
"\"path_suffix\":\"" + PATH_SUFFIX + "\"," +
|
||||
"\"allowed_entity_aliases\":[\"" + ALLOWED_ENTITY_ALIAS_1 + "\",\"" + ALLOWED_ENTITY_ALIAS_3 + "\",\"" + ALLOWED_ENTITY_ALIAS_2 + "\"]," +
|
||||
"\"token_bound_cidrs\":[\"" + TOKEN_BOUND_CIDR_3 + "\",\"" + TOKEN_BOUND_CIDR_2 + "\",\"" + TOKEN_BOUND_CIDR_1 + "\"]," +
|
||||
"\"token_explicit_max_ttl\":" + TOKEN_EXPLICIT_MAX_TTL + "," +
|
||||
"\"token_no_default_policy\":" + TOKEN_NO_DEFAULT_POLICY + "," +
|
||||
"\"token_num_uses\":" + TOKEN_NUM_USES + "," +
|
||||
"\"token_period\":" + TOKEN_PERIOD + "," +
|
||||
"\"token_type\":\"" + TOKEN_TYPE.value() + "\"}";
|
||||
|
||||
TokenRoleTest() {
|
||||
super(TokenRole.class);
|
||||
@@ -89,28 +89,28 @@ class TokenRoleTest extends AbstractModelTest<TokenRole> {
|
||||
@Override
|
||||
protected TokenRole createFull() {
|
||||
return TokenRole.builder()
|
||||
.forName(NAME)
|
||||
.withAllowedPolicies(ALLOWED_POLICIES)
|
||||
.withAllowedPolicy(ALLOWED_POLICY_3)
|
||||
.withAllowedPolicyGlob(ALLOWED_POLICY_GLOB_1)
|
||||
.withAllowedPoliciesGlob(ALLOWED_POLICIES_GLOB)
|
||||
.withDisallowedPolicy(DISALLOWED_POLICY_1)
|
||||
.withDisallowedPolicies(DISALLOWED_POLICIES)
|
||||
.withDisallowedPoliciesGlob(DISALLOWED_POLICIES_GLOB)
|
||||
.withDisallowedPolicyGlob(DISALLOWED_POLICY_GLOB_3)
|
||||
.orphan(ORPHAN)
|
||||
.renewable(RENEWABLE)
|
||||
.withPathSuffix(PATH_SUFFIX)
|
||||
.withAllowedEntityAliases(ALLOWED_ENTITY_ALIASES)
|
||||
.withAllowedEntityAlias(ALLOWED_ENTITY_ALIAS_2)
|
||||
.withTokenBoundCidr(TOKEN_BOUND_CIDR_3)
|
||||
.withTokenBoundCidrs(TOKEN_BOUND_CIDRS)
|
||||
.withTokenExplicitMaxTtl(TOKEN_EXPLICIT_MAX_TTL)
|
||||
.withTokenNoDefaultPolicy(TOKEN_NO_DEFAULT_POLICY)
|
||||
.withTokenNumUses(TOKEN_NUM_USES)
|
||||
.withTokenPeriod(TOKEN_PERIOD)
|
||||
.withTokenType(TOKEN_TYPE)
|
||||
.build();
|
||||
.forName(NAME)
|
||||
.withAllowedPolicies(ALLOWED_POLICIES)
|
||||
.withAllowedPolicy(ALLOWED_POLICY_3)
|
||||
.withAllowedPolicyGlob(ALLOWED_POLICY_GLOB_1)
|
||||
.withAllowedPoliciesGlob(ALLOWED_POLICIES_GLOB)
|
||||
.withDisallowedPolicy(DISALLOWED_POLICY_1)
|
||||
.withDisallowedPolicies(DISALLOWED_POLICIES)
|
||||
.withDisallowedPoliciesGlob(DISALLOWED_POLICIES_GLOB)
|
||||
.withDisallowedPolicyGlob(DISALLOWED_POLICY_GLOB_3)
|
||||
.orphan(ORPHAN)
|
||||
.renewable(RENEWABLE)
|
||||
.withPathSuffix(PATH_SUFFIX)
|
||||
.withAllowedEntityAliases(ALLOWED_ENTITY_ALIASES)
|
||||
.withAllowedEntityAlias(ALLOWED_ENTITY_ALIAS_2)
|
||||
.withTokenBoundCidr(TOKEN_BOUND_CIDR_3)
|
||||
.withTokenBoundCidrs(TOKEN_BOUND_CIDRS)
|
||||
.withTokenExplicitMaxTtl(TOKEN_EXPLICIT_MAX_TTL)
|
||||
.withTokenNoDefaultPolicy(TOKEN_NO_DEFAULT_POLICY)
|
||||
.withTokenNumUses(TOKEN_NUM_USES)
|
||||
.withTokenPeriod(TOKEN_PERIOD)
|
||||
.withTokenType(TOKEN_TYPE)
|
||||
.build();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -141,24 +141,24 @@ class TokenRoleTest extends AbstractModelTest<TokenRole> {
|
||||
@Test
|
||||
void buildNullTest() throws JsonProcessingException {
|
||||
TokenRole role = TokenRole.builder()
|
||||
.forName(null)
|
||||
.withAllowedPolicies(null)
|
||||
.withAllowedPolicy(null)
|
||||
.withDisallowedPolicy(null)
|
||||
.withDisallowedPolicies(null)
|
||||
.orphan(null)
|
||||
.renewable(null)
|
||||
.withPathSuffix(null)
|
||||
.withAllowedEntityAliases(null)
|
||||
.withAllowedEntityAlias(null)
|
||||
.withTokenBoundCidr(null)
|
||||
.withTokenBoundCidrs(null)
|
||||
.withTokenExplicitMaxTtl(null)
|
||||
.withTokenNoDefaultPolicy(null)
|
||||
.withTokenNumUses(null)
|
||||
.withTokenPeriod(null)
|
||||
.withTokenType(null)
|
||||
.build();
|
||||
.forName(null)
|
||||
.withAllowedPolicies(null)
|
||||
.withAllowedPolicy(null)
|
||||
.withDisallowedPolicy(null)
|
||||
.withDisallowedPolicies(null)
|
||||
.orphan(null)
|
||||
.renewable(null)
|
||||
.withPathSuffix(null)
|
||||
.withAllowedEntityAliases(null)
|
||||
.withAllowedEntityAlias(null)
|
||||
.withTokenBoundCidr(null)
|
||||
.withTokenBoundCidrs(null)
|
||||
.withTokenExplicitMaxTtl(null)
|
||||
.withTokenNoDefaultPolicy(null)
|
||||
.withTokenNumUses(null)
|
||||
.withTokenPeriod(null)
|
||||
.withTokenType(null)
|
||||
.build();
|
||||
|
||||
assertNull(role.getAllowedPolicies());
|
||||
assertNull(role.getDisallowedPolicies());
|
||||
@@ -173,7 +173,7 @@ class TokenRoleTest extends AbstractModelTest<TokenRole> {
|
||||
assertNull(role.getTokenType());
|
||||
|
||||
// Empty builder should be equal to no-arg construction.
|
||||
assertEquals(role, new TokenRole());
|
||||
assertEquals(new TokenRole(), role);
|
||||
|
||||
// Optional fields should be ignored, so JSON string should be empty.
|
||||
assertEquals("{}", objectMapper.writeValueAsString(role));
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016-2024 Stefan Kalscheuer
|
||||
* Copyright 2016-2025 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,8 +35,8 @@ class TokenTest extends AbstractModelTest<Token> {
|
||||
private static final String DISPLAY_NAME = "display-name";
|
||||
private static final Boolean NO_PARENT = false;
|
||||
private static final Boolean NO_DEFAULT_POLICY = false;
|
||||
private static final Integer TTL = 123;
|
||||
private static final Integer EXPLICIT_MAX_TTL = 456;
|
||||
private static final Long TTL = 123L;
|
||||
private static final Long EXPLICIT_MAX_TTL = 456L;
|
||||
private static final Integer NUM_USES = 4;
|
||||
private static final List<String> POLICIES = new ArrayList<>();
|
||||
private static final String POLICY = "policy";
|
||||
@@ -59,20 +59,20 @@ class TokenTest extends AbstractModelTest<Token> {
|
||||
@Override
|
||||
protected Token createFull() {
|
||||
return Token.builder()
|
||||
.withId(ID)
|
||||
.withType(Token.Type.SERVICE)
|
||||
.withDisplayName(DISPLAY_NAME)
|
||||
.withNoParent(NO_PARENT)
|
||||
.withNoDefaultPolicy(NO_DEFAULT_POLICY)
|
||||
.withTtl(TTL)
|
||||
.withExplicitMaxTtl(EXPLICIT_MAX_TTL)
|
||||
.withNumUses(NUM_USES)
|
||||
.withPolicies(POLICIES)
|
||||
.withMeta(META)
|
||||
.withRenewable(RENEWABLE)
|
||||
.withPeriod(PERIOD)
|
||||
.withEntityAlias(ENTITY_ALIAS)
|
||||
.build();
|
||||
.withId(ID)
|
||||
.withType(Token.Type.SERVICE)
|
||||
.withDisplayName(DISPLAY_NAME)
|
||||
.withNoParent(NO_PARENT)
|
||||
.withNoDefaultPolicy(NO_DEFAULT_POLICY)
|
||||
.withTtl(TTL)
|
||||
.withExplicitMaxTtl(EXPLICIT_MAX_TTL)
|
||||
.withNumUses(NUM_USES)
|
||||
.withPolicies(POLICIES)
|
||||
.withMeta(META)
|
||||
.withRenewable(RENEWABLE)
|
||||
.withPeriod(PERIOD)
|
||||
.withEntityAlias(ENTITY_ALIAS)
|
||||
.build();
|
||||
}
|
||||
|
||||
@BeforeAll
|
||||
@@ -105,7 +105,7 @@ class TokenTest extends AbstractModelTest<Token> {
|
||||
assertEquals("{}", objectMapper.writeValueAsString(token));
|
||||
|
||||
// Empty builder should be equal to no-arg construction.
|
||||
assertEquals(token, new Token());
|
||||
assertEquals(new Token(), token);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -159,9 +159,9 @@ class TokenTest extends AbstractModelTest<Token> {
|
||||
assertEquals(1, token.getPolicies().size());
|
||||
assertEquals(List.of(POLICY_2), token.getPolicies());
|
||||
token = Token.builder()
|
||||
.withPolicies(POLICY, POLICY_2)
|
||||
.withPolicy(POLICY_3)
|
||||
.build();
|
||||
.withPolicies(POLICY, POLICY_2)
|
||||
.withPolicy(POLICY_3)
|
||||
.build();
|
||||
assertEquals(3, token.getPolicies().size());
|
||||
assertTrue(token.getPolicies().containsAll(List.of(POLICY, POLICY_2, POLICY_3)));
|
||||
|
||||
@@ -171,9 +171,9 @@ class TokenTest extends AbstractModelTest<Token> {
|
||||
assertEquals(Set.of(META_KEY_2), token.getMeta().keySet());
|
||||
assertEquals(META_VALUE_2, token.getMeta().get(META_KEY_2));
|
||||
token = Token.builder()
|
||||
.withMeta(META)
|
||||
.withMeta(META_KEY_2, META_VALUE_2)
|
||||
.build();
|
||||
.withMeta(META)
|
||||
.withMeta(META_KEY_2, META_VALUE_2)
|
||||
.build();
|
||||
assertEquals(2, token.getMeta().size());
|
||||
assertEquals(META_VALUE, token.getMeta().get(META_KEY));
|
||||
assertEquals(META_VALUE_2, token.getMeta().get(META_KEY_2));
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016-2024 Stefan Kalscheuer
|
||||
* Copyright 2016-2025 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,7 +16,6 @@
|
||||
|
||||
package de.stklcode.jvault.connector.model.response;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import de.stklcode.jvault.connector.model.AbstractModelTest;
|
||||
import de.stklcode.jvault.connector.model.AppRole;
|
||||
import org.junit.jupiter.api.Test;
|
||||
@@ -32,34 +31,34 @@ import static org.junit.jupiter.api.Assertions.*;
|
||||
* @since 0.6.2
|
||||
*/
|
||||
class AppRoleResponseTest extends AbstractModelTest<AppRoleResponse> {
|
||||
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;
|
||||
private static final Long ROLE_TOKEN_TTL = 1200L;
|
||||
private static final Long ROLE_TOKEN_MAX_TTL = 1800L;
|
||||
private static final Long ROLE_SECRET_TTL = 600L;
|
||||
private static final Integer ROLE_SECRET_NUM_USES = 40;
|
||||
private static final String ROLE_POLICY = "default";
|
||||
private static final Integer ROLE_PERIOD = 0;
|
||||
private static final Boolean ROLE_BIND_SECRET = true;
|
||||
|
||||
private static final String RES_JSON = "{\n" +
|
||||
" \"auth\": null,\n" +
|
||||
" \"warnings\": null,\n" +
|
||||
" \"wrap_info\": null,\n" +
|
||||
" \"data\": {\n" +
|
||||
" \"token_ttl\": " + ROLE_TOKEN_TTL + ",\n" +
|
||||
" \"token_max_ttl\": " + ROLE_TOKEN_MAX_TTL + ",\n" +
|
||||
" \"secret_id_ttl\": " + ROLE_SECRET_TTL + ",\n" +
|
||||
" \"secret_id_num_uses\": " + ROLE_SECRET_NUM_USES + ",\n" +
|
||||
" \"token_policies\": [\n" +
|
||||
" \"" + ROLE_POLICY + "\"\n" +
|
||||
" ],\n" +
|
||||
" \"token_period\": " + ROLE_PERIOD + ",\n" +
|
||||
" \"bind_secret_id\": " + ROLE_BIND_SECRET + ",\n" +
|
||||
" \"bound_cidr_list\": \"\"\n" +
|
||||
" },\n" +
|
||||
" \"lease_duration\": 0,\n" +
|
||||
" \"renewable\": false,\n" +
|
||||
" \"lease_id\": \"\"\n" +
|
||||
"}";
|
||||
" \"auth\": null,\n" +
|
||||
" \"warnings\": null,\n" +
|
||||
" \"wrap_info\": null,\n" +
|
||||
" \"data\": {\n" +
|
||||
" \"token_ttl\": " + ROLE_TOKEN_TTL + ",\n" +
|
||||
" \"token_max_ttl\": " + ROLE_TOKEN_MAX_TTL + ",\n" +
|
||||
" \"secret_id_ttl\": " + ROLE_SECRET_TTL + ",\n" +
|
||||
" \"secret_id_num_uses\": " + ROLE_SECRET_NUM_USES + ",\n" +
|
||||
" \"token_policies\": [\n" +
|
||||
" \"" + ROLE_POLICY + "\"\n" +
|
||||
" ],\n" +
|
||||
" \"token_period\": " + ROLE_PERIOD + ",\n" +
|
||||
" \"bind_secret_id\": " + ROLE_BIND_SECRET + ",\n" +
|
||||
" \"bound_cidr_list\": \"\"\n" +
|
||||
" },\n" +
|
||||
" \"lease_duration\": 0,\n" +
|
||||
" \"renewable\": false,\n" +
|
||||
" \"lease_id\": \"\"\n" +
|
||||
"}";
|
||||
|
||||
AppRoleResponseTest() {
|
||||
super(AppRoleResponse.class);
|
||||
@@ -67,12 +66,10 @@ class AppRoleResponseTest extends AbstractModelTest<AppRoleResponse> {
|
||||
|
||||
@Override
|
||||
protected AppRoleResponse createFull() {
|
||||
try {
|
||||
return objectMapper.readValue(RES_JSON, AppRoleResponse.class);
|
||||
} catch (JsonProcessingException e) {
|
||||
fail("Creation of full model instance failed", e);
|
||||
return null;
|
||||
}
|
||||
return assertDoesNotThrow(
|
||||
() -> objectMapper.readValue(RES_JSON, AppRoleResponse.class),
|
||||
"Creation of full model instance failed"
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -91,8 +88,8 @@ class AppRoleResponseTest extends AbstractModelTest<AppRoleResponse> {
|
||||
@Test
|
||||
void jsonRoundtrip() {
|
||||
AppRoleResponse res = assertDoesNotThrow(
|
||||
() -> objectMapper.readValue(RES_JSON, AppRoleResponse.class),
|
||||
"AuthResponse deserialization failed"
|
||||
() -> objectMapper.readValue(RES_JSON, AppRoleResponse.class),
|
||||
"AuthResponse deserialization failed"
|
||||
);
|
||||
assertNotNull(res, "Parsed response is NULL");
|
||||
// Extract role data.
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016-2024 Stefan Kalscheuer
|
||||
* Copyright 2016-2025 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,7 +16,6 @@
|
||||
|
||||
package de.stklcode.jvault.connector.model.response;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import de.stklcode.jvault.connector.model.AbstractModelTest;
|
||||
import de.stklcode.jvault.connector.model.AuthBackend;
|
||||
import de.stklcode.jvault.connector.model.response.embedded.AuthMethod;
|
||||
@@ -45,44 +44,44 @@ class AuthMethodsResponseTest extends AbstractModelTest<AuthMethodsResponse> {
|
||||
private static final String TK_UUID = "32ea9681-6bd6-6cec-eec3-d11260ba9741";
|
||||
private static final String TK_ACCESSOR = "auth_token_ac0dd95a";
|
||||
private static final String TK_DESCR = "token based credentials";
|
||||
private static final Integer TK_LEASE_TTL = 0;
|
||||
private static final Long TK_LEASE_TTL = 0L;
|
||||
private static final Boolean TK_FORCE_NO_CACHE = false;
|
||||
private static final Integer TK_MAX_LEASE_TTL = 0;
|
||||
private static final Long TK_MAX_LEASE_TTL = 0L;
|
||||
private static final String TK_TOKEN_TYPE = "default-service";
|
||||
private static final String TK_RUNNING_PLUGIN_VERSION = "v1.15.3+builtin.vault";
|
||||
|
||||
private static final String RES_JSON = "{\n" +
|
||||
" \"data\": {" +
|
||||
" \"" + GH_PATH + "\": {\n" +
|
||||
" \"uuid\": \"" + GH_UUID + "\",\n" +
|
||||
" \"type\": \"" + GH_TYPE + "\",\n" +
|
||||
" \"accessor\": \"" + GH_ACCESSOR + "\",\n" +
|
||||
" \"description\": \"" + GH_DESCR + "\",\n" +
|
||||
" \"external_entropy_access\": false,\n" +
|
||||
" \"local\": false,\n" +
|
||||
" \"seal_wrap\": false\n" +
|
||||
" },\n" +
|
||||
" \"" + TK_PATH + "\": {\n" +
|
||||
" \"config\": {\n" +
|
||||
" \"default_lease_ttl\": " + TK_LEASE_TTL + ",\n" +
|
||||
" \"force_no_cache\": " + TK_FORCE_NO_CACHE + ",\n" +
|
||||
" \"max_lease_ttl\": " + TK_MAX_LEASE_TTL + ",\n" +
|
||||
" \"token_type\": \"" + TK_TOKEN_TYPE + "\"\n" +
|
||||
" },\n" +
|
||||
" \"description\": \"" + TK_DESCR + "\",\n" +
|
||||
" \"options\": null,\n" +
|
||||
" \"plugin_version\": \"\",\n" +
|
||||
" \"running_plugin_version\": \"" + TK_RUNNING_PLUGIN_VERSION + "\",\n" +
|
||||
" \"running_sha256\": \"\",\n" +
|
||||
" \"type\": \"" + TK_TYPE + "\",\n" +
|
||||
" \"uuid\": \"" + TK_UUID + "\",\n" +
|
||||
" \"accessor\": \"" + TK_ACCESSOR + "\",\n" +
|
||||
" \"external_entropy_access\": false,\n" +
|
||||
" \"local\": true,\n" +
|
||||
" \"seal_wrap\": false\n" +
|
||||
" }\n" +
|
||||
" }\n" +
|
||||
"}";
|
||||
" \"data\": {" +
|
||||
" \"" + GH_PATH + "\": {\n" +
|
||||
" \"uuid\": \"" + GH_UUID + "\",\n" +
|
||||
" \"type\": \"" + GH_TYPE + "\",\n" +
|
||||
" \"accessor\": \"" + GH_ACCESSOR + "\",\n" +
|
||||
" \"description\": \"" + GH_DESCR + "\",\n" +
|
||||
" \"external_entropy_access\": false,\n" +
|
||||
" \"local\": false,\n" +
|
||||
" \"seal_wrap\": false\n" +
|
||||
" },\n" +
|
||||
" \"" + TK_PATH + "\": {\n" +
|
||||
" \"config\": {\n" +
|
||||
" \"default_lease_ttl\": " + TK_LEASE_TTL + ",\n" +
|
||||
" \"force_no_cache\": " + TK_FORCE_NO_CACHE + ",\n" +
|
||||
" \"max_lease_ttl\": " + TK_MAX_LEASE_TTL + ",\n" +
|
||||
" \"token_type\": \"" + TK_TOKEN_TYPE + "\"\n" +
|
||||
" },\n" +
|
||||
" \"description\": \"" + TK_DESCR + "\",\n" +
|
||||
" \"options\": null,\n" +
|
||||
" \"plugin_version\": \"\",\n" +
|
||||
" \"running_plugin_version\": \"" + TK_RUNNING_PLUGIN_VERSION + "\",\n" +
|
||||
" \"running_sha256\": \"\",\n" +
|
||||
" \"type\": \"" + TK_TYPE + "\",\n" +
|
||||
" \"uuid\": \"" + TK_UUID + "\",\n" +
|
||||
" \"accessor\": \"" + TK_ACCESSOR + "\",\n" +
|
||||
" \"external_entropy_access\": false,\n" +
|
||||
" \"local\": true,\n" +
|
||||
" \"seal_wrap\": false\n" +
|
||||
" }\n" +
|
||||
" }\n" +
|
||||
"}";
|
||||
|
||||
AuthMethodsResponseTest() {
|
||||
super(AuthMethodsResponse.class);
|
||||
@@ -90,12 +89,10 @@ class AuthMethodsResponseTest extends AbstractModelTest<AuthMethodsResponse> {
|
||||
|
||||
@Override
|
||||
protected AuthMethodsResponse createFull() {
|
||||
try {
|
||||
return objectMapper.readValue(RES_JSON, AuthMethodsResponse.class);
|
||||
} catch (JsonProcessingException e) {
|
||||
fail("Creation of full model instance failed", e);
|
||||
return null;
|
||||
}
|
||||
return assertDoesNotThrow(
|
||||
() -> objectMapper.readValue(RES_JSON, AuthMethodsResponse.class),
|
||||
"Creation of full model instance failed"
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -114,8 +111,8 @@ class AuthMethodsResponseTest extends AbstractModelTest<AuthMethodsResponse> {
|
||||
@Test
|
||||
void jsonRoundtrip() {
|
||||
AuthMethodsResponse res = assertDoesNotThrow(
|
||||
() -> objectMapper.readValue(RES_JSON, AuthMethodsResponse.class),
|
||||
"AuthResponse deserialization failed"
|
||||
() -> objectMapper.readValue(RES_JSON, AuthMethodsResponse.class),
|
||||
"AuthResponse deserialization failed"
|
||||
);
|
||||
assertNotNull(res, "Parsed response is NULL");
|
||||
// Extract auth data.
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016-2024 Stefan Kalscheuer
|
||||
* Copyright 2016-2025 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,7 +16,6 @@
|
||||
|
||||
package de.stklcode.jvault.connector.model.response;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import de.stklcode.jvault.connector.model.AbstractModelTest;
|
||||
import de.stklcode.jvault.connector.model.response.embedded.AuthData;
|
||||
import de.stklcode.jvault.connector.model.response.embedded.MfaConstraintAny;
|
||||
@@ -101,12 +100,10 @@ class AuthResponseTest extends AbstractModelTest<AuthResponse> {
|
||||
|
||||
@Override
|
||||
protected AuthResponse createFull() {
|
||||
try {
|
||||
return objectMapper.readValue(RES_JSON, AuthResponse.class);
|
||||
} catch (JsonProcessingException e) {
|
||||
fail("Creation of full model instance failed", e);
|
||||
return null;
|
||||
}
|
||||
return assertDoesNotThrow(
|
||||
() -> objectMapper.readValue(RES_JSON, AuthResponse.class),
|
||||
"Creation of full model instance failed"
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -122,8 +119,8 @@ class AuthResponseTest extends AbstractModelTest<AuthResponse> {
|
||||
@Test
|
||||
void jsonRoundtrip() {
|
||||
AuthResponse res = assertDoesNotThrow(
|
||||
() -> objectMapper.readValue(RES_JSON, AuthResponse.class),
|
||||
"AuthResponse deserialization failed"
|
||||
() -> objectMapper.readValue(RES_JSON, AuthResponse.class),
|
||||
"AuthResponse deserialization failed"
|
||||
);
|
||||
assertNotNull(res, "Parsed response is NULL");
|
||||
// Extract auth data.
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016-2024 Stefan Kalscheuer
|
||||
* Copyright 2016-2025 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,7 +16,6 @@
|
||||
|
||||
package de.stklcode.jvault.connector.model.response;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import de.stklcode.jvault.connector.model.AbstractModelTest;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
@@ -32,16 +31,16 @@ class CredentialsResponseTest extends AbstractModelTest<CredentialsResponse> {
|
||||
private static final String VAL_USER = "testUserName";
|
||||
private static final String VAL_PASS = "5up3r5ecr3tP455";
|
||||
private static final String JSON = "{\n" +
|
||||
" \"request_id\": \"68315073-6658-e3ff-2da7-67939fb91bbd\",\n" +
|
||||
" \"lease_id\": \"\",\n" +
|
||||
" \"lease_duration\": 2764800,\n" +
|
||||
" \"renewable\": false,\n" +
|
||||
" \"data\": {\n" +
|
||||
" \"username\": \"" + VAL_USER + "\",\n" +
|
||||
" \"password\": \"" + VAL_PASS + "\"\n" +
|
||||
" },\n" +
|
||||
" \"warnings\": null\n" +
|
||||
"}";
|
||||
" \"request_id\": \"68315073-6658-e3ff-2da7-67939fb91bbd\",\n" +
|
||||
" \"lease_id\": \"\",\n" +
|
||||
" \"lease_duration\": 2764800,\n" +
|
||||
" \"renewable\": false,\n" +
|
||||
" \"data\": {\n" +
|
||||
" \"username\": \"" + VAL_USER + "\",\n" +
|
||||
" \"password\": \"" + VAL_PASS + "\"\n" +
|
||||
" },\n" +
|
||||
" \"warnings\": null\n" +
|
||||
"}";
|
||||
|
||||
CredentialsResponseTest() {
|
||||
super(CredentialsResponse.class);
|
||||
@@ -49,12 +48,10 @@ class CredentialsResponseTest extends AbstractModelTest<CredentialsResponse> {
|
||||
|
||||
@Override
|
||||
protected CredentialsResponse createFull() {
|
||||
try {
|
||||
return objectMapper.readValue(JSON, CredentialsResponse.class);
|
||||
} catch (JsonProcessingException e) {
|
||||
fail("Creation of full model instance failed", e);
|
||||
return null;
|
||||
}
|
||||
return assertDoesNotThrow(
|
||||
() -> objectMapper.readValue(JSON, CredentialsResponse.class),
|
||||
"Creation of full model instance failed"
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -68,8 +65,8 @@ class CredentialsResponseTest extends AbstractModelTest<CredentialsResponse> {
|
||||
assertNull(res.getPassword(), "Password not present in data map should not return anything");
|
||||
|
||||
res = assertDoesNotThrow(
|
||||
() -> objectMapper.readValue(JSON, CredentialsResponse.class),
|
||||
"Deserialization of CredentialsResponse failed"
|
||||
() -> objectMapper.readValue(JSON, CredentialsResponse.class),
|
||||
"Deserialization of CredentialsResponse failed"
|
||||
);
|
||||
assertEquals(VAL_USER, res.getUsername(), "Incorrect username");
|
||||
assertEquals(VAL_PASS, res.getPassword(), "Incorrect password");
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016-2021 Stefan Kalscheuer
|
||||
* Copyright 2016-2025 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,7 +16,6 @@
|
||||
|
||||
package de.stklcode.jvault.connector.model.response;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import de.stklcode.jvault.connector.model.AbstractModelTest;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
@@ -42,12 +41,10 @@ class ErrorResponseTest extends AbstractModelTest<ErrorResponse> {
|
||||
|
||||
@Override
|
||||
protected ErrorResponse createFull() {
|
||||
try {
|
||||
return objectMapper.readValue(JSON, ErrorResponse.class);
|
||||
} catch (JsonProcessingException e) {
|
||||
fail("Creation of full model instance failed", e);
|
||||
return null;
|
||||
}
|
||||
return assertDoesNotThrow(
|
||||
() -> objectMapper.readValue(JSON, ErrorResponse.class),
|
||||
"Creation of full model instance failed"
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -56,15 +53,15 @@ class ErrorResponseTest extends AbstractModelTest<ErrorResponse> {
|
||||
@Test
|
||||
void jsonRoundtrip() {
|
||||
ErrorResponse res = assertDoesNotThrow(
|
||||
() -> objectMapper.readValue(JSON, ErrorResponse.class),
|
||||
"ErrorResponse deserialization failed"
|
||||
() -> objectMapper.readValue(JSON, ErrorResponse.class),
|
||||
"ErrorResponse deserialization failed"
|
||||
);
|
||||
assertNotNull(res, "Parsed response is NULL");
|
||||
assertEquals(List.of(ERROR_1, ERROR_2), res.getErrors(), "Unexpected error messages");
|
||||
assertEquals(
|
||||
JSON,
|
||||
assertDoesNotThrow(() -> objectMapper.writeValueAsString(res), "ErrorResponse serialization failed"),
|
||||
"Unexpected JSON string after serialization"
|
||||
JSON,
|
||||
assertDoesNotThrow(() -> objectMapper.writeValueAsString(res), "ErrorResponse serialization failed"),
|
||||
"Unexpected JSON string after serialization"
|
||||
);
|
||||
}
|
||||
|
||||
@@ -72,14 +69,14 @@ class ErrorResponseTest extends AbstractModelTest<ErrorResponse> {
|
||||
@Test
|
||||
void testToString() {
|
||||
ErrorResponse res = assertDoesNotThrow(
|
||||
() -> objectMapper.readValue(JSON, ErrorResponse.class),
|
||||
"ErrorResponse deserialization failed"
|
||||
() -> objectMapper.readValue(JSON, ErrorResponse.class),
|
||||
"ErrorResponse deserialization failed"
|
||||
);
|
||||
assertEquals(ERROR_1, res.toString());
|
||||
|
||||
res = assertDoesNotThrow(
|
||||
() -> objectMapper.readValue(JSON_EMPTY, ErrorResponse.class),
|
||||
"ErrorResponse deserialization failed with empty list"
|
||||
() -> objectMapper.readValue(JSON_EMPTY, ErrorResponse.class),
|
||||
"ErrorResponse deserialization failed with empty list"
|
||||
);
|
||||
assertEquals("error response", res.toString());
|
||||
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016-2024 Stefan Kalscheuer
|
||||
* Copyright 2016-2025 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,7 +16,6 @@
|
||||
|
||||
package de.stklcode.jvault.connector.model.response;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import de.stklcode.jvault.connector.model.AbstractModelTest;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
@@ -45,21 +44,21 @@ class HealthResponseTest extends AbstractModelTest<HealthResponse> {
|
||||
private static final Boolean ENTERPRISE = false;
|
||||
|
||||
private static final String RES_JSON = "{\n" +
|
||||
" \"cluster_id\": \"" + CLUSTER_ID + "\",\n" +
|
||||
" \"cluster_name\": \"" + CLUSTER_NAME + "\",\n" +
|
||||
" \"version\": \"" + VERSION + "\",\n" +
|
||||
" \"server_time_utc\": " + SERVER_TIME_UTC + ",\n" +
|
||||
" \"standby\": " + STANDBY + ",\n" +
|
||||
" \"sealed\": " + SEALED + ",\n" +
|
||||
" \"initialized\": " + INITIALIZED + ",\n" +
|
||||
" \"replication_performance_mode\": \"" + REPL_PERF_MODE + "\",\n" +
|
||||
" \"replication_dr_mode\": \"" + REPL_DR_MODE + "\",\n" +
|
||||
" \"performance_standby\": " + PERF_STANDBY + ",\n" +
|
||||
" \"echo_duration_ms\": " + ECHO_DURATION + ",\n" +
|
||||
" \"clock_skew_ms\": " + CLOCK_SKEW + ",\n" +
|
||||
" \"replication_primary_canary_age_ms\": " + REPL_PRIM_CANARY_AGE + ",\n" +
|
||||
" \"enterprise\": " + ENTERPRISE + "\n" +
|
||||
"}";
|
||||
" \"cluster_id\": \"" + CLUSTER_ID + "\",\n" +
|
||||
" \"cluster_name\": \"" + CLUSTER_NAME + "\",\n" +
|
||||
" \"version\": \"" + VERSION + "\",\n" +
|
||||
" \"server_time_utc\": " + SERVER_TIME_UTC + ",\n" +
|
||||
" \"standby\": " + STANDBY + ",\n" +
|
||||
" \"sealed\": " + SEALED + ",\n" +
|
||||
" \"initialized\": " + INITIALIZED + ",\n" +
|
||||
" \"replication_performance_mode\": \"" + REPL_PERF_MODE + "\",\n" +
|
||||
" \"replication_dr_mode\": \"" + REPL_DR_MODE + "\",\n" +
|
||||
" \"performance_standby\": " + PERF_STANDBY + ",\n" +
|
||||
" \"echo_duration_ms\": " + ECHO_DURATION + ",\n" +
|
||||
" \"clock_skew_ms\": " + CLOCK_SKEW + ",\n" +
|
||||
" \"replication_primary_canary_age_ms\": " + REPL_PRIM_CANARY_AGE + ",\n" +
|
||||
" \"enterprise\": " + ENTERPRISE + "\n" +
|
||||
"}";
|
||||
|
||||
HealthResponseTest() {
|
||||
super(HealthResponse.class);
|
||||
@@ -67,12 +66,10 @@ class HealthResponseTest extends AbstractModelTest<HealthResponse> {
|
||||
|
||||
@Override
|
||||
protected HealthResponse createFull() {
|
||||
try {
|
||||
return objectMapper.readValue(RES_JSON, HealthResponse.class);
|
||||
} catch (JsonProcessingException e) {
|
||||
fail("Creation of full model instance failed", e);
|
||||
return null;
|
||||
}
|
||||
return assertDoesNotThrow(
|
||||
() -> objectMapper.readValue(RES_JSON, HealthResponse.class),
|
||||
"Creation of full model instance failed"
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -81,8 +78,8 @@ class HealthResponseTest extends AbstractModelTest<HealthResponse> {
|
||||
@Test
|
||||
void jsonRoundtrip() {
|
||||
HealthResponse res = assertDoesNotThrow(
|
||||
() -> objectMapper.readValue(RES_JSON, HealthResponse.class),
|
||||
"Health deserialization failed"
|
||||
() -> objectMapper.readValue(RES_JSON, HealthResponse.class),
|
||||
"Health deserialization failed"
|
||||
);
|
||||
assertNotNull(res, "Parsed response is NULL");
|
||||
assertEquals(CLUSTER_ID, res.getClusterID(), "Incorrect cluster ID");
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016-2021 Stefan Kalscheuer
|
||||
* Copyright 2016-2025 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,7 +16,6 @@
|
||||
|
||||
package de.stklcode.jvault.connector.model.response;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import de.stklcode.jvault.connector.model.AbstractModelTest;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
@@ -38,12 +37,10 @@ class HelpResponseTest extends AbstractModelTest<HelpResponse> {
|
||||
|
||||
@Override
|
||||
protected HelpResponse createFull() {
|
||||
try {
|
||||
return objectMapper.readValue(JSON, HelpResponse.class);
|
||||
} catch (JsonProcessingException e) {
|
||||
fail("Creation of full model instance failed", e);
|
||||
return null;
|
||||
}
|
||||
return assertDoesNotThrow(
|
||||
() -> objectMapper.readValue(JSON, HelpResponse.class),
|
||||
"Creation of full model instance failed"
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -52,15 +49,15 @@ class HelpResponseTest extends AbstractModelTest<HelpResponse> {
|
||||
@Test
|
||||
void jsonRoundtrip() {
|
||||
HelpResponse res = assertDoesNotThrow(
|
||||
() -> objectMapper.readValue(JSON, HelpResponse.class),
|
||||
"HelpResponse deserialization failed"
|
||||
() -> objectMapper.readValue(JSON, HelpResponse.class),
|
||||
"HelpResponse deserialization failed"
|
||||
);
|
||||
assertNotNull(res, "Parsed response is NULL");
|
||||
assertEquals(HELP, res.getHelp(), "Unexpected help text");
|
||||
assertEquals(
|
||||
JSON,
|
||||
assertDoesNotThrow(() -> objectMapper.writeValueAsString(res), "HelpResponse serialization failed"),
|
||||
"Unexpected JSON string after serialization"
|
||||
JSON,
|
||||
assertDoesNotThrow(() -> objectMapper.writeValueAsString(res), "HelpResponse serialization failed"),
|
||||
"Unexpected JSON string after serialization"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016-2024 Stefan Kalscheuer
|
||||
* Copyright 2016-2025 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,7 +16,6 @@
|
||||
|
||||
package de.stklcode.jvault.connector.model.response;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import de.stklcode.jvault.connector.model.AbstractModelTest;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
@@ -47,47 +46,47 @@ class MetaSecretResponseTest extends AbstractModelTest<MetaSecretResponse> {
|
||||
private static final String CUSTOM_META_VAL = "bar";
|
||||
|
||||
private static final String SECRET_JSON_V2 = "{\n" +
|
||||
" \"request_id\": \"" + SECRET_REQUEST_ID + "\",\n" +
|
||||
" \"lease_id\": \"" + SECRET_LEASE_ID + "\",\n" +
|
||||
" \"lease_duration\": " + SECRET_LEASE_DURATION + ",\n" +
|
||||
" \"renewable\": " + SECRET_RENEWABLE + ",\n" +
|
||||
" \"data\": {\n" +
|
||||
" \"data\": {\n" +
|
||||
" \"" + SECRET_DATA_K1 + "\": \"" + SECRET_DATA_V1 + "\",\n" +
|
||||
" \"" + SECRET_DATA_K2 + "\": \"" + SECRET_DATA_V2 + "\"\n" +
|
||||
" },\n" +
|
||||
" \"metadata\": {\n" +
|
||||
" \"created_time\": \"" + SECRET_META_CREATED + "\",\n" +
|
||||
" \"custom_metadata\": null,\n" +
|
||||
" \"deletion_time\": \"\",\n" +
|
||||
" \"destroyed\": false,\n" +
|
||||
" \"version\": 1\n" +
|
||||
" }\n" +
|
||||
" },\n" +
|
||||
" \"warnings\": " + SECRET_WARNINGS + "\n" +
|
||||
"}";
|
||||
" \"request_id\": \"" + SECRET_REQUEST_ID + "\",\n" +
|
||||
" \"lease_id\": \"" + SECRET_LEASE_ID + "\",\n" +
|
||||
" \"lease_duration\": " + SECRET_LEASE_DURATION + ",\n" +
|
||||
" \"renewable\": " + SECRET_RENEWABLE + ",\n" +
|
||||
" \"data\": {\n" +
|
||||
" \"data\": {\n" +
|
||||
" \"" + SECRET_DATA_K1 + "\": \"" + SECRET_DATA_V1 + "\",\n" +
|
||||
" \"" + SECRET_DATA_K2 + "\": \"" + SECRET_DATA_V2 + "\"\n" +
|
||||
" },\n" +
|
||||
" \"metadata\": {\n" +
|
||||
" \"created_time\": \"" + SECRET_META_CREATED + "\",\n" +
|
||||
" \"custom_metadata\": null,\n" +
|
||||
" \"deletion_time\": \"\",\n" +
|
||||
" \"destroyed\": false,\n" +
|
||||
" \"version\": 1\n" +
|
||||
" }\n" +
|
||||
" },\n" +
|
||||
" \"warnings\": " + SECRET_WARNINGS + "\n" +
|
||||
"}";
|
||||
private static final String SECRET_JSON_V2_2 = "{\n" +
|
||||
" \"request_id\": \"" + SECRET_REQUEST_ID + "\",\n" +
|
||||
" \"lease_id\": \"" + SECRET_LEASE_ID + "\",\n" +
|
||||
" \"lease_duration\": " + SECRET_LEASE_DURATION + ",\n" +
|
||||
" \"renewable\": " + SECRET_RENEWABLE + ",\n" +
|
||||
" \"data\": {\n" +
|
||||
" \"data\": {\n" +
|
||||
" \"" + SECRET_DATA_K1 + "\": \"" + SECRET_DATA_V1 + "\",\n" +
|
||||
" \"" + SECRET_DATA_K2 + "\": \"" + SECRET_DATA_V2 + "\"\n" +
|
||||
" },\n" +
|
||||
" \"metadata\": {\n" +
|
||||
" \"created_time\": \"" + SECRET_META_CREATED + "\",\n" +
|
||||
" \"custom_metadata\": {" +
|
||||
" \"" + CUSTOM_META_KEY + "\": \"" + CUSTOM_META_VAL + "\"" +
|
||||
" },\n" +
|
||||
" \"deletion_time\": \"" + SECRET_META_DELETED + "\",\n" +
|
||||
" \"destroyed\": true,\n" +
|
||||
" \"version\": 2\n" +
|
||||
" }\n" +
|
||||
" },\n" +
|
||||
" \"warnings\": " + SECRET_WARNINGS + "\n" +
|
||||
"}";
|
||||
" \"request_id\": \"" + SECRET_REQUEST_ID + "\",\n" +
|
||||
" \"lease_id\": \"" + SECRET_LEASE_ID + "\",\n" +
|
||||
" \"lease_duration\": " + SECRET_LEASE_DURATION + ",\n" +
|
||||
" \"renewable\": " + SECRET_RENEWABLE + ",\n" +
|
||||
" \"data\": {\n" +
|
||||
" \"data\": {\n" +
|
||||
" \"" + SECRET_DATA_K1 + "\": \"" + SECRET_DATA_V1 + "\",\n" +
|
||||
" \"" + SECRET_DATA_K2 + "\": \"" + SECRET_DATA_V2 + "\"\n" +
|
||||
" },\n" +
|
||||
" \"metadata\": {\n" +
|
||||
" \"created_time\": \"" + SECRET_META_CREATED + "\",\n" +
|
||||
" \"custom_metadata\": {" +
|
||||
" \"" + CUSTOM_META_KEY + "\": \"" + CUSTOM_META_VAL + "\"" +
|
||||
" },\n" +
|
||||
" \"deletion_time\": \"" + SECRET_META_DELETED + "\",\n" +
|
||||
" \"destroyed\": true,\n" +
|
||||
" \"version\": 2\n" +
|
||||
" }\n" +
|
||||
" },\n" +
|
||||
" \"warnings\": " + SECRET_WARNINGS + "\n" +
|
||||
"}";
|
||||
|
||||
MetaSecretResponseTest() {
|
||||
super(MetaSecretResponse.class);
|
||||
@@ -95,12 +94,10 @@ class MetaSecretResponseTest extends AbstractModelTest<MetaSecretResponse> {
|
||||
|
||||
@Override
|
||||
protected MetaSecretResponse createFull() {
|
||||
try {
|
||||
return objectMapper.readValue(SECRET_JSON_V2, MetaSecretResponse.class);
|
||||
} catch (JsonProcessingException e) {
|
||||
fail("Creation of full model instance failed", e);
|
||||
return null;
|
||||
}
|
||||
return assertDoesNotThrow(
|
||||
() -> objectMapper.readValue(SECRET_JSON_V2, MetaSecretResponse.class),
|
||||
"Creation of full model instance failed"
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -110,14 +107,12 @@ class MetaSecretResponseTest extends AbstractModelTest<MetaSecretResponse> {
|
||||
void jsonRoundtrip() {
|
||||
// KV v2 secret.
|
||||
MetaSecretResponse res = assertDoesNotThrow(
|
||||
() -> objectMapper.readValue(SECRET_JSON_V2, MetaSecretResponse.class),
|
||||
"SecretResponse deserialization failed"
|
||||
() -> objectMapper.readValue(SECRET_JSON_V2, MetaSecretResponse.class),
|
||||
"SecretResponse deserialization failed"
|
||||
);
|
||||
assertSecretData(res);
|
||||
assertNotNull(res.getMetadata(), "SecretResponse does not contain metadata");
|
||||
assertEquals(SECRET_META_CREATED, res.getMetadata().getCreatedTimeString(), "Incorrect creation date string");
|
||||
assertNotNull(res.getMetadata().getCreatedTime(), "Creation date parsing failed");
|
||||
assertNull(res.getMetadata().getDeletionTimeString(), "Incorrect deletion date string");
|
||||
assertNull(res.getMetadata().getDeletionTime(), "Incorrect deletion date");
|
||||
assertFalse(res.getMetadata().isDestroyed(), "Secret destroyed when not expected");
|
||||
assertEquals(1, res.getMetadata().getVersion(), "Incorrect secret version");
|
||||
@@ -125,14 +120,12 @@ class MetaSecretResponseTest extends AbstractModelTest<MetaSecretResponse> {
|
||||
|
||||
// Deleted KV v2 secret.
|
||||
res = assertDoesNotThrow(
|
||||
() -> objectMapper.readValue(SECRET_JSON_V2_2, MetaSecretResponse.class),
|
||||
"SecretResponse deserialization failed"
|
||||
() -> objectMapper.readValue(SECRET_JSON_V2_2, MetaSecretResponse.class),
|
||||
"SecretResponse deserialization failed"
|
||||
);
|
||||
assertSecretData(res);
|
||||
assertNotNull(res.getMetadata(), "SecretResponse does not contain metadata");
|
||||
assertEquals(SECRET_META_CREATED, res.getMetadata().getCreatedTimeString(), "Incorrect creation date string");
|
||||
assertNotNull(res.getMetadata().getCreatedTime(), "Creation date parsing failed");
|
||||
assertEquals(SECRET_META_DELETED, res.getMetadata().getDeletionTimeString(), "Incorrect deletion date string");
|
||||
assertNotNull(res.getMetadata().getDeletionTime(), "Incorrect deletion date");
|
||||
assertTrue(res.getMetadata().isDestroyed(), "Secret destroyed when not expected");
|
||||
assertEquals(2, res.getMetadata().getVersion(), "Incorrect secret version");
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016-2024 Stefan Kalscheuer
|
||||
* Copyright 2016-2025 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,7 +16,6 @@
|
||||
|
||||
package de.stklcode.jvault.connector.model.response;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import de.stklcode.jvault.connector.model.AbstractModelTest;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
@@ -43,36 +42,36 @@ class MetadataResponseTest extends AbstractModelTest<MetadataResponse> {
|
||||
private static final String DELETE_VERSION_AFTER = "0s";
|
||||
|
||||
private static final String META_JSON = "{\n" +
|
||||
" \"data\": {\n" +
|
||||
" \"cas_required\": " + CAS_REQUIRED + ",\n" +
|
||||
" \"created_time\": \"" + V1_TIME + "\",\n" +
|
||||
" \"current_version\": " + CURRENT_VERSION + ",\n" +
|
||||
" \"custom_metadata\": {" +
|
||||
" \"" + CUSTOM_META_KEY + "\": \"" + CUSTOM_META_VAL + "\"" +
|
||||
" },\n" +
|
||||
" \"delete_version_after\": \"" + DELETE_VERSION_AFTER + "\"," +
|
||||
" \"max_versions\": " + MAX_VERSIONS + ",\n" +
|
||||
" \"oldest_version\": " + OLDEST_VERSION + ",\n" +
|
||||
" \"updated_time\": \"" + V3_TIME + "\",\n" +
|
||||
" \"versions\": {\n" +
|
||||
" \"1\": {\n" +
|
||||
" \"created_time\": \"" + V1_TIME + "\",\n" +
|
||||
" \"deletion_time\": \"" + V2_TIME + "\",\n" +
|
||||
" \"destroyed\": true\n" +
|
||||
" },\n" +
|
||||
" \"2\": {\n" +
|
||||
" \"created_time\": \"" + V2_TIME + "\",\n" +
|
||||
" \"deletion_time\": \"\",\n" +
|
||||
" \"destroyed\": false\n" +
|
||||
" },\n" +
|
||||
" \"3\": {\n" +
|
||||
" \"created_time\": \"" + V3_TIME + "\",\n" +
|
||||
" \"deletion_time\": \"\",\n" +
|
||||
" \"destroyed\": false\n" +
|
||||
" }\n" +
|
||||
" }\n" +
|
||||
" }\n" +
|
||||
"}";
|
||||
" \"data\": {\n" +
|
||||
" \"cas_required\": " + CAS_REQUIRED + ",\n" +
|
||||
" \"created_time\": \"" + V1_TIME + "\",\n" +
|
||||
" \"current_version\": " + CURRENT_VERSION + ",\n" +
|
||||
" \"custom_metadata\": {" +
|
||||
" \"" + CUSTOM_META_KEY + "\": \"" + CUSTOM_META_VAL + "\"" +
|
||||
" },\n" +
|
||||
" \"delete_version_after\": \"" + DELETE_VERSION_AFTER + "\"," +
|
||||
" \"max_versions\": " + MAX_VERSIONS + ",\n" +
|
||||
" \"oldest_version\": " + OLDEST_VERSION + ",\n" +
|
||||
" \"updated_time\": \"" + V3_TIME + "\",\n" +
|
||||
" \"versions\": {\n" +
|
||||
" \"1\": {\n" +
|
||||
" \"created_time\": \"" + V1_TIME + "\",\n" +
|
||||
" \"deletion_time\": \"" + V2_TIME + "\",\n" +
|
||||
" \"destroyed\": true\n" +
|
||||
" },\n" +
|
||||
" \"2\": {\n" +
|
||||
" \"created_time\": \"" + V2_TIME + "\",\n" +
|
||||
" \"deletion_time\": \"\",\n" +
|
||||
" \"destroyed\": false\n" +
|
||||
" },\n" +
|
||||
" \"3\": {\n" +
|
||||
" \"created_time\": \"" + V3_TIME + "\",\n" +
|
||||
" \"deletion_time\": \"\",\n" +
|
||||
" \"destroyed\": false\n" +
|
||||
" }\n" +
|
||||
" }\n" +
|
||||
" }\n" +
|
||||
"}";
|
||||
|
||||
MetadataResponseTest() {
|
||||
super(MetadataResponse.class);
|
||||
@@ -80,12 +79,10 @@ class MetadataResponseTest extends AbstractModelTest<MetadataResponse> {
|
||||
|
||||
@Override
|
||||
protected MetadataResponse createFull() {
|
||||
try {
|
||||
return objectMapper.readValue(META_JSON, MetadataResponse.class);
|
||||
} catch (JsonProcessingException e) {
|
||||
fail("Creation of full model instance failed", e);
|
||||
return null;
|
||||
}
|
||||
return assertDoesNotThrow(
|
||||
() -> objectMapper.readValue(META_JSON, MetadataResponse.class),
|
||||
"Creation of full model instance failed"
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -94,26 +91,22 @@ class MetadataResponseTest extends AbstractModelTest<MetadataResponse> {
|
||||
@Test
|
||||
void jsonRoundtrip() {
|
||||
MetadataResponse res = assertDoesNotThrow(
|
||||
() -> objectMapper.readValue(META_JSON, MetadataResponse.class),
|
||||
"MetadataResponse deserialization failed"
|
||||
() -> objectMapper.readValue(META_JSON, MetadataResponse.class),
|
||||
"MetadataResponse deserialization failed"
|
||||
);
|
||||
assertNotNull(res, "Parsed response is NULL");
|
||||
assertNotNull(res.getMetadata(), "Parsed metadata is NULL");
|
||||
assertEquals(CAS_REQUIRED, res.getMetadata().isCasRequired(), "Incorrect CAS required flag");
|
||||
assertEquals(V1_TIME, res.getMetadata().getCreatedTimeString(), "Incorrect created time");
|
||||
assertNotNull(res.getMetadata().getCreatedTime(), "Parting created time failed");
|
||||
assertEquals(CURRENT_VERSION, res.getMetadata().getCurrentVersion(), "Incorrect current version");
|
||||
assertEquals(MAX_VERSIONS, res.getMetadata().getMaxVersions(), "Incorrect max versions");
|
||||
assertEquals(OLDEST_VERSION, res.getMetadata().getOldestVersion(), "Incorrect oldest version");
|
||||
assertEquals(Map.of(CUSTOM_META_KEY, CUSTOM_META_VAL), res.getMetadata().getCustomMetadata(), "Incorrect custom metadata");
|
||||
assertEquals(DELETE_VERSION_AFTER, res.getMetadata().getDeleteVersionAfter(), "Incorrect delete version after");
|
||||
assertEquals(V3_TIME, res.getMetadata().getUpdatedTimeString(), "Incorrect updated time");
|
||||
assertNotNull(res.getMetadata().getUpdatedTime(), "Parting updated time failed");
|
||||
assertEquals(3, res.getMetadata().getVersions().size(), "Incorrect number of versions");
|
||||
assertEquals(V2_TIME, res.getMetadata().getVersions().get(1).getDeletionTimeString(), "Incorrect version 1 delete time");
|
||||
assertNotNull(res.getMetadata().getVersions().get(1).getDeletionTime(), "Parsing version delete time failed");
|
||||
assertTrue(res.getMetadata().getVersions().get(1).isDestroyed(), "Incorrect version 1 destroyed state");
|
||||
assertEquals(V2_TIME, res.getMetadata().getVersions().get(2).getCreatedTimeString(), "Incorrect version 2 created time");
|
||||
assertNotNull(res.getMetadata().getVersions().get(2).getCreatedTime(), "Parsing version created failed");
|
||||
assertFalse(res.getMetadata().getVersions().get(3).isDestroyed(), "Incorrect version 3 destroyed state");
|
||||
}
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016-2021 Stefan Kalscheuer
|
||||
* Copyright 2016-2025 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,6 @@
|
||||
package de.stklcode.jvault.connector.model.response;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import de.stklcode.jvault.connector.exception.InvalidResponseException;
|
||||
import de.stklcode.jvault.connector.model.AbstractModelTest;
|
||||
import org.junit.jupiter.api.Test;
|
||||
@@ -43,16 +42,16 @@ class PlainSecretResponseTest extends AbstractModelTest<PlainSecretResponse> {
|
||||
private static final String SECRET_DATA_V2 = "world";
|
||||
private static final List<String> SECRET_WARNINGS = null;
|
||||
private static final String SECRET_JSON = "{\n" +
|
||||
" \"request_id\": \"" + SECRET_REQUEST_ID + "\",\n" +
|
||||
" \"lease_id\": \"" + SECRET_LEASE_ID + "\",\n" +
|
||||
" \"lease_duration\": " + SECRET_LEASE_DURATION + ",\n" +
|
||||
" \"renewable\": " + SECRET_RENEWABLE + ",\n" +
|
||||
" \"data\": {\n" +
|
||||
" \"" + SECRET_DATA_K1 + "\": \"" + SECRET_DATA_V1 + "\",\n" +
|
||||
" \"" + SECRET_DATA_K2 + "\": \"" + SECRET_DATA_V2 + "\"\n" +
|
||||
" },\n" +
|
||||
" \"warnings\": " + SECRET_WARNINGS + "\n" +
|
||||
"}";
|
||||
" \"request_id\": \"" + SECRET_REQUEST_ID + "\",\n" +
|
||||
" \"lease_id\": \"" + SECRET_LEASE_ID + "\",\n" +
|
||||
" \"lease_duration\": " + SECRET_LEASE_DURATION + ",\n" +
|
||||
" \"renewable\": " + SECRET_RENEWABLE + ",\n" +
|
||||
" \"data\": {\n" +
|
||||
" \"" + SECRET_DATA_K1 + "\": \"" + SECRET_DATA_V1 + "\",\n" +
|
||||
" \"" + SECRET_DATA_K2 + "\": \"" + SECRET_DATA_V2 + "\"\n" +
|
||||
" },\n" +
|
||||
" \"warnings\": " + SECRET_WARNINGS + "\n" +
|
||||
"}";
|
||||
|
||||
PlainSecretResponseTest() {
|
||||
super(PlainSecretResponse.class);
|
||||
@@ -60,12 +59,10 @@ class PlainSecretResponseTest extends AbstractModelTest<PlainSecretResponse> {
|
||||
|
||||
@Override
|
||||
protected PlainSecretResponse createFull() {
|
||||
try {
|
||||
return objectMapper.readValue(SECRET_JSON, PlainSecretResponse.class);
|
||||
} catch (JsonProcessingException e) {
|
||||
fail("Creation of full model instance failed", e);
|
||||
return null;
|
||||
}
|
||||
return assertDoesNotThrow(
|
||||
() -> objectMapper.readValue(SECRET_JSON, PlainSecretResponse.class),
|
||||
"Creation of full model instance failed"
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -74,8 +71,8 @@ class PlainSecretResponseTest extends AbstractModelTest<PlainSecretResponse> {
|
||||
@Test
|
||||
void jsonRoundtrip() {
|
||||
SecretResponse res = assertDoesNotThrow(
|
||||
() -> objectMapper.readValue(SECRET_JSON, PlainSecretResponse.class),
|
||||
"SecretResponse deserialization failed"
|
||||
() -> objectMapper.readValue(SECRET_JSON, PlainSecretResponse.class),
|
||||
"SecretResponse deserialization failed"
|
||||
);
|
||||
|
||||
assertNotNull(res, "Parsed response is NULL");
|
||||
@@ -106,74 +103,74 @@ class PlainSecretResponseTest extends AbstractModelTest<PlainSecretResponse> {
|
||||
final var complexVal = new ComplexType("val1", 678);
|
||||
|
||||
SecretResponse res = assertDoesNotThrow(
|
||||
() -> objectMapper.readValue(
|
||||
"{\n" +
|
||||
" \"request_id\": \"req-id\",\n" +
|
||||
" \"lease_id\": \"lea-id\",\n" +
|
||||
" \"lease_duration\": " + 123456 + ",\n" +
|
||||
" \"renewable\": true,\n" +
|
||||
" \"data\": {\n" +
|
||||
" \"" + stringKey + "\": \"" + stringVal + "\",\n" +
|
||||
" \"" + numberKey + "\": \"" + numberVal + "\",\n" +
|
||||
" \"" + listKey + "\": [\"" + String.join("\", \"", listVal) + "\"],\n" +
|
||||
" \"" + complexKey + "\": {" +
|
||||
" \"field1\": \"" + complexVal.field1 + "\",\n" +
|
||||
" \"field2\": " + complexVal.field2 + "\n" +
|
||||
" },\n" +
|
||||
" \"" + complexKey + "Json\": \"" + objectMapper.writeValueAsString(complexVal).replace("\"", "\\\"") + "\"\n" +
|
||||
" }\n" +
|
||||
"}",
|
||||
PlainSecretResponse.class
|
||||
),
|
||||
"SecretResponse deserialization failed"
|
||||
() -> objectMapper.readValue(
|
||||
"{\n" +
|
||||
" \"request_id\": \"req-id\",\n" +
|
||||
" \"lease_id\": \"lea-id\",\n" +
|
||||
" \"lease_duration\": " + 123456 + ",\n" +
|
||||
" \"renewable\": true,\n" +
|
||||
" \"data\": {\n" +
|
||||
" \"" + stringKey + "\": \"" + stringVal + "\",\n" +
|
||||
" \"" + numberKey + "\": \"" + numberVal + "\",\n" +
|
||||
" \"" + listKey + "\": [\"" + String.join("\", \"", listVal) + "\"],\n" +
|
||||
" \"" + complexKey + "\": {" +
|
||||
" \"field1\": \"" + complexVal.field1 + "\",\n" +
|
||||
" \"field2\": " + complexVal.field2 + "\n" +
|
||||
" },\n" +
|
||||
" \"" + complexKey + "Json\": \"" + objectMapper.writeValueAsString(complexVal).replace("\"", "\\\"") + "\"\n" +
|
||||
" }\n" +
|
||||
"}",
|
||||
PlainSecretResponse.class
|
||||
),
|
||||
"SecretResponse deserialization failed"
|
||||
);
|
||||
|
||||
assertEquals(stringVal, res.get(stringKey), "unexpected value for string (implicit)");
|
||||
assertEquals(
|
||||
stringVal,
|
||||
assertDoesNotThrow(() -> res.get(stringKey, String.class), "getting string failed"),
|
||||
"unexpected value for string (explicit)"
|
||||
stringVal,
|
||||
assertDoesNotThrow(() -> res.get(stringKey, String.class), "getting string failed"),
|
||||
"unexpected value for string (explicit)"
|
||||
);
|
||||
|
||||
assertEquals(String.valueOf(numberVal), res.get(numberKey), "unexpected value for number (implicit)");
|
||||
assertEquals(
|
||||
numberVal,
|
||||
assertDoesNotThrow(() -> res.get(numberKey, Double.class), "getting number failed"),
|
||||
"unexpected value for number (explicit)"
|
||||
numberVal,
|
||||
assertDoesNotThrow(() -> res.get(numberKey, Double.class), "getting number failed"),
|
||||
"unexpected value for number (explicit)"
|
||||
);
|
||||
assertEquals(
|
||||
String.valueOf(numberVal),
|
||||
assertDoesNotThrow(() -> res.get(numberKey, String.class), "getting number as string failed"),
|
||||
"unexpected value for number as string (explicit)"
|
||||
String.valueOf(numberVal),
|
||||
assertDoesNotThrow(() -> res.get(numberKey, String.class), "getting number as string failed"),
|
||||
"unexpected value for number as string (explicit)"
|
||||
);
|
||||
|
||||
assertEquals(listVal, res.get(listKey), "unexpected value for list (implicit)");
|
||||
assertEquals(
|
||||
listVal,
|
||||
assertDoesNotThrow(() -> res.get(listKey, ArrayList.class), "getting list failed"),
|
||||
"unexpected value for list (explicit)"
|
||||
listVal,
|
||||
assertDoesNotThrow(() -> res.get(listKey, ArrayList.class), "getting list failed"),
|
||||
"unexpected value for list (explicit)"
|
||||
);
|
||||
|
||||
assertEquals(complexVal.toMap(), res.get(complexKey), "unexpected value for complex type (implicit)");
|
||||
assertEquals(
|
||||
complexVal.toMap(),
|
||||
assertDoesNotThrow(() -> res.get(complexKey, HashMap.class), "getting complex type as map failed"),
|
||||
"unexpected value for complex type as map (explicit)"
|
||||
complexVal.toMap(),
|
||||
assertDoesNotThrow(() -> res.get(complexKey, HashMap.class), "getting complex type as map failed"),
|
||||
"unexpected value for complex type as map (explicit)"
|
||||
);
|
||||
assertEquals(
|
||||
complexVal,
|
||||
assertDoesNotThrow(() -> res.get(complexKey, ComplexType.class), "getting complex type failed"),
|
||||
"unexpected value for complex type (explicit)"
|
||||
complexVal,
|
||||
assertDoesNotThrow(() -> res.get(complexKey, ComplexType.class), "getting complex type failed"),
|
||||
"unexpected value for complex type (explicit)"
|
||||
);
|
||||
assertThrows(
|
||||
InvalidResponseException.class,
|
||||
() -> res.get(complexKey, Integer.class),
|
||||
"getting complex type as integer should fail"
|
||||
InvalidResponseException.class,
|
||||
() -> res.get(complexKey, Integer.class),
|
||||
"getting complex type as integer should fail"
|
||||
);
|
||||
assertEquals(
|
||||
complexVal,
|
||||
assertDoesNotThrow(() -> res.get(complexKey + "Json", ComplexType.class), "getting complex type from JSON string failed"),
|
||||
"unexpected value for complex type from JSON string"
|
||||
complexVal,
|
||||
assertDoesNotThrow(() -> res.get(complexKey + "Json", ComplexType.class), "getting complex type from JSON string failed"),
|
||||
"unexpected value for complex type from JSON string"
|
||||
);
|
||||
}
|
||||
|
||||
@@ -199,8 +196,8 @@ class PlainSecretResponseTest extends AbstractModelTest<PlainSecretResponse> {
|
||||
|
||||
private Map<String, Object> toMap() {
|
||||
return Map.of(
|
||||
"field1", field1,
|
||||
"field2", field2
|
||||
"field1", field1,
|
||||
"field2", field2
|
||||
);
|
||||
}
|
||||
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016-2024 Stefan Kalscheuer
|
||||
* Copyright 2016-2025 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,7 +16,6 @@
|
||||
|
||||
package de.stklcode.jvault.connector.model.response;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import de.stklcode.jvault.connector.model.AbstractModelTest;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
@@ -46,36 +45,36 @@ class SealResponseTest extends AbstractModelTest<SealResponse> {
|
||||
private static final String STORAGE_TYPE = "file";
|
||||
|
||||
private static final String RES_SEALED = "{\n" +
|
||||
" \"type\": \"" + TYPE + "\",\n" +
|
||||
" \"sealed\": true,\n" +
|
||||
" \"initialized\": true,\n" +
|
||||
" \"t\": " + THRESHOLD + ",\n" +
|
||||
" \"n\": " + SHARES + ",\n" +
|
||||
" \"progress\": " + PROGRESS_SEALED + ",\n" +
|
||||
" \"nonce\": \"\",\n" +
|
||||
" \"version\": \"" + VERSION + "\",\n" +
|
||||
" \"build_date\": \"" + BUILD_DATE + "\",\n" +
|
||||
" \"migration\": \"" + MIGRATION + "\",\n" +
|
||||
" \"recovery_seal\": \"" + RECOVERY_SEAL + "\",\n" +
|
||||
" \"storage_type\": \"" + STORAGE_TYPE + "\"\n" +
|
||||
"}";
|
||||
" \"type\": \"" + TYPE + "\",\n" +
|
||||
" \"sealed\": true,\n" +
|
||||
" \"initialized\": true,\n" +
|
||||
" \"t\": " + THRESHOLD + ",\n" +
|
||||
" \"n\": " + SHARES + ",\n" +
|
||||
" \"progress\": " + PROGRESS_SEALED + ",\n" +
|
||||
" \"nonce\": \"\",\n" +
|
||||
" \"version\": \"" + VERSION + "\",\n" +
|
||||
" \"build_date\": \"" + BUILD_DATE + "\",\n" +
|
||||
" \"migration\": \"" + MIGRATION + "\",\n" +
|
||||
" \"recovery_seal\": \"" + RECOVERY_SEAL + "\",\n" +
|
||||
" \"storage_type\": \"" + STORAGE_TYPE + "\"\n" +
|
||||
"}";
|
||||
|
||||
private static final String RES_UNSEALED = "{\n" +
|
||||
" \"type\": \"" + TYPE + "\",\n" +
|
||||
" \"sealed\": false,\n" +
|
||||
" \"initialized\": true,\n" +
|
||||
" \"t\": " + THRESHOLD + ",\n" +
|
||||
" \"n\": " + SHARES + ",\n" +
|
||||
" \"progress\": " + PROGRESS_UNSEALED + ",\n" +
|
||||
" \"version\": \"" + VERSION + "\",\n" +
|
||||
" \"build_date\": \"" + BUILD_DATE + "\",\n" +
|
||||
" \"cluster_name\": \"" + CLUSTER_NAME + "\",\n" +
|
||||
" \"cluster_id\": \"" + CLUSTER_ID + "\",\n" +
|
||||
" \"nonce\": \"" + NONCE + "\",\n" +
|
||||
" \"migration\": \"" + MIGRATION + "\",\n" +
|
||||
" \"recovery_seal\": \"" + RECOVERY_SEAL + "\",\n" +
|
||||
" \"storage_type\": \"" + STORAGE_TYPE + "\"\n" +
|
||||
"}";
|
||||
" \"type\": \"" + TYPE + "\",\n" +
|
||||
" \"sealed\": false,\n" +
|
||||
" \"initialized\": true,\n" +
|
||||
" \"t\": " + THRESHOLD + ",\n" +
|
||||
" \"n\": " + SHARES + ",\n" +
|
||||
" \"progress\": " + PROGRESS_UNSEALED + ",\n" +
|
||||
" \"version\": \"" + VERSION + "\",\n" +
|
||||
" \"build_date\": \"" + BUILD_DATE + "\",\n" +
|
||||
" \"cluster_name\": \"" + CLUSTER_NAME + "\",\n" +
|
||||
" \"cluster_id\": \"" + CLUSTER_ID + "\",\n" +
|
||||
" \"nonce\": \"" + NONCE + "\",\n" +
|
||||
" \"migration\": \"" + MIGRATION + "\",\n" +
|
||||
" \"recovery_seal\": \"" + RECOVERY_SEAL + "\",\n" +
|
||||
" \"storage_type\": \"" + STORAGE_TYPE + "\"\n" +
|
||||
"}";
|
||||
|
||||
SealResponseTest() {
|
||||
super(SealResponse.class);
|
||||
@@ -83,12 +82,10 @@ class SealResponseTest extends AbstractModelTest<SealResponse> {
|
||||
|
||||
@Override
|
||||
protected SealResponse createFull() {
|
||||
try {
|
||||
return objectMapper.readValue(RES_UNSEALED, SealResponse.class);
|
||||
} catch (JsonProcessingException e) {
|
||||
fail("Creation of full model instance failed", e);
|
||||
return null;
|
||||
}
|
||||
return assertDoesNotThrow(
|
||||
() -> objectMapper.readValue(RES_UNSEALED, SealResponse.class),
|
||||
"Creation of full model instance failed"
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -98,8 +95,8 @@ class SealResponseTest extends AbstractModelTest<SealResponse> {
|
||||
void jsonRoundtripSealed() {
|
||||
// First test sealed Vault's response.
|
||||
SealResponse res = assertDoesNotThrow(
|
||||
() -> objectMapper.readValue(RES_SEALED, SealResponse.class),
|
||||
"SealResponse deserialization failed"
|
||||
() -> objectMapper.readValue(RES_SEALED, SealResponse.class),
|
||||
"SealResponse deserialization failed"
|
||||
);
|
||||
assertNotNull(res, "Parsed response is NULL");
|
||||
assertEquals(TYPE, res.getType(), "Incorrect seal type");
|
||||
@@ -121,8 +118,8 @@ class SealResponseTest extends AbstractModelTest<SealResponse> {
|
||||
|
||||
// Not test unsealed Vault's response.
|
||||
res = assertDoesNotThrow(
|
||||
() -> objectMapper.readValue(RES_UNSEALED, SealResponse.class),
|
||||
"SealResponse deserialization failed"
|
||||
() -> objectMapper.readValue(RES_UNSEALED, SealResponse.class),
|
||||
"SealResponse deserialization failed"
|
||||
);
|
||||
assertNotNull(res, "Parsed response is NULL");
|
||||
assertEquals(TYPE, res.getType(), "Incorrect seal type");
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016-2024 Stefan Kalscheuer
|
||||
* Copyright 2016-2025 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,13 +16,13 @@
|
||||
|
||||
package de.stklcode.jvault.connector.model.response;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import de.stklcode.jvault.connector.model.AbstractModelTest;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
/**
|
||||
* JUnit Test for {@link SecretListResponse} model.
|
||||
@@ -34,17 +34,17 @@ class SecretListResponseTest extends AbstractModelTest<SecretListResponse> {
|
||||
private static final String KEY1 = "key1";
|
||||
private static final String KEY2 = "key-2";
|
||||
private static final String JSON = "{\n" +
|
||||
" \"auth\": null,\n" +
|
||||
" \"data\": {\n" +
|
||||
" \"keys\": [" +
|
||||
" \"" + KEY1 + "\",\n" +
|
||||
" \"" + KEY2 + "\"\n" +
|
||||
" ]\n" +
|
||||
" },\n" +
|
||||
" \"lease_duration\": 2764800,\n" +
|
||||
" \"lease_id\": \"\",\n" +
|
||||
" \"renewable\": false\n" +
|
||||
"}";
|
||||
" \"auth\": null,\n" +
|
||||
" \"data\": {\n" +
|
||||
" \"keys\": [" +
|
||||
" \"" + KEY1 + "\",\n" +
|
||||
" \"" + KEY2 + "\"\n" +
|
||||
" ]\n" +
|
||||
" },\n" +
|
||||
" \"lease_duration\": 2764800,\n" +
|
||||
" \"lease_id\": \"\",\n" +
|
||||
" \"renewable\": false\n" +
|
||||
"}";
|
||||
|
||||
SecretListResponseTest() {
|
||||
super(SecretListResponse.class);
|
||||
@@ -52,12 +52,10 @@ class SecretListResponseTest extends AbstractModelTest<SecretListResponse> {
|
||||
|
||||
@Override
|
||||
protected SecretListResponse createFull() {
|
||||
try {
|
||||
return objectMapper.readValue(JSON, SecretListResponse.class);
|
||||
} catch (JsonProcessingException e) {
|
||||
fail("Creation of full model instance failed", e);
|
||||
return null;
|
||||
}
|
||||
return assertDoesNotThrow(
|
||||
() -> objectMapper.readValue(JSON, SecretListResponse.class),
|
||||
"Creation of full model instance failed"
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -66,8 +64,8 @@ class SecretListResponseTest extends AbstractModelTest<SecretListResponse> {
|
||||
@Test
|
||||
void getKeysTest() {
|
||||
SecretListResponse res = assertDoesNotThrow(
|
||||
() -> objectMapper.readValue(JSON, SecretListResponse.class),
|
||||
"SecretListResponse deserialization failed"
|
||||
() -> objectMapper.readValue(JSON, SecretListResponse.class),
|
||||
"SecretListResponse deserialization failed"
|
||||
);
|
||||
|
||||
assertEquals(List.of(KEY1, KEY2), res.getKeys(), "Unexpected secret keys");
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016-2024 Stefan Kalscheuer
|
||||
* Copyright 2016-2025 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,7 +16,6 @@
|
||||
|
||||
package de.stklcode.jvault.connector.model.response;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import de.stklcode.jvault.connector.model.AbstractModelTest;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
@@ -34,13 +33,13 @@ class SecretVersionResponseTest extends AbstractModelTest<SecretVersionResponse>
|
||||
private static final Integer VERSION = 42;
|
||||
|
||||
private static final String META_JSON = "{\n" +
|
||||
" \"data\": {\n" +
|
||||
" \"created_time\": \"" + CREATION_TIME + "\",\n" +
|
||||
" \"deletion_time\": \"" + DELETION_TIME + "\",\n" +
|
||||
" \"destroyed\": false,\n" +
|
||||
" \"version\": " + VERSION + "\n" +
|
||||
" }\n" +
|
||||
"}";
|
||||
" \"data\": {\n" +
|
||||
" \"created_time\": \"" + CREATION_TIME + "\",\n" +
|
||||
" \"deletion_time\": \"" + DELETION_TIME + "\",\n" +
|
||||
" \"destroyed\": false,\n" +
|
||||
" \"version\": " + VERSION + "\n" +
|
||||
" }\n" +
|
||||
"}";
|
||||
|
||||
SecretVersionResponseTest() {
|
||||
super(SecretVersionResponse.class);
|
||||
@@ -48,12 +47,10 @@ class SecretVersionResponseTest extends AbstractModelTest<SecretVersionResponse>
|
||||
|
||||
@Override
|
||||
protected SecretVersionResponse createFull() {
|
||||
try {
|
||||
return objectMapper.readValue(META_JSON, SecretVersionResponse.class);
|
||||
} catch (JsonProcessingException e) {
|
||||
fail("Creation of full model instance failed", e);
|
||||
return null;
|
||||
}
|
||||
return assertDoesNotThrow(
|
||||
() -> objectMapper.readValue(META_JSON, SecretVersionResponse.class),
|
||||
"Creation of full model instance failed"
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -62,13 +59,11 @@ class SecretVersionResponseTest extends AbstractModelTest<SecretVersionResponse>
|
||||
@Test
|
||||
void jsonRoundtrip() {
|
||||
SecretVersionResponse res = assertDoesNotThrow(
|
||||
() -> objectMapper.readValue(META_JSON, SecretVersionResponse.class),
|
||||
"SecretVersionResponse deserialization failed"
|
||||
() -> objectMapper.readValue(META_JSON, SecretVersionResponse.class),
|
||||
"SecretVersionResponse deserialization failed"
|
||||
);
|
||||
assertNotNull(res, "Parsed response is NULL");
|
||||
assertNotNull(res.getMetadata(), "Parsed metadata is NULL");
|
||||
assertEquals(CREATION_TIME, res.getMetadata().getCreatedTimeString(), "Incorrect created time");
|
||||
assertEquals(DELETION_TIME, res.getMetadata().getDeletionTimeString(), "Incorrect deletion time");
|
||||
assertFalse(res.getMetadata().isDestroyed(), "Incorrect destroyed state");
|
||||
assertEquals(VERSION, res.getMetadata().getVersion(), "Incorrect version");
|
||||
}
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016-2024 Stefan Kalscheuer
|
||||
* Copyright 2016-2025 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,7 +16,6 @@
|
||||
|
||||
package de.stklcode.jvault.connector.model.response;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import de.stklcode.jvault.connector.model.AbstractModelTest;
|
||||
import de.stklcode.jvault.connector.model.response.embedded.TokenData;
|
||||
import org.junit.jupiter.api.Test;
|
||||
@@ -35,8 +34,8 @@ import static org.junit.jupiter.api.Assertions.*;
|
||||
*/
|
||||
class TokenResponseTest extends AbstractModelTest<TokenResponse> {
|
||||
private static final Integer TOKEN_CREATION_TIME = 1457533232;
|
||||
private static final Integer TOKEN_TTL = 2764800;
|
||||
private static final Integer TOKEN_EXPLICIT_MAX_TTL = 0;
|
||||
private static final Long TOKEN_TTL = 2764800L;
|
||||
private static final Long TOKEN_EXPLICIT_MAX_TTL = 0L;
|
||||
private static final String TOKEN_DISPLAY_NAME = "token";
|
||||
private static final String TOKEN_META_KEY = "foo";
|
||||
private static final String TOKEN_META_VALUE = "bar";
|
||||
@@ -47,7 +46,7 @@ class TokenResponseTest extends AbstractModelTest<TokenResponse> {
|
||||
private static final String TOKEN_POLICY_1 = "default";
|
||||
private static final String TOKEN_POLICY_2 = "web";
|
||||
private static final Boolean RES_RENEWABLE = false;
|
||||
private static final Integer RES_TTL = 2591976;
|
||||
private static final Long RES_TTL = 2591976L;
|
||||
private static final Integer RES_LEASE_DURATION = 0;
|
||||
private static final String TOKEN_ACCESSOR = "VKvzT2fKHFsZFUus9LyoXCvu";
|
||||
private static final String TOKEN_ENTITY_ID = "7d2e3179-f69b-450c-7179-ac8ee8bd8ca9";
|
||||
@@ -58,37 +57,37 @@ class TokenResponseTest extends AbstractModelTest<TokenResponse> {
|
||||
private static final String MOUNT_TYPE = "token";
|
||||
|
||||
private static final String RES_JSON = "{\n" +
|
||||
" \"lease_id\": \"\",\n" +
|
||||
" \"renewable\": " + RES_RENEWABLE + ",\n" +
|
||||
" \"lease_duration\": " + RES_LEASE_DURATION + ",\n" +
|
||||
" \"data\": {\n" +
|
||||
" \"accessor\": \"" + TOKEN_ACCESSOR + "\",\n" +
|
||||
" \"creation_time\": " + TOKEN_CREATION_TIME + ",\n" +
|
||||
" \"creation_ttl\": " + TOKEN_TTL + ",\n" +
|
||||
" \"display_name\": \"" + TOKEN_DISPLAY_NAME + "\",\n" +
|
||||
" \"entity_id\": \"" + TOKEN_ENTITY_ID + "\",\n" +
|
||||
" \"expire_time\": \"" + TOKEN_EXPIRE_TIME + "\",\n" +
|
||||
" \"explicit_max_ttl\": \"" + TOKEN_EXPLICIT_MAX_TTL + "\",\n" +
|
||||
" \"id\": \"" + TOKEN_ID + "\",\n" +
|
||||
" \"issue_time\": \"" + TOKEN_ISSUE_TIME + "\",\n" +
|
||||
" \"meta\": {\n" +
|
||||
" \"" + TOKEN_META_KEY + "\": \"" + TOKEN_META_VALUE + "\"\n" +
|
||||
" },\n" +
|
||||
" \"num_uses\": " + TOKEN_NUM_USES + ",\n" +
|
||||
" \"orphan\": " + TOKEN_ORPHAN + ",\n" +
|
||||
" \"path\": \"" + TOKEN_PATH + "\",\n" +
|
||||
" \"policies\": [\n" +
|
||||
" \"" + TOKEN_POLICY_1 + "\", \n" +
|
||||
" \"" + TOKEN_POLICY_2 + "\"\n" +
|
||||
" ],\n" +
|
||||
" \"renewable\": " + TOKEN_RENEWABLE + ",\n" +
|
||||
" \"ttl\": " + RES_TTL + ",\n" +
|
||||
" \"type\": \"" + TOKEN_TYPE + "\"\n" +
|
||||
" },\n" +
|
||||
" \"warnings\": null,\n" +
|
||||
" \"auth\": null,\n" +
|
||||
" \"mount_type\": \"" + MOUNT_TYPE + "\"\n" +
|
||||
"}";
|
||||
" \"lease_id\": \"\",\n" +
|
||||
" \"renewable\": " + RES_RENEWABLE + ",\n" +
|
||||
" \"lease_duration\": " + RES_LEASE_DURATION + ",\n" +
|
||||
" \"data\": {\n" +
|
||||
" \"accessor\": \"" + TOKEN_ACCESSOR + "\",\n" +
|
||||
" \"creation_time\": " + TOKEN_CREATION_TIME + ",\n" +
|
||||
" \"creation_ttl\": " + TOKEN_TTL + ",\n" +
|
||||
" \"display_name\": \"" + TOKEN_DISPLAY_NAME + "\",\n" +
|
||||
" \"entity_id\": \"" + TOKEN_ENTITY_ID + "\",\n" +
|
||||
" \"expire_time\": \"" + TOKEN_EXPIRE_TIME + "\",\n" +
|
||||
" \"explicit_max_ttl\": \"" + TOKEN_EXPLICIT_MAX_TTL + "\",\n" +
|
||||
" \"id\": \"" + TOKEN_ID + "\",\n" +
|
||||
" \"issue_time\": \"" + TOKEN_ISSUE_TIME + "\",\n" +
|
||||
" \"meta\": {\n" +
|
||||
" \"" + TOKEN_META_KEY + "\": \"" + TOKEN_META_VALUE + "\"\n" +
|
||||
" },\n" +
|
||||
" \"num_uses\": " + TOKEN_NUM_USES + ",\n" +
|
||||
" \"orphan\": " + TOKEN_ORPHAN + ",\n" +
|
||||
" \"path\": \"" + TOKEN_PATH + "\",\n" +
|
||||
" \"policies\": [\n" +
|
||||
" \"" + TOKEN_POLICY_1 + "\", \n" +
|
||||
" \"" + TOKEN_POLICY_2 + "\"\n" +
|
||||
" ],\n" +
|
||||
" \"renewable\": " + TOKEN_RENEWABLE + ",\n" +
|
||||
" \"ttl\": " + RES_TTL + ",\n" +
|
||||
" \"type\": \"" + TOKEN_TYPE + "\"\n" +
|
||||
" },\n" +
|
||||
" \"warnings\": null,\n" +
|
||||
" \"auth\": null,\n" +
|
||||
" \"mount_type\": \"" + MOUNT_TYPE + "\"\n" +
|
||||
"}";
|
||||
|
||||
TokenResponseTest() {
|
||||
super(TokenResponse.class);
|
||||
@@ -96,12 +95,10 @@ class TokenResponseTest extends AbstractModelTest<TokenResponse> {
|
||||
|
||||
@Override
|
||||
protected TokenResponse createFull() {
|
||||
try {
|
||||
return objectMapper.readValue(RES_JSON, TokenResponse.class);
|
||||
} catch (JsonProcessingException e) {
|
||||
fail("Creation of full model instance failed", e);
|
||||
return null;
|
||||
}
|
||||
return assertDoesNotThrow(
|
||||
() -> objectMapper.readValue(RES_JSON, TokenResponse.class),
|
||||
"Creation of full model instance failed"
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -120,8 +117,8 @@ class TokenResponseTest extends AbstractModelTest<TokenResponse> {
|
||||
@Test
|
||||
void jsonRoundtrip() {
|
||||
TokenResponse res = assertDoesNotThrow(
|
||||
() -> objectMapper.readValue(RES_JSON, TokenResponse.class),
|
||||
"TokenResponse deserialization failed"
|
||||
() -> objectMapper.readValue(RES_JSON, TokenResponse.class),
|
||||
"TokenResponse deserialization failed"
|
||||
);
|
||||
assertNotNull(res, "Parsed response is NULL");
|
||||
assertEquals(RES_LEASE_DURATION, res.getLeaseDuration(), "Incorrect lease duration");
|
||||
@@ -136,11 +133,9 @@ class TokenResponseTest extends AbstractModelTest<TokenResponse> {
|
||||
assertEquals(TOKEN_TTL, data.getCreationTtl(), "Incorrect token creation TTL");
|
||||
assertEquals(TOKEN_DISPLAY_NAME, data.getName(), "Incorrect token display name");
|
||||
assertEquals(TOKEN_ENTITY_ID, data.getEntityId(), "Incorrect token entity ID");
|
||||
assertEquals(TOKEN_EXPIRE_TIME, data.getExpireTimeString(), "Incorrect token expire time");
|
||||
assertEquals(ZonedDateTime.parse(TOKEN_EXPIRE_TIME), data.getExpireTime(), "Incorrect parsed token expire time");
|
||||
assertEquals(TOKEN_EXPLICIT_MAX_TTL, data.getExplicitMaxTtl(), "Incorrect token explicit max TTL");
|
||||
assertEquals(TOKEN_ID, data.getId(), "Incorrect token ID");
|
||||
assertEquals(TOKEN_ISSUE_TIME, data.getIssueTimeString(), "Incorrect token issue time");
|
||||
assertEquals(ZonedDateTime.parse(TOKEN_ISSUE_TIME), data.getIssueTime(), "Incorrect parsed token issue time");
|
||||
assertEquals(Map.of(TOKEN_META_KEY, TOKEN_META_VALUE), data.getMeta(), "Incorrect token metadata");
|
||||
assertEquals(TOKEN_NUM_USES, data.getNumUses(), "Incorrect token number of uses");
|
||||
|
@@ -0,0 +1,134 @@
|
||||
/*
|
||||
* Copyright 2016-2025 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.model.response;
|
||||
|
||||
import de.stklcode.jvault.connector.model.AbstractModelTest;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
/**
|
||||
* JUnit Test for {@link TransitResponse} model.
|
||||
*
|
||||
* @author Stefan Kalscheuer
|
||||
* @since 1.5.0
|
||||
*/
|
||||
class TransitResponseTest extends AbstractModelTest<TransitResponse> {
|
||||
private static final String CIPHERTEXT = "vault:v1:XjsPWPjqPrBi1N2Ms2s1QM798YyFWnO4TR4lsFA=";
|
||||
private static final String PLAINTEXT = "dGhlIHF1aWNrIGJyb3duIGZveAo=";
|
||||
private static final String SUM = "dGhlIHF1aWNrIGJyb3duIGZveAo=";
|
||||
|
||||
TransitResponseTest() {
|
||||
super(TransitResponse.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected TransitResponse createFull() {
|
||||
return assertDoesNotThrow(
|
||||
() -> objectMapper.readValue(
|
||||
json(
|
||||
"\"ciphertext\": \"" + CIPHERTEXT + "\", " +
|
||||
"\"plaintext\": \"" + PLAINTEXT + "\", " +
|
||||
"\"sum\": \"" + SUM + "\""
|
||||
),
|
||||
TransitResponse.class
|
||||
),
|
||||
"Creation of full model failed"
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
void encryptionTest() {
|
||||
TransitResponse res = assertDoesNotThrow(
|
||||
() -> objectMapper.readValue(
|
||||
json("\"ciphertext\": \"" + CIPHERTEXT + "\""),
|
||||
TransitResponse.class
|
||||
),
|
||||
"TransitResponse deserialization failed"
|
||||
);
|
||||
assertNotNull(res, "Parsed response is NULL");
|
||||
assertEquals("987c6daf-b0e2-4142-a970-1e61fdb249d7", res.getRequestId(), "Incorrect request id");
|
||||
assertEquals("", res.getLeaseId(), "Unexpected lease id");
|
||||
assertFalse(res.isRenewable(), "Unexpected renewable flag");
|
||||
assertEquals(0, res.getLeaseDuration(), "Unexpected lease duration");
|
||||
assertEquals(CIPHERTEXT, res.getCiphertext(), "Incorrect ciphertext");
|
||||
assertNull(res.getPlaintext(), "Unexpected plaintext");
|
||||
assertNull(res.getSum(), "Unexpected sum");
|
||||
assertNull(res.getWrapInfo(), "Unexpected wrap info");
|
||||
assertNull(res.getWarnings(), "Unexpected warnings");
|
||||
assertNull(res.getAuth(), "Unexpected auth");
|
||||
}
|
||||
|
||||
@Test
|
||||
void decryptionTest() {
|
||||
TransitResponse res = assertDoesNotThrow(
|
||||
() -> objectMapper.readValue(
|
||||
json("\"plaintext\": \"" + PLAINTEXT + "\""),
|
||||
TransitResponse.class
|
||||
),
|
||||
"TransitResponse deserialization failed"
|
||||
);
|
||||
assertNotNull(res, "Parsed response is NULL");
|
||||
assertEquals("987c6daf-b0e2-4142-a970-1e61fdb249d7", res.getRequestId(), "Incorrect request id");
|
||||
assertEquals("", res.getLeaseId(), "Unexpected lease id");
|
||||
assertFalse(res.isRenewable(), "Unexpected renewable flag");
|
||||
assertEquals(0, res.getLeaseDuration(), "Unexpected lease duration");
|
||||
assertNull(res.getCiphertext(), "Unexpected ciphertext");
|
||||
assertEquals(PLAINTEXT, res.getPlaintext(), "Incorrect plaintext");
|
||||
assertNull(res.getSum(), "Unexpected sum");
|
||||
assertNull(res.getWrapInfo(), "Unexpected wrap info");
|
||||
assertNull(res.getWarnings(), "Unexpected warnings");
|
||||
assertNull(res.getAuth(), "Unexpected auth");
|
||||
}
|
||||
|
||||
@Test
|
||||
void hashTest() {
|
||||
TransitResponse res = assertDoesNotThrow(
|
||||
() -> objectMapper.readValue(
|
||||
json("\"sum\": \"" + SUM + "\""),
|
||||
TransitResponse.class
|
||||
),
|
||||
"TransitResponse deserialization failed"
|
||||
);
|
||||
assertNotNull(res, "Parsed response is NULL");
|
||||
assertEquals("987c6daf-b0e2-4142-a970-1e61fdb249d7", res.getRequestId(), "Incorrect request id");
|
||||
assertEquals("", res.getLeaseId(), "Unexpected lease id");
|
||||
assertFalse(res.isRenewable(), "Unexpected renewable flag");
|
||||
assertEquals(0, res.getLeaseDuration(), "Unexpected lease duration");
|
||||
assertNull(res.getCiphertext(), "Unexpected ciphertext");
|
||||
assertNull(res.getPlaintext(), "Unexpected plaintext");
|
||||
assertEquals(SUM, res.getSum(), "Incorrect sum");
|
||||
assertNull(res.getWrapInfo(), "Unexpected wrap info");
|
||||
assertNull(res.getWarnings(), "Unexpected warnings");
|
||||
assertNull(res.getAuth(), "Unexpected auth");
|
||||
}
|
||||
|
||||
private static String json(String data) {
|
||||
return "{\n" +
|
||||
" \"request_id\" : \"987c6daf-b0e2-4142-a970-1e61fdb249d7\",\n" +
|
||||
" \"lease_id\" : \"\",\n" +
|
||||
" \"renewable\" : false,\n" +
|
||||
" \"lease_duration\" : 0,\n" +
|
||||
" \"data\" : {\n" +
|
||||
" " + data + "\n" +
|
||||
" },\n" +
|
||||
" \"wrap_info\" : null,\n" +
|
||||
" \"warnings\" : null,\n" +
|
||||
" \"auth\" : null\n" +
|
||||
"}";
|
||||
}
|
||||
}
|
@@ -1,6 +1,5 @@
|
||||
package de.stklcode.jvault.connector.model.response.embedded;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import de.stklcode.jvault.connector.model.AbstractModelTest;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
@@ -14,8 +13,8 @@ import static org.junit.jupiter.api.Assertions.*;
|
||||
* @author Stefan Kalscheuer
|
||||
*/
|
||||
class MountConfigTest extends AbstractModelTest<MountConfig> {
|
||||
private static final Integer DEFAULT_LEASE_TTL = 1800;
|
||||
private static final Integer MAX_LEASE_TTL = 3600;
|
||||
private static final Long DEFAULT_LEASE_TTL = 1800L;
|
||||
private static final Long MAX_LEASE_TTL = 3600L;
|
||||
private static final Boolean FORCE_NO_CACHE = false;
|
||||
private static final String TOKEN_TYPE = "default-service";
|
||||
private static final String AUDIT_NON_HMAC_REQ_KEYS_1 = "req1";
|
||||
@@ -62,12 +61,10 @@ class MountConfigTest extends AbstractModelTest<MountConfig> {
|
||||
|
||||
@Override
|
||||
protected MountConfig createFull() {
|
||||
try {
|
||||
return objectMapper.readValue(RES_JSON, MountConfig.class);
|
||||
} catch (JsonProcessingException e) {
|
||||
fail("Creation of full model instance failed", e);
|
||||
return null;
|
||||
}
|
||||
return assertDoesNotThrow(
|
||||
() -> objectMapper.readValue(RES_JSON, MountConfig.class),
|
||||
"Creation of full model instance failed"
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016-2024 Stefan Kalscheuer
|
||||
* Copyright 2016-2025 Stefan Kalscheuer
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016-2024 Stefan Kalscheuer
|
||||
* Copyright 2016-2025 Stefan Kalscheuer
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -93,14 +93,14 @@ public class VaultConfiguration {
|
||||
@Override
|
||||
public String toString() {
|
||||
return "storage \"file\" {\n" +
|
||||
" path = \"" + dataLocation + "\"\n" +
|
||||
"}\n" +
|
||||
"listener \"tcp\" {\n" +
|
||||
" address = \"" + host + ":" + port + "\"\n" +
|
||||
((disableTLS) ? " tls_disable = 1\n" : "") +
|
||||
((certFile != null) ? " tls_cert_file = \"" + certFile + "\"\n" : "") +
|
||||
((keyFile != null) ? " tls_key_file = \"" + keyFile + "\"\n" : "") +
|
||||
"}\n" +
|
||||
((disableMlock) ? "disable_mlock = true" : "");
|
||||
" path = \"" + dataLocation + "\"\n" +
|
||||
"}\n" +
|
||||
"listener \"tcp\" {\n" +
|
||||
" address = \"" + host + ":" + port + "\"\n" +
|
||||
((disableTLS) ? " tls_disable = 1\n" : "") +
|
||||
((certFile != null) ? " tls_cert_file = \"" + certFile + "\"\n" : "") +
|
||||
((keyFile != null) ? " tls_key_file = \"" + keyFile + "\"\n" : "") +
|
||||
"}\n" +
|
||||
((disableMlock) ? "disable_mlock = true" : "");
|
||||
}
|
||||
}
|
||||
|
@@ -1 +1 @@
|
||||
{"Value":"AAAAAQIOTEuNxtf2ZfGu6k9+65GFonDBiaetJnyLYFk1qfWPrE/VqUunbxuTv/QyK4pgC/q14sqypdxPe4Ygp/5mxzzuY6JXB0VKiDMXe9R5BltTG7++rLmKH/j+G7nEh71LER1/qVktU6x8dmDmTbpTgl5xzAB5DIXLMMKjjWda/7qJ3ivNI0pEOQ3JyT27SkqjqM49Dp1JIgKnjIEVQORqKcsSP+aqIncMjIo2iGXOGlDYAesp5tZ4hln3VCwXaIlrU8z6Mmntgcg7NeK/O2WTl86K644dbJUh6frGFDujrjOh/Pgp9n9u0BI3E9K9GD1Z1S1wEb1MCqzT/e9oHG7I7D8ku8PH11wGWGH6BmYlESYUG/KRVqu0XOQEfroLHZQiLE00yHBdStW/UJ9y5pmGpu1aiQ88Q8fpjF5xmRey99b4c6KUIpHjw5Af0XA9ZKsEJUyjS/dbMKPM6PBOW21LYefXH5b0poXMWgLW6LJV0zLuVMyVZJqANbzCVtheDPSsEjkHHwR/CLa2zs2Z6wJF3j1GDZxUFf4nbnuXQzz3M3kVPPtS6htlb0d8RN0/dkOrqUue+c4UjnXhiacXyVUnQQzUVu0sGak4vrQi0020aBzMXM2ZG7rNgvw+wcYFS4txO90kwJL6aOMXT2BeJiQ3wjjHb7M74/sSd0ffRTUlJSODSDotO7Q7Dfcnc1FLrIhXPRFPavTjFoL5HRy77xuGG7U7jTMoGra+rK54v0sxqKbS5WZi1hADQmAVIO8bPb+jA1qoejRFygW6sLgAdmEFQQJOhCV/BoKP3A=="}
|
||||
{"Value":"AAAAAQJ7mykBIbHX5k81qdXEpvlLgRF1ZSlODETcB1JBZ7nj0Muskpvvl3jofN5XH1Td8ibJlrR0o5o/OUjZAz9t0Da+ZzCy4ga9G2SmgWkUAravTqfPO/ZxWh2hqTso2WPBXRM3/IeR0SAv/zh7m7JILxjKybJmnl9U6fkjPID/us0AscckZ9kgJ4g8jwaTzPfRp5U8jMebHYbABXZ65PeUOvNiDVcOvQDWPJrMxICz12xbeJ8mKs5MHpcNkLtPoRCQSpsh0YYTwkuF7NvpIciqIJ4/Yb7wYO+vp9AATbiIs3sSFBWxXEl0OAg/SAmOvaR27Y7/NHN//mg81jkMOHv62/Fxf11I8t1d63oyWFQhP0xR9eoq5hGNQ/30I2m1prhZtLRC2ieKASBDMxTzyNS5G5bsVXvhCsxn8tiC0Ma+ySOfxMQzBRfbx8rtoGmLFP+l/d6VMOPGFxmYqzLS5HvvpCryscCqLn7A8i6TMSrZiF7ZevyfEBpThqhJiYHzUxf07O5IAe6JBSGuNV9gLE+uJXaiYLedJwSfjRKwdQyzer730dU1IegW3KYTb/5hSW4eaETKkjc/alC536WlvAv+5FyckDBc3aVC+hHB7lKZG5YANkOUS3m5I8epemOmuKQ5pnXLOdDkQ14DyNCC79NwLltkp0d6sTNstQ44XAbs0HlLjs4EFwg5Hps9qHeXgTOXeAvwUerJgM20nKszlB+Oy+JzZm0xOK5xoJwy+z0/U3PtJ+7pwAipesIa2QEzqMt3EneuPuwEcv3bPUcowukq542sCEK0CuZjLqTUU9nNqiZan5f5pWuL0hYw4NFIkNfQyRlqgKpMaplDk/2fBqaV98yn0DWceEMWRY4NXpEMS+ysPDIeamX99auWqakb95AZ7tySpkRAkZYtq1nY5Nu0w7NyJrJZ1lhBHs2ZjW0tpXn2CL0MhMVArg=="}
|
||||
|
@@ -0,0 +1 @@
|
||||
{"Value":"AAAAAQIwsBgPcs7Hxl7UnB8OkTq9+5HERx4Fzn8jAzR8uIhoQZfpNG/15m2LEEsDJw1o+lxc6u+h7XcOB1QRqrKz8k7CFR15A+qsxD0UclHZdnk+MmMwXL9SSvYugp7XPiXmpG/uTZVf1QtigXQuehEEJeFfJVI7aFACu2AHEGVt+5b6yDQEgTUruo0seazRXuVU+J6NFCDU3ZvkR8e0al6OcMail59KamzjSCYiqDF4TeUuOQ6Zyr7zIG7gSaas1sog2JIlvrh+wkHW6I+OyD9SJSTinGEGRXl0tq15qoBJ4srfXdWODmKtExEupArbiDR5PyvSI3KlIHKIFduslJZKkJwiV3dBscdva4Rqb98FffMVYuM4G4s+VpvDDX+WVsqWF1ssoHRAFWCNAJGsenVDTxblzAF/4rGkJ7LC9yjLGsBtMOCkCZAKDQ3C9VFu+LGhbMRA5p2RKxNKWGem4Cyp5AqMmx62UzDAgMLGgm89A0g9s1/3FnCoLPdVmlWc6cg4QahN30qJCInJeAmH7T9NwIjv6/QxyJxyDVtdMtcfnMNxx15Q29lbyWTcbaI1iabHpc16iS/gwAPQeBTSbcvc4OxqwC5PDFThFq6bwZXaekYz4ghC13j9Ht79GVKH9cPZb5M="}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user