Oauth2 Updates (#6226)

* break out go and js build commands

* support oauth providers that return errors via redirect

* remove extra call to get grafana.net org membership

* removed GitHub specifics from generic OAuth

* readded ability to name generic source

* revert to a backward-compatible state, refactor and clean up

* streamline oauth user creation, make generic oauth support more generic
This commit is contained in:
Dan Cech
2016-10-11 02:51:44 -04:00
committed by Torkel Ödegaard
parent d4fd1c82e3
commit 6b16fcea52
9 changed files with 139 additions and 90 deletions

View File

@@ -1,11 +1,17 @@
package api
import (
"crypto/rand"
"crypto/tls"
"crypto/x509"
"encoding/base64"
"errors"
"fmt"
"crypto/rand"
"encoding/base64"
"io/ioutil"
"log"
"net/http"
"golang.org/x/net/context"
"golang.org/x/oauth2"
"github.com/grafana/grafana/pkg/bus"
@@ -17,9 +23,9 @@ import (
)
func GenStateString() string {
rnd := make([]byte, 32)
rand.Read(rnd)
return base64.StdEncoding.EncodeToString(rnd)
rnd := make([]byte, 32)
rand.Read(rnd)
return base64.StdEncoding.EncodeToString(rnd)
}
func OAuthLogin(ctx *middleware.Context) {
@@ -35,6 +41,14 @@ func OAuthLogin(ctx *middleware.Context) {
return
}
error := ctx.Query("error")
if error != "" {
errorDesc := ctx.Query("error_description")
ctx.Logger.Info("OAuthLogin Failed", "error", error, "errorDesc", errorDesc)
ctx.Redirect(setting.AppSubUrl + "/login?failCode=1003")
return
}
code := ctx.Query("code")
if code == "" {
state := GenStateString()
@@ -52,7 +66,38 @@ func OAuthLogin(ctx *middleware.Context) {
}
// handle call back
token, err := connect.Exchange(oauth2.NoContext, code)
// initialize oauth2 context
oauthCtx := oauth2.NoContext
if setting.OAuthService.OAuthInfos[name].TlsClientCert != "" {
cert, err := tls.LoadX509KeyPair(setting.OAuthService.OAuthInfos[name].TlsClientCert, setting.OAuthService.OAuthInfos[name].TlsClientKey)
if err != nil {
log.Fatal(err)
}
// Load CA cert
caCert, err := ioutil.ReadFile(setting.OAuthService.OAuthInfos[name].TlsClientCa)
if err != nil {
log.Fatal(err)
}
caCertPool := x509.NewCertPool()
caCertPool.AppendCertsFromPEM(caCert)
tr := &http.Transport{
TLSClientConfig: &tls.Config{
InsecureSkipVerify: true,
Certificates: []tls.Certificate{cert},
RootCAs: caCertPool,
},
}
sslcli := &http.Client{Transport: tr}
oauthCtx = context.TODO()
oauthCtx = context.WithValue(oauthCtx, oauth2.HTTPClient, sslcli)
}
// get token from provider
token, err := connect.Exchange(oauthCtx, code)
if err != nil {
ctx.Handle(500, "login.OAuthLogin(NewTransportWithCode)", err)
return
@@ -60,7 +105,11 @@ func OAuthLogin(ctx *middleware.Context) {
ctx.Logger.Debug("OAuthLogin Got token")
userInfo, err := connect.UserInfo(token)
// set up oauth2 client
client := connect.Client(oauthCtx, token)
// get user info
userInfo, err := connect.UserInfo(client)
if err != nil {
if err == social.ErrMissingTeamMembership {
ctx.Redirect(setting.AppSubUrl + "/login?failCode=1000")
@@ -100,7 +149,7 @@ func OAuthLogin(ctx *middleware.Context) {
return
}
cmd := m.CreateUserCommand{
Login: userInfo.Email,
Login: userInfo.Login,
Email: userInfo.Email,
Name: userInfo.Name,
Company: userInfo.Company,