Browse Source

Added support for loading some config from env vars

master
Patrick Gaskin 6 months ago
parent
commit
50cdaef3b7
Signed by: geek1011 GPG Key ID: A2FD79F68A2AB707
2 changed files with 50 additions and 7 deletions
  1. +16
    -4
      config.go
  2. +34
    -3
      main.go

+ 16
- 4
config.go View File

@ -4,6 +4,7 @@ import (
"fmt"
"io"
"net/http"
"os"
"sort"
"strings"
@ -181,7 +182,7 @@ func (a AuthProviders) ValidateUserList(u PropList) error {
// Then, include the key contents in the secret option (just use triple quotes
// for a multiline string), and set the alg to ES512.
type AuthProviderJWT struct {
Secret string `toml:"secret"`
Secret string `toml:"secret"` // can also be ENV:varname to take from the env var named varname
Alg string `toml:"alg"`
CookieName string `toml:"cookie_name"`
LoginURL string `toml:"login_url"` // optional
@ -206,19 +207,30 @@ func (a AuthProviderJWT) Validate() error {
}
func (a AuthProviderJWT) KeyFunc() (jwt.Keyfunc, error) {
var secret string
if strings.HasPrefix(a.Secret, "ENV:") {
v := strings.TrimPrefix(a.Secret, "ENV:")
secret = os.Getenv(v)
if secret == "" {
return nil, fmt.Errorf("no secret set from env var %#v", v)
}
} else {
secret = a.Secret
}
switch sm := jwt.GetSigningMethod(a.Alg).(type) {
case *jwt.SigningMethodHMAC:
return jwt.KnownKeyfunc(sm, []byte(a.Secret)), nil
return jwt.KnownKeyfunc(sm, []byte(secret)), nil
case *jwt.SigningMethodRSA, *jwt.SigningMethodRSAPSS:
k, err := jwt.ParseRSAPublicKeyFromPEM([]byte(a.Secret))
k, err := jwt.ParseRSAPublicKeyFromPEM([]byte(secret))
if err != nil {
return nil, fmt.Errorf("error parsing RSA public key from provided PEM: %w", err)
}
return jwt.KnownKeyfunc(sm, k), nil
case *jwt.SigningMethodECDSA:
k, err := jwt.ParseECPublicKeyFromPEM([]byte(aspan>.Secret))
k, err := jwt.ParseECPublicKeyFromPEM([]byte(secret))
if err != nil {
return nil, fmt.Errorf("error parsing ECDSA public key from provided PEM: %w", err)
}

+ 34
- 3
main.go View File

@ -17,8 +17,39 @@ const version = "dev"
func main() {
addr := pflag.StringP("addr", "a", ":8080", "The address to listen on")
iconsDir := pflag.StringP("icons-dir", "i", "./icons", "The directory where icons are stored")
config := pflag.StringP("config", "c", "./services.conf", "The path to the config file")
configFile := pflag.StringP("config-file", "c", "./services.conf", "The path to the config file")
help := pflag.BoolP("help", "h", false, "Show this help text")
envmap := map[string]string{
"addr": "DASHBOARD_ADDR",
"icons-dir": "DASHBOARD_ICONS_DIR",
"config-file": "DASHBOARD_CONFIG_FILE",
}
if val, ok := os.LookupEnv("PORT"); ok {
val = ":" + val
fmt.Printf("Setting --addr from PORT to %#v\n", val)
if err := pflag.Set("addr", val); err != nil {
fmt.Printf("Error: %v\n", err)
os.Exit(2)
return
}
}
pflag.VisitAll(func(flag *pflag.Flag) {
if env, ok := envmap[flag.Name]; ok {
flag.Usage += fmt.Sprintf(" (env %s)", env)
if val, ok := os.LookupEnv(env); ok {
fmt.Printf("Setting --%s from %s to %#v\n", flag.Name, env, val)
if err := flag.Value.Set(val); err != nil {
fmt.Printf("Error: %v\n", err)
os.Exit(2)
return
}
}
}
})
pflag.Parse()
if *help {
@ -38,9 +69,9 @@ func main() {
return
}
f, err := os.OpenFile(*config, os.O_RDONLY, 0)
f, err := os.OpenFile(*configFile, os.O_RDONLY, 0)
if err != nil {
fmt.Fprintf(os.Stderr, "Error: Open config %#v: %v.\n", *config, err)
fmt.Fprintf(os.Stderr, "Error: Open config %#v: %v.\n", *configFile, err)
os.Exit(1)
return
}

Loading…
Cancel
Save