mirror of
https://github.com/thomiceli/opengist.git
synced 2024-12-23 04:52:40 +00:00
150 lines
4.1 KiB
Go
150 lines
4.1 KiB
Go
|
package db
|
||
|
|
||
|
import (
|
||
|
"encoding/hex"
|
||
|
"github.com/go-webauthn/webauthn/webauthn"
|
||
|
"time"
|
||
|
)
|
||
|
|
||
|
type WebAuthnCredential struct {
|
||
|
ID uint `gorm:"primaryKey"`
|
||
|
Name string
|
||
|
UserID uint
|
||
|
User User
|
||
|
CredentialID binaryData `gorm:"type:binary_data"`
|
||
|
PublicKey binaryData `gorm:"type:binary_data"`
|
||
|
AttestationType string
|
||
|
AAGUID binaryData `gorm:"type:binary_data"`
|
||
|
SignCount uint32
|
||
|
CloneWarning bool
|
||
|
FlagUserPresent bool
|
||
|
FlagUserVerified bool
|
||
|
FlagBackupEligible bool
|
||
|
FlagBackupState bool
|
||
|
CreatedAt int64
|
||
|
LastUsedAt int64
|
||
|
}
|
||
|
|
||
|
func (*WebAuthnCredential) TableName() string {
|
||
|
return "webauthn"
|
||
|
}
|
||
|
|
||
|
func GetAllWACredentialsForUser(userID uint) ([]webauthn.Credential, error) {
|
||
|
var creds []WebAuthnCredential
|
||
|
err := db.Where("user_id = ?", userID).Find(&creds).Error
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
webCreds := make([]webauthn.Credential, len(creds))
|
||
|
for i, cred := range creds {
|
||
|
webCreds[i] = webauthn.Credential{
|
||
|
ID: cred.CredentialID,
|
||
|
PublicKey: cred.PublicKey,
|
||
|
AttestationType: cred.AttestationType,
|
||
|
Authenticator: webauthn.Authenticator{
|
||
|
AAGUID: cred.AAGUID,
|
||
|
SignCount: cred.SignCount,
|
||
|
CloneWarning: cred.CloneWarning,
|
||
|
},
|
||
|
Flags: webauthn.CredentialFlags{
|
||
|
UserPresent: cred.FlagUserPresent,
|
||
|
UserVerified: cred.FlagUserVerified,
|
||
|
BackupEligible: cred.FlagBackupEligible,
|
||
|
BackupState: cred.FlagBackupState,
|
||
|
},
|
||
|
}
|
||
|
}
|
||
|
return webCreds, nil
|
||
|
}
|
||
|
|
||
|
func GetAllCredentialsForUser(userID uint) ([]WebAuthnCredential, error) {
|
||
|
var creds []WebAuthnCredential
|
||
|
err := db.Where("user_id = ?", userID).Find(&creds).Error
|
||
|
return creds, err
|
||
|
}
|
||
|
|
||
|
func GetUserByCredentialID(credID binaryData) (*User, error) {
|
||
|
var credential WebAuthnCredential
|
||
|
var err error
|
||
|
|
||
|
switch db.Dialector.Name() {
|
||
|
case "postgres":
|
||
|
hexCredID := hex.EncodeToString(credID)
|
||
|
if err = db.Preload("User").Where("credential_id = decode(?, 'hex')", hexCredID).First(&credential).Error; err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
case "mysql":
|
||
|
case "sqlite":
|
||
|
hexCredID := hex.EncodeToString(credID)
|
||
|
if err = db.Preload("User").Where("credential_id = unhex(?)", hexCredID).First(&credential).Error; err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return &credential.User, err
|
||
|
}
|
||
|
|
||
|
func GetCredentialByIDDB(id uint) (*WebAuthnCredential, error) {
|
||
|
var cred WebAuthnCredential
|
||
|
err := db.Where("id = ?", id).First(&cred).Error
|
||
|
return &cred, err
|
||
|
}
|
||
|
|
||
|
func GetCredentialByID(id binaryData) (*WebAuthnCredential, error) {
|
||
|
var cred WebAuthnCredential
|
||
|
var err error
|
||
|
|
||
|
switch db.Dialector.Name() {
|
||
|
case "postgres":
|
||
|
hexCredID := hex.EncodeToString(id)
|
||
|
if err = db.Where("credential_id = decode(?, 'hex')", hexCredID).First(&cred).Error; err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
case "mysql":
|
||
|
case "sqlite":
|
||
|
hexCredID := hex.EncodeToString(id)
|
||
|
if err = db.Where("credential_id = unhex(?)", hexCredID).First(&cred).Error; err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return &cred, err
|
||
|
}
|
||
|
|
||
|
func CreateFromCrendential(userID uint, name string, cred *webauthn.Credential) (*WebAuthnCredential, error) {
|
||
|
credDb := &WebAuthnCredential{
|
||
|
UserID: userID,
|
||
|
Name: name,
|
||
|
CredentialID: cred.ID,
|
||
|
PublicKey: cred.PublicKey,
|
||
|
AttestationType: cred.AttestationType,
|
||
|
AAGUID: cred.Authenticator.AAGUID,
|
||
|
SignCount: cred.Authenticator.SignCount,
|
||
|
CloneWarning: cred.Authenticator.CloneWarning,
|
||
|
FlagUserPresent: cred.Flags.UserPresent,
|
||
|
FlagUserVerified: cred.Flags.UserVerified,
|
||
|
FlagBackupEligible: cred.Flags.BackupEligible,
|
||
|
FlagBackupState: cred.Flags.BackupState,
|
||
|
}
|
||
|
err := db.Create(credDb).Error
|
||
|
return credDb, err
|
||
|
}
|
||
|
|
||
|
func (w *WebAuthnCredential) UpdateSignCount() error {
|
||
|
return db.Model(w).Update("sign_count", w.SignCount).Error
|
||
|
}
|
||
|
|
||
|
func (w *WebAuthnCredential) UpdateLastUsedAt() error {
|
||
|
return db.Model(w).Update("last_used_at", time.Now().Unix()).Error
|
||
|
}
|
||
|
|
||
|
func (w *WebAuthnCredential) Delete() error {
|
||
|
return db.Delete(w).Error
|
||
|
}
|
||
|
|
||
|
// -- DTO -- //
|
||
|
|
||
|
type CrendentialDTO struct {
|
||
|
PasskeyName string `json:"passkeyname" validate:"max=50"`
|
||
|
}
|