package authn import ( "reflect" "time" "forge.cadoles.com/cadoles/bouncer/internal/store" "github.com/mitchellh/mapstructure" "github.com/pkg/errors" ) type LayerOptions struct { MatchURLs []string `mapstructure:"matchURLs"` Rules []string `mapstructure:"rules"` Templates TemplatesOptions `mapstructure:"templates"` } type TemplatesOptions struct { Forbidden TemplateOptions `mapstructure:"forbidden"` Error TemplateOptions `mapstructure:"error"` } type TemplateOptions struct { Block string `mapstructure:"block"` } func DefaultLayerOptions() LayerOptions { return LayerOptions{ MatchURLs: []string{"*"}, Rules: []string{ "del_headers(ctx, 'Remote-*')", "set_header(ctx,'Remote-User', vars.user.subject)", `map( toPairs(vars.user.attrs), { let name = replace(lower(string(get(#, 0))), '_', '-'); set_header( ctx, 'Remote-User-Attr-' + name, get(#, 1) ) }) `, }, Templates: TemplatesOptions{ Forbidden: TemplateOptions{ Block: "default", }, Error: TemplateOptions{ Block: "default", }, }, } } func fromStoreOptions(storeOptions store.LayerOptions) (*LayerOptions, error) { layerOptions := DefaultLayerOptions() if err := FromStoreOptions(storeOptions, &layerOptions); err != nil { return nil, errors.WithStack(err) } return &layerOptions, nil } func FromStoreOptions(storeOptions store.LayerOptions, dest any) error { config := mapstructure.DecoderConfig{ Result: dest, ZeroFields: true, DecodeHook: mapstructure.ComposeDecodeHookFunc( toDurationHookFunc(), ), } decoder, err := mapstructure.NewDecoder(&config) if err != nil { return errors.WithStack(err) } if err := decoder.Decode(storeOptions); err != nil { return errors.WithStack(err) } return nil } func toDurationHookFunc() mapstructure.DecodeHookFunc { return func( f reflect.Type, t reflect.Type, data interface{}) (interface{}, error) { if t != reflect.TypeOf(*new(time.Duration)) { return data, nil } switch f.Kind() { case reflect.String: return time.ParseDuration(data.(string)) case reflect.Int64: return time.Duration(data.(int64) * int64(time.Second)), nil default: return data, nil } // Convert it by parsing } }