108 lines
2.8 KiB
Go
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
|
|
}
|