Merge pull request #37 from jehiah/env_parsing_37
Better environment variable parsing
This commit is contained in:
commit
3a1db8f457
@ -73,7 +73,7 @@ Usage of google_auth_proxy:
|
|||||||
|
|
||||||
### Environment variables
|
### Environment variables
|
||||||
|
|
||||||
The environment variables `google_auth_client_id`, `google_auth_secret` and `google_auth_cookie_secret` can be used in place of the corresponding command-line arguments.
|
The environment variables `GOOGLE_AUTH_PROXY_CLIENT_ID`, `GOOGLE_AUTH_PROXY_CLIENT_SECRET`, `GOOGLE_AUTH_PROXY_COOKIE_SECRET`, `GOOGLE_AUTH_PROXY_COOKIE_DOMAIN` and `GOOGLE_AUTH_PROXY_COOKIE_EXPIRE` can be used in place of the corresponding command-line arguments.
|
||||||
|
|
||||||
### Example Nginx Configuration
|
### Example Nginx Configuration
|
||||||
|
|
||||||
|
33
env_options.go
Normal file
33
env_options.go
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"reflect"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
func LoadOptionsFromEnv(options interface{}, cfg map[string]interface{}) {
|
||||||
|
val := reflect.ValueOf(options).Elem()
|
||||||
|
typ := val.Type()
|
||||||
|
for i := 0; i < typ.NumField(); i++ {
|
||||||
|
// pull out the struct tags:
|
||||||
|
// flag - the name of the command line flag
|
||||||
|
// deprecated - (optional) the name of the deprecated command line flag
|
||||||
|
// cfg - (optional, defaults to underscored flag) the name of the config file option
|
||||||
|
field := typ.Field(i)
|
||||||
|
flagName := field.Tag.Get("flag")
|
||||||
|
envName := field.Tag.Get("env")
|
||||||
|
cfgName := field.Tag.Get("cfg")
|
||||||
|
if cfgName == "" && flagName != "" {
|
||||||
|
cfgName = strings.Replace(flagName, "-", "_", -1)
|
||||||
|
}
|
||||||
|
if envName == "" || cfgName == "" {
|
||||||
|
// resolvable fields must have the `env` and `cfg` struct tag
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
v := os.Getenv(envName)
|
||||||
|
if v != "" {
|
||||||
|
cfg[cfgName] = v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -17,7 +17,6 @@ type HtpasswdFile struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func NewHtpasswdFromFile(path string) (*HtpasswdFile, error) {
|
func NewHtpasswdFromFile(path string) (*HtpasswdFile, error) {
|
||||||
log.Printf("using htpasswd file %s", path)
|
|
||||||
r, err := os.Open(path)
|
r, err := os.Open(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
27
main.go
27
main.go
@ -35,12 +35,17 @@ func main() {
|
|||||||
flagSet.String("htpasswd-file", "", "additionally authenticate against a htpasswd file. Entries must be created with \"htpasswd -s\" for SHA encryption")
|
flagSet.String("htpasswd-file", "", "additionally authenticate against a htpasswd file. Entries must be created with \"htpasswd -s\" for SHA encryption")
|
||||||
|
|
||||||
flagSet.String("cookie-secret", "", "the seed string for secure cookies")
|
flagSet.String("cookie-secret", "", "the seed string for secure cookies")
|
||||||
flagSet.String("cookie-domain", "", "an optional cookie domain to force cookies to (ie: .yourcompany.com)")
|
flagSet.String("cookie-domain", "", "an optional cookie domain to force cookies to (ie: .yourcompany.com)*")
|
||||||
flagSet.Duration("cookie-expire", time.Duration(168)*time.Hour, "expire timeframe for cookie")
|
flagSet.Duration("cookie-expire", time.Duration(168)*time.Hour, "expire timeframe for cookie")
|
||||||
flagSet.Bool("cookie-https-only", false, "set HTTPS only cookie")
|
flagSet.Bool("cookie-https-only", false, "set HTTPS only cookie")
|
||||||
|
|
||||||
flagSet.Parse(os.Args[1:])
|
flagSet.Parse(os.Args[1:])
|
||||||
|
|
||||||
|
if *showVersion {
|
||||||
|
fmt.Printf("google_auth_proxy v%s\n", VERSION)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
opts := NewOptions()
|
opts := NewOptions()
|
||||||
|
|
||||||
var cfg map[string]interface{}
|
var cfg map[string]interface{}
|
||||||
@ -50,26 +55,9 @@ func main() {
|
|||||||
log.Fatalf("ERROR: failed to load config file %s - %s", *config, err)
|
log.Fatalf("ERROR: failed to load config file %s - %s", *config, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
LoadOptionsFromEnv(opts, cfg)
|
||||||
options.Resolve(opts, flagSet, cfg)
|
options.Resolve(opts, flagSet, cfg)
|
||||||
|
|
||||||
// Try to use env for secrets if no flag is set
|
|
||||||
// TODO: better parsing of these values
|
|
||||||
if opts.ClientID == "" {
|
|
||||||
opts.ClientID = os.Getenv("google_auth_client_id")
|
|
||||||
}
|
|
||||||
if opts.ClientSecret == "" {
|
|
||||||
opts.ClientSecret = os.Getenv("google_auth_secret")
|
|
||||||
}
|
|
||||||
if opts.CookieSecret == "" {
|
|
||||||
opts.CookieSecret = os.Getenv("google_auth_cookie_secret")
|
|
||||||
}
|
|
||||||
|
|
||||||
if *showVersion {
|
|
||||||
fmt.Printf("google_auth_proxy v%s\n", VERSION)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
err := opts.Validate()
|
err := opts.Validate()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("%s", err)
|
log.Printf("%s", err)
|
||||||
@ -88,6 +76,7 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if opts.HtpasswdFile != "" {
|
if opts.HtpasswdFile != "" {
|
||||||
|
log.Printf("using htpasswd file %s", opts.HtpasswdFile)
|
||||||
oauthproxy.HtpasswdFile, err = NewHtpasswdFromFile(opts.HtpasswdFile)
|
oauthproxy.HtpasswdFile, err = NewHtpasswdFromFile(opts.HtpasswdFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("FATAL: unable to open %s %s", opts.HtpasswdFile, err)
|
log.Fatalf("FATAL: unable to open %s %s", opts.HtpasswdFile, err)
|
||||||
|
@ -54,6 +54,7 @@ func NewOauthProxy(opts *Options, validator func(string) bool) *OauthProxy {
|
|||||||
redirectUrl := opts.redirectUrl
|
redirectUrl := opts.redirectUrl
|
||||||
redirectUrl.Path = oauthCallbackPath
|
redirectUrl.Path = oauthCallbackPath
|
||||||
|
|
||||||
|
log.Printf("OauthProxy configured for %s", opts.ClientID)
|
||||||
return &OauthProxy{
|
return &OauthProxy{
|
||||||
CookieKey: "_oauthproxy",
|
CookieKey: "_oauthproxy",
|
||||||
CookieSeed: opts.CookieSecret,
|
CookieSeed: opts.CookieSecret,
|
||||||
|
22
options.go
22
options.go
@ -11,13 +11,13 @@ import (
|
|||||||
type Options struct {
|
type Options struct {
|
||||||
HttpAddress string `flag:"http-address" cfg:"http_address"`
|
HttpAddress string `flag:"http-address" cfg:"http_address"`
|
||||||
RedirectUrl string `flag:"redirect-url" cfg:"redirect_url"`
|
RedirectUrl string `flag:"redirect-url" cfg:"redirect_url"`
|
||||||
ClientID string `flag:"client-id" cfg:"client_id"`
|
ClientID string `flag:"client-id" cfg:"client_id" env:"GOOGLE_AUTH_PROXY_CLIENT_ID"`
|
||||||
ClientSecret string `flag:"client-secret" cfg:"client_secret"`
|
ClientSecret string `flag:"client-secret" cfg:"client_secret" env:"GOOGLE_AUTH_PROXY_CLIENT_SECRET"`
|
||||||
PassBasicAuth bool `flag:"pass-basic-auth" cfg:"pass_basic_auth"`
|
PassBasicAuth bool `flag:"pass-basic-auth" cfg:"pass_basic_auth"`
|
||||||
HtpasswdFile string `flag:"htpasswd-file" cfg:"htpasswd_file"`
|
HtpasswdFile string `flag:"htpasswd-file" cfg:"htpasswd_file"`
|
||||||
CookieSecret string `flag:"cookie-secret" cfg:"cookie_secret"`
|
CookieSecret string `flag:"cookie-secret" cfg:"cookie_secret" env:"GOOGLE_AUTH_PROXY_COOKIE_SECRET"`
|
||||||
CookieDomain string `flag:"cookie-domain" cfg:"cookie_domain"`
|
CookieDomain string `flag:"cookie-domain" cfg:"cookie_domain" env:"GOOGLE_AUTH_PROXY_COOKIE_DOMAIN"`
|
||||||
CookieExpire time.Duration `flag:"cookie-expire" cfg:"cookie_expire"`
|
CookieExpire time.Duration `flag:"cookie-expire" cfg:"cookie_expire" env:"GOOGLE_AUTH_PROXY_COOKIE_EXPIRE"`
|
||||||
CookieHttpsOnly bool `flag:"cookie-https-only" cfg:"cookie_https_only"`
|
CookieHttpsOnly bool `flag:"cookie-https-only" cfg:"cookie_https_only"`
|
||||||
AuthenticatedEmailsFile string `flag:"authenticated-emails-file" cfg:"authenticated_emails_file"`
|
AuthenticatedEmailsFile string `flag:"authenticated-emails-file" cfg:"authenticated_emails_file"`
|
||||||
GoogleAppsDomains []string `flag:"google-apps-domain" cfg:"google_apps_domains"`
|
GoogleAppsDomains []string `flag:"google-apps-domain" cfg:"google_apps_domains"`
|
||||||
@ -34,28 +34,28 @@ func NewOptions() *Options {
|
|||||||
|
|
||||||
func (o *Options) Validate() error {
|
func (o *Options) Validate() error {
|
||||||
if len(o.Upstreams) < 1 {
|
if len(o.Upstreams) < 1 {
|
||||||
return errors.New("missing -upstream")
|
return errors.New("missing setting: upstream")
|
||||||
}
|
}
|
||||||
if o.CookieSecret == "" {
|
if o.CookieSecret == "" {
|
||||||
errors.New("missing -cookie-secret")
|
errors.New("missing setting: cookie-secret")
|
||||||
}
|
}
|
||||||
if o.ClientID == "" {
|
if o.ClientID == "" {
|
||||||
return errors.New("missing -client-id")
|
return errors.New("missing setting: client-id")
|
||||||
}
|
}
|
||||||
if o.ClientSecret == "" {
|
if o.ClientSecret == "" {
|
||||||
return errors.New("missing -client-secret")
|
return errors.New("missing setting: client-secret")
|
||||||
}
|
}
|
||||||
|
|
||||||
redirectUrl, err := url.Parse(o.RedirectUrl)
|
redirectUrl, err := url.Parse(o.RedirectUrl)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("error parsing -redirect-url=%q %s", o.RedirectUrl, err)
|
return fmt.Errorf("error parsing redirect-url=%q %s", o.RedirectUrl, err)
|
||||||
}
|
}
|
||||||
o.redirectUrl = redirectUrl
|
o.redirectUrl = redirectUrl
|
||||||
|
|
||||||
for _, u := range o.Upstreams {
|
for _, u := range o.Upstreams {
|
||||||
upstreamUrl, err := url.Parse(u)
|
upstreamUrl, err := url.Parse(u)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("error parsing -upstream=%q %s", upstreamUrl, err)
|
return fmt.Errorf("error parsing upstream=%q %s", upstreamUrl, err)
|
||||||
}
|
}
|
||||||
if upstreamUrl.Path == "" {
|
if upstreamUrl.Path == "" {
|
||||||
upstreamUrl.Path = "/"
|
upstreamUrl.Path = "/"
|
||||||
|
@ -12,9 +12,10 @@ func NewValidator(domains []string, usersFile string) func(string) bool {
|
|||||||
validUsers := make(map[string]bool)
|
validUsers := make(map[string]bool)
|
||||||
|
|
||||||
if usersFile != "" {
|
if usersFile != "" {
|
||||||
|
log.Printf("using authenticated emails file %s", usersFile)
|
||||||
r, err := os.Open(usersFile)
|
r, err := os.Open(usersFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("failed opening -authenticated-emails-file=%v, %s", usersFile, err.Error())
|
log.Fatalf("failed opening authenticated-emails-file=%q, %s", usersFile, err)
|
||||||
}
|
}
|
||||||
csv_reader := csv.NewReader(r)
|
csv_reader := csv.NewReader(r)
|
||||||
csv_reader.Comma = ','
|
csv_reader.Comma = ','
|
||||||
|
Loading…
Reference in New Issue
Block a user