git.iko.soy/typeable/oauth2-proxy
on v0.1 help sign in
107 lines 3.7 kB history raw
1package main
3import (
4 "flag"
5 "fmt"
6 "log"
7 "net"
8 "net/http"
9 "net/url"
10 "os"
11 "strings"
14const VERSION = "0.1.0"
16var (
17 showVersion = flag.Bool("version", false, "print version string")
18 httpAddr = flag.String("http-address", "127.0.0.1:4180", "<addr>:<port> to listen on for HTTP clients")
19 redirectUrl = flag.String("redirect-url", "", "the OAuth Redirect URL. ie: \"https://internalapp.yourcompany.com/oauth2/callback\"")
20 clientID = flag.String("client-id", "", "the Google OAuth Client ID: ie: \"123456.apps.googleusercontent.com\"")
21 clientSecret = flag.String("client-secret", "", "the OAuth Client Secret")
22 passBasicAuth = flag.Bool("pass-basic-auth", true, "pass HTTP Basic Auth information to upstream")
23 htpasswdFile = flag.String("htpasswd-file", "", "additionally authenticate against a htpasswd file. Entries must be created with \"htpasswd -s\" for SHA encryption")
24 cookieSecret = flag.String("cookie-secret", "", "the seed string for secure cookies")
25 cookieDomain = flag.String("cookie-domain", "", "an optional cookie domain to force cookies to")
26 authenticatedEmailsFile = flag.String("authenticated-emails-file", "", "authenticate against emails via file (one per line)")
27 googleAppsDomains = StringArray{}
28 upstreams = StringArray{}
31func init() {
32 flag.Var(&googleAppsDomains, "google-apps-domain", "authenticate against the given google apps domain (may be given multiple times)")
33 flag.Var(&upstreams, "upstream", "the http url(s) of the upstream endpoint. If multiple, routing is based on path")
36func main() {
38 flag.Parse()
40 // Try to use env for secrets if no flag is set
41 if *clientID == "" {
42 *clientID = os.Getenv("google_auth_client_id")
43 }
44 if *clientSecret == "" {
45 *clientSecret = os.Getenv("google_auth_secret")
46 }
47 if *cookieSecret == "" {
48 *cookieSecret = os.Getenv("google_auth_cookie_secret")
49 }
51 if *showVersion {
52 fmt.Printf("google_auth_proxy v%s\n", VERSION)
53 return
54 }
56 if len(upstreams) < 1 {
57 log.Fatal("missing --upstream")
58 }
59 if *cookieSecret == "" {
60 log.Fatal("missing --cookie-secret")
61 }
62 if *clientID == "" {
63 log.Fatal("missing --client-id")
64 }
65 if *clientSecret == "" {
66 log.Fatal("missing --client-secret")
67 }
69 var upstreamUrls []*url.URL
70 for _, u := range upstreams {
71 upstreamUrl, err := url.Parse(u)
72 if err != nil {
73 log.Fatalf("error parsing --upstream %s", err.Error())
74 }
75 upstreamUrls = append(upstreamUrls, upstreamUrl)
76 }
77 redirectUrl, err := url.Parse(*redirectUrl)
78 if err != nil {
79 log.Fatalf("error parsing --redirect-url %s", err.Error())
80 }
82 validator := NewValidator(googleAppsDomains, *authenticatedEmailsFile)
83 oauthproxy := NewOauthProxy(upstreamUrls, *clientID, *clientSecret, validator)
84 oauthproxy.SetRedirectUrl(redirectUrl)
85 if len(googleAppsDomains) != 0 && *authenticatedEmailsFile == "" {
86 oauthproxy.SignInMessage = fmt.Sprintf("using a email address from the following domains: %v", strings.Join(googleAppsDomains, ", "))
87 }
88 if *htpasswdFile != "" {
89 oauthproxy.HtpasswdFile, err = NewHtpasswdFromFile(*htpasswdFile)
90 if err != nil {
91 log.Fatalf("FATAL: unable to open %s %s", *htpasswdFile, err.Error())
92 }
93 }
94 listener, err := net.Listen("tcp", *httpAddr)
95 if err != nil {
96 log.Fatalf("FATAL: listen (%s) failed - %s", *httpAddr, err.Error())
97 }
98 log.Printf("listening on %s", *httpAddr)
100 server := &http.Server{Handler: oauthproxy}
101 err = server.Serve(listener)
102 if err != nil && !strings.Contains(err.Error(), "use of closed network connection") {
103 log.Printf("ERROR: http.Serve() - %s", err.Error())
104 }
106 log.Printf("HTTP: closing %s", listener.Addr().String())