Skip to content

Commit 3a1db8f

Browse files
committed
Merge pull request bitly#37 from jehiah/env_parsing_37
Better environment variable parsing
2 parents 01969ee + 9060feb commit 3a1db8f

File tree

7 files changed

+56
-33
lines changed

7 files changed

+56
-33
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ Usage of google_auth_proxy:
7373

7474
### Environment variables
7575

76-
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.
76+
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.
7777

7878
### Example Nginx Configuration
7979

env_options.go

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package main
2+
3+
import (
4+
"os"
5+
"reflect"
6+
"strings"
7+
)
8+
9+
func LoadOptionsFromEnv(options interface{}, cfg map[string]interface{}) {
10+
val := reflect.ValueOf(options).Elem()
11+
typ := val.Type()
12+
for i := 0; i < typ.NumField(); i++ {
13+
// pull out the struct tags:
14+
// flag - the name of the command line flag
15+
// deprecated - (optional) the name of the deprecated command line flag
16+
// cfg - (optional, defaults to underscored flag) the name of the config file option
17+
field := typ.Field(i)
18+
flagName := field.Tag.Get("flag")
19+
envName := field.Tag.Get("env")
20+
cfgName := field.Tag.Get("cfg")
21+
if cfgName == "" && flagName != "" {
22+
cfgName = strings.Replace(flagName, "-", "_", -1)
23+
}
24+
if envName == "" || cfgName == "" {
25+
// resolvable fields must have the `env` and `cfg` struct tag
26+
continue
27+
}
28+
v := os.Getenv(envName)
29+
if v != "" {
30+
cfg[cfgName] = v
31+
}
32+
}
33+
}

htpasswd.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ type HtpasswdFile struct {
1717
}
1818

1919
func NewHtpasswdFromFile(path string) (*HtpasswdFile, error) {
20-
log.Printf("using htpasswd file %s", path)
2120
r, err := os.Open(path)
2221
if err != nil {
2322
return nil, err

main.go

Lines changed: 8 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,17 @@ func main() {
3535
flagSet.String("htpasswd-file", "", "additionally authenticate against a htpasswd file. Entries must be created with \"htpasswd -s\" for SHA encryption")
3636

3737
flagSet.String("cookie-secret", "", "the seed string for secure cookies")
38-
flagSet.String("cookie-domain", "", "an optional cookie domain to force cookies to (ie: .yourcompany.com)")
38+
flagSet.String("cookie-domain", "", "an optional cookie domain to force cookies to (ie: .yourcompany.com)*")
3939
flagSet.Duration("cookie-expire", time.Duration(168)*time.Hour, "expire timeframe for cookie")
4040
flagSet.Bool("cookie-https-only", false, "set HTTPS only cookie")
4141

4242
flagSet.Parse(os.Args[1:])
4343

44+
if *showVersion {
45+
fmt.Printf("google_auth_proxy v%s\n", VERSION)
46+
return
47+
}
48+
4449
opts := NewOptions()
4550

4651
var cfg map[string]interface{}
@@ -50,26 +55,9 @@ func main() {
5055
log.Fatalf("ERROR: failed to load config file %s - %s", *config, err)
5156
}
5257
}
53-
58+
LoadOptionsFromEnv(opts, cfg)
5459
options.Resolve(opts, flagSet, cfg)
5560

56-
// Try to use env for secrets if no flag is set
57-
// TODO: better parsing of these values
58-
if opts.ClientID == "" {
59-
opts.ClientID = os.Getenv("google_auth_client_id")
60-
}
61-
if opts.ClientSecret == "" {
62-
opts.ClientSecret = os.Getenv("google_auth_secret")
63-
}
64-
if opts.CookieSecret == "" {
65-
opts.CookieSecret = os.Getenv("google_auth_cookie_secret")
66-
}
67-
68-
if *showVersion {
69-
fmt.Printf("google_auth_proxy v%s\n", VERSION)
70-
return
71-
}
72-
7361
err := opts.Validate()
7462
if err != nil {
7563
log.Printf("%s", err)
@@ -88,6 +76,7 @@ func main() {
8876
}
8977

9078
if opts.HtpasswdFile != "" {
79+
log.Printf("using htpasswd file %s", opts.HtpasswdFile)
9180
oauthproxy.HtpasswdFile, err = NewHtpasswdFromFile(opts.HtpasswdFile)
9281
if err != nil {
9382
log.Fatalf("FATAL: unable to open %s %s", opts.HtpasswdFile, err)

oauthproxy.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ func NewOauthProxy(opts *Options, validator func(string) bool) *OauthProxy {
5454
redirectUrl := opts.redirectUrl
5555
redirectUrl.Path = oauthCallbackPath
5656

57+
log.Printf("OauthProxy configured for %s", opts.ClientID)
5758
return &OauthProxy{
5859
CookieKey: "_oauthproxy",
5960
CookieSeed: opts.CookieSecret,

options.go

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,13 @@ import (
1111
type Options struct {
1212
HttpAddress string `flag:"http-address" cfg:"http_address"`
1313
RedirectUrl string `flag:"redirect-url" cfg:"redirect_url"`
14-
ClientID string `flag:"client-id" cfg:"client_id"`
15-
ClientSecret string `flag:"client-secret" cfg:"client_secret"`
14+
ClientID string `flag:"client-id" cfg:"client_id" env:"GOOGLE_AUTH_PROXY_CLIENT_ID"`
15+
ClientSecret string `flag:"client-secret" cfg:"client_secret" env:"GOOGLE_AUTH_PROXY_CLIENT_SECRET"`
1616
PassBasicAuth bool `flag:"pass-basic-auth" cfg:"pass_basic_auth"`
1717
HtpasswdFile string `flag:"htpasswd-file" cfg:"htpasswd_file"`
18-
CookieSecret string `flag:"cookie-secret" cfg:"cookie_secret"`
19-
CookieDomain string `flag:"cookie-domain" cfg:"cookie_domain"`
20-
CookieExpire time.Duration `flag:"cookie-expire" cfg:"cookie_expire"`
18+
CookieSecret string `flag:"cookie-secret" cfg:"cookie_secret" env:"GOOGLE_AUTH_PROXY_COOKIE_SECRET"`
19+
CookieDomain string `flag:"cookie-domain" cfg:"cookie_domain" env:"GOOGLE_AUTH_PROXY_COOKIE_DOMAIN"`
20+
CookieExpire time.Duration `flag:"cookie-expire" cfg:"cookie_expire" env:"GOOGLE_AUTH_PROXY_COOKIE_EXPIRE"`
2121
CookieHttpsOnly bool `flag:"cookie-https-only" cfg:"cookie_https_only"`
2222
AuthenticatedEmailsFile string `flag:"authenticated-emails-file" cfg:"authenticated_emails_file"`
2323
GoogleAppsDomains []string `flag:"google-apps-domain" cfg:"google_apps_domains"`
@@ -34,28 +34,28 @@ func NewOptions() *Options {
3434

3535
func (o *Options) Validate() error {
3636
if len(o.Upstreams) < 1 {
37-
return errors.New("missing -upstream")
37+
return errors.New("missing setting: upstream")
3838
}
3939
if o.CookieSecret == "" {
40-
errors.New("missing -cookie-secret")
40+
errors.New("missing setting: cookie-secret")
4141
}
4242
if o.ClientID == "" {
43-
return errors.New("missing -client-id")
43+
return errors.New("missing setting: client-id")
4444
}
4545
if o.ClientSecret == "" {
46-
return errors.New("missing -client-secret")
46+
return errors.New("missing setting: client-secret")
4747
}
4848

4949
redirectUrl, err := url.Parse(o.RedirectUrl)
5050
if err != nil {
51-
return fmt.Errorf("error parsing -redirect-url=%q %s", o.RedirectUrl, err)
51+
return fmt.Errorf("error parsing redirect-url=%q %s", o.RedirectUrl, err)
5252
}
5353
o.redirectUrl = redirectUrl
5454

5555
for _, u := range o.Upstreams {
5656
upstreamUrl, err := url.Parse(u)
5757
if err != nil {
58-
return fmt.Errorf("error parsing -upstream=%q %s", upstreamUrl, err)
58+
return fmt.Errorf("error parsing upstream=%q %s", upstreamUrl, err)
5959
}
6060
if upstreamUrl.Path == "" {
6161
upstreamUrl.Path = "/"

validator.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,10 @@ func NewValidator(domains []string, usersFile string) func(string) bool {
1212
validUsers := make(map[string]bool)
1313

1414
if usersFile != "" {
15+
log.Printf("using authenticated emails file %s", usersFile)
1516
r, err := os.Open(usersFile)
1617
if err != nil {
17-
log.Fatalf("failed opening -authenticated-emails-file=%v, %s", usersFile, err.Error())
18+
log.Fatalf("failed opening authenticated-emails-file=%q, %s", usersFile, err)
1819
}
1920
csv_reader := csv.NewReader(r)
2021
csv_reader.Comma = ','

0 commit comments

Comments
 (0)