git.iko.soy/typeable/oauth2-proxy
on master help sign in
better environment parsing
commit9060feb436a5fd00424df345f404a45aad568927 authorJehiah Czebotar <jehiah@gmail.com> dateSun 9 Nov 2014, 21:07 (12 years ago) parent01969ee
7 files changed+56−33
README.md+1−1 env_options.go+33 htpasswd.go−1 main.go+8−19 oauthproxy.go+1 options.go+11−11 validator.go+2−1
README.md+1−1
@@ -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.gonew file+33
@@ -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−1
@@ -17,7 +17,6 @@ type HtpasswdFile struct {
1717}
1818
1919func 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+8−19
@@ -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+1
@@ -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+11−11
@@ -11,13 +11,13 @@ import (
1111type 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
3535func (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+2−1
@@ -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 = ','