The open and composable observability and data visualization platform. Visualize metrics, logs, and traces from multiple sources like Prometheus, Loki, Elasticsearch, InfluxDB, Postgres and many more.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
grafana/pkg/api/api_oauth_google.go

114 lines
2.8 KiB

11 years ago
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 (
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"
)
11 years ago
func init() {
addRoutes(func(self *HttpServer) {
if !self.cfg.Http.GoogleOAuth.Enabled {
return
}
self.router.GET("/oauth2/google", self.oauthGoogle)
self.router.GET("/oauth2/google/callback", self.oauthGoogleCallback)
11 years ago
options := &oauth2.Options{
ClientID: self.cfg.Http.GoogleOAuth.ClientId,
ClientSecret: self.cfg.Http.GoogleOAuth.ClientSecret,
RedirectURL: googleRedirectUrl,
Scopes: []string{googleScopeEmail, googleScopeProfile},
11 years ago
}
cfg, err := oauth2.NewConfig(options, googleAuthUrl, googleTokenUrl)
11 years ago
if err != nil {
log.Error("Failed to init google auth %v", err)
}
googleOAuthConfig = cfg
11 years ago
})
}
func (self *HttpServer) oauthGoogle(c *gin.Context) {
url := googleOAuthConfig.AuthCodeURL("", "online", "auto")
11 years ago
c.Redirect(302, url)
}
type googleUserInfoDto struct {
Email string `json:"email"`
GivenName string `json:"givenName"`
FamilyName string `json:"familyName"`
Name string `json:"name"`
}
func (self *HttpServer) oauthGoogleCallback(c *gin.Context) {
11 years ago
code := c.Request.URL.Query()["code"][0]
log.Info("OAuth code: %v", code)
transport, err := googleOAuthConfig.NewTransportWithCode(code)
11 years ago
if err != nil {
c.String(500, "Failed to exchange oauth token: "+err.Error())
return
}
client := http.Client{Transport: transport}
resp, err := client.Get("https://www.googleapis.com/oauth2/v1/userinfo?alt=json")
if err != nil {
c.String(500, err.Error())
return
}
var userInfo googleUserInfoDto
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.Email,
Email: userInfo.Email,
Name: userInfo.Name,
}
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, "/")
}