Skip to content

Commit

Permalink
Merge pull request #42 from teamhanko/feat/improve-passkey-naming
Browse files Browse the repository at this point in the history
feat(passkeys): improve passkey naming
  • Loading branch information
shentschel authored Feb 12, 2024
2 parents 628b230 + ce7ea32 commit 48ef33a
Show file tree
Hide file tree
Showing 13 changed files with 265 additions and 34 deletions.
2 changes: 2 additions & 0 deletions server/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ COPY commands commands
COPY config config
COPY crypto crypto
COPY persistence persistence
COPY mapper mapper
COPY utils utils

# Build
RUN go generate ./...
Expand Down
5 changes: 3 additions & 2 deletions server/api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,15 @@ import (
"github.com/labstack/echo/v4"
"github.com/teamhanko/passkey-server/api/router"
"github.com/teamhanko/passkey-server/config"
"github.com/teamhanko/passkey-server/mapper"
"github.com/teamhanko/passkey-server/persistence"
"sync"
)

func StartPublic(cfg *config.Config, wg *sync.WaitGroup, persister persistence.Persister) {
func StartPublic(cfg *config.Config, wg *sync.WaitGroup, persister persistence.Persister, authenticatorMetadata mapper.AuthenticatorMetadata) {
defer wg.Done()

mainRouter := router.NewMainRouter(cfg, persister)
mainRouter := router.NewMainRouter(cfg, persister, authenticatorMetadata)
mainRouter.Logger.Fatal(mainRouter.Start(cfg.Address))
}

Expand Down
11 changes: 8 additions & 3 deletions server/api/dto/intern/webauthn_credential.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,24 @@ import (
"github.com/go-webauthn/webauthn/protocol"
"github.com/go-webauthn/webauthn/webauthn"
"github.com/gofrs/uuid"
"github.com/teamhanko/passkey-server/mapper"
"github.com/teamhanko/passkey-server/persistence/models"
"time"
)

func WebauthnCredentialToModel(credential *webauthn.Credential, userId string, webauthnUserId uuid.UUID, backupEligible bool, backupState bool) *models.WebauthnCredential {
func WebauthnCredentialToModel(credential *webauthn.Credential, userId string, webauthnUserId uuid.UUID, backupEligible bool, backupState bool, authenticatorMetadata mapper.AuthenticatorMetadata) *models.WebauthnCredential {
now := time.Now().UTC()
aaguid, _ := uuid.FromBytes(credential.Authenticator.AAGUID)
credentialID := base64.RawURLEncoding.EncodeToString(credential.ID)
name := fmt.Sprintf("cred-%s", credentialID)
name := authenticatorMetadata.GetNameForAaguid(aaguid)
if name == nil {
genericName := fmt.Sprintf("cred-%s", credentialID)
name = &genericName
}

c := &models.WebauthnCredential{
ID: credentialID,
Name: &name,
Name: name,
UserId: userId,
PublicKey: base64.RawURLEncoding.EncodeToString(credential.PublicKey),
AttestationType: credential.AttestationType,
Expand Down
20 changes: 12 additions & 8 deletions server/api/handler/registration.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,23 @@ import (
"github.com/teamhanko/passkey-server/api/dto/response"
"github.com/teamhanko/passkey-server/api/helper"
"github.com/teamhanko/passkey-server/api/services"
"github.com/teamhanko/passkey-server/mapper"
"github.com/teamhanko/passkey-server/persistence"
"github.com/teamhanko/passkey-server/persistence/models"
"net/http"
)

type registrationHandler struct {
*webauthnHandler
mapper.AuthenticatorMetadata
}

func NewRegistrationHandler(persister persistence.Persister) WebauthnHandler {
func NewRegistrationHandler(persister persistence.Persister, authenticatorMetadata mapper.AuthenticatorMetadata) WebauthnHandler {
webauthnHandler := newWebAuthnHandler(persister)

return &registrationHandler{
webauthnHandler,
authenticatorMetadata,
}
}

Expand Down Expand Up @@ -88,13 +91,14 @@ func (r *registrationHandler) Finish(ctx echo.Context) error {
credentialPersister := r.persister.GetWebauthnCredentialPersister(tx)

service := services.NewRegistrationService(services.WebauthnServiceCreateParams{
Ctx: ctx,
Tenant: *h.Tenant,
WebauthnClient: *h.Webauthn,
UserPersister: userPersister,
SessionPersister: sessionPersister,
CredentialPersister: credentialPersister,
Generator: h.Generator,
Ctx: ctx,
Tenant: *h.Tenant,
WebauthnClient: *h.Webauthn,
UserPersister: userPersister,
SessionPersister: sessionPersister,
CredentialPersister: credentialPersister,
Generator: h.Generator,
AuthenticatorMetadata: r.AuthenticatorMetadata,
})

token, userId, err := service.Finalize(parsedRequest)
Expand Down
9 changes: 5 additions & 4 deletions server/api/router/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"github.com/teamhanko/passkey-server/api/template"
"github.com/teamhanko/passkey-server/api/validators"
"github.com/teamhanko/passkey-server/config"
"github.com/teamhanko/passkey-server/mapper"
"github.com/teamhanko/passkey-server/persistence"
)

Expand All @@ -16,7 +17,7 @@ const (
FinishEndpoint = "/finalize"
)

func NewMainRouter(cfg *config.Config, persister persistence.Persister) *echo.Echo {
func NewMainRouter(cfg *config.Config, persister persistence.Persister, authenticatorMetadata mapper.AuthenticatorMetadata) *echo.Echo {
main := echo.New()
main.Renderer = template.NewTemplateRenderer()
main.HideBanner = true
Expand Down Expand Up @@ -45,7 +46,7 @@ func NewMainRouter(cfg *config.Config, persister persistence.Persister) *echo.Ec

RouteWellKnown(tenantGroup)
RouteCredentials(tenantGroup, persister)
RouteRegistration(tenantGroup, persister)
RouteRegistration(tenantGroup, persister, authenticatorMetadata)
RouteLogin(tenantGroup, persister)
RouteTransaction(tenantGroup, persister)

Expand Down Expand Up @@ -78,8 +79,8 @@ func RouteCredentials(parent *echo.Group, persister persistence.Persister) {
return
}

func RouteRegistration(parent *echo.Group, persister persistence.Persister) {
registrationHandler := handler.NewRegistrationHandler(persister)
func RouteRegistration(parent *echo.Group, persister persistence.Persister, authenticatorMetadata mapper.AuthenticatorMetadata) {
registrationHandler := handler.NewRegistrationHandler(persister, authenticatorMetadata)

group := parent.Group("/registration", passkeyMiddleware.WebauthnMiddleware())
group.POST(InitEndpoint, registrationHandler.Init, passkeyMiddleware.ApiKeyMiddleware())
Expand Down
7 changes: 6 additions & 1 deletion server/api/services/registration_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"github.com/go-webauthn/webauthn/webauthn"
"github.com/labstack/echo/v4"
"github.com/teamhanko/passkey-server/api/dto/intern"
"github.com/teamhanko/passkey-server/mapper"
"github.com/teamhanko/passkey-server/persistence/models"
"net/http"
"strings"
Expand All @@ -20,6 +21,7 @@ type RegistrationService interface {

type registrationService struct {
WebauthnService
mapper.AuthenticatorMetadata
}

func NewRegistrationService(params WebauthnServiceCreateParams) RegistrationService {
Expand All @@ -38,6 +40,7 @@ func NewRegistrationService(params WebauthnServiceCreateParams) RegistrationServ
userPersister: params.UserPersister,
sessionDataPersister: params.SessionPersister,
},
params.AuthenticatorMetadata,
}
}

Expand Down Expand Up @@ -201,7 +204,9 @@ func (rs *registrationService) createCredential(dbUser *models.WebauthnUser, ses
session.UserId,
dbUser.ID,
flags.HasBackupEligible(),
flags.HasBackupState())
flags.HasBackupState(),
rs.AuthenticatorMetadata,
)

err = rs.credentialPersister.Create(dbCredential)
if err != nil {
Expand Down
10 changes: 6 additions & 4 deletions server/api/services/webauthn_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"github.com/labstack/echo/v4"
"github.com/teamhanko/passkey-server/api/dto/intern"
"github.com/teamhanko/passkey-server/crypto/jwt"
"github.com/teamhanko/passkey-server/mapper"
"github.com/teamhanko/passkey-server/persistence/models"
"github.com/teamhanko/passkey-server/persistence/persisters"
"net/http"
Expand All @@ -25,10 +26,11 @@ type WebauthnService struct {
}

type WebauthnServiceCreateParams struct {
Ctx echo.Context
Tenant models.Tenant
WebauthnClient webauthn.WebAuthn
Generator jwt.Generator
Ctx echo.Context
Tenant models.Tenant
WebauthnClient webauthn.WebAuthn
Generator jwt.Generator
AuthenticatorMetadata mapper.AuthenticatorMetadata

UserPersister persisters.WebauthnUserPersister
SessionPersister persisters.WebauthnSessionDataPersister
Expand Down
9 changes: 7 additions & 2 deletions server/commands/serve/all.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,16 @@ import (
"github.com/spf13/cobra"
"github.com/teamhanko/passkey-server/api"
"github.com/teamhanko/passkey-server/config"
"github.com/teamhanko/passkey-server/mapper"
"github.com/teamhanko/passkey-server/persistence"
"log"
"sync"
)

func NewServeAllCommand() *cobra.Command {
var (
configFile string
configFile string
authenticatorMetadataFile string
)

cmd := &cobra.Command{
Expand All @@ -25,6 +27,8 @@ func NewServeAllCommand() *cobra.Command {
log.Fatal(err)
}

authenticatorMetadata := mapper.LoadAuthenticatorMetadata(&authenticatorMetadataFile)

persister, err := persistence.NewDatabase(cfg.Database)
if err != nil {
log.Fatal(err)
Expand All @@ -34,14 +38,15 @@ func NewServeAllCommand() *cobra.Command {

prometheus := echoprometheus.NewMiddleware("hanko")

go api.StartPublic(cfg, &wg, persister)
go api.StartPublic(cfg, &wg, persister, authenticatorMetadata)
go api.StartAdmin(cfg, &wg, persister, prometheus)

wg.Wait()
},
}

cmd.Flags().StringVar(&configFile, "config", config.DefaultConfigFilePath, "config file")
cmd.Flags().StringVar(&authenticatorMetadataFile, "auth-meta", "", "authenticator metadata file")

return cmd
}
11 changes: 9 additions & 2 deletions server/commands/serve/public.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,17 @@ import (
"github.com/spf13/cobra"
"github.com/teamhanko/passkey-server/api"
"github.com/teamhanko/passkey-server/config"
"github.com/teamhanko/passkey-server/mapper"
"github.com/teamhanko/passkey-server/persistence"
"log"
"sync"
)

func NewServePublicCommand() *cobra.Command {
var configFile string
var (
configFile string
authenticatorMetadataFile string
)

cmd := &cobra.Command{
Use: "public",
Expand All @@ -22,6 +26,8 @@ func NewServePublicCommand() *cobra.Command {
log.Fatal(err)
}

authenticatorMetadata := mapper.LoadAuthenticatorMetadata(&authenticatorMetadataFile)

persister, err := persistence.NewDatabase(globalConfig.Database)
if err != nil {
log.Fatal(err)
Expand All @@ -30,13 +36,14 @@ func NewServePublicCommand() *cobra.Command {
var wg sync.WaitGroup
wg.Add(1)

go api.StartPublic(globalConfig, &wg, persister)
go api.StartPublic(globalConfig, &wg, persister, authenticatorMetadata)

wg.Wait()
},
}

cmd.Flags().StringVar(&configFile, "config", config.DefaultConfigFilePath, "config file")
cmd.Flags().StringVar(&authenticatorMetadataFile, "auth-meta", "", "authenticator metadata file")

return cmd
}
15 changes: 7 additions & 8 deletions server/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,8 @@ import (
"errors"
"fmt"
"github.com/kelseyhightower/envconfig"
"github.com/knadh/koanf"
"github.com/knadh/koanf/parsers/yaml"
"github.com/knadh/koanf/providers/file"
"github.com/teamhanko/passkey-server/utils"
"log"
"net"
"strings"
Expand Down Expand Up @@ -49,16 +48,16 @@ func (c *Config) Validate() error {
}

func Load(configFile *string) (*Config, error) {
k := koanf.New(".")

var err error

if configFile == nil || strings.TrimSpace(*configFile) == "" {
*configFile = DefaultConfigFilePath
}

if err = k.Load(file.Provider(*configFile), yaml.Parser()); err != nil {
return nil, fmt.Errorf("failed to load config from: %s: %w", *configFile, err)
k, err := utils.LoadFile(configFile, yaml.Parser())
if err != nil {
if *configFile != DefaultConfigFilePath {
return nil, fmt.Errorf("failed to load config from: %s: %w", *configFile, err)
}
log.Println("failed to load config, skipping...")
} else {
log.Println("Using config file:", *configFile)
}
Expand Down
Loading

0 comments on commit 48ef33a

Please sign in to comment.