File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -50,12 +50,20 @@ def get_assertion(
5050 user_verified : false ,
5151 aaguid : AuthenticatorData ::AAGUID ,
5252 sign_count : nil ,
53- extensions : nil
53+ extensions : nil ,
54+ allow_credentials : nil
5455 )
5556 credential_options = credentials [ rp_id ]
5657
5758 if credential_options
58- credential_id , credential = credential_options . first
59+ allow_credentials ||= credential_options . keys
60+ credential_id = ( credential_options . keys & allow_credentials ) . first
61+ unless credential_id
62+ raise "No matching credentials (allowed=#{ allow_credentials } ) " \
63+ "found for RP #{ rp_id } among credentials=#{ credential_options } "
64+ end
65+
66+ credential = credential_options [ credential_id ]
5967 credential_key = credential [ :credential_key ]
6068 credential_sign_count = credential [ :sign_count ]
6169
Original file line number Diff line number Diff line change @@ -74,19 +74,25 @@ def get(challenge: fake_challenge,
7474 user_verified : false ,
7575 sign_count : nil ,
7676 extensions : nil ,
77- user_handle : nil )
77+ user_handle : nil ,
78+ allow_credentials : nil )
7879 rp_id ||= URI . parse ( origin ) . host
7980
8081 client_data_json = data_json_for ( :get , encoder . decode ( challenge ) )
8182 client_data_hash = hashed ( client_data_json )
8283
84+ if allow_credentials
85+ allow_credentials = allow_credentials . map { |credential | encoder . decode ( credential ) }
86+ end
87+
8388 assertion = authenticator . get_assertion (
8489 rp_id : rp_id ,
8590 client_data_hash : client_data_hash ,
8691 user_present : user_present ,
8792 user_verified : user_verified ,
8893 sign_count : sign_count ,
89- extensions : extensions
94+ extensions : extensions ,
95+ allow_credentials : allow_credentials
9096 )
9197
9298 {
Original file line number Diff line number Diff line change 1+ # frozen_string_literal: true
2+
3+ require "spec_helper"
4+
5+ RSpec . describe "FakeClient" do
6+ let ( :client ) { WebAuthn ::FakeClient . new }
7+
8+ context "#get" do
9+ let! ( :credential_1 ) { client . create }
10+ let! ( :credential_2 ) { client . create }
11+
12+ it "returns the first matching credential when allow_credentials is nil" do
13+ assertion = client . get
14+ expect ( assertion [ "id" ] ) . to eq ( credential_1 [ "id" ] )
15+ end
16+
17+ it "returns the matching credential when allow_credentials is passed" do
18+ allow_credentials = [ credential_2 [ "id" ] ]
19+ assertion = client . get ( allow_credentials : allow_credentials )
20+ expect ( assertion [ "id" ] ) . to eq ( credential_2 [ "id" ] )
21+ end
22+
23+ it "raises an error when no matching allow_credential can be found" do
24+ # base64(abc) is surely not a valid credential id (too short)
25+ allow_credentials = [ "YWJj" ]
26+ expect { client . get ( allow_credentials : allow_credentials ) } . to \
27+ raise_error ( RuntimeError , /No matching credentials \( allowed=\[ "abc"\] \) found for RP/ )
28+ end
29+ end
30+ end
You can’t perform that action at this time.
0 commit comments