diff --git a/server/mux.go b/server/mux.go index abbc51c760..78c7731c0e 100644 --- a/server/mux.go +++ b/server/mux.go @@ -31,6 +31,8 @@ type MuxOpts struct { GoogleClientID string // GoogleClientID is the Google OAuth id GoogleClientSecret string // GoogleClientSecret is the Google OAuth secret GoogleDomains []string // GoogleDomains is the list of domains a user may be a member of + HerokuClientID string // HerokuClientID is the Heroku OAuth id + HerokuSecret string // HerokuSecret is the Heroku OAuth secret PublicURL string // PublicURL is the public facing URL for the server } @@ -42,6 +44,10 @@ func (m *MuxOpts) UseGoogle() bool { return m.TokenSecret != "" && m.GoogleClientID != "" && m.GoogleClientSecret != "" && m.PublicURL != "" } +func (m *MuxOpts) UseHeroku() bool { + return m.TokenSecret != "" && m.HerokuClientID != "" && m.HerokuSecret != "" +} + func (m *MuxOpts) Routes() AuthRoutes { routes := AuthRoutes{} if m.UseGithub() { @@ -50,6 +56,9 @@ func (m *MuxOpts) Routes() AuthRoutes { if m.UseGoogle() { routes = append(routes, NewGoogleRoute()) } + if m.UseHeroku() { + routes = append(routes, NewHerokuRoute()) + } return routes } @@ -195,6 +204,19 @@ func AuthAPI(opts MuxOpts, router *httprouter.Router) http.Handler { router.Handler("GET", "/oauth/google/callback", goMux.Callback()) } + if opts.UseHeroku() { + heroku := oauth2.Heroku{ + ClientID: opts.HerokuClientID, + ClientSecret: opts.HerokuSecret, + Logger: opts.Logger, + } + + hMux := oauth2.NewJWTMux(&heroku, &auth, opts.Logger) + router.Handler("GET", "/oauth/heroku/login", hMux.Login()) + router.Handler("GET", "/oauth/heroku/logout", hMux.Logout()) + router.Handler("GET", "/oauth/heroku/callback", hMux.Callback()) + } + tokenMiddleware := oauth2.AuthorizedToken(&auth, &oauth2.CookieExtractor{Name: "session"}, opts.Logger, router) // Wrap the API with token validation middleware. return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { diff --git a/server/routes.go b/server/routes.go index 4dbef40b54..4a8d899876 100644 --- a/server/routes.go +++ b/server/routes.go @@ -79,3 +79,13 @@ func NewGoogleRoute() AuthRoute { Callback: "/oauth/google/callback", } } + +func NewHerokuRoute() AuthRoute { + return AuthRoute{ + Name: "heroku", + Label: "Heroku", + Login: "/oauth/heroku/login", + Logout: "/oauth/heroku/logout", + Callback: "/oauth/heroku/callback", + } +} diff --git a/server/server.go b/server/server.go index 87cd4901ce..81d943fc04 100644 --- a/server/server.go +++ b/server/server.go @@ -40,18 +40,23 @@ type Server struct { TLSCertificateKey flags.Filename `long:"tls-key" description:"the private key to use for secure conections" env:"TLS_PRIVATE_KEY"` */ - Develop bool `short:"d" long:"develop" description:"Run server in develop mode."` - BoltPath string `short:"b" long:"bolt-path" description:"Full path to boltDB file (/var/lib/chronograf/chronograf-v1.db)" env:"BOLT_PATH" default:"chronograf-v1.db"` - CannedPath string `short:"c" long:"canned-path" description:"Path to directory of pre-canned application layouts (/usr/share/chronograf/canned)" env:"CANNED_PATH" default:"canned"` - TokenSecret string `short:"t" long:"token-secret" description:"Secret to sign tokens" env:"TOKEN_SECRET"` + Develop bool `short:"d" long:"develop" description:"Run server in develop mode."` + BoltPath string `short:"b" long:"bolt-path" description:"Full path to boltDB file (/var/lib/chronograf/chronograf-v1.db)" env:"BOLT_PATH" default:"chronograf-v1.db"` + CannedPath string `short:"c" long:"canned-path" description:"Path to directory of pre-canned application layouts (/usr/share/chronograf/canned)" env:"CANNED_PATH" default:"canned"` + TokenSecret string `short:"t" long:"token-secret" description:"Secret to sign tokens" env:"TOKEN_SECRET"` + GithubClientID string `short:"i" long:"github-client-id" description:"Github Client ID for OAuth 2 support" env:"GH_CLIENT_ID"` GithubClientSecret string `short:"s" long:"github-client-secret" description:"Github Client Secret for OAuth 2 support" env:"GH_CLIENT_SECRET"` GithubOrgs []string `short:"o" long:"github-organization" description:"Github organization user is required to have active membership" env:"GH_ORGS" env-delim:","` + GoogleClientID string `long:"google-client-id" description:"Google Client ID for OAuth 2 support" env:"GOOGLE_CLIENT_ID"` GoogleClientSecret string `long:"google-client-secret" description:"Google Client Secret for OAuth 2 support" env:"GOGGLE_CLIENT_SECRET"` GoogleDomains []string `long:"google-domains" description:"Google email domain user is required to have active membership" env:"GOOGLE_DOMAINS" env-delim:","` PublicURL string `long:"public-url" description:"Full public URL used to access Chronograf from a web browser. Used for Google OAuth2 authentication. (http://localhost:8888)" env:"PUBLIC_URL"` + HerokuClientID string `long:"heroku-client-id" description:"Heroku Client ID for OAuth 2 support" env:"HEROKU_CLIENT_ID"` + HerokuSecret string `long:"heroku-secret" description:"Heroku Secret for OAuth 2 support" env:"HEROKU_SECRET"` + ReportingDisabled bool `short:"r" long:"reporting-disabled" description:"Disable reporting of usage stats (os,arch,version,cluster_id,uptime) once every 24hr" env:"REPORTING_DISABLED"` LogLevel string `short:"l" long:"log-level" value-name:"choice" choice:"debug" choice:"info" choice:"warn" choice:"error" choice:"fatal" choice:"panic" default:"info" description:"Set the logging level" env:"LOG_LEVEL"` Basepath string `short:"p" long:"basepath" description:"A URL path prefix under which all chronograf routes will be mounted" env:"BASE_PATH"` @@ -70,7 +75,8 @@ type BuildInfo struct { func (s *Server) useAuth() bool { gh := s.TokenSecret != "" && s.GithubClientID != "" && s.GithubClientSecret != "" google := s.TokenSecret != "" && s.GoogleClientID != "" && s.GoogleClientSecret != "" && s.PublicURL != "" - return gh || google + heroku := s.TokenSecret != "" && s.HerokuClientID != "" && s.HerokuSecret != "" + return gh || google || heroku } // Serve starts and runs the chronograf server @@ -87,6 +93,8 @@ func (s *Server) Serve() error { GoogleClientID: s.GoogleClientID, GoogleClientSecret: s.GoogleClientSecret, GoogleDomains: s.GoogleDomains, + HerokuClientID: s.HerokuClientID, + HerokuSecret: s.HerokuSecret, PublicURL: s.PublicURL, Logger: logger, UseAuth: s.useAuth(),