fix type conversion in SecretResponse getter method (#67)
Some checks failed
continuous-integration/drone/push Build is failing
Some checks failed
continuous-integration/drone/push Build is failing
Converting the payload using toString() is not an appropriate way to feed a JSON parser. We now use JSON roundtrip for type mapping and introduce shortcuts of the type already matches the target type.
This commit is contained in:
parent
622b13f508
commit
f3e1f01e38
@ -1,3 +1,9 @@
|
||||
## unreleased
|
||||
|
||||
### Fix
|
||||
* Fixed JSON type conversion in `SecretResponse#get(String, Class)` (#67)
|
||||
|
||||
|
||||
## 1.1.4 (2023-06-15)
|
||||
|
||||
### Fix
|
||||
|
2
pom.xml
2
pom.xml
@ -4,7 +4,7 @@
|
||||
|
||||
<groupId>de.stklcode.jvault</groupId>
|
||||
<artifactId>jvault-connector</artifactId>
|
||||
<version>1.1.4</version>
|
||||
<version>1.1.5-SNAPSHOT</version>
|
||||
|
||||
<packaging>jar</packaging>
|
||||
|
||||
|
@ -79,8 +79,12 @@ public abstract class SecretResponse extends VaultDataResponse {
|
||||
Object rawValue = get(key);
|
||||
if (rawValue == null) {
|
||||
return null;
|
||||
} else if (type.isInstance(rawValue)) {
|
||||
return type.cast(rawValue);
|
||||
} else {
|
||||
var om = new ObjectMapper();
|
||||
return om.readValue(om.writeValueAsString(rawValue), type);
|
||||
}
|
||||
return new ObjectMapper().readValue(rawValue.toString(), type);
|
||||
} catch (IOException e) {
|
||||
throw new InvalidResponseException("Unable to parse response payload: " + e.getMessage());
|
||||
}
|
||||
|
@ -16,11 +16,13 @@
|
||||
|
||||
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;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
@ -85,4 +87,131 @@ class PlainSecretResponseTest extends AbstractModelTest<PlainSecretResponse> {
|
||||
assertEquals(SECRET_DATA_V1, res.get(SECRET_DATA_K1), "Response does not contain correct data");
|
||||
assertEquals(SECRET_DATA_V2, res.get(SECRET_DATA_K2), "Response does not contain correct data");
|
||||
}
|
||||
|
||||
/**
|
||||
* Test creation from JSON value as returned by Vault (JSON example copied from Vault documentation).
|
||||
*/
|
||||
@Test
|
||||
void testGetter() {
|
||||
final var stringKey = "string";
|
||||
final var stringVal = "test";
|
||||
|
||||
final var numberKey = "number";
|
||||
final var numberVal = 123.45;
|
||||
|
||||
final var listKey = "list";
|
||||
final var listVal = List.of("foo", "bar");
|
||||
|
||||
final var complexKey = "complex";
|
||||
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" +
|
||||
" }\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)"
|
||||
);
|
||||
|
||||
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)"
|
||||
);
|
||||
assertEquals(
|
||||
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)"
|
||||
);
|
||||
|
||||
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)"
|
||||
);
|
||||
assertEquals(
|
||||
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"
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test class for complex field mapping.
|
||||
*/
|
||||
private static class ComplexType {
|
||||
@JsonProperty("field1")
|
||||
private String field1;
|
||||
|
||||
@JsonProperty("field2")
|
||||
private Integer field2;
|
||||
|
||||
private ComplexType() {
|
||||
// Required for JSON deserialization.
|
||||
}
|
||||
|
||||
private ComplexType(String field1, Integer field2) {
|
||||
this.field1 = field1;
|
||||
this.field2 = field2;
|
||||
}
|
||||
|
||||
private Map<String, Object> toMap() {
|
||||
return Map.of(
|
||||
"field1", field1,
|
||||
"field2", field2
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
} else if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
ComplexType that = (ComplexType) o;
|
||||
return Objects.equals(field1, that.field1) && Objects.equals(field2, that.field2);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(field1, field2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user