Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(passkeys): improve passkey naming #42

Merged
merged 1 commit into from
Feb 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading