67 lines
2.9 KiB
Go
67 lines
2.9 KiB
Go
package auth
|
|
|
|
import (
|
|
"encoding/json"
|
|
|
|
"git.mstar.dev/mstar/goutils/sliceutils"
|
|
"github.com/go-webauthn/webauthn/webauthn"
|
|
"github.com/rs/zerolog/log"
|
|
|
|
"git.mstar.dev/mstar/linstrom/storage-new/models"
|
|
)
|
|
|
|
type fakeUser struct {
|
|
actualUser *models.User
|
|
}
|
|
|
|
// Ensure that fakeUser always implements webauthn.User
|
|
var _ webauthn.User = &fakeUser{}
|
|
|
|
// WebAuthnID provides the user handle of the user account. A user handle is an opaque byte sequence with a maximum
|
|
// size of 64 bytes, and is not meant to be displayed to the user.
|
|
//
|
|
// To ensure secure operation, authentication and authorization decisions MUST be made on the basis of this id
|
|
// member, not the displayName nor name members. See Section 6.1 of [RFC8266].
|
|
//
|
|
// It's recommended this value is completely random and uses the entire 64 bytes.
|
|
//
|
|
// Specification: §5.4.3. User Account Parameters for Credential Generation (https://w3c.github.io/webauthn/#dom-publickeycredentialuserentity-id)
|
|
func (fakeuser *fakeUser) WebAuthnID() []byte {
|
|
return fakeuser.actualUser.PasskeyId
|
|
}
|
|
|
|
// WebAuthnName provides the name attribute of the user account during registration and is a human-palatable name for the user
|
|
// account, intended only for display. For example, "Alex Müller" or "田中倫". The Relying Party SHOULD let the user
|
|
// choose this, and SHOULD NOT restrict the choice more than necessary.
|
|
//
|
|
// Specification: §5.4.3. User Account Parameters for Credential Generation (https://w3c.github.io/webauthn/#dictdef-publickeycredentialuserentity)
|
|
func (fakeuser *fakeUser) WebAuthnName() string {
|
|
return fakeuser.actualUser.DisplayName
|
|
}
|
|
|
|
// WebAuthnDisplayName provides the name attribute of the user account during registration and is a human-palatable
|
|
// name for the user account, intended only for display. For example, "Alex Müller" or "田中倫". The Relying Party
|
|
// SHOULD let the user choose this, and SHOULD NOT restrict the choice more than necessary.
|
|
//
|
|
// Specification: §5.4.3. User Account Parameters for Credential Generation (https://www.w3.org/TR/webauthn/#dom-publickeycredentialuserentity-displayname)
|
|
func (fakeuser *fakeUser) WebAuthnDisplayName() string {
|
|
return fakeuser.actualUser.DisplayName
|
|
}
|
|
|
|
// WebAuthnCredentials provides the list of Credential objects owned by the user.
|
|
func (fakeuser *fakeUser) WebAuthnCredentials() []webauthn.Credential {
|
|
// Basically just convert the relevant entries from the user to a credential
|
|
return sliceutils.Map(sliceutils.Filter(
|
|
fakeuser.actualUser.AuthMethods,
|
|
func(t models.UserAuthMethod) bool {
|
|
return t.AuthMethod == models.AuthMethodPasskey ||
|
|
t.AuthMethod == models.AuthMethodPasskey2fa
|
|
}), func(t models.UserAuthMethod) webauthn.Credential {
|
|
var c webauthn.Credential
|
|
if err := json.Unmarshal(t.Token, &c); err != nil {
|
|
// TODO: Is there any better way to handle the error here?
|
|
log.Error().Err(err).Msg("Failed to unmarshal webauthn credential")
|
|
}
|
|
return c
|
|
})
|
|
}
|