Skip to content

Commit

Permalink
fix: fix user import with multiple credentials
Browse files Browse the repository at this point in the history
Fix user import with multiple credential and the same user handle. Check if the user handle already exists and associate the credential with it otherwise create a new user handle in the database.
  • Loading branch information
FreddyDevelop committed Dec 9, 2024
1 parent dadfbde commit 306db83
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 9 deletions.
27 changes: 18 additions & 9 deletions backend/cmd/user/importer.go
Original file line number Diff line number Diff line change
Expand Up @@ -147,20 +147,29 @@ func (i *Importer) createWebauthnCredential(userID uuid.UUID, webauthnCredential
}

if webauthnCredential.UserHandle != nil {
userHandleID, err := uuid.NewV4()
existingUserHandle, err := i.persister.GetWebauthnCredentialUserHandlePersisterWithConnection(i.tx).GetByHandle(*webauthnCredential.UserHandle)
if err != nil {
return err
}

userHandle := models.WebauthnCredentialUserHandle{
ID: userHandleID,
UserID: userID,
Handle: *webauthnCredential.UserHandle,
CreatedAt: i.importTimestamp,
UpdatedAt: i.importTimestamp,
if existingUserHandle != nil {
webauthnCredentialModel.UserHandleID = &existingUserHandle.ID
} else {
userHandleID, err := uuid.NewV4()
if err != nil {
return err
}

userHandle := models.WebauthnCredentialUserHandle{
ID: userHandleID,
UserID: userID,
Handle: *webauthnCredential.UserHandle,
CreatedAt: i.importTimestamp,
UpdatedAt: i.importTimestamp,
}
webauthnCredentialModel.UserHandle = &userHandle
webauthnCredentialModel.UserHandleID = &userHandleID
}
webauthnCredentialModel.UserHandle = &userHandle
webauthnCredentialModel.UserHandleID = &userHandleID
}

err := i.persister.GetWebauthnCredentialPersisterWithConnection(i.tx).Create(webauthnCredentialModel)
Expand Down
10 changes: 10 additions & 0 deletions backend/persistence/persister.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ type Persister interface {
GetSessionPersisterWithConnection(tx *pop.Connection) SessionPersister
GetOTPSecretPersister() OTPSecretPersister
GetOTPSecretPersisterWithConnection(tx *pop.Connection) OTPSecretPersister
GetWebauthnCredentialUserHandlePersister() WebauthnCredentialUserHandlePersister
GetWebauthnCredentialUserHandlePersisterWithConnection(tx *pop.Connection) WebauthnCredentialUserHandlePersister
Transaction(func(tx *pop.Connection) error) error
}

Expand Down Expand Up @@ -276,3 +278,11 @@ func (p *persister) GetSessionPersister() SessionPersister {
func (p *persister) GetSessionPersisterWithConnection(tx *pop.Connection) SessionPersister {
return NewSessionPersister(tx)
}

func (p *persister) GetWebauthnCredentialUserHandlePersister() WebauthnCredentialUserHandlePersister {
return NewWebauthnCredentialUserHandlePersister(p.DB)
}

func (p *persister) GetWebauthnCredentialUserHandlePersisterWithConnection(tx *pop.Connection) WebauthnCredentialUserHandlePersister {
return NewWebauthnCredentialUserHandlePersister(tx)
}
34 changes: 34 additions & 0 deletions backend/persistence/webauthn_credential_user_handle_persister.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package persistence

import (
"database/sql"
"errors"
"fmt"
"github.com/gobuffalo/pop/v6"
"github.com/teamhanko/hanko/backend/persistence/models"
)

type WebauthnCredentialUserHandlePersister interface {
GetByHandle(string) (*models.WebauthnCredentialUserHandle, error)
}

func NewWebauthnCredentialUserHandlePersister(db *pop.Connection) WebauthnCredentialUserHandlePersister {
return &webauthnCredentialUserHandlePersister{db: db}
}

type webauthnCredentialUserHandlePersister struct {
db *pop.Connection
}

func (p *webauthnCredentialUserHandlePersister) GetByHandle(handle string) (*models.WebauthnCredentialUserHandle, error) {
handleModel := models.WebauthnCredentialUserHandle{}
err := p.db.Where("handle = ?", handle).First(&handleModel)
if err != nil && errors.Is(err, sql.ErrNoRows) {
return nil, nil
}
if err != nil {
return nil, fmt.Errorf("failed to get handleModel: %w", err)
}

return &handleModel, nil
}

0 comments on commit 306db83

Please sign in to comment.