Files
golib/hwsauth/authenticator.go
2026-01-13 18:07:11 +11:00

108 lines
2.8 KiB
Go

package hwsauth
import (
"git.haelnorr.com/h/golib/hlog"
"git.haelnorr.com/h/golib/hws"
"git.haelnorr.com/h/golib/jwt"
"github.com/pkg/errors"
)
type Authenticator[T Model, TX DBTransaction] struct {
tokenGenerator *jwt.TokenGenerator
load LoadFunc[T, TX]
beginTx BeginTX
ignoredPaths []string
logger *hlog.Logger
server *hws.Server
errorPage hws.ErrorPageFunc
SSL bool // Use SSL for JWT tokens. Default true
LandingPage string // Path of the desired landing page for logged in users
}
// NewAuthenticator creates and returns a new Authenticator using the provided configuration.
// If cfg is nil or any required fields are not set, default values will be used or an error returned.
// Required fields: SecretKey (no default)
// If SSL is true, TrustedHost is also required.
func NewAuthenticator[T Model, TX DBTransaction](
cfg *Config,
load LoadFunc[T, TX],
server *hws.Server,
beginTx BeginTX,
logger *hlog.Logger,
errorPage hws.ErrorPageFunc,
) (*Authenticator[T, TX], error) {
if load == nil {
return nil, errors.New("No function to load model supplied")
}
if server == nil {
return nil, errors.New("No hws.Server provided")
}
if beginTx == nil {
return nil, errors.New("No beginTx function provided")
}
if logger == nil {
return nil, errors.New("No logger provided")
}
if errorPage == nil {
return nil, errors.New("No ErrorPage provided")
}
// Validate config
if cfg == nil {
return nil, errors.New("Config is required")
}
if cfg.SecretKey == "" {
return nil, errors.New("SecretKey is required")
}
if cfg.SSL && cfg.TrustedHost == "" {
return nil, errors.New("TrustedHost is required when SSL is enabled")
}
if cfg.AccessTokenExpiry == 0 {
cfg.AccessTokenExpiry = 5
}
if cfg.RefreshTokenExpiry == 0 {
cfg.RefreshTokenExpiry = 1440
}
if cfg.TokenFreshTime == 0 {
cfg.TokenFreshTime = 5
}
if cfg.LandingPage == "" {
cfg.LandingPage = "/profile"
}
// Configure JWT table
tableConfig := jwt.DefaultTableConfig()
if cfg.JWTTableName != "" {
tableConfig.TableName = cfg.JWTTableName
}
// Create token generator
tokenGen, err := jwt.CreateGenerator(jwt.GeneratorConfig{
AccessExpireAfter: cfg.AccessTokenExpiry,
RefreshExpireAfter: cfg.RefreshTokenExpiry,
FreshExpireAfter: cfg.TokenFreshTime,
TrustedHost: cfg.TrustedHost,
SecretKey: cfg.SecretKey,
DBType: jwt.DatabaseType{
Type: cfg.DatabaseType,
Version: cfg.DatabaseVersion,
},
TableConfig: tableConfig,
}, beginTx)
if err != nil {
return nil, errors.Wrap(err, "jwt.CreateGenerator")
}
auth := Authenticator[T, TX]{
tokenGenerator: tokenGen,
load: load,
server: server,
beginTx: beginTx,
logger: logger,
errorPage: errorPage,
SSL: cfg.SSL,
LandingPage: cfg.LandingPage,
}
return &auth, nil
}