Skip to content

Commit

Permalink
chore(webauthn): change user_id from uuid.UUID to string
Browse files Browse the repository at this point in the history
Related to: #5
  • Loading branch information
Stefan Jacobi committed Nov 8, 2023
1 parent 8cc2f71 commit 87f38e3
Show file tree
Hide file tree
Showing 15 changed files with 38 additions and 41 deletions.
2 changes: 1 addition & 1 deletion server/api/dto/intern/webauthn_credential.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import (
"time"
)

func WebauthnCredentialToModel(credential *webauthn.Credential, userId uuid.UUID, webauthnUserId uuid.UUID, backupEligible bool, backupState bool) *models.WebauthnCredential {
func WebauthnCredentialToModel(credential *webauthn.Credential, userId string, webauthnUserId uuid.UUID, backupEligible bool, backupState bool) *models.WebauthnCredential {
now := time.Now().UTC()
aaguid, _ := uuid.FromBytes(credential.Authenticator.AAGUID)
credentialID := base64.RawURLEncoding.EncodeToString(credential.ID)
Expand Down
8 changes: 4 additions & 4 deletions server/api/dto/intern/webauthn_session_data.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"github.com/gobuffalo/nulls"
"github.com/gofrs/uuid"
"github.com/teamhanko/passkey-server/persistence/models"
"strings"
"time"
)

Expand All @@ -20,8 +21,8 @@ func WebauthnSessionDataFromModel(data *models.WebauthnSessionData) *webauthn.Se
allowedCredentials = append(allowedCredentials, credentialId)
}
var userId []byte = nil
if !data.UserId.IsNil() {
userId = data.UserId.Bytes()
if strings.TrimSpace(data.UserId) != "" {
userId = []byte(data.UserId)
}
return &webauthn.SessionData{
Challenge: data.Challenge,
Expand All @@ -34,7 +35,6 @@ func WebauthnSessionDataFromModel(data *models.WebauthnSessionData) *webauthn.Se

func WebauthnSessionDataToModel(data *webauthn.SessionData, tenantId uuid.UUID, operation models.Operation) *models.WebauthnSessionData {
id, _ := uuid.NewV4()
userId, _ := uuid.FromBytes(data.UserID)
now := time.Now()

var allowedCredentials []models.WebauthnSessionDataAllowedCredential
Expand All @@ -54,7 +54,7 @@ func WebauthnSessionDataToModel(data *webauthn.SessionData, tenantId uuid.UUID,
return &models.WebauthnSessionData{
ID: id,
Challenge: data.Challenge,
UserId: userId,
UserId: string(data.UserID),
UserVerification: string(data.UserVerification),
CreatedAt: now,
UpdatedAt: now,
Expand Down
5 changes: 2 additions & 3 deletions server/api/dto/intern/webauthn_user.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,11 @@ package intern

import (
"github.com/go-webauthn/webauthn/webauthn"
"github.com/gofrs/uuid"
"github.com/teamhanko/passkey-server/persistence/models"
)

type WebauthnUser struct {
UserId uuid.UUID
UserId string
Name string
Icon string
DisplayName string
Expand All @@ -25,7 +24,7 @@ func NewWebauthnUser(user models.WebauthnUser) *WebauthnUser {
}

func (u *WebauthnUser) WebAuthnID() []byte {
return u.UserId.Bytes()
return []byte(u.UserId)
}

func (u *WebauthnUser) WebAuthnName() string {
Expand Down
2 changes: 1 addition & 1 deletion server/api/dto/request/requests.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ type UpdateCredentialsDto struct {
}

type InitRegistrationDto struct {
UserId string `json:"user_id" validate:"required,uuid4"`
UserId string `json:"user_id" validate:"required"`
Username string `json:"username" validate:"required"`
DisplayName *string `json:"display_name"`
Icon *string `json:"icon"`
Expand Down
7 changes: 1 addition & 6 deletions server/api/handler/login.go
Original file line number Diff line number Diff line change
Expand Up @@ -154,12 +154,7 @@ func (lh *loginHandler) getSessionDataByChallenge(challenge string, persister pe
}

func (lh *loginHandler) getWebauthnUserByUserHandle(userHandle []byte, tenantId uuid.UUID, persister persisters.WebauthnUserPersister) (*intern.WebauthnUser, error) {
userId, err := uuid.FromBytes(userHandle)
if err != nil {
return nil, echo.NewHTTPError(http.StatusBadRequest, "failed to parse userHandle as uuid").SetInternal(err)
}

user, err := persister.GetByUserId(userId, tenantId)
user, err := persister.GetByUserId(string(userHandle), tenantId)
if err != nil {
return nil, fmt.Errorf("failed to get user: %w", err)
}
Expand Down
2 changes: 1 addition & 1 deletion server/api/handler/registration.go
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ func (r *registrationHandler) getSessionByChallenge(challenge string, tenantId u
return sessionData, nil
}

func (r *registrationHandler) GetWebauthnUser(userId uuid.UUID, tenantId uuid.UUID, persister persisters.WebauthnUserPersister) (*intern.WebauthnUser, *models.WebauthnUser, error) {
func (r *registrationHandler) GetWebauthnUser(userId string, tenantId uuid.UUID, persister persisters.WebauthnUserPersister) (*intern.WebauthnUser, *models.WebauthnUser, error) {
user, err := persister.GetByUserId(userId, tenantId)
if err != nil {
return nil, nil, err
Expand Down
14 changes: 7 additions & 7 deletions server/audit_log/logger.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ import (
)

type Logger interface {
Create(echo.Context, *models.Tenant, models.AuditLogType, *uuid.UUID, error) error
CreateWithConnection(*pop.Connection, echo.Context, *models.Tenant, models.AuditLogType, *uuid.UUID, error) error
Create(echo.Context, *models.Tenant, models.AuditLogType, *string, error) error
CreateWithConnection(*pop.Connection, echo.Context, *models.Tenant, models.AuditLogType, *string, error) error
}

type logger struct {
Expand Down Expand Up @@ -46,11 +46,11 @@ func NewLogger(persister persistence.Persister, cfg models.AuditLogConfig) Logge
}
}

func (l *logger) Create(context echo.Context, tenant *models.Tenant, auditLogType models.AuditLogType, user *uuid.UUID, logError error) error {
func (l *logger) Create(context echo.Context, tenant *models.Tenant, auditLogType models.AuditLogType, user *string, logError error) error {
return l.CreateWithConnection(l.persister.GetConnection(), context, tenant, auditLogType, user, logError)
}

func (l *logger) CreateWithConnection(tx *pop.Connection, context echo.Context, tenant *models.Tenant, auditLogType models.AuditLogType, user *uuid.UUID, logError error) error {
func (l *logger) CreateWithConnection(tx *pop.Connection, context echo.Context, tenant *models.Tenant, auditLogType models.AuditLogType, user *string, logError error) error {
if l.storageEnabled {
err := l.store(tx, context, tenant, auditLogType, user, logError)
if err != nil {
Expand All @@ -65,7 +65,7 @@ func (l *logger) CreateWithConnection(tx *pop.Connection, context echo.Context,
return nil
}

func (l *logger) store(tx *pop.Connection, context echo.Context, tenant *models.Tenant, auditLogType models.AuditLogType, user *uuid.UUID, logError error) error {
func (l *logger) store(tx *pop.Connection, context echo.Context, tenant *models.Tenant, auditLogType models.AuditLogType, user *string, logError error) error {
id, err := uuid.NewV4()
if err != nil {
return fmt.Errorf("failed to create id: %w", err)
Expand Down Expand Up @@ -94,7 +94,7 @@ func (l *logger) store(tx *pop.Connection, context echo.Context, tenant *models.
return l.persister.GetAuditLogPersister(tx).Create(al)
}

func (l *logger) logToConsole(context echo.Context, tenant *models.Tenant, auditLogType models.AuditLogType, user *uuid.UUID, logError error) {
func (l *logger) logToConsole(context echo.Context, tenant *models.Tenant, auditLogType models.AuditLogType, user *string, logError error) {
now := time.Now()
loggerEvent := zeroLogger.Log().
Str("audience", "audit").
Expand All @@ -108,7 +108,7 @@ func (l *logger) logToConsole(context echo.Context, tenant *models.Tenant, audit
Str("time_unix", strconv.FormatInt(now.Unix(), 10))

if user != nil {
loggerEvent.Str("user_id", user.String())
loggerEvent.Str("user_id", *user)
}

loggerEvent.Send()
Expand Down
6 changes: 3 additions & 3 deletions server/crypto/jwt/jwt.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import (
type Generator interface {
Sign(jwt.Token) ([]byte, error)
Verify([]byte) (jwt.Token, error)
Generate(userId uuid.UUID, crendetialId string) (string, error)
Generate(userId string, crendetialId string) (string, error)
}

// Generator is used to sign and verify JWTs
Expand Down Expand Up @@ -66,11 +66,11 @@ func (g *generator) Verify(signed []byte) (jwt.Token, error) {
return token, nil
}

func (g *generator) Generate(userId uuid.UUID, credentialId string) (string, error) {
func (g *generator) Generate(userId string, credentialId string) (string, error) {
issuedAt := time.Now()

token := jwt.New()
_ = token.Set(jwt.SubjectKey, userId.String())
_ = token.Set(jwt.SubjectKey, userId)
_ = token.Set(jwt.IssuedAtKey, issuedAt)
_ = token.Set(jwt.AudienceKey, []string{g.config.RelyingParty.RPId})
_ = token.Set("cred", credentialId)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
change_column("webauthn_users", "user_id", "uuid", {})
change_column("webauthn_credentials", "user_id", "uuid", {})
change_column("webauthn_session_data", "user_id", "uuid", {})
change_column("audit_logs", "actor_user_id", "uuid", { "null": true })
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
change_column("webauthn_users", "user_id", "string", {})
change_column("webauthn_credentials", "user_id", "string", {})
change_column("webauthn_session_data", "user_id", "string", {})
change_column("audit_logs", "actor_user_id", "string", { "null": true })
2 changes: 1 addition & 1 deletion server/persistence/models/audit_log.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ type AuditLog struct {
MetaHttpRequestId string `db:"meta_http_request_id" json:"meta_http_request_id"`
MetaSourceIp string `db:"meta_source_ip" json:"meta_source_ip"`
MetaUserAgent string `db:"meta_user_agent" json:"meta_user_agent"`
ActorUserId *uuid.UUID `db:"actor_user_id" json:"actor_user_id,omitempty"`
ActorUserId *string `db:"actor_user_id" json:"actor_user_id,omitempty"`
CreatedAt time.Time `db:"created_at" json:"created_at"`
UpdatedAt time.Time `db:"updated_at" json:"updated_at"`
Tenant *Tenant `json:"tenant" belongs_to:"tenants"`
Expand Down
4 changes: 2 additions & 2 deletions server/persistence/models/webauthn_credential.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import (
// WebauthnCredential is used by pop to map your webauthn_credentials database table to your go code.
type WebauthnCredential struct {
ID string `db:"id" json:"id"`
UserId uuid.UUID `db:"user_id" json:"-"`
UserId string `db:"user_id" json:"-"`
Name *string `db:"name" json:"-"`
PublicKey string `db:"public_key" json:"-"`
AttestationType string `db:"attestation_type" json:"-"`
Expand All @@ -35,7 +35,7 @@ type WebauthnCredentials []WebauthnCredential
func (credential *WebauthnCredential) Validate(tx *pop.Connection) (*validate.Errors, error) {
return validate.Validate(
&validators.StringIsPresent{Name: "ID", Field: credential.ID},
&validators.UUIDIsPresent{Name: "UserId", Field: credential.UserId},
&validators.StringIsPresent{Name: "UserId", Field: credential.UserId},
&validators.StringIsPresent{Name: "PublicKey", Field: credential.PublicKey},
&validators.IntIsGreaterThan{Name: "SignCount", Field: credential.SignCount, Compared: -1},
&validators.TimeIsPresent{Name: "CreatedAt", Field: credential.CreatedAt},
Expand Down
2 changes: 1 addition & 1 deletion server/persistence/models/webauthn_session_data.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ var (
// WebauthnSessionData is used by pop to map your webauthn_session_data database table to your go code.
type WebauthnSessionData struct {
ID uuid.UUID `db:"id"`
UserId uuid.UUID `db:"user_id" json:"-"`
UserId string `db:"user_id" json:"-"`
Challenge string `db:"challenge"`
UserVerification string `db:"user_verification"`
CreatedAt time.Time `db:"created_at"`
Expand Down
13 changes: 4 additions & 9 deletions server/persistence/models/webauthn_user.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import (
// WebauthnUser is used by pop to map your webauthn_users database table to your go code.
type WebauthnUser struct {
ID uuid.UUID `json:"id" db:"id"`
UserID uuid.UUID `json:"user_id" db:"user_id"`
UserID string `json:"user_id" db:"user_id"`
Name string `json:"name" db:"name"`
Icon string `json:"icon" db:"icon"`
DisplayName string `json:"display_name" db:"display_name"`
Expand All @@ -29,7 +29,7 @@ type WebauthnUser struct {
type WebauthnUsers []WebauthnUser

func (webauthnUser *WebauthnUser) WebAuthnID() []byte {
return webauthnUser.UserID.Bytes()
return []byte(webauthnUser.UserID)
}

func (webauthnUser *WebauthnUser) WebAuthnName() string {
Expand All @@ -49,7 +49,7 @@ func (webauthnUser *WebauthnUser) WebAuthnIcon() string {
func (webauthnUser *WebauthnUser) Validate(tx *pop.Connection) (*validate.Errors, error) {
return validate.Validate(
&validators.UUIDIsPresent{Name: "ID", Field: webauthnUser.ID},
&validators.UUIDIsPresent{Name: "UserID", Field: webauthnUser.UserID},
&validators.StringIsPresent{Name: "UserID", Field: webauthnUser.UserID},
&validators.StringIsPresent{Name: "Name", Field: webauthnUser.Name},
&validators.StringIsPresent{Name: "DisplayName", Field: webauthnUser.DisplayName},
&validators.TimeIsPresent{Name: "UpdatedAt", Field: webauthnUser.UpdatedAt},
Expand All @@ -73,16 +73,11 @@ func FromRegistrationDto(dto *request.InitRegistrationDto) (*WebauthnUser, error
return nil, err
}

userId, err := uuid.FromString(dto.UserId)
if err != nil {
return nil, err
}

now := time.Now()

return &WebauthnUser{
ID: webauthnId,
UserID: userId,
UserID: dto.UserId,
Name: dto.Username,
Icon: icon,
DisplayName: displayName,
Expand Down
4 changes: 2 additions & 2 deletions server/persistence/persisters/webauthn_user_persister.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import (
type WebauthnUserPersister interface {
Create(webauthnUser *models.WebauthnUser) error
Get(id uuid.UUID) (*models.WebauthnUser, error)
GetByUserId(userId uuid.UUID, tenantId uuid.UUID) (*models.WebauthnUser, error)
GetByUserId(userId string, tenantId uuid.UUID) (*models.WebauthnUser, error)
Delete(webauthnUser *models.WebauthnUser) error
}

Expand Down Expand Up @@ -64,7 +64,7 @@ func (p *webauthnUserPersister) Delete(webauthnUser *models.WebauthnUser) error
return nil
}

func (p *webauthnUserPersister) GetByUserId(userId uuid.UUID, tenantId uuid.UUID) (*models.WebauthnUser, error) {
func (p *webauthnUserPersister) GetByUserId(userId string, tenantId uuid.UUID) (*models.WebauthnUser, error) {
weauthnUser := models.WebauthnUser{}
err := p.database.Eager().Where("user_id = ? AND tenant_id = ?", userId, tenantId).First(&weauthnUser)
if err != nil && errors.Is(err, sql.ErrNoRows) {
Expand Down

0 comments on commit 87f38e3

Please sign in to comment.