Files
hanko/backend/handler/public_router.go
2023-03-31 09:00:16 +02:00

141 lines
5.1 KiB
Go

package handler
import (
"fmt"
"github.com/labstack/echo-contrib/prometheus"
"github.com/labstack/echo/v4"
"github.com/labstack/echo/v4/middleware"
"github.com/teamhanko/hanko/backend/audit_log"
"github.com/teamhanko/hanko/backend/config"
"github.com/teamhanko/hanko/backend/crypto/jwk"
"github.com/teamhanko/hanko/backend/dto"
"github.com/teamhanko/hanko/backend/mail"
middleware2 "github.com/teamhanko/hanko/backend/middleware"
"github.com/teamhanko/hanko/backend/persistence"
"github.com/teamhanko/hanko/backend/session"
)
func NewPublicRouter(cfg *config.Config, persister persistence.Persister, prometheus *prometheus.Prometheus) *echo.Echo {
e := echo.New()
e.HideBanner = true
e.HTTPErrorHandler = dto.NewHTTPErrorHandler(dto.HTTPErrorHandlerConfig{Debug: false, Logger: e.Logger})
e.Use(middleware.RequestID())
e.Use(middleware2.GetLoggerMiddleware())
if cfg.Server.Public.Cors.Enabled {
e.Use(middleware.CORSWithConfig(middleware.CORSConfig{
AllowOrigins: cfg.Server.Public.Cors.AllowOrigins,
AllowMethods: cfg.Server.Public.Cors.AllowMethods,
AllowHeaders: cfg.Server.Public.Cors.AllowHeaders,
ExposeHeaders: cfg.Server.Public.Cors.ExposeHeaders,
AllowCredentials: cfg.Server.Public.Cors.AllowCredentials,
MaxAge: cfg.Server.Public.Cors.MaxAge,
}))
}
if prometheus != nil {
e.Use(prometheus.HandlerFunc)
}
e.Validator = dto.NewCustomValidator()
jwkManager, err := jwk.NewDefaultManager(cfg.Secrets.Keys, persister.GetJwkPersister())
if err != nil {
panic(fmt.Errorf("failed to create jwk manager: %w", err))
}
sessionManager, err := session.NewManager(jwkManager, cfg.Session)
if err != nil {
panic(fmt.Errorf("failed to create session generator: %w", err))
}
mailer, err := mail.NewMailer(cfg.Passcode.Smtp)
if err != nil {
panic(fmt.Errorf("failed to create mailer: %w", err))
}
auditLogger := auditlog.NewLogger(persister, cfg.AuditLog)
if cfg.Password.Enabled {
passwordHandler := NewPasswordHandler(persister, sessionManager, cfg, auditLogger)
password := e.Group("/password")
password.PUT("", passwordHandler.Set, middleware2.Session(sessionManager))
password.POST("/login", passwordHandler.Login)
}
userHandler := NewUserHandler(cfg, persister, sessionManager, auditLogger)
e.GET("/me", userHandler.Me, middleware2.Session(sessionManager))
user := e.Group("/users")
user.POST("", userHandler.Create)
user.GET("/:id", userHandler.Get, middleware2.Session(sessionManager))
e.POST("/user", userHandler.GetUserIdByEmail)
e.POST("/logout", userHandler.Logout, middleware2.Session(sessionManager))
if cfg.Account.AllowDeletion {
e.DELETE("/user", userHandler.Delete, middleware2.Session(sessionManager))
}
healthHandler := NewHealthHandler()
webauthnHandler, err := NewWebauthnHandler(cfg, persister, sessionManager, auditLogger)
if err != nil {
panic(fmt.Errorf("failed to create public webauthn handler: %w", err))
}
passcodeHandler, err := NewPasscodeHandler(cfg, persister, sessionManager, mailer, auditLogger)
if err != nil {
panic(fmt.Errorf("failed to create public passcode handler: %w", err))
}
health := e.Group("/health")
health.GET("/alive", healthHandler.Alive)
health.GET("/ready", healthHandler.Ready)
wellKnownHandler, err := NewWellKnownHandler(*cfg, jwkManager)
if err != nil {
panic(fmt.Errorf("failed to create well-known handler: %w", err))
}
wellKnown := e.Group("/.well-known")
wellKnown.GET("/jwks.json", wellKnownHandler.GetPublicKeys)
wellKnown.GET("/config", wellKnownHandler.GetConfig)
emailHandler, err := NewEmailHandler(cfg, persister, sessionManager, auditLogger)
if err != nil {
panic(fmt.Errorf("failed to create public email handler: %w", err))
}
webauthn := e.Group("/webauthn")
webauthnRegistration := webauthn.Group("/registration", middleware2.Session(sessionManager))
webauthnRegistration.POST("/initialize", webauthnHandler.BeginRegistration)
webauthnRegistration.POST("/finalize", webauthnHandler.FinishRegistration)
webauthnLogin := webauthn.Group("/login")
webauthnLogin.POST("/initialize", webauthnHandler.BeginAuthentication)
webauthnLogin.POST("/finalize", webauthnHandler.FinishAuthentication)
webauthnCredentials := webauthn.Group("/credentials", middleware2.Session(sessionManager))
webauthnCredentials.GET("", webauthnHandler.ListCredentials)
webauthnCredentials.PATCH("/:id", webauthnHandler.UpdateCredential)
webauthnCredentials.DELETE("/:id", webauthnHandler.DeleteCredential)
passcode := e.Group("/passcode")
passcodeLogin := passcode.Group("/login")
passcodeLogin.POST("/initialize", passcodeHandler.Init)
passcodeLogin.POST("/finalize", passcodeHandler.Finish)
email := e.Group("/emails", middleware2.Session(sessionManager))
email.GET("", emailHandler.List)
email.POST("", emailHandler.Create)
email.DELETE("/:id", emailHandler.Delete)
email.POST("/:id/set_primary", emailHandler.SetPrimaryEmail)
thirdPartyHandler := NewThirdPartyHandler(cfg, persister, sessionManager, auditLogger, jwkManager)
thirdparty := e.Group("thirdparty")
thirdparty.GET("/auth", thirdPartyHandler.Auth)
thirdparty.GET("/callback", thirdPartyHandler.Callback)
return e
}