26
26
27
27
import com .google .common .cache .Cache ;
28
28
import com .google .common .cache .CacheBuilder ;
29
- import com .yubico .internal .util .CollectionUtil ;
30
- import com .yubico .webauthn .AssertionResult ;
31
- import com .yubico .webauthn .CredentialRepository ;
32
- import com .yubico .webauthn .RegisteredCredential ;
29
+ import com .yubico .webauthn .AssertionResultV2 ;
30
+ import com .yubico .webauthn .CredentialRepositoryV2 ;
31
+ import com .yubico .webauthn .UsernameRepository ;
33
32
import com .yubico .webauthn .data .ByteArray ;
34
33
import com .yubico .webauthn .data .PublicKeyCredentialDescriptor ;
35
34
import demo .webauthn .data .CredentialRegistration ;
44
43
import org .slf4j .Logger ;
45
44
import org .slf4j .LoggerFactory ;
46
45
47
- public class InMemoryRegistrationStorage implements CredentialRepository {
46
+ public class InMemoryRegistrationStorage
47
+ implements CredentialRepositoryV2 <CredentialRegistration >, UsernameRepository {
48
48
49
49
private final Cache <String , Set <CredentialRegistration >> storage =
50
50
CacheBuilder .newBuilder ().maximumSize (1000 ).expireAfterAccess (1 , TimeUnit .DAYS ).build ();
51
51
52
52
private static final Logger logger = LoggerFactory .getLogger (InMemoryRegistrationStorage .class );
53
53
54
54
////////////////////////////////////////////////////////////////////////////////
55
- // The following methods are required by the CredentialRepository interface.
55
+ // The following methods are required by the CredentialRepositoryV2 interface.
56
56
////////////////////////////////////////////////////////////////////////////////
57
57
58
58
@ Override
59
- public Set <PublicKeyCredentialDescriptor > getCredentialIdsForUsername ( String username ) {
60
- return getRegistrationsByUsername ( username ).stream ()
59
+ public Set <PublicKeyCredentialDescriptor > getCredentialIdsForUserHandle ( ByteArray userHandle ) {
60
+ return getRegistrationsByUserHandle ( userHandle ).stream ()
61
61
.map (
62
62
registration ->
63
63
PublicKeyCredentialDescriptor .builder ()
@@ -68,63 +68,53 @@ public Set<PublicKeyCredentialDescriptor> getCredentialIdsForUsername(String use
68
68
}
69
69
70
70
@ Override
71
- public Optional <String > getUsernameForUserHandle (ByteArray userHandle ) {
72
- return getRegistrationsByUserHandle (userHandle ).stream ()
73
- .findAny ()
74
- .map (CredentialRegistration ::getUsername );
75
- }
76
-
77
- @ Override
78
- public Optional <ByteArray > getUserHandleForUsername (String username ) {
79
- return getRegistrationsByUsername (username ).stream ()
80
- .findAny ()
81
- .map (reg -> reg .getUserIdentity ().getId ());
82
- }
83
-
84
- @ Override
85
- public Optional <RegisteredCredential > lookup (ByteArray credentialId , ByteArray userHandle ) {
71
+ public Optional <CredentialRegistration > lookup (ByteArray credentialId , ByteArray userHandle ) {
86
72
Optional <CredentialRegistration > registrationMaybe =
87
73
storage .asMap ().values ().stream ()
88
74
.flatMap (Collection ::stream )
89
- .filter (credReg -> credentialId .equals (credReg .getCredential ().getCredentialId ()))
75
+ .filter (
76
+ credReg ->
77
+ credentialId .equals (credReg .getCredential ().getCredentialId ())
78
+ && userHandle .equals (credReg .getUserHandle ()))
90
79
.findAny ();
91
80
92
81
logger .debug (
93
82
"lookup credential ID: {}, user handle: {}; result: {}" ,
94
83
credentialId ,
95
84
userHandle ,
96
85
registrationMaybe );
97
- return registrationMaybe .map (
98
- registration ->
99
- RegisteredCredential .builder ()
100
- .credentialId (registration .getCredential ().getCredentialId ())
101
- .userHandle (registration .getUserIdentity ().getId ())
102
- .publicKeyCose (registration .getCredential ().getPublicKeyCose ())
103
- .signatureCount (registration .getCredential ().getSignatureCount ())
104
- .build ());
86
+
87
+ return registrationMaybe ;
105
88
}
106
89
107
90
@ Override
108
- public Set <RegisteredCredential > lookupAll (ByteArray credentialId ) {
109
- return CollectionUtil .immutableSet (
110
- storage .asMap ().values ().stream ()
111
- .flatMap (Collection ::stream )
112
- .filter (reg -> reg .getCredential ().getCredentialId ().equals (credentialId ))
113
- .map (
114
- reg ->
115
- RegisteredCredential .builder ()
116
- .credentialId (reg .getCredential ().getCredentialId ())
117
- .userHandle (reg .getUserIdentity ().getId ())
118
- .publicKeyCose (reg .getCredential ().getPublicKeyCose ())
119
- .signatureCount (reg .getCredential ().getSignatureCount ())
120
- .build ())
121
- .collect (Collectors .toSet ()));
91
+ public boolean credentialIdExists (ByteArray credentialId ) {
92
+ return storage .asMap ().values ().stream ()
93
+ .flatMap (Collection ::stream )
94
+ .anyMatch (reg -> reg .getCredential ().getCredentialId ().equals (credentialId ));
95
+ }
96
+
97
+ ////////////////////////////////////////////////////////////////////////////////
98
+ // The following methods are required by the UsernameRepository interface.
99
+ ////////////////////////////////////////////////////////////////////////////////
100
+
101
+ @ Override
102
+ public Optional <ByteArray > getUserHandleForUsername (String username ) {
103
+ return getRegistrationsByUsername (username ).stream ()
104
+ .findAny ()
105
+ .map (reg -> reg .getUserIdentity ().getId ());
122
106
}
123
107
124
108
////////////////////////////////////////////////////////////////////////////////
125
109
// The following methods are specific to this demo application.
126
110
////////////////////////////////////////////////////////////////////////////////
127
111
112
+ public Optional <String > getUsernameForUserHandle (ByteArray userHandle ) {
113
+ return getRegistrationsByUserHandle (userHandle ).stream ()
114
+ .findAny ()
115
+ .map (CredentialRegistration ::getUsername );
116
+ }
117
+
128
118
public boolean addRegistrationByUsername (String username , CredentialRegistration reg ) {
129
119
try {
130
120
return storage .get (username , HashSet ::new ).add (reg );
@@ -152,18 +142,19 @@ public Collection<CredentialRegistration> getRegistrationsByUserHandle(ByteArray
152
142
.collect (Collectors .toList ());
153
143
}
154
144
155
- public void updateSignatureCount (AssertionResult result ) {
145
+ public void updateSignatureCount (AssertionResultV2 < CredentialRegistration > result ) {
156
146
CredentialRegistration registration =
157
147
getRegistrationByUsernameAndCredentialId (
158
- result .getUsername (), result .getCredential ().getCredentialId ())
148
+ result .getCredential (). getUsername (), result .getCredential ().getCredentialId ())
159
149
.orElseThrow (
160
150
() ->
161
151
new NoSuchElementException (
162
152
String .format (
163
153
"Credential \" %s\" is not registered to user \" %s\" " ,
164
- result .getCredential ().getCredentialId (), result .getUsername ())));
154
+ result .getCredential ().getCredentialId (),
155
+ result .getCredential ().getUsername ())));
165
156
166
- Set <CredentialRegistration > regs = storage .getIfPresent (result .getUsername ());
157
+ Set <CredentialRegistration > regs = storage .getIfPresent (result .getCredential (). getUsername ());
167
158
regs .remove (registration );
168
159
regs .add (
169
160
registration .withCredential (
0 commit comments