mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
OAuth remake
This commit is contained in:
parent
450d242d5f
commit
d7cd2b970e
1
.gitignore
vendored
1
.gitignore
vendored
@ -15,3 +15,4 @@ config.js
|
|||||||
.idea/
|
.idea/
|
||||||
|
|
||||||
data/sessions
|
data/sessions
|
||||||
|
grafana-pro
|
||||||
|
@ -34,6 +34,25 @@ session_id_hashfunc = sha1
|
|||||||
; Session hash key, default is use random string
|
; Session hash key, default is use random string
|
||||||
session_id_hashkey =
|
session_id_hashkey =
|
||||||
|
|
||||||
|
[oauth]
|
||||||
|
enabled = true
|
||||||
|
|
||||||
|
[oauth.github]
|
||||||
|
enabled = true
|
||||||
|
client_id = de054205006b9baa2e17
|
||||||
|
client_secret = 72b7ea52d9f1096fdf36cea95e95362a307e0322
|
||||||
|
scopes = user:email
|
||||||
|
auth_url = https://github.com/login/oauth/authorize
|
||||||
|
token_url = https://github.com/login/oauth/access_token
|
||||||
|
|
||||||
|
[oauth.google]
|
||||||
|
enabled = true
|
||||||
|
client_id = 106011922963-4pvl05e9urtrm8bbqr0vouosj3e8p8kb.apps.googleusercontent.com
|
||||||
|
client_secret = K2evIa4QhfbhhAm3SO72t2Zv
|
||||||
|
scopes = https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email
|
||||||
|
auth_url = https://accounts.google.com/o/oauth2/auth
|
||||||
|
token_url = https://accounts.google.com/o/oauth2/token
|
||||||
|
|
||||||
[log]
|
[log]
|
||||||
root_path =
|
root_path =
|
||||||
; Either "console", "file", "conn", "smtp" or "database", default is "console"
|
; Either "console", "file", "conn", "smtp" or "database", default is "console"
|
||||||
|
BIN
grafana-pro
BIN
grafana-pro
Binary file not shown.
@ -16,6 +16,7 @@ import (
|
|||||||
"github.com/torkelo/grafana-pro/pkg/middleware"
|
"github.com/torkelo/grafana-pro/pkg/middleware"
|
||||||
"github.com/torkelo/grafana-pro/pkg/routes"
|
"github.com/torkelo/grafana-pro/pkg/routes"
|
||||||
"github.com/torkelo/grafana-pro/pkg/setting"
|
"github.com/torkelo/grafana-pro/pkg/setting"
|
||||||
|
"github.com/torkelo/grafana-pro/pkg/social"
|
||||||
"github.com/torkelo/grafana-pro/pkg/stores/rethink"
|
"github.com/torkelo/grafana-pro/pkg/stores/rethink"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -65,6 +66,7 @@ func runWeb(*cli.Context) {
|
|||||||
setting.NewConfigContext()
|
setting.NewConfigContext()
|
||||||
setting.InitServices()
|
setting.InitServices()
|
||||||
rethink.Init()
|
rethink.Init()
|
||||||
|
social.NewOAuthService()
|
||||||
|
|
||||||
log.Info("Starting Grafana-Pro v.1-alpha")
|
log.Info("Starting Grafana-Pro v.1-alpha")
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@ package middleware
|
|||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
"github.com/Unknwon/macaron"
|
"github.com/Unknwon/macaron"
|
||||||
"github.com/macaron-contrib/session"
|
"github.com/macaron-contrib/session"
|
||||||
@ -52,7 +53,7 @@ func (ctx *Context) Handle(status int, title string, err error) {
|
|||||||
ctx.Data["Title"] = "Internal Server Error"
|
ctx.Data["Title"] = "Internal Server Error"
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.HTML(status, "index")
|
ctx.HTML(status, strconv.Itoa(status))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ctx *Context) JsonApiErr(status int, message string, err error) {
|
func (ctx *Context) JsonApiErr(status int, message string, err error) {
|
||||||
|
@ -13,14 +13,14 @@ import (
|
|||||||
|
|
||||||
func OAuthLogin(ctx *middleware.Context) {
|
func OAuthLogin(ctx *middleware.Context) {
|
||||||
if setting.OAuthService == nil {
|
if setting.OAuthService == nil {
|
||||||
ctx.Handle(404, "social.SocialSignIn(oauth service not enabled)", nil)
|
ctx.Handle(404, "login.OAuthLogin(oauth service not enabled)", nil)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
name := ctx.Params(":name")
|
name := ctx.Params(":name")
|
||||||
connect, ok := social.SocialMap[name]
|
connect, ok := social.SocialMap[name]
|
||||||
if !ok {
|
if !ok {
|
||||||
ctx.Handle(404, "social.SocialSignIn(social login not enabled)", errors.New(name))
|
ctx.Handle(404, "login.OAuthLogin(social login not enabled)", errors.New(name))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -29,23 +29,24 @@ func OAuthLogin(ctx *middleware.Context) {
|
|||||||
ctx.Redirect(connect.AuthCodeURL("", "online", "auto"))
|
ctx.Redirect(connect.AuthCodeURL("", "online", "auto"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
log.Info("code: %v", code)
|
||||||
|
|
||||||
// handle call back
|
// handle call back
|
||||||
transport, err := connect.NewTransportWithCode(code)
|
transport, err := connect.NewTransportWithCode(code)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.Handle(500, "social.SocialSignIn(NewTransportWithCode)", err)
|
ctx.Handle(500, "login.OAuthLogin(NewTransportWithCode)", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Trace("social.SocialSignIn(Got token)")
|
log.Trace("login.OAuthLogin(Got token)")
|
||||||
|
|
||||||
userInfo, err := connect.UserInfo(transport)
|
userInfo, err := connect.UserInfo(transport)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.Handle(500, fmt.Sprintf("social.SocialSignIn(get info from %s)", name), err)
|
ctx.Handle(500, fmt.Sprintf("login.OAuthLogin(get info from %s)", name), err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Info("social.SocialSignIn(social login): %s", userInfo)
|
log.Info("login.OAuthLogin(social login): %s", userInfo)
|
||||||
|
|
||||||
account, err := models.GetAccountByLogin(userInfo.Email)
|
account, err := models.GetAccountByLogin(userInfo.Email)
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@ type OAuthInfo struct {
|
|||||||
ClientId, ClientSecret string
|
ClientId, ClientSecret string
|
||||||
Scopes []string
|
Scopes []string
|
||||||
AuthUrl, TokenUrl string
|
AuthUrl, TokenUrl string
|
||||||
|
Enabled bool
|
||||||
}
|
}
|
||||||
|
|
||||||
type OAuther struct {
|
type OAuther struct {
|
||||||
|
@ -29,31 +29,33 @@ type SocialConnector interface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
SocialBaseUrl = "/login"
|
SocialBaseUrl = "/login/"
|
||||||
SocialMap = make(map[string]SocialConnector)
|
SocialMap = make(map[string]SocialConnector)
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewOauthService() {
|
func NewOAuthService() {
|
||||||
if !setting.Cfg.MustBool("oauth", "enabled") {
|
if !setting.Cfg.MustBool("oauth", "enabled") {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
var err error
|
|
||||||
setting.OAuthService = &setting.OAuther{}
|
setting.OAuthService = &setting.OAuther{}
|
||||||
setting.OAuthService.OAuthInfos = make(map[string]*setting.OAuthInfo)
|
setting.OAuthService.OAuthInfos = make(map[string]*setting.OAuthInfo)
|
||||||
|
|
||||||
socialConfigs := make(map[string]*oauth2.Config)
|
|
||||||
|
|
||||||
allOauthes := []string{"github", "google", "twitter"}
|
allOauthes := []string{"github", "google", "twitter"}
|
||||||
|
|
||||||
// Load all OAuth config data.
|
// Load all OAuth config data.
|
||||||
for _, name := range allOauthes {
|
for _, name := range allOauthes {
|
||||||
info := &setting.OAuthInfo{
|
info := &setting.OAuthInfo{
|
||||||
ClientId: setting.Cfg.MustValue("oauth."+name, "client_id"),
|
ClientId: setting.Cfg.MustValue("oauth."+name, "client_id"),
|
||||||
ClientSecret: setting.Cfg.MustValue("oauth."+name, "client_secrect"),
|
ClientSecret: setting.Cfg.MustValue("oauth."+name, "client_secret"),
|
||||||
Scopes: setting.Cfg.MustValueArray("oauth."+name, "scopes", " "),
|
Scopes: setting.Cfg.MustValueArray("oauth."+name, "scopes", " "),
|
||||||
AuthUrl: setting.Cfg.MustValue("oauth."+name, "auth_url"),
|
AuthUrl: setting.Cfg.MustValue("oauth."+name, "auth_url"),
|
||||||
TokenUrl: setting.Cfg.MustValue("oauth."+name, "token_url"),
|
TokenUrl: setting.Cfg.MustValue("oauth."+name, "token_url"),
|
||||||
|
Enabled: setting.Cfg.MustBool("oauth."+name, "enabled"),
|
||||||
|
}
|
||||||
|
|
||||||
|
if !info.Enabled {
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
opts := &oauth2.Options{
|
opts := &oauth2.Options{
|
||||||
@ -64,26 +66,24 @@ func NewOauthService() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
setting.OAuthService.OAuthInfos[name] = info
|
setting.OAuthService.OAuthInfos[name] = info
|
||||||
socialConfigs[name], err = oauth2.NewConfig(opts, info.AuthUrl, info.TokenUrl)
|
config, err := oauth2.NewConfig(opts, info.AuthUrl, info.TokenUrl)
|
||||||
if err != nil {
|
|
||||||
log.Error(4, "Failed to init oauth service", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
enabledOauths := make([]string, 0, 10)
|
if err != nil {
|
||||||
|
log.Error(3, "Failed to init oauth service", err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
// GitHub.
|
// GitHub.
|
||||||
if setting.Cfg.MustBool("oauth.github", "enabled") {
|
if name == "github" {
|
||||||
setting.OAuthService.GitHub = true
|
setting.OAuthService.GitHub = true
|
||||||
newGitHubOAuth(socialConfigs["github"])
|
SocialMap["github"] = &SocialGithub{Config: config}
|
||||||
enabledOauths = append(enabledOauths, "GitHub")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Google.
|
// Google.
|
||||||
if setting.Cfg.MustBool("oauth.google", "enabled") {
|
if name == "google" {
|
||||||
setting.OAuthService.Google = true
|
setting.OAuthService.Google = true
|
||||||
newGoogleOAuth(socialConfigs["google"])
|
SocialMap["google"] = &SocialGoogle{Config: config}
|
||||||
enabledOauths = append(enabledOauths, "Google")
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -95,12 +95,6 @@ func (s *SocialGithub) Type() int {
|
|||||||
return int(models.GITHUB)
|
return int(models.GITHUB)
|
||||||
}
|
}
|
||||||
|
|
||||||
func newGitHubOAuth(config *oauth2.Config) {
|
|
||||||
SocialMap["github"] = &SocialGithub{
|
|
||||||
Config: config,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *SocialGithub) UserInfo(transport *oauth2.Transport) (*BasicUserInfo, error) {
|
func (s *SocialGithub) UserInfo(transport *oauth2.Transport) (*BasicUserInfo, error) {
|
||||||
var data struct {
|
var data struct {
|
||||||
Id int `json:"id"`
|
Id int `json:"id"`
|
||||||
@ -143,12 +137,6 @@ func (s *SocialGoogle) Type() int {
|
|||||||
return int(models.GOOGLE)
|
return int(models.GOOGLE)
|
||||||
}
|
}
|
||||||
|
|
||||||
func newGoogleOAuth(config *oauth2.Config) {
|
|
||||||
SocialMap["google"] = &SocialGoogle{
|
|
||||||
Config: config,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *SocialGoogle) UserInfo(transport *oauth2.Transport) (*BasicUserInfo, error) {
|
func (s *SocialGoogle) UserInfo(transport *oauth2.Transport) (*BasicUserInfo, error) {
|
||||||
var data struct {
|
var data struct {
|
||||||
Id string `json:"id"`
|
Id string `json:"id"`
|
||||||
|
@ -0,0 +1,18 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
||||||
|
<meta name="viewport" content="width=device-width">
|
||||||
|
|
||||||
|
<title>Grafana</title>
|
||||||
|
<link rel="stylesheet" href="/public/css/grafana.dark.min.css" title="Dark">
|
||||||
|
<link rel="icon" type="image/png" href="img/fav32.png">
|
||||||
|
<base href="/">
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<h1>404</h1>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
Loading…
Reference in New Issue
Block a user