mirror of
https://github.com/grafana/grafana.git
synced 2025-02-20 11:48:34 -06:00
Github oauth login works
This commit is contained in:
parent
b0b77d667c
commit
3bba8b2c26
2
grafana
2
grafana
@ -1 +1 @@
|
||||
Subproject commit 071ac0dc85e48be546315dde196f90f01ad7b274
|
||||
Subproject commit d584076b93b4ebfb33e5a5f375feb6d6ff7f9bfc
|
1
pkg/api/api_oauth.go
Normal file
1
pkg/api/api_oauth.go
Normal file
@ -0,0 +1 @@
|
||||
package api
|
112
pkg/api/api_oauth_github.go
Normal file
112
pkg/api/api_oauth_github.go
Normal file
@ -0,0 +1,112 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
|
||||
log "github.com/alecthomas/log4go"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/golang/oauth2"
|
||||
"github.com/torkelo/grafana-pro/pkg/models"
|
||||
"github.com/torkelo/grafana-pro/pkg/stores"
|
||||
)
|
||||
|
||||
var (
|
||||
githubOAuthConfig *oauth2.Config
|
||||
githubRedirectUrl string = "http://localhost:3000/oauth2/github/callback"
|
||||
githubAuthUrl string = "https://github.com/login/oauth/authorize"
|
||||
githubTokenUrl string = "https://github.com/login/oauth/access_token"
|
||||
)
|
||||
|
||||
func init() {
|
||||
addRoutes(func(self *HttpServer) {
|
||||
if !self.cfg.Http.GithubOAuth.Enabled {
|
||||
return
|
||||
}
|
||||
|
||||
self.router.GET("/oauth2/github", self.oauthGithub)
|
||||
self.router.GET("/oauth2/github/callback", self.oauthGithubCallback)
|
||||
|
||||
options := &oauth2.Options{
|
||||
ClientID: self.cfg.Http.GithubOAuth.ClientId,
|
||||
ClientSecret: self.cfg.Http.GithubOAuth.ClientSecret,
|
||||
RedirectURL: githubRedirectUrl,
|
||||
Scopes: []string{"user:email"},
|
||||
}
|
||||
|
||||
cfg, err := oauth2.NewConfig(options, githubAuthUrl, githubTokenUrl)
|
||||
|
||||
if err != nil {
|
||||
log.Error("Failed to init github auth %v", err)
|
||||
}
|
||||
|
||||
githubOAuthConfig = cfg
|
||||
})
|
||||
}
|
||||
|
||||
func (self *HttpServer) oauthGithub(c *gin.Context) {
|
||||
url := githubOAuthConfig.AuthCodeURL("", "online", "auto")
|
||||
c.Redirect(302, url)
|
||||
}
|
||||
|
||||
type githubUserInfoDto struct {
|
||||
Login string `json:"login"`
|
||||
Name string `json:"name"`
|
||||
Email string `json:"email"`
|
||||
Company string `json:"company"`
|
||||
}
|
||||
|
||||
func (self *HttpServer) oauthGithubCallback(c *gin.Context) {
|
||||
code := c.Request.URL.Query()["code"][0]
|
||||
log.Info("OAuth code: %v", code)
|
||||
|
||||
transport, err := githubOAuthConfig.NewTransportWithCode(code)
|
||||
if err != nil {
|
||||
c.String(500, "Failed to exchange oauth token: "+err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
client := http.Client{Transport: transport}
|
||||
resp, err := client.Get("https://api.github.com/user")
|
||||
if err != nil {
|
||||
c.String(500, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
var userInfo githubUserInfoDto
|
||||
decoder := json.NewDecoder(resp.Body)
|
||||
err = decoder.Decode(&userInfo)
|
||||
if err != nil {
|
||||
c.String(500, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
if len(userInfo.Email) < 5 {
|
||||
c.String(500, "Invalid email")
|
||||
return
|
||||
}
|
||||
|
||||
// try find existing account
|
||||
account, err := self.store.GetAccountByLogin(userInfo.Email)
|
||||
|
||||
// create account if missing
|
||||
if err == stores.ErrAccountNotFound {
|
||||
account = &models.Account{
|
||||
Login: userInfo.Login,
|
||||
Email: userInfo.Email,
|
||||
Name: userInfo.Name,
|
||||
Company: userInfo.Company,
|
||||
}
|
||||
|
||||
if err = self.store.CreateAccount(account); err != nil {
|
||||
log.Error("Failed to create account %v", err)
|
||||
c.String(500, "Failed to create account")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// login
|
||||
loginUserWithAccount(account, c)
|
||||
|
||||
c.Redirect(302, "/")
|
||||
}
|
@ -11,7 +11,14 @@ import (
|
||||
"github.com/torkelo/grafana-pro/pkg/stores"
|
||||
)
|
||||
|
||||
var oauthCfg *oauth2.Config
|
||||
var (
|
||||
googleOAuthConfig *oauth2.Config
|
||||
googleRedirectUrl string = "http://localhost:3000/oauth2/google/callback"
|
||||
googleAuthUrl string = "https://accounts.google.com/o/oauth2/auth"
|
||||
googleTokenUrl string = "https://accounts.google.com/o/oauth2/token"
|
||||
googleScopeProfile string = "https://www.googleapis.com/auth/userinfo.profile"
|
||||
googleScopeEmail string = "https://www.googleapis.com/auth/userinfo.email"
|
||||
)
|
||||
|
||||
func init() {
|
||||
addRoutes(func(self *HttpServer) {
|
||||
@ -19,33 +26,28 @@ func init() {
|
||||
return
|
||||
}
|
||||
|
||||
self.router.GET("/login/google", self.loginGoogle)
|
||||
self.router.GET("/oauth2callback", self.oauthCallback)
|
||||
self.router.GET("/oauth2/google", self.oauthGoogle)
|
||||
self.router.GET("/oauth2/google/callback", self.oauthGoogleCallback)
|
||||
|
||||
options := &oauth2.Options{
|
||||
ClientID: self.cfg.Http.GoogleOAuth.ClientId,
|
||||
ClientSecret: self.cfg.Http.GoogleOAuth.ClientSecret,
|
||||
RedirectURL: "http://localhost:3000/oauth2callback",
|
||||
Scopes: []string{
|
||||
"https://www.googleapis.com/auth/userinfo.profile",
|
||||
"https://www.googleapis.com/auth/userinfo.email",
|
||||
},
|
||||
RedirectURL: googleRedirectUrl,
|
||||
Scopes: []string{googleScopeEmail, googleScopeProfile},
|
||||
}
|
||||
|
||||
cfg, err := oauth2.NewConfig(options,
|
||||
"https://accounts.google.com/o/oauth2/auth",
|
||||
"https://accounts.google.com/o/oauth2/token")
|
||||
cfg, err := oauth2.NewConfig(options, googleAuthUrl, googleTokenUrl)
|
||||
|
||||
if err != nil {
|
||||
log.Error("Failed to init google auth %v", err)
|
||||
}
|
||||
|
||||
oauthCfg = cfg
|
||||
googleOAuthConfig = cfg
|
||||
})
|
||||
}
|
||||
|
||||
func (self *HttpServer) loginGoogle(c *gin.Context) {
|
||||
url := oauthCfg.AuthCodeURL("", "online", "auto")
|
||||
func (self *HttpServer) oauthGoogle(c *gin.Context) {
|
||||
url := googleOAuthConfig.AuthCodeURL("", "online", "auto")
|
||||
c.Redirect(302, url)
|
||||
}
|
||||
|
||||
@ -56,11 +58,11 @@ type googleUserInfoDto struct {
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
func (self *HttpServer) oauthCallback(c *gin.Context) {
|
||||
func (self *HttpServer) oauthGoogleCallback(c *gin.Context) {
|
||||
code := c.Request.URL.Query()["code"][0]
|
||||
log.Info("OAuth code: %v", code)
|
||||
|
||||
transport, err := oauthCfg.NewTransportWithCode(code)
|
||||
transport, err := googleOAuthConfig.NewTransportWithCode(code)
|
||||
if err != nil {
|
||||
c.String(500, "Failed to exchange oauth token: "+err.Error())
|
||||
return
|
@ -6,10 +6,11 @@ type Cfg struct {
|
||||
|
||||
type HttpCfg struct {
|
||||
Port string
|
||||
GoogleOAuth GoogleOAuthCfg
|
||||
GoogleOAuth OAuthCfg
|
||||
GithubOAuth OAuthCfg
|
||||
}
|
||||
|
||||
type GoogleOAuthCfg struct {
|
||||
type OAuthCfg struct {
|
||||
Enabled bool
|
||||
ClientId string
|
||||
ClientSecret string
|
||||
@ -24,11 +25,16 @@ func NewCfg(port string) *Cfg {
|
||||
return &Cfg{
|
||||
Http: HttpCfg{
|
||||
Port: port,
|
||||
GoogleOAuth: GoogleOAuthCfg{
|
||||
GoogleOAuth: OAuthCfg{
|
||||
Enabled: true,
|
||||
ClientId: "106011922963-4pvl05e9urtrm8bbqr0vouosj3e8p8kb.apps.googleusercontent.com",
|
||||
ClientSecret: "K2evIa4QhfbhhAm3SO72t2Zv",
|
||||
},
|
||||
GithubOAuth: OAuthCfg{
|
||||
Enabled: true,
|
||||
ClientId: "de054205006b9baa2e17",
|
||||
ClientSecret: "72b7ea52d9f1096fdf36cea95e95362a307e0322",
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
@ -27,6 +27,7 @@ type Account struct {
|
||||
AccountName string
|
||||
Password string
|
||||
Name string
|
||||
Company string
|
||||
NextDashboardId int
|
||||
UsingAccountId int
|
||||
Collaborators []CollaboratorLink
|
||||
|
Loading…
Reference in New Issue
Block a user