From e5571ffad0dc8bd9b3250759e799b0206969584e Mon Sep 17 00:00:00 2001 From: Emil Lundberg Date: Fri, 22 Nov 2019 18:08:44 +0100 Subject: [PATCH 01/24] Use keyserver keys.openpgp.org --- .github/workflows/release-verify-signatures.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release-verify-signatures.yml b/.github/workflows/release-verify-signatures.yml index 57dbdafd2..360247e13 100644 --- a/.github/workflows/release-verify-signatures.yml +++ b/.github/workflows/release-verify-signatures.yml @@ -26,7 +26,7 @@ jobs: run: ./gradlew jar - name: Fetch keys - run: gpg --no-default-keyring --keyring yubico --recv-keys 57A9DEED4C6D962A923BB691816F3ED99921835E + run: gpg --no-default-keyring --keyring yubico --keyserver hkps://keys.openpgp.org --recv-keys 57A9DEED4C6D962A923BB691816F3ED99921835E - name: Verify signatures from GitHub release run: | From 642a076158eab564b7f30a658b289c9aaa4e3a8e Mon Sep 17 00:00:00 2001 From: Gabriel Kihlman Date: Tue, 14 Jan 2020 15:25:09 +0100 Subject: [PATCH 02/24] Adding a static code analysis github workflow --- .github/workflows/scan.yml | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 .github/workflows/scan.yml diff --git a/.github/workflows/scan.yml b/.github/workflows/scan.yml new file mode 100644 index 000000000..cee251402 --- /dev/null +++ b/.github/workflows/scan.yml @@ -0,0 +1,31 @@ +name: static code analysis + +on: [push] +env: + SCAN_IMG: + yes-docker-local.artifactory.in.yubico.org/static-code-analysis/java:v1 + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@master + + - name: Prep scan + run: | + docker login yes-docker-local.artifactory.in.yubico.org/ \ + -u svc-static-code-analysis-reader \ + -p ${{ secrets.ARTIFACTORY_READER_TOKEN }} + docker pull ${SCAN_IMG} + + - name: Scan and fail on warnings + run: | + docker run -v${PWD}:/k \ + -e PROJECT_NAME=${GITHUB_REPOSITORY#Yubico/} -t ${SCAN_IMG} + + - uses: actions/upload-artifact@master + if: failure() + with: + name: suppression_files + path: suppression_files From 921c2370fb88c29c6b2905e041e9c8119bea3fe9 Mon Sep 17 00:00:00 2001 From: Gabriel Kihlman Date: Thu, 16 Jan 2020 10:47:17 +0100 Subject: [PATCH 03/24] Use https for maven repo. As seen from build logs: "Could not GET 'http://repo.maven.apache.org/maven2/com/fasterxml/jackson/core/jackson-databind/2.9.10.1/jackson-databind-2.9.10.1.pom'. Received status code 501 from server: HTTPS Required" --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 8264dadb6..39eacab6b 100644 --- a/build.gradle +++ b/build.gradle @@ -87,7 +87,7 @@ subprojects { repositories { mavenLocal() - maven { url "http://repo.maven.apache.org/maven2" } + maven { url "https://repo.maven.apache.org/maven2" } } } From 48cfcd1cbcc35368ed4910cb407eba6e7737a158 Mon Sep 17 00:00:00 2001 From: Gabriel Kihlman Date: Thu, 16 Jan 2020 12:27:48 +0100 Subject: [PATCH 04/24] Schedule re-scans once a week --- .github/workflows/scan.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/scan.yml b/.github/workflows/scan.yml index cee251402..10e404f3f 100644 --- a/.github/workflows/scan.yml +++ b/.github/workflows/scan.yml @@ -1,6 +1,10 @@ name: static code analysis -on: [push] +on: + push: + schedule: + - cron: '0 0 * * 1' + env: SCAN_IMG: yes-docker-local.artifactory.in.yubico.org/static-code-analysis/java:v1 From 20d02d97aeef578b6c222022d5de30dc851a8d61 Mon Sep 17 00:00:00 2001 From: Emil Lundberg Date: Thu, 16 Jan 2020 13:43:59 +0100 Subject: [PATCH 05/24] Merge identical switch branches --- .../java/com/yubico/webauthn/FinishRegistrationSteps.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/webauthn-server-core/src/main/java/com/yubico/webauthn/FinishRegistrationSteps.java b/webauthn-server-core/src/main/java/com/yubico/webauthn/FinishRegistrationSteps.java index ae47d614f..15c34acc8 100644 --- a/webauthn-server-core/src/main/java/com/yubico/webauthn/FinishRegistrationSteps.java +++ b/webauthn-server-core/src/main/java/com/yubico/webauthn/FinishRegistrationSteps.java @@ -507,6 +507,7 @@ public Step16 nextStep() { public Optional trustResolver() { switch (attestationType) { + case NONE: case SELF_ATTESTATION: return Optional.empty(); @@ -526,9 +527,6 @@ public Optional trustResolver() { )); } - case NONE: - return Optional.empty(); - default: throw new UnsupportedOperationException("Attestation type not implemented: " + attestationType); } From 23acdf9291e246fdff38b65c9a6c3484592e0dae Mon Sep 17 00:00:00 2001 From: Emil Lundberg Date: Fri, 17 Jan 2020 12:28:05 +0100 Subject: [PATCH 06/24] Add link to yes-static-code-analysis repo --- .github/workflows/scan.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/scan.yml b/.github/workflows/scan.yml index 10e404f3f..7d897184e 100644 --- a/.github/workflows/scan.yml +++ b/.github/workflows/scan.yml @@ -1,4 +1,5 @@ name: static code analysis +# Documentation: https://github.com/Yubico/yes-static-code-analysis on: push: From 2a48a8514ccf37163577eae040c4b6baca9d5a12 Mon Sep 17 00:00:00 2001 From: Emil Lundberg Date: Fri, 24 Jan 2020 14:15:18 +0100 Subject: [PATCH 07/24] Upgrade Gradle wrapper to version 6.1 --- build.gradle | 2 +- gradle/wrapper/gradle-wrapper.jar | Bin 55616 -> 58695 bytes gradle/wrapper/gradle-wrapper.properties | 2 +- gradlew | 35 ++++++++++------------- gradlew.bat | 2 +- 5 files changed, 18 insertions(+), 23 deletions(-) diff --git a/build.gradle b/build.gradle index 39eacab6b..a22cdaadf 100644 --- a/build.gradle +++ b/build.gradle @@ -30,7 +30,7 @@ if (publishEnabled) { } wrapper { - gradleVersion = '5.4' + gradleVersion = '6.1' } allprojects { diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 5c2d1cf016b3885f6930543d57b744ea8c220a1a..f3d88b1c2faf2fc91d853cd5d4242b5547257070 100644 GIT binary patch delta 22808 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 delta 20005 zcmV)NK)1ig$^*c%1F$Or3aZ&=*aHOs0O|>o?>!llP5~5?9@GYZjaFM%6IT@ej+ta& z90g-QgNlPU5-y3g)>g2zO1&TfEdgvq+YZSgj810K$;3T}Lh^P8=451Lj40^Byo?0}XR#>b#!kfWj*MIfZVGox zV!0)j+Z}jU!FzaLhTef?vCS(ugn|st5IJX9hC9I!N+cHty)Km8Rina?%-BvbU3Bz<$Y0>ZqLf+3lDh1@ zi(FJZz(dMg@JxtXs8aDEK4R$J6kl7uL$s^-7@ttZ0`!xnUEzX96`$g0kZ+w9>Uq;x z7P)<<;&XhV;!Au*X#J!{gQP}NL$`<$%Kwpyukj7ldo%1@)pCsz-zX5n#Ywwr7BtIt zHIpiT?{dvu<(dyn3w&x<&(CRw6^IK4)xcP;3J==g@ycLI#kcrQr1m|-;Qzc`4Ewk1 zL%KnmM-9n#EwwgE*tHktrij`^vhjLMjW-v2s;-&YqM0Gho|bY2?Gh_;H~X;S@>26f z3_P@2c(<6l*L8%L=5YmeV4lWY@;v#UNrfti;`PK zRMfn{r_Cz;Rk5o^U@- z(5m_h7({}e)U6mIEiz^Uq$iV%4~?v0$Lte?a?&4=a-q>0!Zk#)>yT^cSVQNSv<@XM z)vz-zMb#R1jfLak=x);P%7voc*&6nLj78!RMuKQAG)(V%Z^Wg)5PK}lenSs~NKW#S zJAqDG`zZJU!f_D8^wB?!eq6#~EI`9;!djpck^B`u!FuvyH;fSv5XUG|1SCSg8`883 zk;Mg^#7h+AG_9xbGJzI8PvaHRI#Z{@KYNwVUL#3A*mDXd%NUT+Eu+`_56S3%lIiyg zFy>{=Fiw%^n^R}~XUZx<&*>-V%?(HQtzmx+@tKjQ6QMIwk96oq93JVBP6?7~=!+hx z;oxIL;^AK&N$jWR|2)B=T(m#nY8{8yp#ABUR?yQ+sR@!a0zFEwPtyJj!4`CAq@$r5 z69iajO>Yo0?a{$JP`eR&hM0^EHyAtcFX_=W_B!MIf0K;}@dd}_?x`D-8xBH$PZL2D zJ+m!rUA9yn2;J0lWIs%62sHbPTDogPBWca`j1S|L|=qx;t%jg z8Sj*W4KzjfVQ1#vbIv_?ZsynT?>_hmdy5+gJs-y zkbrMv#l{_m@n>Ni>gNmzKflF)kSxoZV7OQbWAVDZyCc*az7tWztH>&kwzvw-xgSjG zM%bds_d zvjQcCsk+b`MDIvd8_0z+W?1y|mG}Gu4`QK%;h>U@y9^8d$ik~7)3vpKS7eww2gu-T z%C@SC_0aU5K28;k4;N`nlEyin7$zH9Hw#VE@7tD8HtxA7AfQY9n>gk&z$A+{R$ZFz z15@OojYkZH|GP|v?1`~ciJ6g2Gh}+ih{yF{v)j^Qmtn%pMM*;HF2k~48GvXN#`RME zY>45>5a2&jGpA!@Ld$Z0gR3>AIGITL`Ry`8Zb*skvYGJoh&C}#uf~P>60po5K`($# z0j)FxjIA8N`brxM8Tya+f*)}SW@3IG5I2mk;8K>#(jJe$A{005jF001EXlcCfdlaJK~ zf1Ozgd|by_|9{f%zNgjG;q|$`vQF$+)@eJA9m|OmOTJ{wlB|{F%68&BNl((+t6k;o zTiZ%XLrM*$C4{3i&C#Sl+dwJcwDro3+9m|*K!I{opyen~&QR_aXj=C_vxj!2tw`%% zG;ijcZ|1xIGqd^Jw_f@TfSvNzAlBp8e}d@2XRFw|p_NlOUGkPlE{I&w_X!UsTgyQq7;6 z_=_OkkH1vSUm5ta`u=qg&*5)^_*;BMHGfw{X@76xAA!v-(9$sW7F|5ML1c@mW*+{7QfQ#Qg6yK z15X$d3d(X>VaiIi>ncN58?wfff3PWQ4OwT(`XGj6gDD$Lxkc?8p(e7)lv_=?&6Lfi zY%%3_Q?{DYpf=cMNTVT50;?;LaNN$gok}?=L8#A7UY^a`k zd#dN$(4qclS8os5y3gAe?Y6j`m}rZ7ZY(jePf*jDOr$(J;SJgGv|~!Mf1tLnzxPQ0 zp=k76=TUAVkgiJQYe99#;NioE`p-qXP9LfS8b}JnlM@pT<*n;Zx)W^^u00la+Ag{F z^t9u)b?ZrrF*xqAryTm1y&=a<#gYj@{j{5$aGg}DJC^dCgxaU2+&%}BmlE-$J=V8? zojV8ajwNE=enCgW5*jQve|<4!+mOK5nH-~%b=|Rq)03VWaohoWBtx@5)JuCEE_i;*OSJ*kfZ#HKt1`E3;(GNqMnEe@<3y=~^bhq06Jr zw3_7N`n=4pgy*;kJ5J@&ZhXP6-CS0iPC4#@2`87S4E#uXd|YKr#hDK3lSohXJ4*K& z+D>nI-A-b{n`A8WIo6p>DwUQnM`|vRRwc; z)82I2qthLGiqjP_e=c8HnC(i;Pa4uo+PG>*ePfCu0x4YT>-Z@l*z1e z08&5Uc-ckn3CEjE(wA$C_*`c^PHAn~Ir3YMX3p~(*`Zqse^0$5=ebBlUD59Bbr0EY zJf^r-7I764DbKj4h%ule%g*Ye6&fdD3d%G zO{U#ZN0k_Je>OF3u)C{#3c*gkH_e~Nza>ZomOC>G&kf< zOLpTUg4QMAY4hT9hjL_(A$M7_SK2MvCwE(NkLKcCP)&y=opR8^hwxzwFJX=@P>Q!`f1g`&NDfjf8bZqOIb256M`$J4)phQ^&E)|rkH4vqXPqd5sey=QrL(jFFJ0-PEgyFGs>eP zGLH-qFB!=rbA*c`N3;VYV?2o5*hpIOv_|^k4lzS5OT}1Gk#s>|w3S(?#3kL>!#R*z zy|4y4(y_R%&_Gr_<()|jKaY=C5>r;5mkXA}e}(x_uhzCwY`nEY!;~cnVW|e^!G}P< zpw2CsmWOh=RJ?X`VMT2gdrI=A;=Kdl9aHD{euICTbS2rxmd!NU%I>uE(s!v zdb#!TRJ?U0mKbY2XnVFdGwl$R>3w|~Et}>BURJdZ9-HnA5p;gDejZw}DW_=9`}4V` zf4p5LFsaC;m^ZmZ;A5#sBI!j^>FMbtbr_3~HbeY~92+{J^Ys#uEL$?Ixsp+}#RI66 z*q6gS6}Zcm%&02VK-PLO2WwVtl!L3f>~LzHVkA?oSriSjS3RR%!JVGofQ{i0)3wN0fOCi_}e^%!9eBI^nhKOD6jHmhKkJVyKNEERb7jt(> zf(%T$$xGQw*Sg}0kIp1K`*KmJSC&1xO7m}qcSB06W+@PlX`MHt&#)!U)>nafdltMM zf+@#4=#1OxI1_(e(Q#P9r}wB)Vr`eitn2FYhu!>zFEDjsEas;4wevI!$xCW~e-t?9 z?|91^7GE^O4driKYOa>%CW-^GcEO${7q}3u>USPW^L9G#sI6u0Ipy!vwY0P(zN?E& zExzt$??j!Yw@}*N#apJUuc-cpGaYJJUy>5J+iTiY-pr3nFArI&dbY(i}uOWx4%3bo5&%fhye}&Oh!vsZcFJ9a^X}eM7+r+3-a$!24xmB)Ho2KvL ztwZhdClKE$UOGh)i3w%v@&)&^W5<-v{!4DmV*(oVZC96~RPt#``e;0vQr9NNBsx0j zD6BEqKblN=*o#yDrSmI*x0z<#Ij33XGac#NBh;mrRjHiBbSyj$L z^$u-ZI!6k~pM9n`bS@Puf0cdn&yv7+(w(xs1tyg7R2dU;T-b#5=z+k2fiPk?&;A7f z6^LUkrjRI%lN?VMjUPfty&l*PsRxAqrgL9DBlr!H_cCVKKFrY|{P6Kx)z~D>Ewhjp z^)`=a#tOEZVB%K1mA%F+BfbxB(?9D~X+ffUN>qjJDPfgb#G^S8fA8ds`XO**<18u~ zo35d?kjbYz4_#2zAA;1Y^UhYO34Q!^gE!^*R)M6`Epn;Cqh7Ht0>9Q-kV?mdV z1zk33Gb?n@)4Hgh(#l6FA5l52dbO6oija97RX0#Ohv2ZxqWU^4rAwvOrB<(Rp$}TI z9NV>QE4wZy`|X-nf0mQ@19%5TWW8Fc7uGdrP?JIJsm7+}S=7zjnBDgd?z@ZqJN3Si z?2>{_b-02b)UxXEL)wc!%)XD5DEsfq3#;6Ofd1L9h7Y55f75l;XRxe2Fo)3a9F`AL z@QPWi>-pYzq5kv6?Pl({6-)p>Wv9U~Sl!!Mb+;f3gOA%4|2)Xv6Mc)t>6A zJvCu}*vw$#@b0RL=P`91w`34`3M)T`O`%&exNQ!bheKOtar?`wYF1WVvG>%hs@C7? zRn;r7b*kz;&!MUD6Q~Sr%b@X;COUhnNeSFQNPU`C2CuBD`6QYGXbGE@E2}bSe&Oc3 z^_rFpTEqSue=x)T4BA?5pplgAFW|QJy7Kdenh)2#{Gv{}&*OEv>~(xqf3qQdFVhOx z%lUoexQFiF&jh)b)ceqk1K5cU&UCUph%OvPACA!BM=`|F7>=>}jx(LQnch7NOD~=v z$J028527C*CFjR6fLC#fvQOg+ID;?YEWV5f@D-e+e-@|lb<*CzSrI%Sew>pk*kWNs zr@)U=n_9ercjHGG)SY-1k27%%O1{FmCzvh|veti$e^r$FHvBkyLCSmtKY^b_HFdm< z_pnz(YhJ@o(N>>IjC@M5mrE)3vME&|)p!!`L#3#+&aUu_iKl3jUnlpgsJh9GYYeP6 zu*1MJe+Hg4@O}f&8F=16zkw4FALZO+jV{F{n(G_rxJgX|ix~+~H)&1D3=~}qeBdSv zu71%>{vR3G+@w8a_bn_NX`%8!#NSZn1k2-e~nGE*xS?c8hkH?+M6gVgMClK(n)+b zlejr_&m8s-&*I+DeHk2RBoue>n?Wb5a~_Yf*qEdq({$BCbYu#viE|O6-aW*)n09NCW-7+^XHcj4zWHojeBcEua0W{g%8jMz*jzVEY8DRBx7aOQEk<6s7dPBe!O ze`jzcbhPr*=*r+&Pjl$F8h86R9!U_`2DI5^imzdk zx6-V=#LJT`t9};LBunX07Sm%aB;~KOfAqi_a{L0zx02kqF=`*B8}^d=OZa6*aFRaG z(jH^fui{1a`Uw&rV^3lB;{{(ouKmg@2<3kqpP-J)!%e8TN%56BH(3hTR7yv0@?7y1 zNF-<~mt-)TJEWfGNCk68Xqbo8iO^}bJE{f6iVl zWXvjkQofe~e3H7qk7e`}VeXltOxaP;euvIwUSX*5b$y~+1d>k{GNl^wO*CtL`#Jd% z=5l&|kwR2r-XFT38g_>s(Au6;+J+uv+wKe5>f;ZMs81j?T5swAGyi?jVIM#K=rGeH zIvfbIXM_XMVY4YZTpws=W3)uCU1My%3bR%4JoWql)UTBxmUNi9M_7GZS$)d3qgjP= zwgm{tpVE=B7>G}6+d>3@&uH7ig!-5D4I#oRdWAhd_t}kKVJ|?=SGD9{#e}{_RbX8I zUriJ0|3ywB_-(VTAEFfsa6sYpV+Q~L2@sQSG#Zo8Kn9bb*9d=|SNVS&WgULr>@m~L zgrc` z%9W4Gm5-_TxK#N>4EN!aa^+La_%uEv1@4#A&o<*QKG%$Kd|ozRQ1L~%{G}MajIYFS zr*xLVS7q~ng0HFgx{3!?d_%=IW9Y=U)i}b>YKJ~9WG7_v<1#A z-Oi9-4>Zdp=pr)itsZh`v~O9?K#ghsQ%6WM)EKez*_1iYhTY8~jaC+?$Ct16Z zhYr&cqtu${tPgI?o6c85AIi!I3yxM+<@yioJDGnm^5w9^rgeA9a0Brc+c2_)KIepO zIeM0g7?dl?YwO@dVlz9{NaTkHvwBV@5_oST=0tY~3rmbhmf0 zKn;HY@;Xy=UBmWLy}VfIt^uCduv2t1MsQbJIUL&^k9dEo!F&e557-ZwXQV$0Q~}2*OTkkqG@FfSHlnSBMndC zG{f8NOlf#p&iCNQ8h(PGYIsIAKa*=e$FqM5&S-cJ&kIDl^SbM4_=Vg)i&=WD1e(S> zq{Whga~kGwUc(Expx~DpeuWn`yo8rE{2IT}@Ctsb;dj!)tGJuo=rb(Clj`Iduhel* z(a`Vl2L*rB@EZQ4;dT63!(Z@M3O67inbYeOt!#(wcpXLiUNhf8=5%-tJJBtm4jF%X z!LfU2^$mHVH}N+Of0zDmlXtXwsVt%G`j88(Su*C8NR%r9tKdS8GKc3E`aOenz;P=l z^ZnGE?3#;%Bb73)p?iK_32bjzxEhw6Md=<&$ePoVGrWVkJWD`Mh4Vpu+Ne*B`Qj>V z+f4DUM1v}}XsOISDyp6nED2nnXjFei>&s!YS?H^f!-vb75;Y3}&gI0pccS1}Mb9{> zdy~8vJ(DpCtos{S`O}wO(Hk6N{;pOvFg9Q86j|s-T$9x|vG76YtbYrmS;>229_>bn zws9CMXdAwjX(yNSuXRBf%JpffFvKrvjCX7~jLynNfgPQPyh%dddHIn0D>r|(<0APt zf1_%)I=rs#N*9Jk;!??8GWL+ePmMZaNy=1UZ~ot~>y#HiO{!T<-S$N7ekG+TqfF|B zLE|K|Gi>`^1;EV`K-c8}Ao_KenBPH0)V{VgZ~Q#}Dp`Q-?MJ}kBgT@KDgbsfBZic|kh_<%M2Nqzzt=#jO^?Saw ze$U6&@A(?@FF}aEJ=ja_TR9p>6BPD0CfCnGByXBUQ?hFop=3Nfi*Pa?nMEWSkIo{R zJO|}DN;aXFZIt@J2K2FQ=Nc_wA3gy1Bk75+n0%?YM?Xz(BO?8Xw=RD`J)As?rV^H2 zKw&L$WDY5s-7pr9oPiL%Vn~ee?^)PqhmBSKpU-~;S-PDpO_Q5P$jdA_ zIZ0MNNKQUPR-PqOUL{xFAV>Z|&3Diz)?lAlhy5an+e9yJ7ehEm%V{x&0r3C^#j`jd zp2v`Q1;gTX91?G0)Mw!lETi39@Ihuln3mS#c8;RdyNmt@$Um~L%+Z8+27}xcI3iBs z01lF+S&_#bL>qr1l7C_d!wA#I3LK(b1S8baC?D*N(!&^6Zh-m@(hAg;J>p$>LcyKy zVx@w^3daA1-eU?n-zKoTC>oZ|TK6&~?haA{DL+NP{3>DNnTDCA1p;N%RWocq@3IG5I2mk;8K>!U@s4Rai6aWBpD*yl>ldx$P zlg~g6f1Ozgd{oudKPR)i$?(_$Aq?w?1hR)635bLwNHhsZSd0|mW#%OrnI+D=Aqll= zEmmu_ty?Wx*Q#ixRZtQjifh$c+^VhGO{=!ns-L#~7X6B*|MT9=WReU5@+0@Xcb9X| z@;}SH^V}B)4-wHE{>V++dAKwqq!}sAC}~D#f1}BfW{iA}byFedDm>0c{OV(Fa&w-H zjhDvb<_SDenn`Y+%v0QS15cI4tMEx~8q3pU{>chYcX7U(9^e@Y&verSE^yNxE|i`k zX^Istann@Jb#p0~xv7%N<#U!av!$6cj1KZ#h3C0=zQPM+#zHsEL zd7dvkMHP;@sZ|u(%EmDInB&rHQ@F!TL9UgiQzmvPyj|h1yXkzH+s+rrf^Uet7rN;a zzDPbVlDCV+G#4rSO(wNA9M+>%K`j>3V@#gvniZAn>egShK zT)UDfr|vv$n^qpw!mZ_vMl=v^UCcDRDiV$vTG&{x1>?GlFJW>9Bdx7^lxbpJB-&cu z8rA$ky}To;wYTfh@;Y-6D_#CbM>rVK{7h3aO{}d>jLRtT)6%&3bgLhC#7F#HR(k*3oWAuBITkJF@-OEoT>1*NkJk%f3}YXn&a}l zE*fMSVUZ8(M)|rmwV0BdKBciun=^kwV?4w(Iw+!7rwuCnEp*on?q-^IOf63zvI;vZ zvU7DHnqsP7X4TyMoItyLLzlpb-Y&~x3h#hfFzAa1q24rxrxgsOQkcnmY;Afc69@2D z3rn_`iOJUVnC^>5e*;EWc|EWQAXW!j^_U?mTg2$OsXc1L?QsKibuENZh8mpB z@s<{Wde+9}@V4eISYIoH$6&~Dk%?hiyEf9EJ`1;&HrbpcZW z;|BUdS9{VQyo2U08Mxch#R^}B<=ZUw6P{Vsru(+W#BTEohBACif#9@C$g&XhtNDz$ z7Bo?i9gD=HKHbFnFuk)~_Zhn19B~CLxIsE^W~lT_tMKI@)fi|EYeqb(57qJD6+>i( zrDM8L(+M~kqNde)e>4<`#RS4|qQTT4PL{xHe5&6PA# zvN+qX2XzUa(G1GML?sqClLc7Dm&?}%*`hk&J7!}>uLr0VdW*>s4{r}Z{HYmTCfytk zJ#0j~QWi0_jiu#?Ni{MeK?>$b#Q^b-B#~8V{SxPdR6vq_UK+8Qa6F`^0=3O#%kI}D zTPWL;fiG|9f9@uS3SXh{cNM-8A>J2h?@9|sOl1WbgH&erEa*XVHWOU7plH#pncAH` zYt}5Lx{SFindnY9^kj9;l4iCvbNaWMEn8(ylgX_zCcad4lO!}p2rW5rLh02{lGfZ~ z(>g{V>8CYMXqBD_t#kSp&zHq#9mnDm4We0{bNhE$e;~UoK4EjGyG@eR!V{KO7B`x) z+k(EDm{%s#RC=18QRy9eSEXKhSf$_7A5?mro>1u$`j$!;(>GOmkRDR$a=r>1pHQhO zi@vAQx9KvKb`Y}e_f`G@U#;>re67OQ$;b67|B!D``A2*M((%!Snm${I?Ns?jz6m0v zO9;1ae_UBvifTpWAM?%d?ex(!M+F7Q%D3>XD&NMpt9%Fl1kojP*`V;9D&NI-tGtWv zQTbl}sWkVgyqm98`DgS7azX#fHSw?!2J>Z?0ADij*NA#FC95K8o zKMgGq_G;lSOp79+MkJb*d215c)oVn&EePaZf4vilIN0T#otoEGhEk$`|5eTBpb3$5|w@urodz*DV>@~DdyQFPzN5E(+%MY6cc{JoT+B5@= zf9{=`vD}{NZI4E<(CG3)(_ONc1+dZtz{(Qi5Zfz7t2YpXa-t$54C9w2UM&jN58!<%g5e&?{A+3|ZYNjr$VyTZL&T zknvWUMc9x5m3zdE_N#n=4=UWN^21{Ie@FNbvUPv7tc*srE(w_`KT2f}*NOJm@!_7_}&zBUy}k+xx3gZ%ZUv;gzWI8-;(X@@xD6 z67lMwuEhjSUODWF>%q2gtU!wiwGJ(8h||R}M_`t4jCHl}cO?=l3!{ot`E`Cn;oqtJ zd;WvUf8;-5tivk!RDP4+Qu)vPe>Muvj3tgr@AEq7Vp3l|SICRQ`}}NANs)tVfBP>=B_4sxsqA$wUj1GvJA1mr-5?<^%`>E?ul_ z4*`ckKvROS4-(GKaNaLGf5zpD9oX{=zBVo|tOa-RcE4swNresza!!B3H|zz4a{V%T zU<@^{Acq-|mHjs{xdpWuvE#%MsMTmQF)e$E&g1|)v7l<`{M6-5$XFj>heq;KF5?4af>k_}HGw*$t zoDgP)+#X2~s!v|1rI`{j-gLd;30F^k4-C9k?_#;rNfs>T@$a}?B6%<6IqLCV?j<6v zRv=lOD3qCI92fn?NpY;iC~;bD$<{TdeqTu&SZoG~x=072e82TYJ2bLQi`7S>dQDId!3F^Su&~}~Bt8clBjwEs)MeeL zIYV2mdtFaIjD}nTm8Z)(;I8Xvcy;)K5z&&P15sP2lW02?5|M*EbOC*Xm@dRu7F|R+ zaze*@jvUv`ei+ai3lrwBJJ=;U-J{n$B zypNQkl6~YXD&0pT_Lw_-7wrUcqMe47UK&d$gNNxfh4S$>gRaC#kwufPqVExzZ^9Fs zZ^BiU`6hhX(EEM*0eXa+{p2PE&!xrPG_oGesD`44e`o|=MpxK9_HN3laL8j!g%kb5 zJvm#lc&CyCNvfI(8LDY0{iGu^suYKk!#Pol_r&X9Njc&fj!rLOW!9Y9)~R# zLQdY*_ijlyO{svCQ=59oTcOw%xN=<{=b<}j)@bVUICEWdFWgTjRb+dzyJ?#JHX7zp zM$PJ`lQ(!2>6*S_hl_Xhz2H&0DPPoLGu5(!e@3I-1h&tmk+d1m*a8!3G?kiZCi$Q! zKb=CYP)C4Hr}JnHZN-crzCv_9MW_pX7g5wyVG9J5)we@Q*>ncYr#t8;1 zgp%MISalcO4dslaZM2K-0Y5nuqkFN!4jMuFDcuLPF2%09@#e&HDgBIo4l~^kI;G_3 zf5SAVLfaL}Q|JMO_OL>GiKcu(qw%89R6as86sr7;h7YjGgY-}WW4{71L1#k|OyOuK zJwP)UW*y&4Gn;Y>?2k}kldYt2Kfxi2AH`@1!pW_P;nKmwwgXg_MG4H=(=gY8wi9A@ z0q0)_;x3>ncxb7*q;Bega`vNFH5Dg42hbyG$fm3#G+m*C zQwE6GOAjYRdArQnNSY%u!59iW{5k=$PBsIKHrzqOVAQdQC?3R=8Svk^c%A~^Sq8tUe}#XCtY@i-6Ak}TS= z!vXhrv!vg8Q%r(80pJ^9y_={2e_YMN_KWa-8bF@3U;$j{PSf+TeM*|jge_f|FBZ&7 zS`p}t+S5yU zO~pA&d+4-!Zs?_DP0mNCvdNaS90tv)f;nN;>c$?bvEt?m#7!9V^qsV#f0tG^^-^t< ze4o)nXZBE?M3{Ogu%SW`4XtXba6L_V9wleBg?Epuv764?fOsTsx<3g_$aYf&;=yu6gbh&S7TSZzv=>q3A*}BOrEX}e2XO2K zwfzX(2VjnaFx$hR_6Tru2=4!wX~cE_aswRmS^6b(y9LSXIWsi0(PTOd__?s#8hV~y zfUzs+OnTAusw*(}W%@Pxu7_D)rdLcjA5H<_Ffb_q7=xXEW5PKXfBgJ51?L)ax%#lL zD`|QBuT*H6La!;bQlWaHBQynleUg{cClM`IsPPPi)(tNN+1KffLYLJXBg(C;CCE)D6`ANPnLG#Z>><14wHwJ{+r7gk z-iE2O`&pW1<_gjLVQl<7g31f9#fxyVmym~^r#aA`us9Ffn|2TZhLi1c8llkJJoz&a$&#No68ZUMe{3#pbxkj|N@i}eU>%UG zaGqp^0A98-AQQA4D72IEM7R?92t&MXioh>k>7{l!)%i^W#(F5)Lot*p9=miI9%m25 z#lg1iqT!aSZSyFP?&`ZvHtmp3m-*&#J-P=%ZbF)kg1aag=F<(JO9giss<+Eh3Tyz_ z2$pd}HKU*ke-D%~o!*A>-l0<==`wl`l->ue50JV)1f>sK4^!D|pqJ@%HvNVE3XN?-VelUP4Hh4Ty!Jl*9Xms3DP>;+idF`@26P4VSL4f? z=Y~^$ME?b8#1tASpVKIXK31sp2$d@o?4#MFq~Tmff6%Rf8D#ceXzPCH3c87 z=1?Cj=NPmSTO>0@BiQ&S{VS0vZbqNLHGi}nWmiLSDax&;1@@b0L`kVxY<2GH`v}17 zLa5r-pYg0*{@-Z-5Aps}RD1tM#f#)ipQk_xqA5+}W9~hsCi3ZjpfSniQ_Z5r2FT{o z|C)u)fBmM9A%`RW?>$1f+|TqV7k2tI!E_B)iKdmJV&rgFe_87^x0qt3 zWnOIsBxg!0rzI8WWU(z19sBMRq+@4CLd~n8RUHY7E~puY2-}{Fl&rGNm7?SVC9808 zLC;p<;$o*6>C-gM3cE6zGb{5pUvAEu(##30a5lR$DT6c9K8i9Zi-*a4R#B-+j>tj~ zw*K9~lj%pq{{gdrRk{KVZ*Cb8wgCVDU;_XEIFqnx7L!0)4U_EH7=M*gTT2^36#mX; zv#aS= zCG!2Gbf`4J%e!i@`G1zM-pF((?r70YWPG7Tzb|$CMdaQ3U?9($iPVhqKB!dX9|`r^ z?DlEW>1gYO;2vacNmy*CR2~n{no@rg3?zh&tR<2Yp_PdzN!JJ^EZN#2%h#$o%vF{W zf=_8G^+6(-np@t@l(zZL5PnJ-aJQ07cD z#$t&NtYa3Riz=Je$;ZbTDq1j3zvN5bWLuUp@eK z@XXrhtQ)M5xbm9cM1KHKO9KQ7000OG0000%03Ax$;uZ%009y_K049^LX%>?}S`~k3 zV;ff$J!4B6SsurZVkfm@7sWBHEZG(bG(g-2yfsm4*}+?J($*bY6L}JOq>e_34P_~i zmVGHuD3r28*B*CUi}$dH#|Lxm;V1z8kTJRN^Q1UcEUMJk2i$Xt#<#ZB41CBvqQtq6|c6A^q; z{)^+8Fg_K*r}3ExbbMB%XH|So=FdlP5?_$vwu9X34S5)v|wM7Ayr? z+OiCLBCnT9MoGbmi*sX>(^D&p^HXyxmu53lEAtC;>6wcPqSM#)n|dm*Te;Lc4OqER z1#J@rtK{gGv!v(ChJquP=Vl+7npmivI+C;XY~ENb8TO^ZhG=+Z%tGp6GjGsD=t0vm zoeK(@$>jg1(wJ1YgK6>9#3re>32$n`GTTU9fX04=Q!b z){8~MPF>cW^)Y(2K~0-LN8|gU1+6`2IQ!$V5^rSdF>j`~*UVhm)us+WuzT>=@-(yS-8+Jyq$u)UQke{khXSInY<+4z53v-d9iY>;`i zZ09fOrFBY-p(owf0HxvKwhg0H(sRb7nKMd`f<8~FWUQ5K)7eU8_Wn)%;Odqm)!B4) zT!BI#yY^U}+FUb=etbeD7lH`$j=pvyqZj=`X}67y!cAjp(=n`)8}@+ZMoVFIlr&@L zSArMAe%}+za8iqN=|g`)AmLrK^R=Sh)u!>K7s)Ip)Fn zLfKw3WRu0eudGJogoaT(sNusnui}RqCh)R`$MJ-Qk7HIt8q>Vndo64D5nj=-iZ$Ny zgDl3&Wqxc)kRVw3rjMW!2OR=(b!z$b&-;TO7v#ZyQ zHD}+}ykFw?zr*{>!|}m`1$yj2;~RHtt~1`S&<`q$|0FL^R#w6AJG%CMiAfW43cEg> zKG2gJ7+Uh~5Zjo?(O-BR#u|3({hhxN!rnJP+Z!4MC;xv>EArYz+I{lY$mPu8o*&xF z!qO1Db{2>aN<#~ki&@>FxnTV2xG)N3eY8+K?d^2M(+x9|Xw=v1I}7V};g&Q&*U?r! z@+6-%HfOJi$p+l%e@m&ny4yvM$J32*rRV!qU_4#c^Q8m!ys{k~yt2P?w@Qw&;RW%s zU0|x5twVo^Ea4QtlFssrtQp;S0Oz3KgIqOXkn0caStt2p6QmsG9(y9khq!t_XN7Yx zQHAoFt9pTBgfq~G0Pe*{C~2M&K8i8UVqn}i@Gvz+HzEcS$vbGOTRB2n;CEGkG+WT` zS~~7&`<6r!T0&w1lfKRW5=rHJJCUrQxr#t0F;ss=a3(RFtRi$iumg2j{t8#ovV+KS z6|G!p6|_ZIiSA%`sEW?*nmauRag5WI zL9`=*6O8HvhOmiY*R@L?>6&Y|F~#t(R`3iiG8aueb(31>7?u;T`1+htJN#btbq_^pi39OilUH01>> zy55Y`*pFbzW&arE5R_GwI8E}T`>e0?q?BG~GJ3j#froluMliXZZ0@b#z1!|>5l&Ip zvqzb=X`*Bp{aKew%sX2{>%_8)rc&byt`f<|{TJH!wI$yZKJK$TDK>i;r~5KPlA3>k z3w;D1+8*i)JXOK{b@b!(81ykn|1^5oL7$@Zp`NXt8iO7@i4|f5(S@hnO44|_giEu_ zr3K2r5mliJ9e%s`bY7qt3EX5dI#@yCC4>{NqiH)CO}eWNxf{`;yBMxwWLvW5msK>y za&l|yeY=<9%$o;@KTgmmNa9JRYK0<2r0==ilQrU#$kq}?E=Rifzu^|?HKtt3l<{)lOUxelWK({e_J?ZTcA`yydzeGw$KYAAcz)} zixdh$N$}sYtaYL6lIb?SYQhw@y|JPX6Afz*_qk% z^Uv3B0MeM3(11i8ElCNDNJvN_9Y8PcarANA7m@)99D^JWIEEzzFd{+1BaX)$8HQTx zwN{KIe;L}dhM7;~O?joDCX|Af7&F$_Wql>9>FS(p7FBbIw1+iavql&uI^EU()v(zs zWqLzhiwwRoV?||X6pY!;^<~w3E-x2|6V4inTv(J%O`JSN?69Evlb9B3Yqf11ij80rmu!IDiYw_$09&N0T&vJL%gy zIwC-_qO8rx8}_H*c*3xDE>++jYs#(^&)cL}QesInM5?*RAT1c1rlO8(qI_B^bb3Ut ze}V|(LJ%P|aXbxT91|RqK}_KpLz`P_7zSM(d7-cA#+H6WJ+vMt3gRlR3CCurkX;Q- z9|PZVoS?hP0&@z8TC4mh+?o|jj-l^NJyuOjj>XKDY^sN2I!=&2ebZ3wyI0YPMc^n= zoym%#7K@RABvol|6^+s5wCSd$6%y1{f1<+RSzJ~493tEyt{-7RNv%+cIB z6xzF^X3aUYWBJgjwt1(kntRov{W`a`fbu_lFnY*gVES0c%rfR4!j@e>_IcF4MN5yP{Sq>U{h!zUJJ=cAD3_if3PW< zOvGcjPSzaM_wd6y!Qhv(JbD0}Z6d z$KU}3005f{002CbAf+Uejour7#a8Q5+eQ@r))uTIi^RB?gtnv(H359V+>&6MBn6sV zad28Ev?jgDLU9#rIU~zWUZIcBw@7E&At}?O|2osR=-<9WJ3T8oU}A$zCNuq`-97v1 zoNqs!Jvx8>`|Aq;b9f+Q2#Y7^k&zL>B1cY!ge4hSTn^$2u5x@N7RwxeD+2bh3>nur zt_N^~W6owHmsWBlMDC8uk^28sva*DPdS|*2=ndS1nh`63*8( zwYs5NhFG_ZlAy~FS#Fvgb+G-=qSCb zp(8~Qj-Y^2gisZO(g~3&Maoj73J1Z^q)9K*5fH%=N+KeS5Q?s2zee_hA?({;06fkFE zOviFf>)qNmI9=U}bRy7Na9+LbOt5o83 zPBoU@ziZ`(0^NjBNf)F%!?<4Hd-V`DcAakr9PbI=7Qj_0i|*s>r^3ia(Sah_oKIK> znQOFX2hK=^S??TwWO`t;$%oQ{hqWf&FzHA`q&bPq2Y*7EPUt`^0+jSs60NfO;FnS9 zj)wOfOW*kq6hFl-aFR-DTmex3^7AtEJ3VM#yqJlukx3zUS@|t{~h1)*b#ye>wlA;qQw#$z%_gz$ukQ+XvE|LNt&mkIA zQ;Pv+h7XF&bd(uw54e!7kDayK4df;W9KLk}XM7l#aCBVUhUUig!JHd77vlXpbgB?l zIAXJ>R?Ck;RmtC7mAQ*_$@lZFl@|?;H^a-5-ka09$Tp?1Iu2X%{`+^!4~zKu_2*yw z(jBM!h4xooY(=bZ-FiCSzDt#h8roHe&3Hd_yUpliRol#7 zAS5FMLFd=XRym~iW~EM6kv*|eR5vlr&eX@~mNN5oXtM|Ev=|+cg`}BSXf9w2N_AZ` zSdP@JXnKUynGt;H8~0*l=SOt0rc@%`)R@-XmsPML4ZVe3pB*6Qi_AX$+;T9c1Gyj4 z;P=5IyE{8MW*Ej7(_5(U<->qRgXbCH3D?2l%cJ+ja}jej_U(jylU^Ic=l64w=j95v zbQQbjIPr7N_g!N>2>EC~X`eF@e}46SrrcJo?`5Zi#D(%>`Up>^ZI~U}AgeZ0eGc|}$J zkUqY+<$Io#Oqnl1x}_ml%`m$oW9n^h`E{@H63ckS(6bH&`3 z@+GvNuOYPg-F*556nCIJ=&mO7kI^%Vg0J^jrx%2pPkeOP)O_;l{B<=+{|gN~eF5A? zI(Vsy;)h(F$wU{`mw{`iiw2(6&yxjIucHPzkUZ0GeIIL!+oGaNbbl#Yh)OR80?n|1;0J!B3|psn6Pf!>R++GI)x*Mv zhGXk4_@oQ!a*H~A>q|*Vrx)-^>>I^Nr*De4?O2-_Jqmdq-;{Z3>=m!AJQ=PqO{)GYurw&9HxsH{d=NrD?pV2KaUx&rA1jyGuet%MKJj&bACJKtSH@gL? zx@>p3B&(ph-pQ!JX6Omp6!zE)7u)MQu`co^-&3yCj=l0trP@l4W~kUVNCJaZp|f@7 zb(gx0hwkF}A{Q?zjK#IqaH1+Vx3$-vAaeOLl`Yyp6O62q6?)IKtuyBHR-5O_?1iiA zKt482>mKY=_e~Yv*FNoj`-5zs26Z5lnS39EwKWc{HTY2MIyWzAS_%#?ZTDV~@uK=TWCAwO zO5t9KeSUYReglVutdPz$&;lhnE~9*c>mYTj$6zj>&pm6aZW(Xh6!&!AK?kv{7}f5G zF87Q`;708b?d5>zf!yR%$&2D&pWBrrcnVtDk@I7(f_GbJw_V^2_ z{hsv);Z-YPKgj&o(~N!9-ytn~Jl2NESC}47{hH9kd+t#PDdY@6~^V_ej~8 z7saZK7hSpvoRfDU2)F-=#bA={M(#m{I0zb&WY>#zUzor0To3e&K^ccU+a_v$9MwO2 zg*0R4W6EclP=Du6mvGNGL&_EW^5vhqJU>_I5bimjH0n>(h>Zqek2Mxf5;#(@tA-(t z=8Gp_(=hdd+da7f=O^E>kFYwz!{wA(atMEN+(_(x)S^Oss~OX#G`}~+b>XyL+VHE{ z)H3h*`m_4Ppm%wPQ22;uBk0HG&n(k_ZDhz&s^Y<-)uzT^KkU2BA>)buZ1ocdG3Uth z+o-S@Y=X?=r@hNyvlJxIDnHR5dsjQ~>4Wl%VM4bTZTH~&5xiAp&)X6NIB#Du$cbh= zNFi3HIxdv4oS0jR8~v-+7@2wlbI#kmsLTyP-s?#1T*<8+D;X6pNP2Mo7YhvW9b!Bf z)n%{vbBA7hNu)Uv9s*BkSvkO0ItvjUvNNpHl1q3*-Wtx6X!jUL)Fbq{d1y-ikp zk>Y{X*p->aMtyE*@9lve|2Nna4UHUl_q94D*3?PBn}HG;LlE?P14B}StN=7LW|YCY zG9`q@KgUCy1tS%bCrI)ijjHhvLPPTq*A5m@DoP=o1lr(W55W*_m~$R3?y!0N!|jtQZM!ZW#%c z`iG~a4{^$9&<7&}vXi8Na5Shz(gLc`;Pu;l;64TcR#Lob-V{@ZBB7x8TLkdoIw(?# z1RdU<1tR>ZGM^*_5-B-zH>qaR5)zc3MF8T#6jKbuMl*uLuc62zpFfVYfIWl?dc`2X z*;#3zDV%Du-Q@&z=b*?V^SLAC$|I>@@|*!c7ekd>b1KOH4e2;&XmpP7jd4`Sd)^S> zPNB-lc>{neog$?`^#We7n+yeg77zeDlj_nbf`Z6-D9Bs#|BqPmJ~h+4goDbfEg}Gk zT#8Etj9-)nL<%TU0W`z^U6huL0H8$_ml&u}`F84c zrDskYX>wsH1r!C@mQDiO&ET<7QP71V>ANXXp0c7G3c_Cef7_(`z_lfJV80*yHLgYN nvEpR}Ffj;rE}sKLhd|1%F5dI!=ox-rLy2 Date: Fri, 24 Jan 2020 17:35:23 +0100 Subject: [PATCH 08/24] Use test fixtures feature of Gradle 6 --- webauthn-server-attestation/build.gradle | 8 ++------ webauthn-server-core/build.gradle | 15 +++++++++++++-- .../yubico/scalacheck/gen/JacksonGenerators.scala | 0 .../scala/com/yubico/webauthn/Generators.scala | 0 .../yubico/webauthn/RegistrationTestData.scala | 0 .../com/yubico/webauthn/TestAuthenticator.scala | 0 .../com/yubico/webauthn/WebAuthnTestCodecs.scala | 0 .../yubico/webauthn/attestation/Generators.scala | 0 .../com/yubico/webauthn/data/Generators.scala | 0 .../webauthn/extension/appid/Generators.scala | 0 .../scala/com/yubico/webauthn/test/Helpers.scala | 0 .../com/yubico/webauthn/test/RealExamples.scala | 0 .../scala/com/yubico/webauthn/test/Test.scala | 0 .../scala/com/yubico/webauthn/test/Util.scala | 0 webauthn-server-demo/build.gradle | 2 +- yubico-util-scala/build.gradle | 3 --- 16 files changed, 16 insertions(+), 12 deletions(-) rename webauthn-server-core/src/{test => testFixtures}/scala/com/yubico/scalacheck/gen/JacksonGenerators.scala (100%) rename webauthn-server-core/src/{test => testFixtures}/scala/com/yubico/webauthn/Generators.scala (100%) rename webauthn-server-core/src/{test => testFixtures}/scala/com/yubico/webauthn/RegistrationTestData.scala (100%) rename webauthn-server-core/src/{test => testFixtures}/scala/com/yubico/webauthn/TestAuthenticator.scala (100%) rename webauthn-server-core/src/{test => testFixtures}/scala/com/yubico/webauthn/WebAuthnTestCodecs.scala (100%) rename webauthn-server-core/src/{test => testFixtures}/scala/com/yubico/webauthn/attestation/Generators.scala (100%) rename webauthn-server-core/src/{test => testFixtures}/scala/com/yubico/webauthn/data/Generators.scala (100%) rename webauthn-server-core/src/{test => testFixtures}/scala/com/yubico/webauthn/extension/appid/Generators.scala (100%) rename webauthn-server-core/src/{test => testFixtures}/scala/com/yubico/webauthn/test/Helpers.scala (100%) rename webauthn-server-core/src/{test => testFixtures}/scala/com/yubico/webauthn/test/RealExamples.scala (100%) rename webauthn-server-core/src/{test => testFixtures}/scala/com/yubico/webauthn/test/Test.scala (100%) rename webauthn-server-core/src/{test => testFixtures}/scala/com/yubico/webauthn/test/Util.scala (100%) diff --git a/webauthn-server-attestation/build.gradle b/webauthn-server-attestation/build.gradle index 7560b3b38..5ee952617 100644 --- a/webauthn-server-attestation/build.gradle +++ b/webauthn-server-attestation/build.gradle @@ -17,25 +17,21 @@ dependencies { implementation( project(':yubico-util'), - addVersion('com.google.guava:guava'), addVersion('com.fasterxml.jackson.core:jackson-databind'), + addVersion('com.google.guava:guava'), addVersion('org.bouncycastle:bcprov-jdk15on'), addVersion('org.slf4j:slf4j-api'), ) testImplementation( - project(':webauthn-server-core').sourceSets.test.output, project(':yubico-util-scala'), + testFixtures(project(':webauthn-server-core')), addVersion('junit:junit'), addVersion('org.mockito:mockito-core'), addVersion('org.scala-lang:scala-library'), addVersion('org.scalacheck:scalacheck_2.12'), addVersion('org.scalatest:scalatest_2.12'), ) - testRuntimeOnly( - // Transitive dependency from :webauthn-server-core:test - addVersion('org.bouncycastle:bcpkix-jdk15on'), - ) } diff --git a/webauthn-server-core/build.gradle b/webauthn-server-core/build.gradle index c72f63201..802ab4844 100644 --- a/webauthn-server-core/build.gradle +++ b/webauthn-server-core/build.gradle @@ -1,5 +1,6 @@ plugins { id 'java-library' + id 'java-test-fixtures' id 'scala' id 'info.solidsoft.pitest' } @@ -24,14 +25,24 @@ dependencies { addVersion('org.slf4j:slf4j-api'), ) + testFixturesApi( + addVersion('com.augustcellars.cose:cose-java'), + addVersion('org.scala-lang:scala-library'), + addVersion('org.scalacheck:scalacheck_2.12'), + ) + + testFixturesImplementation( + project(':yubico-util-scala'), + addVersion('com.upokecenter:cbor'), + addVersion('org.bouncycastle:bcpkix-jdk15on'), + ) + testImplementation( project(':yubico-util-scala'), addVersion('com.fasterxml.jackson.datatype:jackson-datatype-jdk8'), addVersion('junit:junit'), - addVersion('org.bouncycastle:bcpkix-jdk15on'), addVersion('org.mockito:mockito-core'), addVersion('org.scala-lang:scala-library'), - addVersion('org.scalacheck:scalacheck_2.12'), addVersion('org.scalatest:scalatest_2.12'), ) diff --git a/webauthn-server-core/src/test/scala/com/yubico/scalacheck/gen/JacksonGenerators.scala b/webauthn-server-core/src/testFixtures/scala/com/yubico/scalacheck/gen/JacksonGenerators.scala similarity index 100% rename from webauthn-server-core/src/test/scala/com/yubico/scalacheck/gen/JacksonGenerators.scala rename to webauthn-server-core/src/testFixtures/scala/com/yubico/scalacheck/gen/JacksonGenerators.scala diff --git a/webauthn-server-core/src/test/scala/com/yubico/webauthn/Generators.scala b/webauthn-server-core/src/testFixtures/scala/com/yubico/webauthn/Generators.scala similarity index 100% rename from webauthn-server-core/src/test/scala/com/yubico/webauthn/Generators.scala rename to webauthn-server-core/src/testFixtures/scala/com/yubico/webauthn/Generators.scala diff --git a/webauthn-server-core/src/test/scala/com/yubico/webauthn/RegistrationTestData.scala b/webauthn-server-core/src/testFixtures/scala/com/yubico/webauthn/RegistrationTestData.scala similarity index 100% rename from webauthn-server-core/src/test/scala/com/yubico/webauthn/RegistrationTestData.scala rename to webauthn-server-core/src/testFixtures/scala/com/yubico/webauthn/RegistrationTestData.scala diff --git a/webauthn-server-core/src/test/scala/com/yubico/webauthn/TestAuthenticator.scala b/webauthn-server-core/src/testFixtures/scala/com/yubico/webauthn/TestAuthenticator.scala similarity index 100% rename from webauthn-server-core/src/test/scala/com/yubico/webauthn/TestAuthenticator.scala rename to webauthn-server-core/src/testFixtures/scala/com/yubico/webauthn/TestAuthenticator.scala diff --git a/webauthn-server-core/src/test/scala/com/yubico/webauthn/WebAuthnTestCodecs.scala b/webauthn-server-core/src/testFixtures/scala/com/yubico/webauthn/WebAuthnTestCodecs.scala similarity index 100% rename from webauthn-server-core/src/test/scala/com/yubico/webauthn/WebAuthnTestCodecs.scala rename to webauthn-server-core/src/testFixtures/scala/com/yubico/webauthn/WebAuthnTestCodecs.scala diff --git a/webauthn-server-core/src/test/scala/com/yubico/webauthn/attestation/Generators.scala b/webauthn-server-core/src/testFixtures/scala/com/yubico/webauthn/attestation/Generators.scala similarity index 100% rename from webauthn-server-core/src/test/scala/com/yubico/webauthn/attestation/Generators.scala rename to webauthn-server-core/src/testFixtures/scala/com/yubico/webauthn/attestation/Generators.scala diff --git a/webauthn-server-core/src/test/scala/com/yubico/webauthn/data/Generators.scala b/webauthn-server-core/src/testFixtures/scala/com/yubico/webauthn/data/Generators.scala similarity index 100% rename from webauthn-server-core/src/test/scala/com/yubico/webauthn/data/Generators.scala rename to webauthn-server-core/src/testFixtures/scala/com/yubico/webauthn/data/Generators.scala diff --git a/webauthn-server-core/src/test/scala/com/yubico/webauthn/extension/appid/Generators.scala b/webauthn-server-core/src/testFixtures/scala/com/yubico/webauthn/extension/appid/Generators.scala similarity index 100% rename from webauthn-server-core/src/test/scala/com/yubico/webauthn/extension/appid/Generators.scala rename to webauthn-server-core/src/testFixtures/scala/com/yubico/webauthn/extension/appid/Generators.scala diff --git a/webauthn-server-core/src/test/scala/com/yubico/webauthn/test/Helpers.scala b/webauthn-server-core/src/testFixtures/scala/com/yubico/webauthn/test/Helpers.scala similarity index 100% rename from webauthn-server-core/src/test/scala/com/yubico/webauthn/test/Helpers.scala rename to webauthn-server-core/src/testFixtures/scala/com/yubico/webauthn/test/Helpers.scala diff --git a/webauthn-server-core/src/test/scala/com/yubico/webauthn/test/RealExamples.scala b/webauthn-server-core/src/testFixtures/scala/com/yubico/webauthn/test/RealExamples.scala similarity index 100% rename from webauthn-server-core/src/test/scala/com/yubico/webauthn/test/RealExamples.scala rename to webauthn-server-core/src/testFixtures/scala/com/yubico/webauthn/test/RealExamples.scala diff --git a/webauthn-server-core/src/test/scala/com/yubico/webauthn/test/Test.scala b/webauthn-server-core/src/testFixtures/scala/com/yubico/webauthn/test/Test.scala similarity index 100% rename from webauthn-server-core/src/test/scala/com/yubico/webauthn/test/Test.scala rename to webauthn-server-core/src/testFixtures/scala/com/yubico/webauthn/test/Test.scala diff --git a/webauthn-server-core/src/test/scala/com/yubico/webauthn/test/Util.scala b/webauthn-server-core/src/testFixtures/scala/com/yubico/webauthn/test/Util.scala similarity index 100% rename from webauthn-server-core/src/test/scala/com/yubico/webauthn/test/Util.scala rename to webauthn-server-core/src/testFixtures/scala/com/yubico/webauthn/test/Util.scala diff --git a/webauthn-server-demo/build.gradle b/webauthn-server-demo/build.gradle index 56e3184e0..8e1576739 100644 --- a/webauthn-server-demo/build.gradle +++ b/webauthn-server-demo/build.gradle @@ -48,8 +48,8 @@ dependencies { ) testImplementation( - project(':webauthn-server-core').sourceSets.test.output, project(':yubico-util-scala'), + testFixtures(project(':webauthn-server-core')), addVersion('junit:junit'), addVersion('org.mockito:mockito-core'), diff --git a/yubico-util-scala/build.gradle b/yubico-util-scala/build.gradle index e3e1ed1ec..05c2d3a83 100644 --- a/yubico-util-scala/build.gradle +++ b/yubico-util-scala/build.gradle @@ -11,8 +11,5 @@ dependencies { addVersion('org.scalacheck:scalacheck_2.12'), ) - testImplementation( - addVersion('org.scalatest:scalatest_2.12'), - ) } From a9088e15d76fc6c961897734d888873fedb8aa8f Mon Sep 17 00:00:00 2001 From: Emil Lundberg Date: Fri, 24 Jan 2020 21:07:35 +0100 Subject: [PATCH 09/24] Run test coverage on GitHub Actions instead of Travis (JDK 11) --- .github/workflows/coverage.yml | 29 +++++++++++++++++++++++++++++ .travis.yml | 26 -------------------------- build.gradle | 4 ---- 3 files changed, 29 insertions(+), 30 deletions(-) create mode 100644 .github/workflows/coverage.yml delete mode 100644 .travis.yml diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml new file mode 100644 index 000000000..450b2e4ed --- /dev/null +++ b/.github/workflows/coverage.yml @@ -0,0 +1,29 @@ +# This name is shown in the status badge in the README +name: Test coverage + +on: + push: + branches: [master] + +jobs: + test: + name: JDK ${{matrix.java}} + + runs-on: ubuntu-latest + + steps: + - name: Check out code + uses: actions/checkout@v1 + + - name: Set up JDK 11 + uses: actions/setup-java@v1 + with: + java-version: 11 + + - name: Run mutation test + run: ./gradlew pitest + + - name: Report to Coveralls + env: + COVERALLS_REPO_TOKEN: ${{ secrets.COVERALLS_REPO_TOKEN }} + run: ./gradlew coveralls diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 5e6de831f..000000000 --- a/.travis.yml +++ /dev/null @@ -1,26 +0,0 @@ -language: java - -branches: - except: - - /^tmp-?.*/ - -jdk: - - oraclejdk11 - - openjdk8 - - openjdk11 - -script: - - ./gradlew check assembleJavadoc - -stages: - - test - - mutation-test - -jobs: - include: - - stage: mutation-test - jdk: oraclejdk11 - script: ./gradlew pitest coveralls - - # Workaround to TLS issues in JDK 11, see https://github.com/kt3k/coveralls-gradle-plugin/issues/85 - after_success: curl -F 'json_file=@build/coveralls/report.json' 'https://coveralls.io/api/v1/jobs' diff --git a/build.gradle b/build.gradle index 39eacab6b..ad00d3f30 100644 --- a/build.gradle +++ b/build.gradle @@ -244,10 +244,6 @@ task pitestMerge(type: com.yubico.gradle.pitest.tasks.PitestMergeTask) coveralls { sourceDirs = subprojects.sourceSets.main.allSource.srcDirs.flatten() - - // Workaround to TLS issues in JDK 11, see https://github.com/kt3k/coveralls-gradle-plugin/issues/85 - saveAsFile = true - sendToCoveralls = false } tasks.coveralls { inputs.files pitestMerge.outputs.files From c4f70ae79b143f2c72f6a63c1d0e5f8868097c6a Mon Sep 17 00:00:00 2001 From: Emil Lundberg Date: Fri, 24 Jan 2020 21:12:46 +0100 Subject: [PATCH 10/24] Upgrade pitest and pitest plugin --- buildSrc/build.gradle | 2 +- webauthn-server-core/build.gradle | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/buildSrc/build.gradle b/buildSrc/build.gradle index 812ff1aba..f5f2842a1 100644 --- a/buildSrc/build.gradle +++ b/buildSrc/build.gradle @@ -7,6 +7,6 @@ repositories { dependencies { implementation( 'commons-io:commons-io:2.5', - 'info.solidsoft.gradle.pitest:gradle-pitest-plugin:1.4.0', + 'info.solidsoft.gradle.pitest:gradle-pitest-plugin:1.4.6', ) } diff --git a/webauthn-server-core/build.gradle b/webauthn-server-core/build.gradle index c72f63201..e1a468b7b 100644 --- a/webauthn-server-core/build.gradle +++ b/webauthn-server-core/build.gradle @@ -61,7 +61,7 @@ jar { } pitest { - pitestVersion = '1.4.9' + pitestVersion = '1.4.11' timestampedReports = false outputFormats = ['XML', 'HTML'] From 6e5efacd3d66778fa01ee882b9318be81b5677d4 Mon Sep 17 00:00:00 2001 From: Misagh Moayyed Date: Sat, 25 Jan 2020 13:51:03 +0400 Subject: [PATCH 11/24] Update .gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index b5ae30103..903685d5b 100644 --- a/.gitignore +++ b/.gitignore @@ -9,6 +9,7 @@ out/ *.iml *.iws */out/ +*/bin/ .attach_pid* # Mac From 0002aa0fa4121ac89af43b88b42c039813c35627 Mon Sep 17 00:00:00 2001 From: Emil Lundberg Date: Tue, 28 Jan 2020 12:40:22 +0100 Subject: [PATCH 12/24] Rearrange IntelliJ ignore patterns --- .gitignore | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index 903685d5b..896796d4c 100644 --- a/.gitignore +++ b/.gitignore @@ -3,13 +3,12 @@ .project .settings/ -# Intellij +# IntelliJ .idea/ +bin/ out/ *.iml *.iws -*/out/ -*/bin/ .attach_pid* # Mac From ed2db421927ce930357ae2ed723a7e0b914cfea1 Mon Sep 17 00:00:00 2001 From: Misagh Moayyed Date: Mon, 3 Feb 2020 09:58:11 +0400 Subject: [PATCH 13/24] Update readme to reflect latest version --- README | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README b/README index f781da809..43946201e 100644 --- a/README +++ b/README @@ -26,7 +26,7 @@ Maven: com.yubico webauthn-server-core - 1.5.0 + 1.6.0 compile ---------- @@ -34,7 +34,7 @@ Maven: Gradle: ---------- -compile 'com.yubico:webauthn-server-core:1.5.0' +compile 'com.yubico:webauthn-server-core:1.6.0' ---------- From cb4060e8ab1e5ba354b79fb0cee15580573247f8 Mon Sep 17 00:00:00 2001 From: Emil Lundberg Date: Thu, 6 Feb 2020 16:35:47 +0100 Subject: [PATCH 14/24] Remove empty test class --- .../com/yubico/webauthn/data/AuthenticatorTransportTest.java | 4 ---- 1 file changed, 4 deletions(-) delete mode 100644 webauthn-server-core/src/main/java/com/yubico/webauthn/data/AuthenticatorTransportTest.java diff --git a/webauthn-server-core/src/main/java/com/yubico/webauthn/data/AuthenticatorTransportTest.java b/webauthn-server-core/src/main/java/com/yubico/webauthn/data/AuthenticatorTransportTest.java deleted file mode 100644 index 754a6be46..000000000 --- a/webauthn-server-core/src/main/java/com/yubico/webauthn/data/AuthenticatorTransportTest.java +++ /dev/null @@ -1,4 +0,0 @@ -package com.yubico.webauthn.data; - -public class AuthenticatorTransportTest { -} From 185f445e95b07a1369675b4c10c7d09647241c88 Mon Sep 17 00:00:00 2001 From: Emil Lundberg Date: Thu, 6 Feb 2020 16:51:06 +0100 Subject: [PATCH 15/24] Work around Gradle incompatibility with gradle-pitest --- webauthn-server-core/build.gradle | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/webauthn-server-core/build.gradle b/webauthn-server-core/build.gradle index 802ab4844..57284f332 100644 --- a/webauthn-server-core/build.gradle +++ b/webauthn-server-core/build.gradle @@ -74,6 +74,10 @@ jar { pitest { pitestVersion = '1.4.9' + // Workaround to an incompatibility issue between Gradle and gradle-pitest + // See https://github.com/szpak/gradle-pitest-plugin/issues/173 + testSourceSets.add(sourceSets.main) + timestampedReports = false outputFormats = ['XML', 'HTML'] @@ -86,3 +90,6 @@ pitest { ] } +// Workaround to an incompatibility issue between Gradle and gradle-pitest +// See https://github.com/szpak/gradle-pitest-plugin/issues/173 +task mainClasses {} From ca4137c3d2c94916d48258076cfb970d049e3478 Mon Sep 17 00:00:00 2001 From: Emil Lundberg Date: Fri, 24 Jan 2020 19:16:25 +0100 Subject: [PATCH 16/24] Convert subproject yubico-util-scala to test fixtures of yubico-util --- settings.gradle | 1 - webauthn-server-attestation/build.gradle | 2 +- webauthn-server-core/build.gradle | 4 ++-- webauthn-server-demo/build.gradle | 2 +- yubico-util-scala/build.gradle | 15 --------------- yubico-util/build.gradle | 7 ++++++- .../internal/util/scala/JavaConverters.scala | 0 .../yubico/scalacheck/gen/JavaGenerators.scala | 0 8 files changed, 10 insertions(+), 21 deletions(-) delete mode 100644 yubico-util-scala/build.gradle rename {yubico-util-scala/src/main => yubico-util/src/testFixtures}/scala/com/yubico/internal/util/scala/JavaConverters.scala (100%) rename {yubico-util-scala/src/main => yubico-util/src/testFixtures}/scala/com/yubico/scalacheck/gen/JavaGenerators.scala (100%) diff --git a/settings.gradle b/settings.gradle index 14392fbb1..e3581443b 100644 --- a/settings.gradle +++ b/settings.gradle @@ -3,7 +3,6 @@ include ':webauthn-server-attestation' include ':webauthn-server-core' include ':webauthn-server-demo' include ':yubico-util' -include ':yubico-util-scala' include ':test-dependent-projects:java-dep-webauthn-server-attestation' include ':test-dependent-projects:java-dep-webauthn-server-core' diff --git a/webauthn-server-attestation/build.gradle b/webauthn-server-attestation/build.gradle index 5ee952617..abdac02c7 100644 --- a/webauthn-server-attestation/build.gradle +++ b/webauthn-server-attestation/build.gradle @@ -24,7 +24,7 @@ dependencies { ) testImplementation( - project(':yubico-util-scala'), + testFixtures(project(':yubico-util')), testFixtures(project(':webauthn-server-core')), addVersion('junit:junit'), addVersion('org.mockito:mockito-core'), diff --git a/webauthn-server-core/build.gradle b/webauthn-server-core/build.gradle index 57284f332..a6a8e3693 100644 --- a/webauthn-server-core/build.gradle +++ b/webauthn-server-core/build.gradle @@ -32,13 +32,13 @@ dependencies { ) testFixturesImplementation( - project(':yubico-util-scala'), + testFixtures(project(':yubico-util')), addVersion('com.upokecenter:cbor'), addVersion('org.bouncycastle:bcpkix-jdk15on'), ) testImplementation( - project(':yubico-util-scala'), + testFixtures(project(':yubico-util')), addVersion('com.fasterxml.jackson.datatype:jackson-datatype-jdk8'), addVersion('junit:junit'), addVersion('org.mockito:mockito-core'), diff --git a/webauthn-server-demo/build.gradle b/webauthn-server-demo/build.gradle index 8e1576739..d6d34f1f7 100644 --- a/webauthn-server-demo/build.gradle +++ b/webauthn-server-demo/build.gradle @@ -48,7 +48,7 @@ dependencies { ) testImplementation( - project(':yubico-util-scala'), + testFixtures(project(':yubico-util')), testFixtures(project(':webauthn-server-core')), addVersion('junit:junit'), diff --git a/yubico-util-scala/build.gradle b/yubico-util-scala/build.gradle deleted file mode 100644 index 05c2d3a83..000000000 --- a/yubico-util-scala/build.gradle +++ /dev/null @@ -1,15 +0,0 @@ -plugins { - id 'scala' -} - -description = 'Yubico internal Scala utilities' - -dependencies { - - implementation( - addVersion('org.scala-lang:scala-library'), - addVersion('org.scalacheck:scalacheck_2.12'), - ) - -} - diff --git a/yubico-util/build.gradle b/yubico-util/build.gradle index 78bcb8cad..237a3de8c 100644 --- a/yubico-util/build.gradle +++ b/yubico-util/build.gradle @@ -1,5 +1,6 @@ plugins { id 'java-library' + id 'java-test-fixtures' id 'scala' } @@ -21,8 +22,12 @@ dependencies { addVersion('org.slf4j:slf4j-api'), ) + testFixturesApi( + addVersion('org.scala-lang:scala-library'), + addVersion('org.scalacheck:scalacheck_2.12'), + ) + testImplementation( - project(':yubico-util-scala'), addVersion('junit:junit'), addVersion('org.scala-lang:scala-library'), addVersion('org.scalacheck:scalacheck_2.12'), diff --git a/yubico-util-scala/src/main/scala/com/yubico/internal/util/scala/JavaConverters.scala b/yubico-util/src/testFixtures/scala/com/yubico/internal/util/scala/JavaConverters.scala similarity index 100% rename from yubico-util-scala/src/main/scala/com/yubico/internal/util/scala/JavaConverters.scala rename to yubico-util/src/testFixtures/scala/com/yubico/internal/util/scala/JavaConverters.scala diff --git a/yubico-util-scala/src/main/scala/com/yubico/scalacheck/gen/JavaGenerators.scala b/yubico-util/src/testFixtures/scala/com/yubico/scalacheck/gen/JavaGenerators.scala similarity index 100% rename from yubico-util-scala/src/main/scala/com/yubico/scalacheck/gen/JavaGenerators.scala rename to yubico-util/src/testFixtures/scala/com/yubico/scalacheck/gen/JavaGenerators.scala From 01b33b6a56e4e3f3bfb1ec7af9264dad8298c119 Mon Sep 17 00:00:00 2001 From: Emil Lundberg Date: Fri, 24 Jan 2020 19:35:54 +0100 Subject: [PATCH 17/24] Exclude test fixtures from publications --- build.gradle | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/build.gradle b/build.gradle index a22cdaadf..046726d6c 100644 --- a/build.gradle +++ b/build.gradle @@ -187,9 +187,7 @@ subprojects { project -> publishing { publications { jars(MavenPublication) { - from components.java - artifact javadocJar - artifact sourcesJar + setArtifacts([jar, javadocJar, sourcesJar]) pom { name = project.name From d57d4a0c03083c80ccace87bb9b35bfdb5f34630 Mon Sep 17 00:00:00 2001 From: Emil Lundberg Date: Fri, 24 Jan 2020 20:32:15 +0100 Subject: [PATCH 18/24] Use new withJavadocJar() and withSourcesJar() API --- build.gradle | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/build.gradle b/build.gradle index 046726d6c..2997b751f 100644 --- a/build.gradle +++ b/build.gradle @@ -138,9 +138,9 @@ subprojects { project -> } if (project.hasProperty('publishMe') && project.publishMe) { - task sourcesJar(type: Jar) { - archiveClassifier = 'sources' - from sourceSets.main.allSource + java { + withJavadocJar() + withSourcesJar() } task delombok(type: DelombokTask, dependsOn: classes) { @@ -165,11 +165,6 @@ subprojects { project -> options.addStringOption('charset', 'UTF-8') } - task javadocJar(type: Jar) { - archiveClassifier = 'javadoc' - from javadoc - } - rootProject.tasks.assembleJavadoc { dependsOn javadoc inputs.dir javadoc.destinationDir From b94ca47c52a04099197601be81a3319dda82ca99 Mon Sep 17 00:00:00 2001 From: Emil Lundberg Date: Fri, 24 Jan 2020 17:46:44 +0100 Subject: [PATCH 19/24] Bump Scala dependencies to Scala 2.13 --- build.gradle | 6 +++--- webauthn-server-attestation/build.gradle | 4 ++-- .../DeviceIdentificationSpec.scala | 8 +++---- .../StandardMetadataServiceSpec.scala | 9 ++++---- webauthn-server-core/build.gradle | 4 ++-- .../yubico/webauthn/OriginMatcherSpec.scala | 8 +++---- ...ckedAttestationStatementVerifierSpec.scala | 2 +- .../webauthn/RelyingPartyAssertionSpec.scala | 8 +++---- .../webauthn/RelyingPartyCeremoniesSpec.scala | 6 +++--- .../RelyingPartyRegistrationSpec.scala | 10 ++++----- .../RelyingPartyStartOperationSpec.scala | 21 +++++++++---------- .../RelyingPartyUserIdentificationSpec.scala | 15 +++++++------ .../yubico/webauthn/WebAuthnCodecsSpec.scala | 8 +++---- ...AuthenticatorAttestationResponseSpec.scala | 2 +- .../data/AuthenticatorDataFlagsSpec.scala | 2 +- .../webauthn/data/AuthenticatorDataSpec.scala | 2 +- .../data/AuthenticatorTransportSpec.scala | 5 +++-- .../yubico/webauthn/data/BuildersSpec.scala | 6 +++--- .../data/CollectedClientDataSpec.scala | 2 +- .../com/yubico/webauthn/data/JsonIoSpec.scala | 6 +++--- .../PublicKeyCredentialDescriptorSpec.scala | 8 +++---- .../scalacheck/gen/JacksonGenerators.scala | 2 +- .../webauthn/RegistrationTestData.scala | 4 ++-- .../yubico/webauthn/TestAuthenticator.scala | 2 +- .../com/yubico/webauthn/data/Generators.scala | 6 +++--- .../com/yubico/webauthn/test/Helpers.scala | 2 +- .../scala/com/yubico/webauthn/test/Test.scala | 2 +- webauthn-server-demo/build.gradle | 4 ++-- .../demo/webauthn/JsonSerializationSpec.scala | 2 +- .../demo/webauthn/WebAuthnServerSpec.scala | 4 ++-- yubico-util/build.gradle | 6 +++--- .../yubico/internal/util/BinaryUtilSpec.scala | 8 +++---- .../internal/util/CollectionUtilSpec.scala | 6 +++--- .../internal/util/ComparableUtilSpec.scala | 10 ++++----- .../scalacheck/gen/JavaGenerators.scala | 2 +- 35 files changed, 100 insertions(+), 102 deletions(-) diff --git a/build.gradle b/build.gradle index 2997b751f..126be4daa 100644 --- a/build.gradle +++ b/build.gradle @@ -69,9 +69,9 @@ Map dependencyVersions = [ 'org.glassfish.jersey.containers:jersey-container-servlet:2.26', 'org.glassfish.jersey.inject:jersey-hk2:2.26', 'org.mockito:mockito-core:2.27.0', - 'org.scala-lang:scala-library:2.12.8', - 'org.scalacheck:scalacheck_2.12:1.14.0', - 'org.scalatest:scalatest_2.12:3.0.4', + 'org.scala-lang:scala-library:2.13.1', + 'org.scalacheck:scalacheck_2.13:1.14.0', + 'org.scalatest:scalatest_2.13:3.0.8', 'org.slf4j:slf4j-api:1.7.25', ].collectEntries { [(it.split(':')[0..1].join(':')): it] } rootProject.ext.addVersion = { dep -> dependencyVersions[dep] } diff --git a/webauthn-server-attestation/build.gradle b/webauthn-server-attestation/build.gradle index abdac02c7..845fd0c49 100644 --- a/webauthn-server-attestation/build.gradle +++ b/webauthn-server-attestation/build.gradle @@ -29,8 +29,8 @@ dependencies { addVersion('junit:junit'), addVersion('org.mockito:mockito-core'), addVersion('org.scala-lang:scala-library'), - addVersion('org.scalacheck:scalacheck_2.12'), - addVersion('org.scalatest:scalatest_2.12'), + addVersion('org.scalacheck:scalacheck_2.13'), + addVersion('org.scalatest:scalatest_2.13'), ) } diff --git a/webauthn-server-attestation/src/test/scala/com/yubico/webauthn/attestation/DeviceIdentificationSpec.scala b/webauthn-server-attestation/src/test/scala/com/yubico/webauthn/attestation/DeviceIdentificationSpec.scala index 77f1a2971..19a96fb00 100644 --- a/webauthn-server-attestation/src/test/scala/com/yubico/webauthn/attestation/DeviceIdentificationSpec.scala +++ b/webauthn-server-attestation/src/test/scala/com/yubico/webauthn/attestation/DeviceIdentificationSpec.scala @@ -42,9 +42,9 @@ import com.yubico.webauthn.test.Helpers import org.junit.runner.RunWith import org.scalatest.FunSpec import org.scalatest.Matchers -import org.scalatest.junit.JUnitRunner +import org.scalatestplus.junit.JUnitRunner -import scala.collection.JavaConverters._ +import scala.jdk.CollectionConverters._ @RunWith(classOf[JUnitRunner]) @@ -60,7 +60,7 @@ class DeviceIdentificationSpec extends FunSpec with Matchers { describe("A RelyingParty with the default StandardMetadataService") { describe("correctly identifies") { - def check(expectedName: String, testData: RealExamples.Example, transports: Set[Transport]) { + def check(expectedName: String, testData: RealExamples.Example, transports: Set[Transport]): Unit = { val rp = RelyingParty.builder() .identity(testData.rp) .credentialRepository(Helpers.CredentialRepository.empty) @@ -114,7 +114,7 @@ class DeviceIdentificationSpec extends FunSpec with Matchers { describe("The default AttestationResolver") { describe("successfully identifies") { - def check(expectedName: String, testData: RealExamples.Example, transports: Set[Transport]) { + def check(expectedName: String, testData: RealExamples.Example, transports: Set[Transport]): Unit = { val cert = CertificateParser.parseDer(testData.attestationCert.getBytes) val resolved = StandardMetadataService.createDefaultAttestationResolver().resolve(cert) resolved.isPresent should be (true) diff --git a/webauthn-server-attestation/src/test/scala/com/yubico/webauthn/attestation/StandardMetadataServiceSpec.scala b/webauthn-server-attestation/src/test/scala/com/yubico/webauthn/attestation/StandardMetadataServiceSpec.scala index 5f9abd8fd..c1d362627 100644 --- a/webauthn-server-attestation/src/test/scala/com/yubico/webauthn/attestation/StandardMetadataServiceSpec.scala +++ b/webauthn-server-attestation/src/test/scala/com/yubico/webauthn/attestation/StandardMetadataServiceSpec.scala @@ -34,16 +34,15 @@ import com.yubico.internal.util.JacksonCodecs import com.yubico.webauthn.TestAuthenticator import com.yubico.webauthn.attestation.resolver.SimpleAttestationResolver import com.yubico.webauthn.attestation.resolver.SimpleTrustResolver -import com.yubico.webauthn.WebAuthnCodecs -import org.bouncycastle.asn1.DEROctetString import org.bouncycastle.asn1.DERBitString +import org.bouncycastle.asn1.DEROctetString import org.bouncycastle.asn1.x500.X500Name import org.junit.runner.RunWith -import org.scalatest.Matchers import org.scalatest.FunSpec -import org.scalatest.junit.JUnitRunner +import org.scalatest.Matchers +import org.scalatestplus.junit.JUnitRunner -import scala.collection.JavaConverters._ +import scala.jdk.CollectionConverters._ @RunWith(classOf[JUnitRunner]) diff --git a/webauthn-server-core/build.gradle b/webauthn-server-core/build.gradle index a6a8e3693..9e11cff3b 100644 --- a/webauthn-server-core/build.gradle +++ b/webauthn-server-core/build.gradle @@ -28,7 +28,7 @@ dependencies { testFixturesApi( addVersion('com.augustcellars.cose:cose-java'), addVersion('org.scala-lang:scala-library'), - addVersion('org.scalacheck:scalacheck_2.12'), + addVersion('org.scalacheck:scalacheck_2.13'), ) testFixturesImplementation( @@ -43,7 +43,7 @@ dependencies { addVersion('junit:junit'), addVersion('org.mockito:mockito-core'), addVersion('org.scala-lang:scala-library'), - addVersion('org.scalatest:scalatest_2.12'), + addVersion('org.scalatest:scalatest_2.13'), ) } diff --git a/webauthn-server-core/src/test/scala/com/yubico/webauthn/OriginMatcherSpec.scala b/webauthn-server-core/src/test/scala/com/yubico/webauthn/OriginMatcherSpec.scala index 14aac7245..2e5dccd47 100644 --- a/webauthn-server-core/src/test/scala/com/yubico/webauthn/OriginMatcherSpec.scala +++ b/webauthn-server-core/src/test/scala/com/yubico/webauthn/OriginMatcherSpec.scala @@ -32,13 +32,13 @@ import org.scalacheck.Arbitrary.arbitrary import org.scalacheck.Gen import org.scalatest.FunSpec import org.scalatest.Matchers -import org.scalatest.junit.JUnitRunner -import org.scalatest.prop.GeneratorDrivenPropertyChecks +import org.scalatestplus.junit.JUnitRunner +import org.scalatestplus.scalacheck.ScalaCheckDrivenPropertyChecks -import scala.collection.JavaConverters._ +import scala.jdk.CollectionConverters._ @RunWith(classOf[JUnitRunner]) -class OriginMatcherSpec extends FunSpec with Matchers with GeneratorDrivenPropertyChecks { +class OriginMatcherSpec extends FunSpec with Matchers with ScalaCheckDrivenPropertyChecks { private def urlWithMaybePort(protocol: String, host: String, port: Option[Int], file: String): URL = port diff --git a/webauthn-server-core/src/test/scala/com/yubico/webauthn/PackedAttestationStatementVerifierSpec.scala b/webauthn-server-core/src/test/scala/com/yubico/webauthn/PackedAttestationStatementVerifierSpec.scala index 7c0fa2316..89f8a102b 100644 --- a/webauthn-server-core/src/test/scala/com/yubico/webauthn/PackedAttestationStatementVerifierSpec.scala +++ b/webauthn-server-core/src/test/scala/com/yubico/webauthn/PackedAttestationStatementVerifierSpec.scala @@ -32,7 +32,7 @@ import com.yubico.webauthn.TestAuthenticator.AttestationMaker import org.junit.runner.RunWith import org.scalatest.FunSpec import org.scalatest.Matchers -import org.scalatest.junit.JUnitRunner +import org.scalatestplus.junit.JUnitRunner import scala.util.Success import scala.util.Try diff --git a/webauthn-server-core/src/test/scala/com/yubico/webauthn/RelyingPartyAssertionSpec.scala b/webauthn-server-core/src/test/scala/com/yubico/webauthn/RelyingPartyAssertionSpec.scala index 882c1b2e0..0d9b4f25b 100644 --- a/webauthn-server-core/src/test/scala/com/yubico/webauthn/RelyingPartyAssertionSpec.scala +++ b/webauthn-server-core/src/test/scala/com/yubico/webauthn/RelyingPartyAssertionSpec.scala @@ -57,16 +57,16 @@ import org.junit.runner.RunWith import org.scalacheck.Gen import org.scalatest.FunSpec import org.scalatest.Matchers -import org.scalatest.junit.JUnitRunner -import org.scalatest.prop.GeneratorDrivenPropertyChecks +import org.scalatestplus.junit.JUnitRunner +import org.scalatestplus.scalacheck.ScalaCheckDrivenPropertyChecks -import scala.collection.JavaConverters._ +import scala.jdk.CollectionConverters._ import scala.util.Failure import scala.util.Success import scala.util.Try @RunWith(classOf[JUnitRunner]) -class RelyingPartyAssertionSpec extends FunSpec with Matchers with GeneratorDrivenPropertyChecks { +class RelyingPartyAssertionSpec extends FunSpec with Matchers with ScalaCheckDrivenPropertyChecks { private def jsonFactory: JsonNodeFactory = JsonNodeFactory.instance private val crypto = new BouncyCastleCrypto() diff --git a/webauthn-server-core/src/test/scala/com/yubico/webauthn/RelyingPartyCeremoniesSpec.scala b/webauthn-server-core/src/test/scala/com/yubico/webauthn/RelyingPartyCeremoniesSpec.scala index f0fb3b734..7834cb69d 100644 --- a/webauthn-server-core/src/test/scala/com/yubico/webauthn/RelyingPartyCeremoniesSpec.scala +++ b/webauthn-server-core/src/test/scala/com/yubico/webauthn/RelyingPartyCeremoniesSpec.scala @@ -33,9 +33,9 @@ import com.yubico.webauthn.test.RealExamples import org.junit.runner.RunWith import org.scalatest.FunSpec import org.scalatest.Matchers -import org.scalatest.junit.JUnitRunner +import org.scalatestplus.junit.JUnitRunner -import scala.collection.JavaConverters._ +import scala.jdk.CollectionConverters._ @RunWith(classOf[JUnitRunner]) @@ -50,7 +50,7 @@ class RelyingPartyCeremoniesSpec extends FunSpec with Matchers { describe("The default RelyingParty settings") { describe("can register and then authenticate") { - def check(testData: RealExamples.Example) { + def check(testData: RealExamples.Example): Unit = { val registrationRp = newRp(testData, Helpers.CredentialRepository.empty) val registrationResult = registrationRp.finishRegistration(FinishRegistrationOptions.builder() diff --git a/webauthn-server-core/src/test/scala/com/yubico/webauthn/RelyingPartyRegistrationSpec.scala b/webauthn-server-core/src/test/scala/com/yubico/webauthn/RelyingPartyRegistrationSpec.scala index 464afedd1..7a7500b96 100644 --- a/webauthn-server-core/src/test/scala/com/yubico/webauthn/RelyingPartyRegistrationSpec.scala +++ b/webauthn-server-core/src/test/scala/com/yubico/webauthn/RelyingPartyRegistrationSpec.scala @@ -66,20 +66,20 @@ import org.mockito.Mockito import org.scalacheck.Gen import org.scalatest.FunSpec import org.scalatest.Matchers -import org.scalatest.junit.JUnitRunner -import org.scalatest.prop.GeneratorDrivenPropertyChecks +import org.scalatestplus.junit.JUnitRunner +import org.scalatestplus.scalacheck.ScalaCheckDrivenPropertyChecks -import scala.collection.JavaConverters._ +import scala.jdk.CollectionConverters._ import scala.util.Failure import scala.util.Success import scala.util.Try @RunWith(classOf[JUnitRunner]) -class RelyingPartyRegistrationSpec extends FunSpec with Matchers with GeneratorDrivenPropertyChecks { +class RelyingPartyRegistrationSpec extends FunSpec with Matchers with ScalaCheckDrivenPropertyChecks { private def jsonFactory: JsonNodeFactory = JsonNodeFactory.instance private def toJsonObject(obj: Map[String, JsonNode]): JsonNode = jsonFactory.objectNode().setAll(obj.asJava) - private def toJson(obj: Map[String, String]): JsonNode = toJsonObject(obj.mapValues(jsonFactory.textNode)) + private def toJson(obj: Map[String, String]): JsonNode = toJsonObject(obj.view.mapValues(jsonFactory.textNode).toMap) private val crypto = new BouncyCastleCrypto private def sha256(bytes: ByteArray): ByteArray = crypto.hash(bytes) diff --git a/webauthn-server-core/src/test/scala/com/yubico/webauthn/RelyingPartyStartOperationSpec.scala b/webauthn-server-core/src/test/scala/com/yubico/webauthn/RelyingPartyStartOperationSpec.scala index 672656f31..c5569f242 100644 --- a/webauthn-server-core/src/test/scala/com/yubico/webauthn/RelyingPartyStartOperationSpec.scala +++ b/webauthn-server-core/src/test/scala/com/yubico/webauthn/RelyingPartyStartOperationSpec.scala @@ -30,27 +30,26 @@ import com.yubico.internal.util.scala.JavaConverters._ import com.yubico.scalacheck.gen.JavaGenerators._ import com.yubico.webauthn.data.AuthenticatorAttachment import com.yubico.webauthn.data.AuthenticatorSelectionCriteria -import com.yubico.webauthn.data.PublicKeyCredentialDescriptor import com.yubico.webauthn.data.ByteArray -import com.yubico.webauthn.data.UserIdentity -import com.yubico.webauthn.data.RelyingPartyIdentity +import com.yubico.webauthn.data.PublicKeyCredentialDescriptor import com.yubico.webauthn.data.PublicKeyCredentialParameters -import com.yubico.webauthn.data.Generators._ +import com.yubico.webauthn.data.RelyingPartyIdentity +import com.yubico.webauthn.data.UserIdentity import com.yubico.webauthn.extension.appid.AppId import com.yubico.webauthn.extension.appid.Generators._ import org.junit.runner.RunWith -import org.scalacheck.Arbitrary._ import org.scalacheck.Gen import org.scalatest.FunSpec import org.scalatest.Matchers -import org.scalatest.junit.JUnitRunner -import org.scalatest.prop.GeneratorDrivenPropertyChecks +import org.scalatestplus.junit.JUnitRunner +import org.scalatestplus.scalacheck.ScalaCheckDrivenPropertyChecks +import com.yubico.webauthn.data.Generators._ -import scala.collection.JavaConverters._ +import scala.jdk.CollectionConverters._ @RunWith(classOf[JUnitRunner]) -class RelyingPartyStartOperationSpec extends FunSpec with Matchers with GeneratorDrivenPropertyChecks { +class RelyingPartyStartOperationSpec extends FunSpec with Matchers with ScalaCheckDrivenPropertyChecks { def credRepo(credentials: Set[PublicKeyCredentialDescriptor]): CredentialRepository = new CredentialRepository { override def getCredentialIdsForUsername(username: String): java.util.Set[PublicKeyCredentialDescriptor] = credentials.asJava @@ -127,7 +126,7 @@ class RelyingPartyStartOperationSpec extends FunSpec with Matchers with Generato .user(userId) .timeout(Optional.empty[java.lang.Long]) .build()) - pkcco.getTimeout.asScala shouldBe 'empty + pkcco.getTimeout.asScala shouldBe empty } it("allows setting the timeout to a positive value.") { @@ -224,7 +223,7 @@ class RelyingPartyStartOperationSpec extends FunSpec with Matchers with Generato StartAssertionOptions.builder() .timeout(Optional.empty[java.lang.Long]) .build()) - req.getPublicKeyCredentialRequestOptions.getTimeout.asScala shouldBe 'empty + req.getPublicKeyCredentialRequestOptions.getTimeout.asScala shouldBe empty } it("allows setting the timeout to a positive value.") { diff --git a/webauthn-server-core/src/test/scala/com/yubico/webauthn/RelyingPartyUserIdentificationSpec.scala b/webauthn-server-core/src/test/scala/com/yubico/webauthn/RelyingPartyUserIdentificationSpec.scala index 5d3aa898d..a29810537 100644 --- a/webauthn-server-core/src/test/scala/com/yubico/webauthn/RelyingPartyUserIdentificationSpec.scala +++ b/webauthn-server-core/src/test/scala/com/yubico/webauthn/RelyingPartyUserIdentificationSpec.scala @@ -31,22 +31,21 @@ import java.util.Optional import com.fasterxml.jackson.databind.node.JsonNodeFactory import com.fasterxml.jackson.databind.node.ObjectNode import com.yubico.internal.util.scala.JavaConverters._ -import com.yubico.webauthn.data.CollectedClientData -import com.yubico.webauthn.data.PublicKeyCredentialDescriptor import com.yubico.webauthn.data.AuthenticatorAssertionResponse -import com.yubico.webauthn.data.PublicKeyCredential -import com.yubico.webauthn.data.RelyingPartyIdentity -import com.yubico.webauthn.data.PublicKeyCredentialRequestOptions import com.yubico.webauthn.data.ByteArray import com.yubico.webauthn.data.ClientAssertionExtensionOutputs +import com.yubico.webauthn.data.CollectedClientData +import com.yubico.webauthn.data.PublicKeyCredential +import com.yubico.webauthn.data.PublicKeyCredentialDescriptor +import com.yubico.webauthn.data.RelyingPartyIdentity import org.junit.runner.RunWith import org.scalatest.FunSpec import org.scalatest.Matchers -import org.scalatest.junit.JUnitRunner +import org.scalatestplus.junit.JUnitRunner -import scala.collection.JavaConverters._ -import scala.util.Success +import scala.jdk.CollectionConverters._ import scala.util.Failure +import scala.util.Success import scala.util.Try diff --git a/webauthn-server-core/src/test/scala/com/yubico/webauthn/WebAuthnCodecsSpec.scala b/webauthn-server-core/src/test/scala/com/yubico/webauthn/WebAuthnCodecsSpec.scala index 9b5391778..657bd42bb 100644 --- a/webauthn-server-core/src/test/scala/com/yubico/webauthn/WebAuthnCodecsSpec.scala +++ b/webauthn-server-core/src/test/scala/com/yubico/webauthn/WebAuthnCodecsSpec.scala @@ -30,16 +30,16 @@ import com.yubico.webauthn.data.ByteArray import org.junit.runner.RunWith import org.scalacheck.Arbitrary import org.scalacheck.Gen -import org.scalatest.Matchers import org.scalatest.FunSpec -import org.scalatest.junit.JUnitRunner -import org.scalatest.prop.GeneratorDrivenPropertyChecks +import org.scalatest.Matchers +import org.scalatestplus.junit.JUnitRunner +import org.scalatestplus.scalacheck.ScalaCheckDrivenPropertyChecks import scala.util.Try @RunWith(classOf[JUnitRunner]) -class WebAuthnCodecsSpec extends FunSpec with Matchers with GeneratorDrivenPropertyChecks { +class WebAuthnCodecsSpec extends FunSpec with Matchers with ScalaCheckDrivenPropertyChecks { private val javaCryptoProvider: java.security.Provider = new BouncyCastleCrypto().getProvider diff --git a/webauthn-server-core/src/test/scala/com/yubico/webauthn/data/AuthenticatorAttestationResponseSpec.scala b/webauthn-server-core/src/test/scala/com/yubico/webauthn/data/AuthenticatorAttestationResponseSpec.scala index e0f53cb08..2032ceecf 100644 --- a/webauthn-server-core/src/test/scala/com/yubico/webauthn/data/AuthenticatorAttestationResponseSpec.scala +++ b/webauthn-server-core/src/test/scala/com/yubico/webauthn/data/AuthenticatorAttestationResponseSpec.scala @@ -27,7 +27,7 @@ package com.yubico.webauthn.data import org.junit.runner.RunWith import org.scalatest.Matchers import org.scalatest.FunSpec -import org.scalatest.junit.JUnitRunner +import org.scalatestplus.junit.JUnitRunner @RunWith(classOf[JUnitRunner]) diff --git a/webauthn-server-core/src/test/scala/com/yubico/webauthn/data/AuthenticatorDataFlagsSpec.scala b/webauthn-server-core/src/test/scala/com/yubico/webauthn/data/AuthenticatorDataFlagsSpec.scala index 651beb123..c21bfd2aa 100644 --- a/webauthn-server-core/src/test/scala/com/yubico/webauthn/data/AuthenticatorDataFlagsSpec.scala +++ b/webauthn-server-core/src/test/scala/com/yubico/webauthn/data/AuthenticatorDataFlagsSpec.scala @@ -28,7 +28,7 @@ import com.yubico.internal.util.BinaryUtil import org.junit.runner.RunWith import org.scalatest.FunSpec import org.scalatest.Matchers -import org.scalatest.junit.JUnitRunner +import org.scalatestplus.junit.JUnitRunner @RunWith(classOf[JUnitRunner]) diff --git a/webauthn-server-core/src/test/scala/com/yubico/webauthn/data/AuthenticatorDataSpec.scala b/webauthn-server-core/src/test/scala/com/yubico/webauthn/data/AuthenticatorDataSpec.scala index 62fb78a82..769f8e257 100644 --- a/webauthn-server-core/src/test/scala/com/yubico/webauthn/data/AuthenticatorDataSpec.scala +++ b/webauthn-server-core/src/test/scala/com/yubico/webauthn/data/AuthenticatorDataSpec.scala @@ -32,7 +32,7 @@ import com.yubico.webauthn.WebAuthnTestCodecs import org.junit.runner.RunWith import org.scalatest.FunSpec import org.scalatest.Matchers -import org.scalatest.junit.JUnitRunner +import org.scalatestplus.junit.JUnitRunner import scala.util.Failure import scala.util.Try diff --git a/webauthn-server-core/src/test/scala/com/yubico/webauthn/data/AuthenticatorTransportSpec.scala b/webauthn-server-core/src/test/scala/com/yubico/webauthn/data/AuthenticatorTransportSpec.scala index 120860e05..f2b7ad1cf 100644 --- a/webauthn-server-core/src/test/scala/com/yubico/webauthn/data/AuthenticatorTransportSpec.scala +++ b/webauthn-server-core/src/test/scala/com/yubico/webauthn/data/AuthenticatorTransportSpec.scala @@ -27,11 +27,12 @@ package com.yubico.webauthn.data import org.junit.runner.RunWith import org.scalatest.FunSpec import org.scalatest.Matchers -import org.scalatest.junit.JUnitRunner +import org.scalatestplus.junit.JUnitRunner import org.scalatest.prop.GeneratorDrivenPropertyChecks +import org.scalatestplus.scalacheck.ScalaCheckDrivenPropertyChecks @RunWith(classOf[JUnitRunner]) -class AuthenticatorTransportSpec extends FunSpec with Matchers with GeneratorDrivenPropertyChecks { +class AuthenticatorTransportSpec extends FunSpec with Matchers with ScalaCheckDrivenPropertyChecks { describe("The AuthenticatorTransport type") { diff --git a/webauthn-server-core/src/test/scala/com/yubico/webauthn/data/BuildersSpec.scala b/webauthn-server-core/src/test/scala/com/yubico/webauthn/data/BuildersSpec.scala index 60ccd3781..a82514e36 100644 --- a/webauthn-server-core/src/test/scala/com/yubico/webauthn/data/BuildersSpec.scala +++ b/webauthn-server-core/src/test/scala/com/yubico/webauthn/data/BuildersSpec.scala @@ -36,14 +36,14 @@ import org.junit.runner.RunWith import org.scalacheck.Arbitrary import org.scalatest.FunSpec import org.scalatest.Matchers -import org.scalatest.junit.JUnitRunner -import org.scalatest.prop.GeneratorDrivenPropertyChecks +import org.scalatestplus.junit.JUnitRunner +import org.scalatestplus.scalacheck.ScalaCheckDrivenPropertyChecks import scala.language.reflectiveCalls @RunWith(classOf[JUnitRunner]) -class BuildersSpec extends FunSpec with Matchers with GeneratorDrivenPropertyChecks { +class BuildersSpec extends FunSpec with Matchers with ScalaCheckDrivenPropertyChecks { type ToBuilder[A] = { def toBuilder(): { def build(): A } } diff --git a/webauthn-server-core/src/test/scala/com/yubico/webauthn/data/CollectedClientDataSpec.scala b/webauthn-server-core/src/test/scala/com/yubico/webauthn/data/CollectedClientDataSpec.scala index da3dbf5be..dc15d6222 100644 --- a/webauthn-server-core/src/test/scala/com/yubico/webauthn/data/CollectedClientDataSpec.scala +++ b/webauthn-server-core/src/test/scala/com/yubico/webauthn/data/CollectedClientDataSpec.scala @@ -31,7 +31,7 @@ import com.yubico.webauthn.WebAuthnCodecs import org.junit.runner.RunWith import org.scalatest.FunSpec import org.scalatest.Matchers -import org.scalatest.junit.JUnitRunner +import org.scalatestplus.junit.JUnitRunner @RunWith(classOf[JUnitRunner]) diff --git a/webauthn-server-core/src/test/scala/com/yubico/webauthn/data/JsonIoSpec.scala b/webauthn-server-core/src/test/scala/com/yubico/webauthn/data/JsonIoSpec.scala index 23d70438f..4f89273fb 100644 --- a/webauthn-server-core/src/test/scala/com/yubico/webauthn/data/JsonIoSpec.scala +++ b/webauthn-server-core/src/test/scala/com/yubico/webauthn/data/JsonIoSpec.scala @@ -44,12 +44,12 @@ import org.junit.runner.RunWith import org.scalacheck.Arbitrary import org.scalatest.FunSpec import org.scalatest.Matchers -import org.scalatest.junit.JUnitRunner -import org.scalatest.prop.GeneratorDrivenPropertyChecks +import org.scalatestplus.junit.JUnitRunner +import org.scalatestplus.scalacheck.ScalaCheckDrivenPropertyChecks @RunWith(classOf[JUnitRunner]) -class JsonIoSpec extends FunSpec with Matchers with GeneratorDrivenPropertyChecks { +class JsonIoSpec extends FunSpec with Matchers with ScalaCheckDrivenPropertyChecks { def json: ObjectMapper = new ObjectMapper() .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, true) diff --git a/webauthn-server-core/src/test/scala/com/yubico/webauthn/data/PublicKeyCredentialDescriptorSpec.scala b/webauthn-server-core/src/test/scala/com/yubico/webauthn/data/PublicKeyCredentialDescriptorSpec.scala index 07e239184..fc4f97978 100644 --- a/webauthn-server-core/src/test/scala/com/yubico/webauthn/data/PublicKeyCredentialDescriptorSpec.scala +++ b/webauthn-server-core/src/test/scala/com/yubico/webauthn/data/PublicKeyCredentialDescriptorSpec.scala @@ -24,13 +24,13 @@ package com.yubico.webauthn.data -import org.scalatest.Matchers +import com.yubico.webauthn.data.Generators._ import org.scalatest.FunSpec -import org.scalatest.prop.GeneratorDrivenPropertyChecks -import Generators._ +import org.scalatest.Matchers +import org.scalatestplus.scalacheck.ScalaCheckDrivenPropertyChecks -class PublicKeyCredentialDescriptorSpec extends FunSpec with Matchers with GeneratorDrivenPropertyChecks { +class PublicKeyCredentialDescriptorSpec extends FunSpec with Matchers with ScalaCheckDrivenPropertyChecks { describe("PublicKeyCredentialDescriptor") { diff --git a/webauthn-server-core/src/testFixtures/scala/com/yubico/scalacheck/gen/JacksonGenerators.scala b/webauthn-server-core/src/testFixtures/scala/com/yubico/scalacheck/gen/JacksonGenerators.scala index ee300e009..920c3b1fa 100644 --- a/webauthn-server-core/src/testFixtures/scala/com/yubico/scalacheck/gen/JacksonGenerators.scala +++ b/webauthn-server-core/src/testFixtures/scala/com/yubico/scalacheck/gen/JacksonGenerators.scala @@ -32,7 +32,7 @@ import org.scalacheck.Arbitrary import org.scalacheck.Gen import org.scalacheck.Arbitrary.arbitrary -import scala.collection.JavaConverters._ +import scala.jdk.CollectionConverters._ object JacksonGenerators { diff --git a/webauthn-server-core/src/testFixtures/scala/com/yubico/webauthn/RegistrationTestData.scala b/webauthn-server-core/src/testFixtures/scala/com/yubico/webauthn/RegistrationTestData.scala index 851460340..69d5af65b 100644 --- a/webauthn-server-core/src/testFixtures/scala/com/yubico/webauthn/RegistrationTestData.scala +++ b/webauthn-server-core/src/testFixtures/scala/com/yubico/webauthn/RegistrationTestData.scala @@ -55,7 +55,7 @@ import com.yubico.webauthn.data.AuthenticatorAssertionResponse import com.yubico.webauthn.data.ClientAssertionExtensionOutputs import org.bouncycastle.asn1.x500.X500Name -import scala.collection.JavaConverters._ +import scala.jdk.CollectionConverters._ import scala.util.Failure import scala.util.Success import scala.util.Try @@ -287,7 +287,7 @@ case class RegistrationTestData( ) }) - protected def validate() { + protected def validate(): Unit = { val alg = WebAuthnCodecs.getCoseKeyAlg(response.getResponse.getParsedAuthenticatorData.getAttestedCredentialData.get.getCredentialPublicKey).get assert(alg == this.alg, s"Expected alg: ${this.alg}; was: ${alg}") } diff --git a/webauthn-server-core/src/testFixtures/scala/com/yubico/webauthn/TestAuthenticator.scala b/webauthn-server-core/src/testFixtures/scala/com/yubico/webauthn/TestAuthenticator.scala index c725e5387..3d56002fa 100644 --- a/webauthn-server-core/src/testFixtures/scala/com/yubico/webauthn/TestAuthenticator.scala +++ b/webauthn-server-core/src/testFixtures/scala/com/yubico/webauthn/TestAuthenticator.scala @@ -86,7 +86,7 @@ import org.bouncycastle.openssl.PEMParser import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder -import scala.collection.JavaConverters._ +import scala.jdk.CollectionConverters._ import scala.util.Try diff --git a/webauthn-server-core/src/testFixtures/scala/com/yubico/webauthn/data/Generators.scala b/webauthn-server-core/src/testFixtures/scala/com/yubico/webauthn/data/Generators.scala index df273a557..1775c60a2 100644 --- a/webauthn-server-core/src/testFixtures/scala/com/yubico/webauthn/data/Generators.scala +++ b/webauthn-server-core/src/testFixtures/scala/com/yubico/webauthn/data/Generators.scala @@ -47,7 +47,7 @@ import org.scalacheck.Arbitrary import org.scalacheck.Arbitrary.arbitrary import org.scalacheck.Gen -import scala.collection.JavaConverters._ +import scala.jdk.CollectionConverters._ object Generators { @@ -185,7 +185,7 @@ object Generators { implicit val arbitraryAuthenticatorTransport: Arbitrary[AuthenticatorTransport] = Arbitrary( Gen.oneOf( - Gen.oneOf(AuthenticatorTransport.values()), + Gen.oneOf(AuthenticatorTransport.values().toIndexedSeq), arbitrary[String] map AuthenticatorTransport.of )) @@ -238,7 +238,7 @@ object Generators { } } yield new ByteArray(JacksonCodecs.json().writeValueAsBytes(json)) - implicit val arbitraryCOSEAlgorithmIdentifier: Arbitrary[COSEAlgorithmIdentifier] = Arbitrary(Gen.oneOf(COSEAlgorithmIdentifier.values())) + implicit val arbitraryCOSEAlgorithmIdentifier: Arbitrary[COSEAlgorithmIdentifier] = Arbitrary(Gen.oneOf(COSEAlgorithmIdentifier.values().toIndexedSeq)) implicit val arbitraryPublicKeyCredentialWithAssertion: Arbitrary[PublicKeyCredential[AuthenticatorAssertionResponse, ClientAssertionExtensionOutputs]] = Arbitrary(for { id <- arbitrary[ByteArray] diff --git a/webauthn-server-core/src/testFixtures/scala/com/yubico/webauthn/test/Helpers.scala b/webauthn-server-core/src/testFixtures/scala/com/yubico/webauthn/test/Helpers.scala index f8792fd91..708b118fa 100644 --- a/webauthn-server-core/src/testFixtures/scala/com/yubico/webauthn/test/Helpers.scala +++ b/webauthn-server-core/src/testFixtures/scala/com/yubico/webauthn/test/Helpers.scala @@ -10,7 +10,7 @@ import com.yubico.webauthn.data.UserIdentity import com.yubico.webauthn.CredentialRepository import com.yubico.webauthn.RegistrationResult -import scala.collection.JavaConverters._ +import scala.jdk.CollectionConverters._ object Helpers { diff --git a/webauthn-server-core/src/testFixtures/scala/com/yubico/webauthn/test/Test.scala b/webauthn-server-core/src/testFixtures/scala/com/yubico/webauthn/test/Test.scala index 79b3ef162..b97fb1947 100644 --- a/webauthn-server-core/src/testFixtures/scala/com/yubico/webauthn/test/Test.scala +++ b/webauthn-server-core/src/testFixtures/scala/com/yubico/webauthn/test/Test.scala @@ -42,7 +42,7 @@ import com.yubico.webauthn.data.AuthenticatorDataFlags import com.yubico.webauthn.data.ByteArray import com.yubico.webauthn.WebAuthnTestCodecs -import scala.collection.JavaConverters._ +import scala.jdk.CollectionConverters._ object Test extends App { diff --git a/webauthn-server-demo/build.gradle b/webauthn-server-demo/build.gradle index d6d34f1f7..ac243004a 100644 --- a/webauthn-server-demo/build.gradle +++ b/webauthn-server-demo/build.gradle @@ -54,8 +54,8 @@ dependencies { addVersion('junit:junit'), addVersion('org.mockito:mockito-core'), addVersion('org.scala-lang:scala-library'), - addVersion('org.scalacheck:scalacheck_2.12'), - addVersion('org.scalatest:scalatest_2.12'), + addVersion('org.scalacheck:scalacheck_2.13'), + addVersion('org.scalatest:scalatest_2.13'), ) modules { diff --git a/webauthn-server-demo/src/test/scala/demo/webauthn/JsonSerializationSpec.scala b/webauthn-server-demo/src/test/scala/demo/webauthn/JsonSerializationSpec.scala index 0c5980b0d..d51ce503a 100644 --- a/webauthn-server-demo/src/test/scala/demo/webauthn/JsonSerializationSpec.scala +++ b/webauthn-server-demo/src/test/scala/demo/webauthn/JsonSerializationSpec.scala @@ -32,7 +32,7 @@ import demo.webauthn.data.RegistrationResponse import org.junit.runner.RunWith import org.scalatest.FunSpec import org.scalatest.Matchers -import org.scalatest.junit.JUnitRunner +import org.scalatestplus.junit.JUnitRunner @RunWith(classOf[JUnitRunner]) class JsonSerializationSpec extends FunSpec with Matchers { diff --git a/webauthn-server-demo/src/test/scala/demo/webauthn/WebAuthnServerSpec.scala b/webauthn-server-demo/src/test/scala/demo/webauthn/WebAuthnServerSpec.scala index 429584575..778a998c3 100644 --- a/webauthn-server-demo/src/test/scala/demo/webauthn/WebAuthnServerSpec.scala +++ b/webauthn-server-demo/src/test/scala/demo/webauthn/WebAuthnServerSpec.scala @@ -53,9 +53,9 @@ import demo.webauthn.data.RegistrationResponse import org.junit.runner.RunWith import org.scalatest.FunSpec import org.scalatest.Matchers -import org.scalatest.junit.JUnitRunner +import org.scalatestplus.junit.JUnitRunner -import scala.collection.JavaConverters._ +import scala.jdk.CollectionConverters._ @RunWith(classOf[JUnitRunner]) diff --git a/yubico-util/build.gradle b/yubico-util/build.gradle index 237a3de8c..ff1a2b2ec 100644 --- a/yubico-util/build.gradle +++ b/yubico-util/build.gradle @@ -24,14 +24,14 @@ dependencies { testFixturesApi( addVersion('org.scala-lang:scala-library'), - addVersion('org.scalacheck:scalacheck_2.12'), + addVersion('org.scalacheck:scalacheck_2.13'), ) testImplementation( addVersion('junit:junit'), addVersion('org.scala-lang:scala-library'), - addVersion('org.scalacheck:scalacheck_2.12'), - addVersion('org.scalatest:scalatest_2.12'), + addVersion('org.scalacheck:scalacheck_2.13'), + addVersion('org.scalatest:scalatest_2.13'), ) } diff --git a/yubico-util/src/test/scala/com/yubico/internal/util/BinaryUtilSpec.scala b/yubico-util/src/test/scala/com/yubico/internal/util/BinaryUtilSpec.scala index 00bad57bc..df88ae90b 100644 --- a/yubico-util/src/test/scala/com/yubico/internal/util/BinaryUtilSpec.scala +++ b/yubico-util/src/test/scala/com/yubico/internal/util/BinaryUtilSpec.scala @@ -26,14 +26,14 @@ package com.yubico.internal.util import org.junit.runner.RunWith import org.scalacheck.Gen -import org.scalatest.Matchers import org.scalatest.FunSpec -import org.scalatest.junit.JUnitRunner -import org.scalatest.prop.GeneratorDrivenPropertyChecks +import org.scalatest.Matchers +import org.scalatestplus.junit.JUnitRunner +import org.scalatestplus.scalacheck.ScalaCheckDrivenPropertyChecks @RunWith(classOf[JUnitRunner]) -class BinaryUtilSpec extends FunSpec with Matchers with GeneratorDrivenPropertyChecks { +class BinaryUtilSpec extends FunSpec with Matchers with ScalaCheckDrivenPropertyChecks { describe("BinaryUtil.fromHex") { diff --git a/yubico-util/src/test/scala/com/yubico/internal/util/CollectionUtilSpec.scala b/yubico-util/src/test/scala/com/yubico/internal/util/CollectionUtilSpec.scala index 361852645..e5a28f326 100644 --- a/yubico-util/src/test/scala/com/yubico/internal/util/CollectionUtilSpec.scala +++ b/yubico-util/src/test/scala/com/yubico/internal/util/CollectionUtilSpec.scala @@ -4,11 +4,11 @@ import com.yubico.scalacheck.gen.JavaGenerators._ import org.junit.runner.RunWith import org.scalatest.FunSpec import org.scalatest.Matchers -import org.scalatest.junit.JUnitRunner -import org.scalatest.prop.GeneratorDrivenPropertyChecks +import org.scalatestplus.junit.JUnitRunner +import org.scalatestplus.scalacheck.ScalaCheckDrivenPropertyChecks @RunWith(classOf[JUnitRunner]) -class CollectionUtilSpec extends FunSpec with Matchers with GeneratorDrivenPropertyChecks { +class CollectionUtilSpec extends FunSpec with Matchers with ScalaCheckDrivenPropertyChecks { describe("immutableMap") { it("returns a Map instance which throws exceptions on modification attempts.") { diff --git a/yubico-util/src/test/scala/com/yubico/internal/util/ComparableUtilSpec.scala b/yubico-util/src/test/scala/com/yubico/internal/util/ComparableUtilSpec.scala index 0547c5b65..5c515f94b 100644 --- a/yubico-util/src/test/scala/com/yubico/internal/util/ComparableUtilSpec.scala +++ b/yubico-util/src/test/scala/com/yubico/internal/util/ComparableUtilSpec.scala @@ -1,18 +1,18 @@ package com.yubico.internal.util import org.junit.runner.RunWith -import org.scalacheck.Gen import org.scalacheck.Arbitrary.arbitrary -import org.scalatest.junit.JUnitRunner -import org.scalatest.prop.GeneratorDrivenPropertyChecks +import org.scalacheck.Gen +import org.scalatestplus.junit.JUnitRunner import org.scalatest.FunSpec import org.scalatest.Matchers +import org.scalatestplus.scalacheck.ScalaCheckDrivenPropertyChecks -import _root_.scala.collection.JavaConverters._ +import _root_.scala.jdk.CollectionConverters._ @RunWith(classOf[JUnitRunner]) -class ComparableUtilSpec extends FunSpec with Matchers with GeneratorDrivenPropertyChecks { +class ComparableUtilSpec extends FunSpec with Matchers with ScalaCheckDrivenPropertyChecks { def sameSizeSets[T](implicit gent: Gen[T]): Gen[(Set[T], Set[T])] = for { n: Int <- Gen.chooseNum(0, 100) diff --git a/yubico-util/src/testFixtures/scala/com/yubico/scalacheck/gen/JavaGenerators.scala b/yubico-util/src/testFixtures/scala/com/yubico/scalacheck/gen/JavaGenerators.scala index dbe1393b3..98e768220 100644 --- a/yubico-util/src/testFixtures/scala/com/yubico/scalacheck/gen/JavaGenerators.scala +++ b/yubico-util/src/testFixtures/scala/com/yubico/scalacheck/gen/JavaGenerators.scala @@ -8,7 +8,7 @@ import org.scalacheck.Arbitrary import org.scalacheck.Gen import org.scalacheck.Arbitrary.arbitrary -import scala.collection.JavaConverters._ +import scala.jdk.CollectionConverters._ object JavaGenerators { From 1f484827f722383e6dc86d15e4f5cc12a0a089ef Mon Sep 17 00:00:00 2001 From: Emil Lundberg Date: Fri, 24 Jan 2020 19:37:18 +0100 Subject: [PATCH 20/24] Enable logging in tests --- webauthn-server-attestation/build.gradle | 4 ++++ .../src/test/resources/logback.xml | 15 +++++++++++++++ webauthn-server-core/build.gradle | 3 +++ .../src/test/resources/logback.xml | 15 +++++++++++++++ .../src/test/resources/logback-test.xml | 15 +++++++++++++++ yubico-util/build.gradle | 4 ++++ 6 files changed, 56 insertions(+) create mode 100644 webauthn-server-attestation/src/test/resources/logback.xml create mode 100644 webauthn-server-core/src/test/resources/logback.xml create mode 100644 webauthn-server-demo/src/test/resources/logback-test.xml diff --git a/webauthn-server-attestation/build.gradle b/webauthn-server-attestation/build.gradle index 845fd0c49..1738ae677 100644 --- a/webauthn-server-attestation/build.gradle +++ b/webauthn-server-attestation/build.gradle @@ -32,6 +32,10 @@ dependencies { addVersion('org.scalacheck:scalacheck_2.13'), addVersion('org.scalatest:scalatest_2.13'), ) + + testRuntimeOnly( + addVersion('ch.qos.logback:logback-classic'), + ) } diff --git a/webauthn-server-attestation/src/test/resources/logback.xml b/webauthn-server-attestation/src/test/resources/logback.xml new file mode 100644 index 000000000..6f078dd41 --- /dev/null +++ b/webauthn-server-attestation/src/test/resources/logback.xml @@ -0,0 +1,15 @@ + + + + + %d{HH:mm:ss.SSSZ} [%thread] %-5level %logger{36} - %msg%n%rEx + + + + + + + + + + diff --git a/webauthn-server-core/build.gradle b/webauthn-server-core/build.gradle index 9e11cff3b..e7e459a7c 100644 --- a/webauthn-server-core/build.gradle +++ b/webauthn-server-core/build.gradle @@ -46,6 +46,9 @@ dependencies { addVersion('org.scalatest:scalatest_2.13'), ) + testRuntimeOnly( + addVersion('ch.qos.logback:logback-classic'), + ) } diff --git a/webauthn-server-core/src/test/resources/logback.xml b/webauthn-server-core/src/test/resources/logback.xml new file mode 100644 index 000000000..6f078dd41 --- /dev/null +++ b/webauthn-server-core/src/test/resources/logback.xml @@ -0,0 +1,15 @@ + + + + + %d{HH:mm:ss.SSSZ} [%thread] %-5level %logger{36} - %msg%n%rEx + + + + + + + + + + diff --git a/webauthn-server-demo/src/test/resources/logback-test.xml b/webauthn-server-demo/src/test/resources/logback-test.xml new file mode 100644 index 000000000..6f078dd41 --- /dev/null +++ b/webauthn-server-demo/src/test/resources/logback-test.xml @@ -0,0 +1,15 @@ + + + + + %d{HH:mm:ss.SSSZ} [%thread] %-5level %logger{36} - %msg%n%rEx + + + + + + + + + + diff --git a/yubico-util/build.gradle b/yubico-util/build.gradle index ff1a2b2ec..aa5f0edc4 100644 --- a/yubico-util/build.gradle +++ b/yubico-util/build.gradle @@ -33,6 +33,10 @@ dependencies { addVersion('org.scalacheck:scalacheck_2.13'), addVersion('org.scalatest:scalatest_2.13'), ) + + testRuntimeOnly( + addVersion('ch.qos.logback:logback-classic'), + ) } From edd1e5fca226028a7d8def7724a727f22088491d Mon Sep 17 00:00:00 2001 From: Emil Lundberg Date: Thu, 6 Feb 2020 17:42:32 +0100 Subject: [PATCH 21/24] Add JDK 13 to CI builds --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 261669cdf..88a16d70b 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -10,7 +10,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - java: [8, 11] + java: [8, 11, 13] steps: - name: Check out code From ea4db1f9f7b4da38c7a58742ba58240c4f34fc7a Mon Sep 17 00:00:00 2001 From: Emil Lundberg Date: Thu, 13 Feb 2020 17:16:00 +0100 Subject: [PATCH 22/24] Remove Travis badge from README --- README | 1 - 1 file changed, 1 deletion(-) diff --git a/README b/README index 43946201e..315690186 100644 --- a/README +++ b/README @@ -4,7 +4,6 @@ java-webauthn-server :toc-placement: macro :toc-title: -image:https://travis-ci.org/Yubico/java-webauthn-server.svg?branch=master["Build Status", link="https://travis-ci.org/Yubico/java-webauthn-server"] image:https://github.com/Yubico/java-webauthn-server/workflows/build/badge.svg["Build Status", link="https://github.com/Yubico/java-webauthn-server/actions"] image:https://coveralls.io/repos/github/Yubico/java-webauthn-server/badge.svg["Coverage Status", link="https://coveralls.io/github/Yubico/java-webauthn-server"] From 336cb3ba36f683b65f5a9765db4f2379fa73e745 Mon Sep 17 00:00:00 2001 From: Emil Lundberg Date: Thu, 13 Feb 2020 19:35:28 +0100 Subject: [PATCH 23/24] Default displayName to user name in demo --- webauthn-server-demo/src/main/webapp/index.html | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/webauthn-server-demo/src/main/webapp/index.html b/webauthn-server-demo/src/main/webapp/index.html index 6b953d501..5dd90ece8 100644 --- a/webauthn-server-demo/src/main/webapp/index.html +++ b/webauthn-server-demo/src/main/webapp/index.html @@ -186,7 +186,7 @@ return fetch(urls.register, { body: new URLSearchParams({ username, - displayName, + displayName: displayName || username, credentialNickname, requireResidentKey, sessionToken: session.sessionToken || null, @@ -522,6 +522,11 @@ }); } +function usernameChanged(event) { + const displayNameField = document.getElementById("displayName"); + displayNameField.placeholder = event.target.value; +} + function init() { hideDeviceInfo(); return false; @@ -548,7 +553,7 @@

Test your WebAuthn device

-
+
From 59245209640f16442ac265d8f4445786d0821612 Mon Sep 17 00:00:00 2001 From: Emil Lundberg Date: Thu, 5 Mar 2020 12:22:50 +0100 Subject: [PATCH 24/24] Bump Jackson dependency version to 2.9.10.3 --- NEWS | 8 ++++++++ build.gradle | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index afa999c8c..9042f5d09 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,11 @@ +== Version 1.6.1 (unreleased) == + +Security fixes: + +- Bumped Jackson dependency to version 2.9.10.3 in response to CVE-2019-20330 + and CVE-2020-8840 + + == Version 1.6.0 == Security fixes: diff --git a/build.gradle b/build.gradle index 2e80d7c2b..89b396d56 100644 --- a/build.gradle +++ b/build.gradle @@ -51,7 +51,7 @@ allprojects { Map dependencyVersions = [ 'ch.qos.logback:logback-classic:1.2.3', 'com.augustcellars.cose:cose-java:1.0.0', - 'com.fasterxml.jackson.core:jackson-databind:2.9.10.1', + 'com.fasterxml.jackson.core:jackson-databind:2.9.10.3', 'com.fasterxml.jackson.dataformat:jackson-dataformat-cbor:2.9.10', 'com.fasterxml.jackson.datatype:jackson-datatype-jdk8:2.9.10', 'com.google.guava:guava:19.0',