1
1
package services
2
2
3
3
import (
4
- "encoding/base64"
5
4
"errors"
6
5
"fmt"
7
6
"github.com/go-webauthn/webauthn/protocol"
@@ -178,45 +177,38 @@ func (s *webauthnService) VerifyAssertionResponse(p VerifyAssertionResponseParam
178
177
return nil , fmt .Errorf ("%s: %w" , err , ErrInvalidWebauthnCredential )
179
178
}
180
179
181
- sessionDataModel , err := s .persister .GetWebauthnSessionDataPersister ( ).Get (p .SessionDataID )
180
+ sessionDataModel , err := s .persister .GetWebauthnSessionDataPersisterWithConnection ( p . Tx ).Get (p .SessionDataID )
182
181
if err != nil {
183
182
return nil , fmt .Errorf ("failed to get session data from db: %w" , err )
184
183
}
185
184
186
- var userID uuid.UUID
187
- if p .IsMFA {
188
- userID = sessionDataModel .UserId
189
- } else {
190
- userID , err = uuid .FromBytes (credentialAssertionData .Response .UserHandle )
191
- if err != nil {
192
- return nil , fmt .Errorf ("failed to parse user id from user handle: %w" , err )
193
- }
194
- }
195
-
196
- userModel , err := s .persister .GetUserPersister ().Get (userID )
185
+ credentialModel , err := s .persister .GetWebauthnCredentialPersister ().Get (credentialAssertionData .ID )
197
186
if err != nil {
198
- return nil , fmt .Errorf ("failed to fetch user from db: %w" , err )
187
+ return nil , fmt .Errorf ("failed to get webauthncredential from db: %w" , err )
199
188
}
200
189
201
- if userModel == nil {
202
- return nil , fmt . Errorf ( "%s: %w" , err , ErrInvalidWebauthnCredential )
190
+ if credentialModel == nil {
191
+ return nil , ErrInvalidWebauthnCredential
203
192
}
204
193
205
- cred := userModel .GetWebauthnCredentialById (credentialAssertionData .ID )
206
- if cred != nil && (! p .IsMFA && cred .MFAOnly ) {
194
+ if ! p .IsMFA && credentialModel .MFAOnly {
207
195
return nil , ErrInvalidWebauthnCredentialMFAOnly
208
196
}
209
197
198
+ webAuthnUser , userModel , err := s .GetWebAuthnUser (p .Tx , * credentialModel )
199
+ if err != nil {
200
+ return nil , err
201
+ }
202
+
210
203
discoverableUserHandler := func (rawID , userHandle []byte ) (webauthn.User , error ) {
211
- return userModel , nil
204
+ return webAuthnUser , nil
212
205
}
213
206
214
207
sessionData := sessionDataModel .ToSessionData ()
215
- var credential * webauthn.Credential
216
208
if p .IsMFA {
217
- credential , err = s .cfg .Webauthn .Handler .ValidateLogin (userModel , * sessionData , credentialAssertionData )
209
+ _ , err = s .cfg .Webauthn .Handler .ValidateLogin (webAuthnUser , * sessionData , credentialAssertionData )
218
210
} else {
219
- credential , err = s .cfg .Webauthn .Handler .ValidateDiscoverableLogin (
211
+ _ , err = s .cfg .Webauthn .Handler .ValidateDiscoverableLogin (
220
212
discoverableUserHandler ,
221
213
* sessionData ,
222
214
credentialAssertionData ,
@@ -226,19 +218,16 @@ func (s *webauthnService) VerifyAssertionResponse(p VerifyAssertionResponseParam
226
218
return nil , fmt .Errorf ("%s: %w" , err , ErrInvalidWebauthnCredential )
227
219
}
228
220
229
- encodedCredentialId := base64 .RawURLEncoding .EncodeToString (credential .ID )
230
- if credentialModel := userModel .GetWebauthnCredentialById (encodedCredentialId ); credentialModel != nil {
231
- now := time .Now ().UTC ()
232
- flags := credentialAssertionData .Response .AuthenticatorData .Flags
221
+ now := time .Now ().UTC ()
222
+ flags := credentialAssertionData .Response .AuthenticatorData .Flags
233
223
234
- credentialModel .LastUsedAt = & now
235
- credentialModel .BackupState = flags .HasBackupState ()
236
- credentialModel .BackupEligible = flags .HasBackupEligible ()
224
+ credentialModel .LastUsedAt = & now
225
+ credentialModel .BackupState = flags .HasBackupState ()
226
+ credentialModel .BackupEligible = flags .HasBackupEligible ()
237
227
238
- err = s .persister .GetWebauthnCredentialPersisterWithConnection (p .Tx ).Update (* credentialModel )
239
- if err != nil {
240
- return nil , fmt .Errorf ("failed to update webauthn credential: %w" , err )
241
- }
228
+ err = s .persister .GetWebauthnCredentialPersisterWithConnection (p .Tx ).Update (* credentialModel )
229
+ if err != nil {
230
+ return nil , fmt .Errorf ("failed to update webauthn credential: %w" , err )
242
231
}
243
232
244
233
err = s .persister .GetWebauthnSessionDataPersisterWithConnection (p .Tx ).Delete (* sessionDataModel )
@@ -279,11 +268,10 @@ func (s *webauthnService) generateCreationOptions(p GenerateCreationOptionsParam
279
268
280
269
err = s .persister .GetWebauthnSessionDataPersisterWithConnection (p .Tx ).Create (* sessionDataModel )
281
270
if err != nil {
282
- return nil , nil , fmt .Errorf ("failed to store session data to the db: %W " , err )
271
+ return nil , nil , fmt .Errorf ("failed to store session data to the db: %w " , err )
283
272
}
284
273
285
274
return sessionDataModel , options , nil
286
-
287
275
}
288
276
289
277
func (s * webauthnService ) GenerateCreationOptionsSecurityKey (p GenerateCreationOptionsParams ) (* models.WebauthnSessionData , * protocol.CredentialCreation , error ) {
@@ -354,3 +342,31 @@ func (s *webauthnService) VerifyAttestationResponse(p VerifyAttestationResponseP
354
342
355
343
return credential , nil
356
344
}
345
+
346
+ func (s * webauthnService ) GetWebAuthnUser (tx * pop.Connection , credential models.WebauthnCredential ) (webauthn.User , * models.User , error ) {
347
+ user , err := s .persister .GetUserPersisterWithConnection (tx ).Get (credential .UserId )
348
+ if err != nil {
349
+ return nil , nil , fmt .Errorf ("failed to fetch user from db: %w" , err )
350
+ }
351
+ if user == nil {
352
+ return nil , nil , ErrInvalidWebauthnCredential
353
+ }
354
+
355
+ if credential .UserHandle != nil {
356
+ return & webauthnUserWithCustomUserHandle {
357
+ CustomUserHandle : []byte (credential .UserHandle .Handle ),
358
+ User : * user ,
359
+ }, user , nil
360
+ }
361
+
362
+ return user , user , err
363
+ }
364
+
365
+ type webauthnUserWithCustomUserHandle struct {
366
+ models.User
367
+ CustomUserHandle []byte
368
+ }
369
+
370
+ func (u * webauthnUserWithCustomUserHandle ) WebAuthnID () []byte {
371
+ return u .CustomUserHandle
372
+ }
0 commit comments