Skip to content

Commit 6e7c5b6

Browse files
committed
Merge branch 'release-2.5.0' into fido-mds-no-verify-cache
2 parents 61f9300 + d970f44 commit 6e7c5b6

File tree

8 files changed

+68
-16
lines changed

8 files changed

+68
-16
lines changed

NEWS

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,13 @@
22

33
`webauthn-server-core`:
44

5+
Breaking changes to experimental features:
6+
7+
* Added Jackson annotation `@JsonProperty` to method
8+
`RegisteredCredential.isBackedUp()`, changing the property name from
9+
`backedUp` to `backupState`. `backedUp` is still accepted during
10+
deserialization but will no longer be emitted during serialization.
11+
512
New features:
613

714
* Added method `.isUserVerified()` to `RegistrationResult` and `AssertionResult`
@@ -18,6 +25,11 @@ New features:
1825
from cache or when explicitly given. Default setting is `false`, which
1926
preserves the previous behaviour.
2027

28+
Fixes:
29+
30+
* Made Jackson setting `PROPAGATE_TRANSIENT_MARKER` unnecessary for JSON
31+
serialization with Jackson version 2.15.0-rc1 and later.
32+
2133

2234
== Version 2.4.1 ==
2335

webauthn-server-core/build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ dependencies {
2626
testImplementation(platform(project(":test-platform")))
2727
testImplementation(project(":yubico-util-scala"))
2828
testImplementation("com.fasterxml.jackson.core:jackson-databind")
29+
testImplementation("com.fasterxml.jackson.datatype:jackson-datatype-jdk8")
2930
testImplementation("com.upokecenter:cbor")
3031
testImplementation("junit:junit")
3132
testImplementation("org.bouncycastle:bcpkix-jdk18on")

webauthn-server-core/src/main/java/com/yubico/webauthn/RegisteredCredential.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424

2525
package com.yubico.webauthn;
2626

27+
import com.fasterxml.jackson.annotation.JsonAlias;
2728
import com.fasterxml.jackson.annotation.JsonCreator;
2829
import com.fasterxml.jackson.annotation.JsonProperty;
2930
import com.yubico.webauthn.data.AttestedCredentialData;
@@ -153,7 +154,7 @@ private RegisteredCredential(
153154
@NonNull @JsonProperty("publicKeyCose") ByteArray publicKeyCose,
154155
@JsonProperty("signatureCount") long signatureCount,
155156
@JsonProperty("backupEligible") Boolean backupEligible,
156-
@JsonProperty("backupState") Boolean backupState) {
157+
@JsonProperty("backupState") @JsonAlias("backedUp") Boolean backupState) {
157158
this.credentialId = credentialId;
158159
this.userHandle = userHandle;
159160
this.publicKeyCose = publicKeyCose;
@@ -183,6 +184,7 @@ private RegisteredCredential(
183184
* the standard matures.
184185
*/
185186
@Deprecated
187+
@JsonProperty("backupEligible")
186188
public Optional<Boolean> isBackupEligible() {
187189
return Optional.ofNullable(backupEligible);
188190
}
@@ -206,6 +208,7 @@ public Optional<Boolean> isBackupEligible() {
206208
* the standard matures.
207209
*/
208210
@Deprecated
211+
@JsonProperty("backupState")
209212
public Optional<Boolean> isBackedUp() {
210213
return Optional.ofNullable(backupState);
211214
}

webauthn-server-core/src/main/java/com/yubico/webauthn/data/AuthenticatorAttestationResponse.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,10 @@ public class AuthenticatorAttestationResponse implements AuthenticatorResponse {
8282
private final SortedSet<AuthenticatorTransport> transports;
8383

8484
/** The {@link #attestationObject} parsed as a domain object. */
85-
@NonNull @JsonIgnore private final transient AttestationObject attestation;
85+
@NonNull
86+
@JsonIgnore
87+
@Getter(onMethod = @__({@JsonIgnore}))
88+
private final transient AttestationObject attestation;
8689

8790
@NonNull
8891
@JsonIgnore

webauthn-server-core/src/test/scala/com/yubico/webauthn/Generators.scala

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -73,13 +73,21 @@ object Generators {
7373
userHandle <- arbitrary[ByteArray]
7474
publicKeyCose <- arbitrary[ByteArray]
7575
signatureCount <- arbitrary[Int]
76-
} yield RegisteredCredential
77-
.builder()
78-
.credentialId(credentialId)
79-
.userHandle(userHandle)
80-
.publicKeyCose(publicKeyCose)
81-
.signatureCount(signatureCount)
82-
.build()
76+
backupFlags <- Gen.option(arbitraryBackupFlags.arbitrary)
77+
} yield {
78+
val b = RegisteredCredential
79+
.builder()
80+
.credentialId(credentialId)
81+
.userHandle(userHandle)
82+
.publicKeyCose(publicKeyCose)
83+
.signatureCount(signatureCount)
84+
backupFlags.foreach({
85+
case ((be, bs)) =>
86+
b.backupEligible(be)
87+
b.backupState(bs)
88+
})
89+
b.build()
90+
}
8391
)
8492
)
8593

webauthn-server-core/src/test/scala/com/yubico/webauthn/data/Generators.scala

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -273,13 +273,16 @@ object Generators {
273273
)
274274
)
275275

276+
val arbitraryBackupFlags: Arbitrary[(Boolean, Boolean)] = Arbitrary(
277+
arbitrary[(Boolean, Boolean)].map({ case (be, bs) => (be, be && bs) })
278+
)
279+
276280
def authenticatorDataBytes(
277281
extensionsGen: Gen[Option[CBORObject]],
278282
rpIdHashGen: Gen[ByteArray] = byteArray(32),
279283
upFlagGen: Gen[Boolean] = Gen.const(true),
280284
uvFlagGen: Gen[Boolean] = arbitrary[Boolean],
281-
backupFlagsGen: Gen[(Boolean, Boolean)] =
282-
arbitrary[(Boolean, Boolean)].map({ case (be, bs) => (be, be && bs) }),
285+
backupFlagsGen: Gen[(Boolean, Boolean)] = arbitraryBackupFlags.arbitrary,
283286
signatureCountGen: Gen[ByteArray] = byteArray(4),
284287
): Gen[ByteArray] =
285288
halfsized(

webauthn-server-core/src/test/scala/com/yubico/webauthn/data/JsonIoSpec.scala

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,11 @@ package com.yubico.webauthn.data
2727
import com.fasterxml.jackson.core.`type`.TypeReference
2828
import com.fasterxml.jackson.databind.ObjectMapper
2929
import com.fasterxml.jackson.databind.exc.ValueInstantiationException
30+
import com.fasterxml.jackson.databind.json.JsonMapper
31+
import com.fasterxml.jackson.databind.node.BooleanNode
3032
import com.fasterxml.jackson.databind.node.ObjectNode
3133
import com.fasterxml.jackson.databind.node.TextNode
34+
import com.fasterxml.jackson.datatype.jdk8.Jdk8Module
3235
import com.yubico.internal.util.JacksonCodecs
3336
import com.yubico.webauthn.AssertionRequest
3437
import com.yubico.webauthn.AssertionResult
@@ -54,7 +57,11 @@ class JsonIoSpec
5457
with Matchers
5558
with ScalaCheckDrivenPropertyChecks {
5659

57-
def json: ObjectMapper = JacksonCodecs.json()
60+
val json: ObjectMapper =
61+
JsonMapper
62+
.builder()
63+
.addModule(new Jdk8Module())
64+
.build()
5865

5966
describe("The class") {
6067

@@ -533,4 +540,23 @@ class JsonIoSpec
533540
}
534541
}
535542

543+
describe("The class RegisteredCredential") {
544+
it("""does not have a "backedUp" property when newly serialized.""") {
545+
forAll { cred: RegisteredCredential =>
546+
val tree = json.valueToTree(cred).asInstanceOf[ObjectNode]
547+
tree.has("backedUp") should be(false)
548+
}
549+
}
550+
551+
it("""can be parsed with the previous "backedUp" property name.""") {
552+
forAll { cred: RegisteredCredential =>
553+
val tree = json.valueToTree(cred).asInstanceOf[ObjectNode]
554+
tree.set[ObjectNode]("backedUp", BooleanNode.TRUE)
555+
tree.remove("backupState")
556+
val cred2 = json.treeToValue(tree, classOf[RegisteredCredential])
557+
cred2.isBackedUp.toScala should equal(Some(true))
558+
}
559+
}
560+
}
561+
536562
}

yubico-util/src/main/java/com/yubico/internal/util/JacksonCodecs.java

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,7 @@
33
import com.fasterxml.jackson.annotation.JsonInclude.Include;
44
import com.fasterxml.jackson.core.Base64Variants;
55
import com.fasterxml.jackson.databind.DeserializationFeature;
6-
import com.fasterxml.jackson.databind.MapperFeature;
76
import com.fasterxml.jackson.databind.ObjectMapper;
8-
import com.fasterxml.jackson.databind.SerializationFeature;
97
import com.fasterxml.jackson.databind.json.JsonMapper;
108
import com.fasterxml.jackson.databind.node.ObjectNode;
119
import com.fasterxml.jackson.dataformat.cbor.CBORFactory;
@@ -23,8 +21,6 @@ public static ObjectMapper cbor() {
2321
public static ObjectMapper json() {
2422
return JsonMapper.builder()
2523
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, true)
26-
.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false)
27-
.configure(MapperFeature.PROPAGATE_TRANSIENT_MARKER, true)
2824
.serializationInclusion(Include.NON_ABSENT)
2925
.defaultBase64Variant(Base64Variants.MODIFIED_FOR_URL)
3026
.addModule(new Jdk8Module())

0 commit comments

Comments
 (0)