Commit d5dd1c9b by Dan Cech

update auth proxy

parent 23f163e8
...@@ -9,7 +9,7 @@ import ( ...@@ -9,7 +9,7 @@ import (
"github.com/grafana/grafana/pkg/services/quota" "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 extUser := cmd.ExternalUser
userQuery := m.GetUserByAuthInfoQuery{ userQuery := m.GetUserByAuthInfoQuery{
...@@ -87,14 +87,26 @@ func createUser(extUser *m.ExternalUserInfo) (*m.User, error) { ...@@ -87,14 +87,26 @@ func createUser(extUser *m.ExternalUserInfo) (*m.User, error) {
func updateUser(user *m.User, extUser *m.ExternalUserInfo) error { func updateUser(user *m.User, extUser *m.ExternalUserInfo) error {
// sync user info // sync user info
if user.Login != extUser.Login || user.Email != extUser.Email || user.Name != extUser.Name { updateCmd := m.UpdateUserCommand{
log.Debug("Syncing user info", "id", user.Id, "login", extUser.Login, "email", extUser.Email) UserId: user.Id,
updateCmd := m.UpdateUserCommand{ }
UserId: user.Id, needsUpdate := false
Login: extUser.Login,
Email: extUser.Email, if extUser.Login != "" && extUser.Login != user.Login {
Name: extUser.Name, 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) err := bus.Dispatch(&updateCmd)
if err != nil { if err != nil {
return err return err
......
...@@ -3,6 +3,7 @@ package middleware ...@@ -3,6 +3,7 @@ package middleware
import ( import (
"fmt" "fmt"
"net" "net"
"net/mail"
"strings" "strings"
"time" "time"
...@@ -14,6 +15,8 @@ import ( ...@@ -14,6 +15,8 @@ import (
"github.com/grafana/grafana/pkg/setting" "github.com/grafana/grafana/pkg/setting"
) )
var AUTH_PROXY_SESSION_VAR = "authProxyHeaderValue"
func initContextWithAuthProxy(ctx *m.ReqContext, orgID int64) bool { func initContextWithAuthProxy(ctx *m.ReqContext, orgID int64) bool {
if !setting.AuthProxyEnabled { if !setting.AuthProxyEnabled {
return false return false
...@@ -30,51 +33,75 @@ func initContextWithAuthProxy(ctx *m.ReqContext, orgID int64) bool { ...@@ -30,51 +33,75 @@ func initContextWithAuthProxy(ctx *m.ReqContext, orgID int64) bool {
return true return true
} }
query := getSignedInUserQueryForProxyAuth(proxyHeaderValue) // initialize session
query.OrgId = orgID if err := ctx.Session.Start(ctx.Context); err != nil {
if err := bus.Dispatch(query); err != nil { log.Error(3, "Failed to start session", err)
if err != m.ErrUserNotFound { return false
ctx.Handle(500, "Failed to find user specified in auth proxy header", 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 return true
} }
} else {
if !setting.AuthProxyAutoSignUp { extUser := m.ExternalUserInfo{
return false AuthModule: "authproxy",
AuthId: proxyHeaderValue,
} }
cmd := getCreateUserCommandForProxyAuth(proxyHeaderValue) if setting.AuthProxyHeaderProperty == "username" {
if setting.LdapEnabled { extUser.Login = proxyHeaderValue
cmd.SkipOrgSetup = true
// 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 { // add/update user in grafana
ctx.Handle(500, "Failed to create user specified in auth proxy header", err) 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 return true
} }
query = &m.GetSignedInUserQuery{UserId: cmd.Result.Id, OrgId: orgID}
query.UserId = userQuery.User.Id
if err := bus.Dispatch(query); err != nil { 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 return true
} }
}
// initialize session // Make sure that we cannot share a session between different users!
if err := ctx.Session.Start(ctx.Context); err != nil { if getRequestUserId(ctx) > 0 && getRequestUserId(ctx) != query.Result.UserId {
log.Error(3, "Failed to start session", err) // remove session
return false 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! // initialize a new session
if getRequestUserId(ctx) > 0 && getRequestUserId(ctx) != query.Result.UserId { if err := ctx.Session.Start(ctx.Context); err != nil {
// remove session log.Error(3, "Failed to start session", err)
if err := ctx.Session.Destory(ctx.Context); err != nil { }
log.Error(3, "Failed to destroy session, err")
} }
// initialize a new session ctx.Session.Set(AUTH_PROXY_SESSION_VAR, proxyHeaderValue)
if err := ctx.Session.Start(ctx.Context); err != nil {
log.Error(3, "Failed to start session", err)
}
} }
// When ldap is enabled, sync userinfo and org roles // When ldap is enabled, sync userinfo and org roles
...@@ -143,29 +170,3 @@ func checkAuthenticationProxy(remoteAddr string, proxyHeaderValue string) error ...@@ -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) 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 ( ...@@ -9,6 +9,7 @@ import (
ms "github.com/go-macaron/session" ms "github.com/go-macaron/session"
"github.com/grafana/grafana/pkg/bus" "github.com/grafana/grafana/pkg/bus"
"github.com/grafana/grafana/pkg/login"
m "github.com/grafana/grafana/pkg/models" m "github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/session" "github.com/grafana/grafana/pkg/services/session"
"github.com/grafana/grafana/pkg/setting" "github.com/grafana/grafana/pkg/setting"
...@@ -182,6 +183,11 @@ func TestMiddlewareContext(t *testing.T) { ...@@ -182,6 +183,11 @@ func TestMiddlewareContext(t *testing.T) {
return nil return nil
}) })
login.UpsertUser = func(ctx *m.ReqContext, cmd *m.UpsertUserCommand) error {
cmd.User = &m.User{Id: 12}
return nil
}
sc.fakeReq("GET", "/") sc.fakeReq("GET", "/")
sc.req.Header.Add("X-WEBAUTH-USER", "torkelo") sc.req.Header.Add("X-WEBAUTH-USER", "torkelo")
sc.exec() sc.exec()
...@@ -208,10 +214,10 @@ func TestMiddlewareContext(t *testing.T) { ...@@ -208,10 +214,10 @@ func TestMiddlewareContext(t *testing.T) {
} }
}) })
bus.AddHandler("test", func(cmd *m.CreateUserCommand) error { login.UpsertUser = func(ctx *m.ReqContext, cmd *m.UpsertUserCommand) error {
cmd.Result = m.User{Id: 33} cmd.User = &m.User{Id: 33}
return nil return nil
}) }
sc.fakeReq("GET", "/") sc.fakeReq("GET", "/")
sc.req.Header.Add("X-WEBAUTH-USER", "torkelo") sc.req.Header.Add("X-WEBAUTH-USER", "torkelo")
...@@ -270,6 +276,11 @@ func TestMiddlewareContext(t *testing.T) { ...@@ -270,6 +276,11 @@ func TestMiddlewareContext(t *testing.T) {
return nil return nil
}) })
login.UpsertUser = func(ctx *m.ReqContext, cmd *m.UpsertUserCommand) error {
cmd.User = &m.User{Id: 33}
return nil
}
sc.fakeReq("GET", "/") sc.fakeReq("GET", "/")
sc.req.Header.Add("X-WEBAUTH-USER", "torkelo") sc.req.Header.Add("X-WEBAUTH-USER", "torkelo")
sc.req.RemoteAddr = "[2001::23]:12345" sc.req.RemoteAddr = "[2001::23]:12345"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment