mirror of
https://github.com/davidallendj/opaal.git
synced 2025-12-20 03:27:02 -07:00
218 lines
6.7 KiB
Go
218 lines
6.7 KiB
Go
package cmd
|
|
|
|
import (
|
|
opaal "davidallendj/opaal/internal"
|
|
"fmt"
|
|
"os"
|
|
"strconv"
|
|
"strings"
|
|
|
|
"github.com/davidallendj/go-utils/pathx"
|
|
"github.com/spf13/cobra"
|
|
)
|
|
|
|
var (
|
|
confPath = ""
|
|
config opaal.Config
|
|
)
|
|
var rootCmd = &cobra.Command{
|
|
Use: "opaal",
|
|
Short: "An experimental OIDC helper tool for handling logins",
|
|
Run: func(cmd *cobra.Command, args []string) {
|
|
// print help and exit
|
|
if len(args) <= 0 {
|
|
err := cmd.Help()
|
|
if err != nil {
|
|
fmt.Printf("failed to print help message: %v\n", err)
|
|
}
|
|
os.Exit(0)
|
|
}
|
|
},
|
|
}
|
|
|
|
func Execute() {
|
|
initialize()
|
|
if err := rootCmd.Execute(); err != nil {
|
|
fmt.Fprintf(os.Stderr, "failed to start CLI: %s", err)
|
|
os.Exit(1)
|
|
}
|
|
}
|
|
|
|
func init() {
|
|
rootCmd.PersistentFlags().BoolVarP(&config.Options.Verbose, "verbose", "v", false, "set the verbose flag")
|
|
rootCmd.PersistentFlags().StringVarP(&confPath, "config", "c", "", "set the config path")
|
|
rootCmd.PersistentFlags().StringVar(&config.Options.CachePath, "cache", "", "set the cache path")
|
|
}
|
|
|
|
func initialize() {
|
|
initConfig()
|
|
initEnv()
|
|
}
|
|
|
|
func initConfig() {
|
|
// load config if found or create a new one
|
|
if confPath != "" {
|
|
exists, err := pathx.PathExists(confPath)
|
|
if err != nil {
|
|
fmt.Printf("failed to load config")
|
|
os.Exit(1)
|
|
} else if exists {
|
|
config = opaal.LoadConfig(confPath)
|
|
} else {
|
|
config = opaal.NewConfig()
|
|
}
|
|
}
|
|
}
|
|
|
|
func initEnv() error {
|
|
// set environment variables before by CLI, but after config
|
|
var errList []error
|
|
err := parseEnv("OPAAL_LOGIN_HOST", &config.Server.Host)
|
|
if err != nil {
|
|
errList = append(errList, fmt.Errorf("OPAAL_LOGIN_HOST: %q", err))
|
|
}
|
|
err = parseEnv("OPAAL_LOGIN_PORT", &config.Server.Port)
|
|
if err != nil {
|
|
errList = append(errList, fmt.Errorf("OPAAL_LOGIN_PORT: %q", err))
|
|
}
|
|
err = parseEnv("OPAAL_IDP_HOST", &config.Server.Issuer.Host)
|
|
if err != nil {
|
|
errList = append(errList, fmt.Errorf("OPAAL_IDP_HOST: %q", err))
|
|
}
|
|
err = parseEnv("OPAAL_IDP_PORT", &config.Server.Issuer.Port)
|
|
if err != nil {
|
|
errList = append(errList, fmt.Errorf("OPAAL_IDP_PORT: %q", err))
|
|
}
|
|
|
|
// authentication env vars
|
|
err = parseEnv("OPAAL_IDP_REGISTERED_CLIENTS", &config.Server.Issuer.Clients)
|
|
if err != nil {
|
|
errList = append(errList, fmt.Errorf("OPAAL_IDP_REGISTERED_CLIENTS: %q", err))
|
|
}
|
|
err = parseEnv("OPAAL_AUTHN_CLIENTS", &config.Authentication.Clients)
|
|
if err != nil {
|
|
errList = append(errList, fmt.Errorf("OPAAL_AUTHN_CLIENTS: %q", err))
|
|
}
|
|
|
|
// authorization token env vars
|
|
err = parseEnv("OPAAL_AUTHZ_TOKEN_FORWARDING", &config.Authorization)
|
|
if err != nil {
|
|
errList = append(errList, fmt.Errorf("OPAAL_AUTHZ_TOKEN_FORWARDING: %q", err))
|
|
}
|
|
err = parseEnv("OPAAL_AUTHZ_TOKEN_REFRESH", &config.Authorization.Token.Refresh)
|
|
if err != nil {
|
|
errList = append(errList, fmt.Errorf("OPAAL_AUTHZ_TOKEN_REFRESH: %q", err))
|
|
}
|
|
err = parseEnv("OPAAL_AUTHZ_TOKEN_DURATION", &config.Authorization.Token.Duration)
|
|
if err != nil {
|
|
errList = append(errList, fmt.Errorf("OPAAL_AUTHZ_TOKEN_DURATION: %q", err))
|
|
}
|
|
err = parseEnv("OPAAL_AUTHZ_TOKEN_SCOPE", &config.Authorization.Token.Scope)
|
|
if err != nil {
|
|
errList = append(errList, fmt.Errorf("OPAAL_AUTHZ_TOKEN_SCOPE: %q", err))
|
|
}
|
|
|
|
// authorization endpoint env vars
|
|
err = parseEnv("OPAAL_AUTHZ_KEY_PATH", &config.Authorization.KeyPath)
|
|
if err != nil {
|
|
errList = append(errList, fmt.Errorf("OPAAL_AUTHZ_KEY_PATH: %q", err))
|
|
}
|
|
err = parseEnv("OPAAL_AUTHZ_ENDPOINT_ISSUER", &config.Authorization.Endpoints.Issuer)
|
|
if err != nil {
|
|
errList = append(errList, fmt.Errorf("OPAAL_AUTHZ_ENDPOINT_ISSUER: %q", err))
|
|
}
|
|
err = parseEnv("OPAAL_AUTHZ_ENDPOINT_CONFIG", &config.Authorization.Endpoints.Config)
|
|
if err != nil {
|
|
errList = append(errList, fmt.Errorf("OPAAL_AUTHZ_ENDPOINT_CONFIG: %q", err))
|
|
}
|
|
err = parseEnv("OPAAL_AUTHZ_ENDPOINT_JWKS", &config.Authorization.Endpoints.JwksUri)
|
|
if err != nil {
|
|
errList = append(errList, fmt.Errorf("OPAAL_AUTHZ_ENDPOINT_JWKS: %q", err))
|
|
}
|
|
err = parseEnv("OPAAL_AUTHZ_ENDPOINT_TRUSTED_ISSUER", &config.Authorization.Endpoints.TrustedIssuers)
|
|
if err != nil {
|
|
errList = append(errList, fmt.Errorf("OPAAL_AUTHZ_ENDPOINT_TRUSTED_ISSUER: %q", err))
|
|
}
|
|
err = parseEnv("OPAAL_AUTHZ_ENDPOINT_CLIENTS", &config.Authorization.Endpoints.Clients)
|
|
if err != nil {
|
|
errList = append(errList, fmt.Errorf("OPAAL_AUTHZ_ENDPOINT_CILENTS: %q", err))
|
|
}
|
|
err = parseEnv("OPAAL_AUTHZ_ENDPOINT_AUTHORIZE", &config.Authorization.Endpoints.Authorize)
|
|
if err != nil {
|
|
errList = append(errList, fmt.Errorf("OPAAL_AUTHZ_ENDPOINT_AUTHORIZE: %q", err))
|
|
}
|
|
err = parseEnv("OPAAL_AUTHZ_ENDPOINT_REGISTER", &config.Authorization.Endpoints.Register)
|
|
if err != nil {
|
|
errList = append(errList, fmt.Errorf("OPAAL_AUTHZ_ENDPOINT_REGISTER: %q", err))
|
|
}
|
|
err = parseEnv("OPAAL_AUTHZ_ENDPOINT_TOKEN", &config.Authorization.Endpoints.Token)
|
|
if err != nil {
|
|
errList = append(errList, fmt.Errorf("OPAAL_AUTHZ_ENDPOINT_TOKEN: %q", err))
|
|
}
|
|
|
|
// other miscellaneous option env vars
|
|
err = parseEnv("OPAAL_OPT_VERBOSE", &config.Options.Verbose)
|
|
if err != nil {
|
|
errList = append(errList, fmt.Errorf("OPAAL_OPT_VERBOSE: %q", err))
|
|
}
|
|
err = parseEnv("OPAAL_OPT_RUN_ONCE", &config.Options.RunOnce)
|
|
if err != nil {
|
|
errList = append(errList, fmt.Errorf("OPAAL_OPT_RUN_ONCE: %q", err))
|
|
}
|
|
err = parseEnv("OPAAL_OPT_OPEN_BROWSER", &config.Options.OpenBrowser)
|
|
if err != nil {
|
|
errList = append(errList, fmt.Errorf("OPAAL_OPT_OPEN_BROWSER: %q", err))
|
|
}
|
|
err = parseEnv("OPAAL_OPT_CACHE_ONLY", &config.Options.CacheOnly)
|
|
if err != nil {
|
|
errList = append(errList, fmt.Errorf("OPAAL_OPT_CACHE_ONLY: %q", err))
|
|
}
|
|
err = parseEnv("OPAAL_OPT_CACHE_PATH", &config.Options.CachePath)
|
|
if err != nil {
|
|
errList = append(errList, fmt.Errorf("OPAAL_OPT_CACHE_PATH: %q", err))
|
|
}
|
|
if len(errList) > 0 {
|
|
err = fmt.Errorf("Error(s) parsing environment variables: %v", errList)
|
|
}
|
|
return err
|
|
}
|
|
|
|
func parseEnv(evar string, v interface{}) error {
|
|
if val := os.Getenv(evar); val != "" {
|
|
switch vp := v.(type) {
|
|
case *int:
|
|
var temp int64
|
|
temp, err := strconv.ParseInt(val, 0, 64)
|
|
if err == nil {
|
|
*vp = int(temp)
|
|
}
|
|
case *uint:
|
|
var temp uint64
|
|
temp, err := strconv.ParseUint(val, 0, 64)
|
|
if err == nil {
|
|
*vp = uint(temp)
|
|
}
|
|
case *string:
|
|
*vp = val
|
|
case *bool:
|
|
switch strings.ToLower(val) {
|
|
case "0", "off", "no", "false":
|
|
*vp = false
|
|
case "1", "on", "yes", "true":
|
|
*vp = true
|
|
default:
|
|
return fmt.Errorf("unrecognized bool value: '%s'", val)
|
|
}
|
|
case *[]string:
|
|
*vp = strings.Split(val, ",")
|
|
default:
|
|
// try unmarshaling into an object using JSON
|
|
// err := json.Unmarshal([]byte(val), &v)
|
|
// if err != nil {
|
|
// return fmt.Errorf("invalid type for receiving ENV variable value %T", v)
|
|
// }
|
|
return fmt.Errorf("invalid type for receiving ENV variable value %T", v)
|
|
}
|
|
}
|
|
return nil
|
|
}
|