25
25
package com .yubico .webauthn .data
26
26
27
27
import com .fasterxml .jackson .core .`type` .TypeReference
28
+ import com .fasterxml .jackson .databind .JsonNode
28
29
import com .fasterxml .jackson .databind .ObjectMapper
29
30
import com .fasterxml .jackson .databind .exc .ValueInstantiationException
30
31
import com .fasterxml .jackson .databind .json .JsonMapper
31
32
import com .fasterxml .jackson .databind .node .BooleanNode
33
+ import com .fasterxml .jackson .databind .node .JsonNodeFactory
32
34
import com .fasterxml .jackson .databind .node .ObjectNode
33
35
import com .fasterxml .jackson .databind .node .TextNode
34
36
import com .fasterxml .jackson .datatype .jdk8 .Jdk8Module
@@ -44,6 +46,7 @@ import com.yubico.webauthn.extension.appid.Generators._
44
46
import org .junit .runner .RunWith
45
47
import org .scalacheck .Arbitrary
46
48
import org .scalacheck .Arbitrary .arbitrary
49
+ import org .scalacheck .Gen
47
50
import org .scalatest .funspec .AnyFunSpec
48
51
import org .scalatest .matchers .should .Matchers
49
52
import org .scalatestplus .junit .JUnitRunner
@@ -62,6 +65,7 @@ class JsonIoSpec
62
65
.builder()
63
66
.addModule(new Jdk8Module ())
64
67
.build()
68
+ val jf : JsonNodeFactory = JsonNodeFactory .instance
65
69
66
70
describe(" The class" ) {
67
71
@@ -133,52 +137,6 @@ class JsonIoSpec
133
137
}
134
138
135
139
describe(" The class PublicKeyCredential" ) {
136
- it(
137
- " has an alternative parseRegistrationResponseJson function as an alias."
138
- ) {
139
- def test [A ](tpe : TypeReference [A ])(implicit a : Arbitrary [A ]): Unit = {
140
- forAll { value : A =>
141
- val encoded : String = json.writeValueAsString(value)
142
- val decoded : A = json.readValue(encoded, tpe)
143
- val altDecoded =
144
- PublicKeyCredential .parseRegistrationResponseJson(encoded)
145
- val altRecoded : String = json.writeValueAsString(altDecoded)
146
-
147
- altDecoded should equal(decoded)
148
- altRecoded should equal(encoded)
149
- }
150
- }
151
- test(
152
- new TypeReference [PublicKeyCredential [
153
- AuthenticatorAttestationResponse ,
154
- ClientRegistrationExtensionOutputs ,
155
- ]]() {}
156
- )
157
- }
158
-
159
- it(
160
- " has an alternative parseAuthenticationResponseJson function as an alias."
161
- ) {
162
- def test [A ](tpe : TypeReference [A ])(implicit a : Arbitrary [A ]): Unit = {
163
- forAll { value : A =>
164
- val encoded : String = json.writeValueAsString(value)
165
- val decoded : A = json.readValue(encoded, tpe)
166
- val altDecoded =
167
- PublicKeyCredential .parseAssertionResponseJson(encoded)
168
- val altRecoded : String = json.writeValueAsString(altDecoded)
169
-
170
- altDecoded should equal(decoded)
171
- altRecoded should equal(encoded)
172
- }
173
- }
174
- test(
175
- new TypeReference [PublicKeyCredential [
176
- AuthenticatorAssertionResponse ,
177
- ClientAssertionExtensionOutputs ,
178
- ]]() {}
179
- )
180
- }
181
-
182
140
it(" allows rawId to be present without id." ) {
183
141
def test [P <: PublicKeyCredential [_, _]](tpe : TypeReference [P ])(implicit
184
142
a : Arbitrary [P ]
@@ -416,6 +374,92 @@ class JsonIoSpec
416
374
}
417
375
}
418
376
377
+ describe(" The function PublicKeyCredential.parseRegistrationResponseJson" ) {
378
+ it(" can parse registration responses." ) {
379
+ def test [A ](tpe : TypeReference [A ])(implicit a : Arbitrary [A ]): Unit = {
380
+ forAll { value : A =>
381
+ val encoded : String = json.writeValueAsString(value)
382
+ val decoded : A = json.readValue(encoded, tpe)
383
+ val altDecoded =
384
+ PublicKeyCredential .parseRegistrationResponseJson(encoded)
385
+ val altRecoded : String = json.writeValueAsString(altDecoded)
386
+
387
+ altDecoded should equal(decoded)
388
+ altRecoded should equal(encoded)
389
+ }
390
+ }
391
+
392
+ test(
393
+ new TypeReference [PublicKeyCredential [
394
+ AuthenticatorAttestationResponse ,
395
+ ClientRegistrationExtensionOutputs ,
396
+ ]]() {}
397
+ )
398
+ }
399
+
400
+ describe(""" tolerates and ignores the "response" sub-attribute:""" ) {
401
+ def test [T <: JsonNode ](attrName : String , genAttrValue : Gen [T ]): Unit = {
402
+ type P = PublicKeyCredential [
403
+ AuthenticatorAttestationResponse ,
404
+ ClientRegistrationExtensionOutputs ,
405
+ ]
406
+ it(s " ${attrName}. " ) {
407
+ forAll(
408
+ arbitrary[P ],
409
+ genAttrValue,
410
+ ) { (value : P , attrValue : T ) =>
411
+ val tree : ObjectNode = json.valueToTree(value)
412
+ tree
413
+ .get(" response" )
414
+ .asInstanceOf [ObjectNode ]
415
+ .set(attrName, attrValue)
416
+ val encoded = json.writeValueAsString(tree)
417
+ val decoded =
418
+ PublicKeyCredential .parseRegistrationResponseJson(encoded)
419
+ val recoded : ObjectNode = json.valueToTree[ObjectNode ](decoded)
420
+ recoded.has(attrName) should be(false )
421
+ }
422
+ }
423
+ }
424
+
425
+ test(
426
+ " publicKeyAlgorithm" ,
427
+ arbitraryCOSEAlgorithmIdentifier.arbitrary.map(i =>
428
+ jf.numberNode(i.getId)
429
+ ),
430
+ )
431
+
432
+ test(
433
+ " publicKey" ,
434
+ arbitrary[String ].map(new TextNode (_)),
435
+ )
436
+ }
437
+ }
438
+
439
+ describe(" The function PublicKeyCredential.parseAssertionResponseJson" ) {
440
+ it(" can parse assertion responses." ) {
441
+ def test [A ](tpe : TypeReference [A ])(implicit a : Arbitrary [A ]): Unit = {
442
+ forAll { value : A =>
443
+ val encoded : String = json.writeValueAsString(value)
444
+ val decoded : A = json.readValue(encoded, tpe)
445
+ val altDecoded =
446
+ PublicKeyCredential .parseAssertionResponseJson(encoded)
447
+ val altRecoded : String = json.writeValueAsString(altDecoded)
448
+
449
+ altDecoded should equal(decoded)
450
+ altRecoded should equal(encoded)
451
+ }
452
+ }
453
+
454
+ test(
455
+ new TypeReference [PublicKeyCredential [
456
+ AuthenticatorAssertionResponse ,
457
+ ClientAssertionExtensionOutputs ,
458
+ ]]() {}
459
+ )
460
+ }
461
+ }
462
+
419
463
describe(" The class PublicKeyCredentialCreationOptions" ) {
420
464
it(""" has a toCredentialsCreateJson() method which returns a JSON object with the PublicKeyCredentialCreationOptions set as a top-level "publicKey" property.""" ) {
421
465
forAll { pkcco : PublicKeyCredentialCreationOptions =>
0 commit comments