浏览代码

update auth proxy

Dan Cech 7 年之前
父节点
当前提交
d5dd1c9bca
共有 3 个文件被更改,包括 92 次插入68 次删除
  1. 21 9
      pkg/login/ext_user.go
  2. 57 56
      pkg/middleware/auth_proxy.go
  3. 14 3
      pkg/middleware/middleware_test.go

+ 21 - 9
pkg/login/ext_user.go

@@ -9,7 +9,7 @@ import (
 	"github.com/grafana/grafana/pkg/services/quota"
 )
 
-func UpsertUser(ctx *m.ReqContext, cmd *m.UpsertUserCommand) error {
+var UpsertUser = func(ctx *m.ReqContext, cmd *m.UpsertUserCommand) error {
 	extUser := cmd.ExternalUser
 
 	userQuery := m.GetUserByAuthInfoQuery{
@@ -87,14 +87,26 @@ func createUser(extUser *m.ExternalUserInfo) (*m.User, error) {
 
 func updateUser(user *m.User, extUser *m.ExternalUserInfo) error {
 	// sync user info
-	if user.Login != extUser.Login || user.Email != extUser.Email || user.Name != extUser.Name {
-		log.Debug("Syncing user info", "id", user.Id, "login", extUser.Login, "email", extUser.Email)
-		updateCmd := m.UpdateUserCommand{
-			UserId: user.Id,
-			Login:  extUser.Login,
-			Email:  extUser.Email,
-			Name:   extUser.Name,
-		}
+	updateCmd := m.UpdateUserCommand{
+		UserId: user.Id,
+	}
+	needsUpdate := false
+
+	if extUser.Login != "" && extUser.Login != user.Login {
+		updateCmd.Login = extUser.Login
+		needsUpdate = true
+	}
+	if extUser.Email != "" && extUser.Email != user.Email {
+		updateCmd.Email = extUser.Email
+		needsUpdate = true
+	}
+	if extUser.Name != "" && extUser.Name != user.Name {
+		updateCmd.Name = extUser.Name
+		needsUpdate = true
+	}
+
+	if needsUpdate {
+		log.Debug("Syncing user info", "id", user.Id, "update", updateCmd)
 		err := bus.Dispatch(&updateCmd)
 		if err != nil {
 			return err

+ 57 - 56
pkg/middleware/auth_proxy.go

@@ -3,6 +3,7 @@ package middleware
 import (
 	"fmt"
 	"net"
+	"net/mail"
 	"strings"
 	"time"
 
@@ -14,6 +15,8 @@ import (
 	"github.com/grafana/grafana/pkg/setting"
 )
 
+var AUTH_PROXY_SESSION_VAR = "authProxyHeaderValue"
+
 func initContextWithAuthProxy(ctx *m.ReqContext, orgID int64) bool {
 	if !setting.AuthProxyEnabled {
 		return false
@@ -30,51 +33,75 @@ func initContextWithAuthProxy(ctx *m.ReqContext, orgID int64) bool {
 		return true
 	}
 
-	query := getSignedInUserQueryForProxyAuth(proxyHeaderValue)
-	query.OrgId = orgID
-	if err := bus.Dispatch(query); err != nil {
-		if err != m.ErrUserNotFound {
-			ctx.Handle(500, "Failed to find user specified in auth proxy header", err)
+	// initialize session
+	if err := ctx.Session.Start(ctx.Context); err != nil {
+		log.Error(3, "Failed to start session", err)
+		return false
+	}
+
+	query := &m.GetSignedInUserQuery{OrgId: orgID}
+
+	// if this session has already been authenticated by authProxy just load the user
+	sessProxyValue := ctx.Session.Get(AUTH_PROXY_SESSION_VAR)
+	if sessProxyValue != nil && sessProxyValue.(string) == proxyHeaderValue && getRequestUserId(ctx) > 0 {
+		query.UserId = getRequestUserId(ctx)
+		if err := bus.Dispatch(query); err != nil {
+			ctx.Handle(500, "Failed to find user", err)
 			return true
 		}
-
-		if !setting.AuthProxyAutoSignUp {
-			return false
+	} else {
+		extUser := m.ExternalUserInfo{
+			AuthModule: "authproxy",
+			AuthId:     proxyHeaderValue,
 		}
 
-		cmd := getCreateUserCommandForProxyAuth(proxyHeaderValue)
-		if setting.LdapEnabled {
-			cmd.SkipOrgSetup = true
+		if setting.AuthProxyHeaderProperty == "username" {
+			extUser.Login = proxyHeaderValue
+
+			// only set Email if it can be parsed as an email address
+			emailAddr, emailErr := mail.ParseAddress(proxyHeaderValue)
+			if emailErr == nil {
+				extUser.Email = emailAddr.Address
+			}
+		} else if setting.AuthProxyHeaderProperty == "email" {
+			extUser.Email = proxyHeaderValue
+			extUser.Login = proxyHeaderValue
+		} else {
+			ctx.Handle(500, "Auth proxy header property invalid", nil)
 		}
 
-		if err := bus.Dispatch(cmd); err != nil {
-			ctx.Handle(500, "Failed to create user specified in auth proxy header", err)
+		// add/update user in grafana
+		userQuery := &m.UpsertUserCommand{
+			ExternalUser:  &extUser,
+			SignupAllowed: setting.AuthProxyAutoSignUp,
+		}
+		err := login.UpsertUser(ctx, userQuery)
+		if err != nil {
+			ctx.Handle(500, "Failed to login as user specified in auth proxy header", err)
 			return true
 		}
-		query = &m.GetSignedInUserQuery{UserId: cmd.Result.Id, OrgId: orgID}
+
+		query.UserId = userQuery.User.Id
+
 		if err := bus.Dispatch(query); err != nil {
-			ctx.Handle(500, "Failed find user after creation", err)
+			ctx.Handle(500, "Failed to find user", err)
 			return true
 		}
-	}
 
-	// initialize session
-	if err := ctx.Session.Start(ctx.Context); err != nil {
-		log.Error(3, "Failed to start session", err)
-		return false
-	}
+		// Make sure that we cannot share a session between different users!
+		if getRequestUserId(ctx) > 0 && getRequestUserId(ctx) != query.Result.UserId {
+			// remove session
+			if err := ctx.Session.Destory(ctx.Context); err != nil {
+				log.Error(3, "Failed to destroy session, err")
+			}
 
-	// Make sure that we cannot share a session between different users!
-	if getRequestUserId(ctx) > 0 && getRequestUserId(ctx) != query.Result.UserId {
-		// remove session
-		if err := ctx.Session.Destory(ctx.Context); err != nil {
-			log.Error(3, "Failed to destroy session, err")
+			// initialize a new session
+			if err := ctx.Session.Start(ctx.Context); err != nil {
+				log.Error(3, "Failed to start session", err)
+			}
 		}
 
-		// initialize a new session
-		if err := ctx.Session.Start(ctx.Context); err != nil {
-			log.Error(3, "Failed to start session", err)
-		}
+		ctx.Session.Set(AUTH_PROXY_SESSION_VAR, proxyHeaderValue)
 	}
 
 	// When ldap is enabled, sync userinfo and org roles
@@ -143,29 +170,3 @@ func checkAuthenticationProxy(remoteAddr string, proxyHeaderValue string) error
 
 	return fmt.Errorf("Request for user (%s) from %s is not from the authentication proxy", proxyHeaderValue, sourceIP)
 }
-
-func getSignedInUserQueryForProxyAuth(headerVal string) *m.GetSignedInUserQuery {
-	query := m.GetSignedInUserQuery{}
-	if setting.AuthProxyHeaderProperty == "username" {
-		query.Login = headerVal
-	} else if setting.AuthProxyHeaderProperty == "email" {
-		query.Email = headerVal
-	} else {
-		panic("Auth proxy header property invalid")
-	}
-	return &query
-}
-
-func getCreateUserCommandForProxyAuth(headerVal string) *m.CreateUserCommand {
-	cmd := m.CreateUserCommand{}
-	if setting.AuthProxyHeaderProperty == "username" {
-		cmd.Login = headerVal
-		cmd.Email = headerVal
-	} else if setting.AuthProxyHeaderProperty == "email" {
-		cmd.Email = headerVal
-		cmd.Login = headerVal
-	} else {
-		panic("Auth proxy header property invalid")
-	}
-	return &cmd
-}

+ 14 - 3
pkg/middleware/middleware_test.go

@@ -9,6 +9,7 @@ import (
 
 	ms "github.com/go-macaron/session"
 	"github.com/grafana/grafana/pkg/bus"
+	"github.com/grafana/grafana/pkg/login"
 	m "github.com/grafana/grafana/pkg/models"
 	"github.com/grafana/grafana/pkg/services/session"
 	"github.com/grafana/grafana/pkg/setting"
@@ -182,6 +183,11 @@ func TestMiddlewareContext(t *testing.T) {
 				return nil
 			})
 
+			login.UpsertUser = func(ctx *m.ReqContext, cmd *m.UpsertUserCommand) error {
+				cmd.User = &m.User{Id: 12}
+				return nil
+			}
+
 			sc.fakeReq("GET", "/")
 			sc.req.Header.Add("X-WEBAUTH-USER", "torkelo")
 			sc.exec()
@@ -208,10 +214,10 @@ func TestMiddlewareContext(t *testing.T) {
 				}
 			})
 
-			bus.AddHandler("test", func(cmd *m.CreateUserCommand) error {
-				cmd.Result = m.User{Id: 33}
+			login.UpsertUser = func(ctx *m.ReqContext, cmd *m.UpsertUserCommand) error {
+				cmd.User = &m.User{Id: 33}
 				return nil
-			})
+			}
 
 			sc.fakeReq("GET", "/")
 			sc.req.Header.Add("X-WEBAUTH-USER", "torkelo")
@@ -270,6 +276,11 @@ func TestMiddlewareContext(t *testing.T) {
 				return nil
 			})
 
+			login.UpsertUser = func(ctx *m.ReqContext, cmd *m.UpsertUserCommand) error {
+				cmd.User = &m.User{Id: 33}
+				return nil
+			}
+
 			sc.fakeReq("GET", "/")
 			sc.req.Header.Add("X-WEBAUTH-USER", "torkelo")
 			sc.req.RemoteAddr = "[2001::23]:12345"