From 32a011ecf8a0f5c03aa9b512a2583c8338cd0869 Mon Sep 17 00:00:00 2001 From: Darren Hague Date: Tue, 21 Jun 2016 14:42:38 +0100 Subject: [PATCH 1/6] Log the URL when calling a datasource from the proxy --- pkg/api/dataproxy.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pkg/api/dataproxy.go b/pkg/api/dataproxy.go index 2b55e9197db34..0c736ed608693 100644 --- a/pkg/api/dataproxy.go +++ b/pkg/api/dataproxy.go @@ -11,6 +11,7 @@ import ( "github.com/grafana/grafana/pkg/api/cloudwatch" "github.com/grafana/grafana/pkg/api/keystone" "github.com/grafana/grafana/pkg/bus" + "github.com/grafana/grafana/pkg/log" "github.com/grafana/grafana/pkg/metrics" "github.com/grafana/grafana/pkg/middleware" m "github.com/grafana/grafana/pkg/models" @@ -67,6 +68,8 @@ func NewReverseProxy(ds *m.DataSource, proxyPath string, targetUrl *url.URL) *ht // clear cookie headers req.Header.Del("Cookie") req.Header.Del("Set-Cookie") + + log.Info("Proxying call to %s", req.URL.String()) } return &httputil.ReverseProxy{Director: director, FlushInterval: time.Millisecond * 200} From 38a01560d901115d67eabb28c0fc814c42876171 Mon Sep 17 00:00:00 2001 From: Darren Hague Date: Fri, 19 Aug 2016 14:49:41 +0100 Subject: [PATCH 2/6] Fixes https://github.com/twc-openstack/grafana/issues/5 Configuration options: cookie_credentials - set to true to use cookie instead of session for storing Keystone password credential_aes_key - 32-char encryption key. If set, this key is used to encrypt/decrypt the stored Keystone password --- conf/sample.ini | 5 +++ pkg/api/keystone/keystone.go | 75 +++++++++++++++++++++++++++++++++++- pkg/api/login.go | 27 ++++++++++--- pkg/middleware/middleware.go | 4 ++ pkg/middleware/session.go | 5 +-- pkg/setting/setting.go | 26 +++++++------ 6 files changed, 121 insertions(+), 21 deletions(-) diff --git a/conf/sample.ini b/conf/sample.ini index a64a03d650353..7dc14bb671513 100644 --- a/conf/sample.ini +++ b/conf/sample.ini @@ -268,6 +268,11 @@ ;viewer_roles = ;verify_ssl_cert = true ;root_ca_pem_file = /etc/grafana/Keystone_CA.crt +# Whether to store keystone password in a cookie (true) or in a session variable (false) +;cookie_credentials = true +# Encryption key for storing keystone password (empty = no encryption) +# AES key should be 32 bytes +;credential_aes_key = 123456789,123456789,123456789,12 #################################### SMTP / Emailing ########################## [smtp] diff --git a/pkg/api/keystone/keystone.go b/pkg/api/keystone/keystone.go index 7ca8d63dd5476..8057314527111 100644 --- a/pkg/api/keystone/keystone.go +++ b/pkg/api/keystone/keystone.go @@ -3,11 +3,17 @@ package keystone import ( "time" + "crypto/aes" + "crypto/cipher" + "crypto/rand" + "encoding/base64" "errors" "github.com/grafana/grafana/pkg/bus" + "github.com/grafana/grafana/pkg/log" "github.com/grafana/grafana/pkg/middleware" m "github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/setting" + "io" ) const ( @@ -19,7 +25,13 @@ const ( func getUserName(c *middleware.Context) (string, error) { var keystoneUserIdObj interface{} - if keystoneUserIdObj = c.Session.Get(middleware.SESS_KEY_USERID); keystoneUserIdObj == nil { + if setting.KeystoneCookieCredentials { + if keystoneUserIdObj = c.GetCookie(setting.CookieUserName); keystoneUserIdObj == nil { + return "", errors.New("Couldn't find cookie containing keystone userId") + } else { + return keystoneUserIdObj.(string), nil + } + } else if keystoneUserIdObj = c.Session.Get(middleware.SESS_KEY_USERID); keystoneUserIdObj == nil { return "", errors.New("Session timed out trying to get keystone userId") } @@ -53,8 +65,23 @@ func getNewToken(c *middleware.Context) (string, error) { } var keystonePasswordObj interface{} - if keystonePasswordObj = c.Session.Get(middleware.SESS_KEY_PASSWORD); keystonePasswordObj == nil { + if setting.KeystoneCookieCredentials { + if keystonePasswordObj = c.GetCookie(middleware.SESS_KEY_PASSWORD); keystonePasswordObj == nil { + return "", errors.New("Couldn't find cookie containing keystone password") + } else { + log.Debug("Got password from cookie") + } + } else if keystonePasswordObj = c.Session.Get(middleware.SESS_KEY_PASSWORD); keystonePasswordObj == nil { return "", errors.New("Session timed out trying to get keystone password") + } else if keystonePasswordObj != nil { + log.Debug("Got password from session") + } + + if setting.KeystoneCredentialAesKey != "" { + keystonePasswordObj = decryptPassword(keystonePasswordObj.(string)) + log.Debug("Decrypted password") + } else { + log.Warn("Password stored in cleartext!") } auth := Auth_data{ @@ -65,6 +92,11 @@ func getNewToken(c *middleware.Context) (string, error) { Server: setting.KeystoneURL, } if err := AuthenticateScoped(&auth); err != nil { + if setting.KeystoneCookieCredentials { + c.SetCookie(middleware.SESS_KEY_PASSWORD, "", -1, setting.AppSubUrl+"/", nil, middleware.IsSecure(c), true) + } else { + c.Session.Set(middleware.SESS_KEY_PASSWORD, nil) + } return "", err } @@ -124,3 +156,42 @@ func GetToken(c *middleware.Context) (string, error) { } return token, nil } + +func EncryptPassword(password string) string { + key := []byte(setting.KeystoneCredentialAesKey) + block, err := aes.NewCipher(key) + if err != nil { + log.Error(3, "Error: NewCipher(%d bytes) = %s", len(setting.KeystoneCredentialAesKey), err) + } + ciphertext := make([]byte, aes.BlockSize+len(password)) + iv := ciphertext[:aes.BlockSize] + if _, err := io.ReadFull(rand.Reader, iv); err != nil { + log.Error(3, "Error: %s", err) + } + stream := cipher.NewOFB(block, iv) + stream.XORKeyStream(ciphertext[aes.BlockSize:], []byte(password)) + + return base64.StdEncoding.EncodeToString(ciphertext) +} + +func decryptPassword(base64ciphertext string) string { + key := []byte(setting.KeystoneCredentialAesKey) + block, err := aes.NewCipher(key) + if err != nil { + log.Error(3, "Error: NewCipher(%d bytes) = %s", len(setting.KeystoneCredentialAesKey), err) + } + ciphertext, err := base64.StdEncoding.DecodeString(base64ciphertext) + if err != nil { + log.Error(3, "Error: %s", err) + return "" + } + iv := ciphertext[:aes.BlockSize] + if aes.BlockSize > len(ciphertext) { + log.Error(3, "Error: ciphertext %s is shorter than AES blocksize %d", ciphertext, aes.BlockSize) + return "" + } + password := make([]byte, len(ciphertext)-aes.BlockSize) + stream := cipher.NewOFB(block, iv) + stream.XORKeyStream(password, ciphertext[aes.BlockSize:]) + return string(password) +} diff --git a/pkg/api/login.go b/pkg/api/login.go index 76bee051cf01e..e79fcdce686b9 100644 --- a/pkg/api/login.go +++ b/pkg/api/login.go @@ -4,6 +4,7 @@ import ( "net/url" "github.com/grafana/grafana/pkg/api/dtos" + "github.com/grafana/grafana/pkg/api/keystone" "github.com/grafana/grafana/pkg/bus" "github.com/grafana/grafana/pkg/log" "github.com/grafana/grafana/pkg/login" @@ -112,7 +113,21 @@ func LoginPost(c *middleware.Context, cmd dtos.LoginCommand) Response { loginUserWithUser(user, c) if setting.KeystoneEnabled { - c.Session.Set(middleware.SESS_KEY_PASSWORD, cmd.Password) + if setting.KeystoneCredentialAesKey != "" { + cmd.Password = keystone.EncryptPassword(cmd.Password) + } + if setting.KeystoneCookieCredentials { + log.Debug("c.Req.Header.Get(\"X-Forwarded-Proto\"): %s", c.Req.Header.Get("X-Forwarded-Proto")) + var days interface{} + if setting.LogInRememberDays == 0 { + days = nil + } else { + days = 86400 * setting.LogInRememberDays + } + c.SetCookie(middleware.SESS_KEY_PASSWORD, cmd.Password, days, setting.AppSubUrl+"/", nil, middleware.IsSecure(c), true) + } else { + c.Session.Set(middleware.SESS_KEY_PASSWORD, cmd.Password) + } } result := map[string]interface{}{ @@ -136,16 +151,18 @@ func loginUserWithUser(user *m.User, c *middleware.Context) { days := 86400 * setting.LogInRememberDays if days > 0 { - c.SetCookie(setting.CookieUserName, user.Login, days, setting.AppSubUrl+"/") - c.SetSuperSecureCookie(util.EncodeMd5(user.Rands+user.Password), setting.CookieRememberName, user.Login, days, setting.AppSubUrl+"/") + c.SetCookie(setting.CookieUserName, user.Login, days, setting.AppSubUrl+"/", nil, middleware.IsSecure(c), true) + c.SetSuperSecureCookie(util.EncodeMd5(user.Rands+user.Password), + setting.CookieRememberName, user.Login, days, setting.AppSubUrl+"/", nil, middleware.IsSecure(c), true) } c.Session.Set(middleware.SESS_KEY_USERID, user.Id) } func Logout(c *middleware.Context) { - c.SetCookie(setting.CookieUserName, "", -1, setting.AppSubUrl+"/") - c.SetCookie(setting.CookieRememberName, "", -1, setting.AppSubUrl+"/") + c.SetCookie(setting.CookieUserName, "", -1, setting.AppSubUrl+"/", nil, middleware.IsSecure(c), true) + c.SetCookie(setting.CookieRememberName, "", -1, setting.AppSubUrl+"/", nil, middleware.IsSecure(c), true) + c.SetCookie(middleware.SESS_KEY_PASSWORD, "", -1, setting.AppSubUrl+"/", nil, middleware.IsSecure(c), true) c.Session.Destory(c) c.Redirect(setting.AppSubUrl + "/login") } diff --git a/pkg/middleware/middleware.go b/pkg/middleware/middleware.go index a546d7e76fc3b..c3e4bbc850f92 100644 --- a/pkg/middleware/middleware.go +++ b/pkg/middleware/middleware.go @@ -232,3 +232,7 @@ func (ctx *Context) HasUserRole(role m.RoleType) bool { func (ctx *Context) TimeRequest(timer metrics.Timer) { ctx.Data["perfmon.timer"] = timer } + +func IsSecure(ctx *Context) bool { + return (ctx.Req.TLS != nil) || (ctx.Req.Header.Get("X-Forwarded-Proto") == "https") +} diff --git a/pkg/middleware/session.go b/pkg/middleware/session.go index 8858abfbd8924..1189858ba3df9 100644 --- a/pkg/middleware/session.go +++ b/pkg/middleware/session.go @@ -12,10 +12,9 @@ import ( ) const ( - SESS_KEY_USERID = "uid" + SESS_KEY_USERID = "uid" SESS_KEY_OAUTH_STATE = "state" - SESS_KEY_APIKEY = "apikey_id" // used fror render requests with api keys - SESS_KEY_PASSWORD = "password" + SESS_KEY_PASSWORD = "grafana_password" ) var sessionManager *session.Manager diff --git a/pkg/setting/setting.go b/pkg/setting/setting.go index d24b0d7408ded..c0f459d125d77 100644 --- a/pkg/setting/setting.go +++ b/pkg/setting/setting.go @@ -139,17 +139,19 @@ var ( LdapAllowSignup bool = true // Keystone - KeystoneEnabled bool - KeystoneURL string - KeystoneDefaultDomain string - KeystoneDefaultRole string - KeystoneViewerRoles []string - KeystoneReadEditorRoles []string - KeystoneEditorRoles []string - KeystoneAdminRoles []string - KeystoneGlobalAdminRoles []string - KeystoneVerifySSLCert bool - KeystoneRootCAPEMFile string + KeystoneEnabled bool + KeystoneCookieCredentials bool + KeystoneCredentialAesKey string + KeystoneURL string + KeystoneDefaultDomain string + KeystoneDefaultRole string + KeystoneViewerRoles []string + KeystoneReadEditorRoles []string + KeystoneEditorRoles []string + KeystoneAdminRoles []string + KeystoneGlobalAdminRoles []string + KeystoneVerifySSLCert bool + KeystoneRootCAPEMFile string // SMTP email settings Smtp SmtpSettings @@ -572,6 +574,8 @@ func NewConfigContext(args *CommandLineArgs) error { keystone := Cfg.Section("auth.keystone") KeystoneEnabled = keystone.Key("enabled").MustBool(false) + KeystoneCookieCredentials = keystone.Key("cookie_credentials").MustBool(false) + KeystoneCredentialAesKey = keystone.Key("credential_aes_key").String() KeystoneURL = keystone.Key("auth_url").String() KeystoneDefaultDomain = keystone.Key("default_domain").String() KeystoneDefaultRole = keystone.Key("default_role").String() From f2679832863237abc41e55a18946a142635ff0f1 Mon Sep 17 00:00:00 2001 From: Darren Hague Date: Fri, 11 Nov 2016 18:08:27 +0000 Subject: [PATCH 3/6] Multi-domain login --- pkg/api/keystone/keystone.go | 28 ++++++++++++++++++++-------- pkg/login/auth.go | 7 ++++++- pkg/login/keystone.go | 12 ++++++++++-- 3 files changed, 36 insertions(+), 11 deletions(-) diff --git a/pkg/api/keystone/keystone.go b/pkg/api/keystone/keystone.go index 8057314527111..818a15cc461cd 100644 --- a/pkg/api/keystone/keystone.go +++ b/pkg/api/keystone/keystone.go @@ -14,6 +14,7 @@ import ( m "github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/setting" "io" + "strings" ) const ( @@ -84,19 +85,20 @@ func getNewToken(c *middleware.Context) (string, error) { log.Warn("Password stored in cleartext!") } + user, domain := UserDomain(username) + keystoneProject := strings.Replace(project, "@"+domain, "", 1) auth := Auth_data{ - Username: username, - Project: project, + Username: user, + Project: keystoneProject, Password: keystonePasswordObj.(string), - Domain: setting.KeystoneDefaultDomain, + Domain: domain, Server: setting.KeystoneURL, } if err := AuthenticateScoped(&auth); err != nil { - if setting.KeystoneCookieCredentials { - c.SetCookie(middleware.SESS_KEY_PASSWORD, "", -1, setting.AppSubUrl+"/", nil, middleware.IsSecure(c), true) - } else { - c.Session.Set(middleware.SESS_KEY_PASSWORD, nil) - } + c.SetCookie(setting.CookieUserName, "", -1, setting.AppSubUrl+"/", nil, middleware.IsSecure(c), true) + c.SetCookie(setting.CookieRememberName, "", -1, setting.AppSubUrl+"/", nil, middleware.IsSecure(c), true) + c.SetCookie(middleware.SESS_KEY_PASSWORD, "", -1, setting.AppSubUrl+"/", nil, middleware.IsSecure(c), true) + c.Session.Destory(c) return "", err } @@ -195,3 +197,13 @@ func decryptPassword(base64ciphertext string) string { stream.XORKeyStream(password, ciphertext[aes.BlockSize:]) return string(password) } + +func UserDomain(username string) (string, string) { + user := username + domain := setting.KeystoneDefaultDomain + if at_idx := strings.IndexRune(username, '@'); at_idx > 0 { + domain = username[at_idx+1:] + user = username[:at_idx] + } + return user, domain +} diff --git a/pkg/login/auth.go b/pkg/login/auth.go index d229cf95143c5..6183dc9db71d9 100644 --- a/pkg/login/auth.go +++ b/pkg/login/auth.go @@ -4,6 +4,7 @@ import ( "errors" "crypto/subtle" + "github.com/grafana/grafana/pkg/api/keystone" "github.com/grafana/grafana/pkg/bus" m "github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/setting" @@ -42,8 +43,12 @@ func AuthenticateUser(query *LoginUserQuery) error { } if setting.KeystoneEnabled { + user, domain := keystone.UserDomain(query.Username) + if domain == setting.KeystoneDefaultDomain { + query.Username = user + } auther := NewKeystoneAuthenticator(setting.KeystoneURL, - setting.KeystoneDefaultDomain, + domain, setting.KeystoneDefaultRole, setting.KeystoneGlobalAdminRoles, setting.KeystoneAdminRoles, diff --git a/pkg/login/keystone.go b/pkg/login/keystone.go index fe4c3c38cc07a..9c7c6b9a65dcc 100644 --- a/pkg/login/keystone.go +++ b/pkg/login/keystone.go @@ -56,9 +56,10 @@ func (a *keystoneAuther) login(query *LoginUserQuery) error { } func (a *keystoneAuther) authenticate(username, password string) error { + user, _ := keystone.UserDomain(username) auth := keystone.Auth_data{ Server: a.server, - Username: username, + Username: user, Password: password, Domain: a.domainname, } @@ -109,10 +110,14 @@ func (a *keystoneAuther) updateGrafanaUserPermissions(userid int64, isAdmin bool } func (a *keystoneAuther) getGrafanaOrgFor(orgname string) (*m.Org, error) { + + log.Debug("getGrafanaOrgFor( %v )", orgname) + // get org from grafana db orgQuery := m.GetOrgByNameQuery{Name: orgname} if err := bus.Dispatch(&orgQuery); err != nil { if err == m.ErrOrgNotFound { + log.Debug("orgname %s not found - create it", orgname) return a.createGrafanaOrg(orgname) } else { return nil, err @@ -209,6 +214,7 @@ func (a *keystoneAuther) syncOrgRoles(username, password string, user *m.User) e // add missing org roles for project, _ := range a.project_list { if grafanaOrg, err := a.getGrafanaOrgFor(project); err != nil { + log.Error(3, "Couldn't find Grafana org %s", project) return err } else { if _, exists := handledOrgIds[grafanaOrg.Id]; exists { @@ -284,6 +290,7 @@ func (a *keystoneAuther) syncOrgRoles(username, password string, user *m.User) e } func (a *keystoneAuther) getProjectList(username, password string) error { + log.Trace("getProjectList() with username %s", username) projects_data := keystone.Projects_data{ Token: a.token, Server: a.server, @@ -306,12 +313,13 @@ func (a *keystoneAuther) getProjectList(username, password string) error { for _, role := range auth.Roles { roles = append(roles, role.Name) } - a.project_list[project] = roles + a.project_list[project+"@"+a.domainname] = roles } return nil } func (a *keystoneAuther) getRole(user_roles []string) m.RoleType { + log.Trace("getRole(%v)", user_roles) role_map := make(map[string]bool) for _, role := range user_roles { role_map[role] = true From 66316d7d238c800b277cef61223be063c0a2d2c2 Mon Sep 17 00:00:00 2001 From: Darren Hague Date: Thu, 24 Nov 2016 17:14:52 +0000 Subject: [PATCH 4/6] Fix: allow users with cross-domain role assignments to log in --- pkg/api/keystone/keystone_requests.go | 30 ++++++++++++++++++++------- pkg/login/keystone.go | 7 +++++-- 2 files changed, 28 insertions(+), 9 deletions(-) diff --git a/pkg/api/keystone/keystone_requests.go b/pkg/api/keystone/keystone_requests.go index eb7498662cdd5..582b11da4e097 100644 --- a/pkg/api/keystone/keystone_requests.go +++ b/pkg/api/keystone/keystone_requests.go @@ -93,8 +93,9 @@ type auth_response_struct struct { } type auth_token_struct struct { - Roles []auth_roles_struct `json:"roles"` - Expires_at string `json:"expires_at"` + Roles []auth_roles_struct `json:"roles"` + Expires_at string `json:"expires_at"` + User auth_user_response_struct `json:"user"` } type auth_roles_struct struct { @@ -102,14 +103,26 @@ type auth_roles_struct struct { Name string `json:"name"` } +type auth_user_response_struct struct { + Name string `json:"name"` + Id string `json:"id"` + Domain auth_userdomain_response_struct `json:"domain"` +} + +type auth_userdomain_response_struct struct { + Name string `json:"name"` + Id string `json:"id"` +} + // Projects Response type project_response_struct struct { Projects []project_struct } type project_struct struct { - Name string - Enabled bool + Name string + Enabled bool + DomainId string `json:"domain_id"` } //////////////////////// @@ -120,6 +133,7 @@ type project_struct struct { type Auth_data struct { Server string Domain string + DomainId string Username string Password string Project string @@ -205,6 +219,7 @@ func authenticate(data *Auth_data, b []byte) error { data.Token = resp.Header.Get("X-Subject-Token") data.Expiration = auth_response.Token.Expires_at data.Roles = auth_response.Token.Roles + data.DomainId = auth_response.Token.User.Domain.Id return nil } @@ -225,8 +240,9 @@ func anonymisePasswordsTokens(data *Auth_data, json []byte) []byte { // Projects Section type Projects_data struct { - Token string - Server string + Token string + Server string + DomainId string //response Projects []string } @@ -264,7 +280,7 @@ func GetProjects(data *Projects_data) error { return err } for _, project := range project_response.Projects { - if project.Enabled { + if project.Enabled && (project.DomainId == data.DomainId) { data.Projects = append(data.Projects, project.Name) } } diff --git a/pkg/login/keystone.go b/pkg/login/keystone.go index 9c7c6b9a65dcc..4ca3dd738f855 100644 --- a/pkg/login/keystone.go +++ b/pkg/login/keystone.go @@ -13,6 +13,7 @@ import ( type keystoneAuther struct { server string domainname string + domainId string defaultrole string roles map[m.RoleType][]string admin_roles []string @@ -67,6 +68,7 @@ func (a *keystoneAuther) authenticate(username, password string) error { return err } a.token = auth.Token + a.domainId = auth.DomainId return nil } @@ -292,8 +294,9 @@ func (a *keystoneAuther) syncOrgRoles(username, password string, user *m.User) e func (a *keystoneAuther) getProjectList(username, password string) error { log.Trace("getProjectList() with username %s", username) projects_data := keystone.Projects_data{ - Token: a.token, - Server: a.server, + Token: a.token, + Server: a.server, + DomainId: a.domainId, } if err := keystone.GetProjects(&projects_data); err != nil { return err From 1b8b6f9023ae502ec3b08bd7dc5f7abdc567ffee Mon Sep 17 00:00:00 2001 From: Darren Hague Date: Thu, 24 Nov 2016 17:52:29 +0000 Subject: [PATCH 5/6] Case sensitive login fix If the backend Keystone is case-insensitive (perhaps using AD for authentication) then we could end up with several users in Grafana, one for each combination of upper & lowercase chars in the username. This fix always uses the username returned in the Keystone response as the username for Grafana, regardless of the case used in the login screen. --- pkg/api/keystone/keystone_requests.go | 1 + pkg/login/keystone.go | 9 +++++---- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/pkg/api/keystone/keystone_requests.go b/pkg/api/keystone/keystone_requests.go index 582b11da4e097..7e590388ffd6f 100644 --- a/pkg/api/keystone/keystone_requests.go +++ b/pkg/api/keystone/keystone_requests.go @@ -220,6 +220,7 @@ func authenticate(data *Auth_data, b []byte) error { data.Expiration = auth_response.Token.Expires_at data.Roles = auth_response.Token.Roles data.DomainId = auth_response.Token.User.Domain.Id + data.Username = auth_response.Token.User.Name return nil } diff --git a/pkg/login/keystone.go b/pkg/login/keystone.go index 4ca3dd738f855..6c4d3cc98f82e 100644 --- a/pkg/login/keystone.go +++ b/pkg/login/keystone.go @@ -37,7 +37,7 @@ func (a *keystoneAuther) login(query *LoginUserQuery) error { log.Trace("perform initial authentication") // perform initial authentication - if err := a.authenticate(query.Username, query.Password); err != nil { + if err := a.authenticate(query); err != nil { return err } @@ -56,12 +56,12 @@ func (a *keystoneAuther) login(query *LoginUserQuery) error { } -func (a *keystoneAuther) authenticate(username, password string) error { - user, _ := keystone.UserDomain(username) +func (a *keystoneAuther) authenticate(query *LoginUserQuery) error { + user, _ := keystone.UserDomain(query.Username) auth := keystone.Auth_data{ Server: a.server, Username: user, - Password: password, + Password: query.Password, Domain: a.domainname, } if err := keystone.AuthenticateUnscoped(&auth); err != nil { @@ -69,6 +69,7 @@ func (a *keystoneAuther) authenticate(username, password string) error { } a.token = auth.Token a.domainId = auth.DomainId + query.Username = auth.Username // in case the actual username is a different case return nil } From fc7fc71d5b4bbf01209c880958d158717be3a159 Mon Sep 17 00:00:00 2001 From: Darren Hague Date: Fri, 2 Dec 2016 11:00:41 +0000 Subject: [PATCH 6/6] Formatting updates - "go fmt" applied --- pkg/api/login_oauth.go | 8 ++--- pkg/bus/bus.go | 2 +- .../sqlstore/migrator/mysql_dialect.go | 6 ++-- pkg/services/sqlstore/user.go | 2 +- pkg/social/generic_oauth.go | 12 +++---- pkg/social/github_oauth.go | 6 ++-- pkg/social/google_oauth.go | 6 ++-- pkg/social/grafananet_oauth.go | 16 +++++----- pkg/social/social.go | 30 ++++++++--------- pkg/tsdb/opentsdb/opentsdb_test.go | 32 +++++++++---------- pkg/tsdb/opentsdb/types.go | 12 +++---- 11 files changed, 66 insertions(+), 66 deletions(-) diff --git a/pkg/api/login_oauth.go b/pkg/api/login_oauth.go index 2e58d9155fc9d..574d08af09f74 100644 --- a/pkg/api/login_oauth.go +++ b/pkg/api/login_oauth.go @@ -55,8 +55,8 @@ func OAuthLogin(ctx *middleware.Context) { ctx.Session.Set(middleware.SESS_KEY_OAUTH_STATE, state) if setting.OAuthService.OAuthInfos[name].HostedDomain == "" { ctx.Redirect(connect.AuthCodeURL(state, oauth2.AccessTypeOnline)) - }else{ - ctx.Redirect(connect.AuthCodeURL(state, oauth2.SetParam("hd", setting.OAuthService.OAuthInfos[name].HostedDomain), oauth2.AccessTypeOnline)); + } else { + ctx.Redirect(connect.AuthCodeURL(state, oauth2.SetParam("hd", setting.OAuthService.OAuthInfos[name].HostedDomain), oauth2.AccessTypeOnline)) } return } @@ -90,8 +90,8 @@ func OAuthLogin(ctx *middleware.Context) { tr := &http.Transport{ TLSClientConfig: &tls.Config{ InsecureSkipVerify: true, - Certificates: []tls.Certificate{cert}, - RootCAs: caCertPool, + Certificates: []tls.Certificate{cert}, + RootCAs: caCertPool, }, } sslcli := &http.Client{Transport: tr} diff --git a/pkg/bus/bus.go b/pkg/bus/bus.go index 55188b2bc73ef..59d4592766e56 100644 --- a/pkg/bus/bus.go +++ b/pkg/bus/bus.go @@ -7,7 +7,7 @@ import ( ) type HandlerFunc interface{} -type CtxHandlerFunc func() +type CtxHandlerFunc func() type Msg interface{} type Bus interface { diff --git a/pkg/services/sqlstore/migrator/mysql_dialect.go b/pkg/services/sqlstore/migrator/mysql_dialect.go index c36baa3afbfdb..48c2cd3ea5554 100644 --- a/pkg/services/sqlstore/migrator/mysql_dialect.go +++ b/pkg/services/sqlstore/migrator/mysql_dialect.go @@ -31,9 +31,9 @@ func (db *Mysql) AutoIncrStr() string { func (db *Mysql) BooleanStr(value bool) string { if value { - return "1" - } - return "0" + return "1" + } + return "0" } func (db *Mysql) SqlType(c *Column) string { diff --git a/pkg/services/sqlstore/user.go b/pkg/services/sqlstore/user.go index bb21995f54a63..9129247a0f000 100644 --- a/pkg/services/sqlstore/user.go +++ b/pkg/services/sqlstore/user.go @@ -207,7 +207,7 @@ func GetUserByEmail(query *m.GetUserByEmailQuery) error { if err != nil { return err } else if has == false { - return m.ErrUserNotFound + return m.ErrUserNotFound } query.Result = user diff --git a/pkg/social/generic_oauth.go b/pkg/social/generic_oauth.go index 4b7ec065bc3fd..f0e36ac064c75 100644 --- a/pkg/social/generic_oauth.go +++ b/pkg/social/generic_oauth.go @@ -181,12 +181,12 @@ func (s *GenericOAuth) UserInfo(client *http.Client) (*BasicUserInfo, error) { } userInfo := &BasicUserInfo{ - Name: data.Name, - Login: data.Login, - Email: data.Email, + Name: data.Name, + Login: data.Login, + Email: data.Email, } - if (userInfo.Email == "" && data.Attributes["email:primary"] != nil) { + if userInfo.Email == "" && data.Attributes["email:primary"] != nil { userInfo.Email = data.Attributes["email:primary"][0] } @@ -197,11 +197,11 @@ func (s *GenericOAuth) UserInfo(client *http.Client) (*BasicUserInfo, error) { } } - if (userInfo.Login == "" && data.Username != "") { + if userInfo.Login == "" && data.Username != "" { userInfo.Login = data.Username } - if (userInfo.Login == "") { + if userInfo.Login == "" { userInfo.Login = data.Email } diff --git a/pkg/social/github_oauth.go b/pkg/social/github_oauth.go index f3a9d4ece0f20..64ff1d86851a5 100644 --- a/pkg/social/github_oauth.go +++ b/pkg/social/github_oauth.go @@ -187,9 +187,9 @@ func (s *SocialGithub) UserInfo(client *http.Client) (*BasicUserInfo, error) { } userInfo := &BasicUserInfo{ - Name: data.Login, - Login: data.Login, - Email: data.Email, + Name: data.Login, + Login: data.Login, + Email: data.Email, } if !s.IsTeamMember(client) { diff --git a/pkg/social/google_oauth.go b/pkg/social/google_oauth.go index 847cbb75c6d4c..d140f385b66ef 100644 --- a/pkg/social/google_oauth.go +++ b/pkg/social/google_oauth.go @@ -45,8 +45,8 @@ func (s *SocialGoogle) UserInfo(client *http.Client) (*BasicUserInfo, error) { return nil, err } return &BasicUserInfo{ - Name: data.Name, - Email: data.Email, - Login: data.Email, + Name: data.Name, + Email: data.Email, + Login: data.Email, }, nil } diff --git a/pkg/social/grafananet_oauth.go b/pkg/social/grafananet_oauth.go index 119b7a31cfce7..83c6d147b7077 100644 --- a/pkg/social/grafananet_oauth.go +++ b/pkg/social/grafananet_oauth.go @@ -50,10 +50,10 @@ func (s *SocialGrafanaNet) IsOrganizationMember(organizations []OrgRecord) bool func (s *SocialGrafanaNet) UserInfo(client *http.Client) (*BasicUserInfo, error) { var data struct { - Name string `json:"name"` - Login string `json:"username"` - Email string `json:"email"` - Role string `json:"role"` + Name string `json:"name"` + Login string `json:"username"` + Email string `json:"email"` + Role string `json:"role"` Orgs []OrgRecord `json:"orgs"` } @@ -70,10 +70,10 @@ func (s *SocialGrafanaNet) UserInfo(client *http.Client) (*BasicUserInfo, error) } userInfo := &BasicUserInfo{ - Name: data.Name, - Login: data.Login, - Email: data.Email, - Role: data.Role, + Name: data.Name, + Login: data.Login, + Email: data.Email, + Role: data.Role, } if !s.IsOrganizationMember(data.Orgs) { diff --git a/pkg/social/social.go b/pkg/social/social.go index 46a2d76b7f1ed..860d068957e08 100644 --- a/pkg/social/social.go +++ b/pkg/social/social.go @@ -11,11 +11,11 @@ import ( ) type BasicUserInfo struct { - Name string - Email string - Login string - Company string - Role string + Name string + Email string + Login string + Company string + Role string } type SocialConnector interface { @@ -91,11 +91,11 @@ func NewOAuthService() { // Google. if name == "google" { SocialMap["google"] = &SocialGoogle{ - Config: &config, - allowedDomains: info.AllowedDomains, - hostedDomain: info.HostedDomain, - apiUrl: info.ApiUrl, - allowSignup: info.AllowSignup, + Config: &config, + allowedDomains: info.AllowedDomains, + hostedDomain: info.HostedDomain, + apiUrl: info.ApiUrl, + allowSignup: info.AllowSignup, } } @@ -115,12 +115,12 @@ func NewOAuthService() { config = oauth2.Config{ ClientID: info.ClientId, ClientSecret: info.ClientSecret, - Endpoint: oauth2.Endpoint{ - AuthURL: setting.GrafanaNetUrl + "/oauth2/authorize", - TokenURL: setting.GrafanaNetUrl + "/api/oauth2/token", + Endpoint: oauth2.Endpoint{ + AuthURL: setting.GrafanaNetUrl + "/oauth2/authorize", + TokenURL: setting.GrafanaNetUrl + "/api/oauth2/token", }, - RedirectURL: strings.TrimSuffix(setting.AppUrl, "/") + SocialBaseUrl + name, - Scopes: info.Scopes, + RedirectURL: strings.TrimSuffix(setting.AppUrl, "/") + SocialBaseUrl + name, + Scopes: info.Scopes, } SocialMap["grafananet"] = &SocialGrafanaNet{ diff --git a/pkg/tsdb/opentsdb/opentsdb_test.go b/pkg/tsdb/opentsdb/opentsdb_test.go index 905c42b06338c..094deb9e8ecea 100644 --- a/pkg/tsdb/opentsdb/opentsdb_test.go +++ b/pkg/tsdb/opentsdb/opentsdb_test.go @@ -3,9 +3,9 @@ package opentsdb import ( "testing" + "github.com/grafana/grafana/pkg/components/simplejson" "github.com/grafana/grafana/pkg/tsdb" . "github.com/smartystreets/goconvey/convey" - "github.com/grafana/grafana/pkg/components/simplejson" ) func TestOpenTsdbExecutor(t *testing.T) { @@ -23,8 +23,8 @@ func TestOpenTsdbExecutor(t *testing.T) { query.Model.Set("aggregator", "avg") query.Model.Set("disableDownsampling", false) query.Model.Set("downsampleInterval", "") - query.Model.Set("downsampleAggregator","avg") - query.Model.Set("downsampleFillPolicy","none") + query.Model.Set("downsampleAggregator", "avg") + query.Model.Set("downsampleFillPolicy", "none") metric := exec.buildMetric(query) @@ -45,15 +45,15 @@ func TestOpenTsdbExecutor(t *testing.T) { query.Model.Set("aggregator", "avg") query.Model.Set("disableDownsampling", true) query.Model.Set("downsampleInterval", "") - query.Model.Set("downsampleAggregator","avg") - query.Model.Set("downsampleFillPolicy","none") + query.Model.Set("downsampleAggregator", "avg") + query.Model.Set("downsampleFillPolicy", "none") metric := exec.buildMetric(query) So(len(metric), ShouldEqual, 2) So(metric["metric"], ShouldEqual, "cpu.average.percent") So(metric["aggregator"], ShouldEqual, "avg") - + }) Convey("Build metric with downsampling enabled with params", func() { @@ -66,8 +66,8 @@ func TestOpenTsdbExecutor(t *testing.T) { query.Model.Set("aggregator", "avg") query.Model.Set("disableDownsampling", false) query.Model.Set("downsampleInterval", "5m") - query.Model.Set("downsampleAggregator","sum") - query.Model.Set("downsampleFillPolicy","null") + query.Model.Set("downsampleAggregator", "sum") + query.Model.Set("downsampleFillPolicy", "null") metric := exec.buildMetric(query) @@ -87,8 +87,8 @@ func TestOpenTsdbExecutor(t *testing.T) { query.Model.Set("aggregator", "avg") query.Model.Set("disableDownsampling", true) query.Model.Set("downsampleInterval", "5m") - query.Model.Set("downsampleAggregator","sum") - query.Model.Set("downsampleFillPolicy","null") + query.Model.Set("downsampleAggregator", "sum") + query.Model.Set("downsampleFillPolicy", "null") tags := simplejson.New() tags.Set("env", "prod") @@ -117,8 +117,8 @@ func TestOpenTsdbExecutor(t *testing.T) { query.Model.Set("aggregator", "avg") query.Model.Set("disableDownsampling", true) query.Model.Set("shouldComputeRate", true) - query.Model.Set("isCounter",false) - + query.Model.Set("isCounter", false) + tags := simplejson.New() tags.Set("env", "prod") tags.Set("app", "grafana") @@ -147,9 +147,9 @@ func TestOpenTsdbExecutor(t *testing.T) { query.Model.Set("aggregator", "avg") query.Model.Set("disableDownsampling", true) query.Model.Set("shouldComputeRate", true) - query.Model.Set("isCounter",true) - query.Model.Set("counterMax",45) - query.Model.Set("counterResetValue",60) + query.Model.Set("isCounter", true) + query.Model.Set("counterMax", 45) + query.Model.Set("counterResetValue", 60) tags := simplejson.New() tags.Set("env", "prod") @@ -173,4 +173,4 @@ func TestOpenTsdbExecutor(t *testing.T) { }) }) -} \ No newline at end of file +} diff --git a/pkg/tsdb/opentsdb/types.go b/pkg/tsdb/opentsdb/types.go index abd216dc47d2c..752dee0fb3bbe 100644 --- a/pkg/tsdb/opentsdb/types.go +++ b/pkg/tsdb/opentsdb/types.go @@ -1,12 +1,12 @@ package opentsdb type OpenTsdbQuery struct { - Start int64 `json:"start"` - End int64 `json:"end"` - Queries []map[string]interface{} `json:"queries"` + Start int64 `json:"start"` + End int64 `json:"end"` + Queries []map[string]interface{} `json:"queries"` } type OpenTsdbResponse struct { - Metric string `json:"metric"` - DataPoints map[string]float64 `json:"dps"` -} \ No newline at end of file + Metric string `json:"metric"` + DataPoints map[string]float64 `json:"dps"` +}