mirror of
https://github.com/grafana/grafana.git
synced 2025-07-31 05:02:35 +08:00
update auth proxy
This commit is contained in:
@ -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
|
||||
|
@ -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)
|
||||
return true
|
||||
}
|
||||
|
||||
if !setting.AuthProxyAutoSignUp {
|
||||
return false
|
||||
}
|
||||
|
||||
cmd := getCreateUserCommandForProxyAuth(proxyHeaderValue)
|
||||
if setting.LdapEnabled {
|
||||
cmd.SkipOrgSetup = true
|
||||
}
|
||||
|
||||
if err := bus.Dispatch(cmd); err != nil {
|
||||
ctx.Handle(500, "Failed to create user specified in auth proxy header", err)
|
||||
return true
|
||||
}
|
||||
query = &m.GetSignedInUserQuery{UserId: cmd.Result.Id, OrgId: orgID}
|
||||
if err := bus.Dispatch(query); err != nil {
|
||||
ctx.Handle(500, "Failed find user after creation", 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")
|
||||
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
|
||||
}
|
||||
} else {
|
||||
extUser := m.ExternalUserInfo{
|
||||
AuthModule: "authproxy",
|
||||
AuthId: proxyHeaderValue,
|
||||
}
|
||||
|
||||
// initialize a new session
|
||||
if err := ctx.Session.Start(ctx.Context); err != nil {
|
||||
log.Error(3, "Failed to start session", err)
|
||||
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)
|
||||
}
|
||||
|
||||
// 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.UserId = userQuery.User.Id
|
||||
|
||||
if err := bus.Dispatch(query); err != nil {
|
||||
ctx.Handle(500, "Failed to find user", err)
|
||||
return true
|
||||
}
|
||||
|
||||
// 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)
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
@ -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"
|
||||
|
Reference in New Issue
Block a user