diff --git a/pkg/api/frontendsettings.go b/pkg/api/frontendsettings.go index 789613047c8..c4ae06f62e3 100644 --- a/pkg/api/frontendsettings.go +++ b/pkg/api/frontendsettings.go @@ -105,7 +105,7 @@ func (hs *HTTPServer) getFrontendSettings(c *contextmodel.ReqContext) (*dtos.Fro AppUrl: hs.Cfg.AppURL, AppSubUrl: hs.Cfg.AppSubURL, AllowOrgCreate: (setting.AllowUserOrgCreate && c.IsSignedIn) || c.IsGrafanaAdmin, - AuthProxyEnabled: setting.AuthProxyEnabled, + AuthProxyEnabled: hs.Cfg.AuthProxyEnabled, LdapEnabled: hs.Cfg.LDAPEnabled, JwtHeaderName: hs.Cfg.JWTAuthHeaderName, JwtUrlLogin: hs.Cfg.JWTAuthURLLogin, @@ -132,7 +132,7 @@ func (hs *HTTPServer) getFrontendSettings(c *contextmodel.ReqContext) (*dtos.Fro FeedbackLinksEnabled: hs.Cfg.FeedbackLinksEnabled, ApplicationInsightsConnectionString: hs.Cfg.ApplicationInsightsConnectionString, ApplicationInsightsEndpointUrl: hs.Cfg.ApplicationInsightsEndpointUrl, - DisableLoginForm: setting.DisableLoginForm, + DisableLoginForm: hs.Cfg.DisableLoginForm, DisableUserSignUp: !setting.AllowUserSignUp, LoginHint: setting.LoginHint, PasswordHint: setting.PasswordHint, diff --git a/pkg/api/login.go b/pkg/api/login.go index f200a9ca301..11bdd24fc66 100644 --- a/pkg/api/login.go +++ b/pkg/api/login.go @@ -151,9 +151,10 @@ func (hs *HTTPServer) tryAutoLogin(c *contextmodel.ReqContext) bool { } } // If no auto_login option configured for specific OAuth, use legacy option - if setting.OAuthAutoLogin && autoLoginProvidersLen == 0 { + if hs.Cfg.OAuthAutoLogin && autoLoginProvidersLen == 0 { autoLoginProvidersLen = len(oauthInfos) } + if samlAutoLogin { autoLoginProvidersLen++ } @@ -162,13 +163,14 @@ func (hs *HTTPServer) tryAutoLogin(c *contextmodel.ReqContext) bool { c.Logger.Warn("Skipping auto login because multiple auth providers are configured with auto_login option") return false } - if autoLoginProvidersLen == 0 && setting.OAuthAutoLogin { + + if hs.Cfg.OAuthAutoLogin && autoLoginProvidersLen == 0 { c.Logger.Warn("Skipping auto login because no auth providers are configured") return false } for providerName, provider := range oauthInfos { - if provider.AutoLogin || setting.OAuthAutoLogin { + if provider.AutoLogin || hs.Cfg.OAuthAutoLogin { redirectUrl := hs.Cfg.AppSubURL + "/login/" + providerName c.Logger.Info("OAuth auto login enabled. Redirecting to " + redirectUrl) c.Redirect(redirectUrl, 307) @@ -245,7 +247,7 @@ func (hs *HTTPServer) LoginPost(c *contextmodel.ReqContext) response.Response { }, c) }() - if setting.DisableLoginForm { + if hs.Cfg.DisableLoginForm { resp = response.Error(http.StatusUnauthorized, "Login is disabled", nil) return resp } diff --git a/pkg/api/login_test.go b/pkg/api/login_test.go index 95c1b8df329..fea8b19bbbd 100644 --- a/pkg/api/login_test.go +++ b/pkg/api/login_test.go @@ -113,7 +113,7 @@ func TestLoginErrorCookieAPIEndpoint(t *testing.T) { cfg.LoginCookieName = "grafana_session" setting.SecretKey = "login_testing" - setting.OAuthAutoLogin = true + cfg.OAuthAutoLogin = true oauthError := errors.New("User not a member of one of the required organizations") encryptedError, err := hs.SecretsService.Encrypt(context.Background(), []byte(oauthError.Error()), secrets.WithoutScope()) @@ -498,7 +498,7 @@ func TestLoginOAuthRedirect(t *testing.T) { return response.Empty(http.StatusOK) }) - setting.OAuthAutoLogin = true + hs.Cfg.OAuthAutoLogin = true sc.m.Get(sc.url, sc.defaultHandler) sc.fakeReqNoAssertions("GET", sc.url).exec() @@ -525,7 +525,7 @@ func TestLoginInternal(t *testing.T) { return response.Empty(http.StatusOK) }) - setting.OAuthAutoLogin = true + hs.Cfg.OAuthAutoLogin = true sc.m.Get(sc.url, sc.defaultHandler) sc.fakeReqNoAssertions("GET", sc.url).exec() diff --git a/pkg/api/org_invite.go b/pkg/api/org_invite.go index 855c26c2922..381fc33a848 100644 --- a/pkg/api/org_invite.go +++ b/pkg/api/org_invite.go @@ -90,7 +90,7 @@ func (hs *HTTPServer) AddOrgInvite(c *contextmodel.ReqContext) response.Response return hs.inviteExistingUserToOrg(c, usr, &inviteDto) } - if setting.DisableLoginForm { + if hs.Cfg.DisableLoginForm { return response.Error(400, "Cannot invite when login is disabled.", nil) } diff --git a/pkg/api/password.go b/pkg/api/password.go index 704ffe0843f..2b628f39be9 100644 --- a/pkg/api/password.go +++ b/pkg/api/password.go @@ -11,7 +11,6 @@ import ( "github.com/grafana/grafana/pkg/services/login" "github.com/grafana/grafana/pkg/services/notifications" "github.com/grafana/grafana/pkg/services/user" - "github.com/grafana/grafana/pkg/setting" "github.com/grafana/grafana/pkg/util" "github.com/grafana/grafana/pkg/web" ) @@ -21,7 +20,7 @@ func (hs *HTTPServer) SendResetPasswordEmail(c *contextmodel.ReqContext) respons if err := web.Bind(c.Req, &form); err != nil { return response.Error(http.StatusBadRequest, "bad request data", err) } - if setting.DisableLoginForm { + if hs.Cfg.DisableLoginForm { return response.Error(401, "Not allowed to reset password when login form is disabled", nil) } diff --git a/pkg/api/user.go b/pkg/api/user.go index b287d3102a2..80057c67431 100644 --- a/pkg/api/user.go +++ b/pkg/api/user.go @@ -14,7 +14,6 @@ import ( "github.com/grafana/grafana/pkg/services/org" "github.com/grafana/grafana/pkg/services/team" "github.com/grafana/grafana/pkg/services/user" - "github.com/grafana/grafana/pkg/setting" "github.com/grafana/grafana/pkg/util" "github.com/grafana/grafana/pkg/web" ) @@ -129,11 +128,11 @@ func (hs *HTTPServer) UpdateSignedInUser(c *contextmodel.ReqContext) response.Re cmd.Email = strings.TrimSpace(cmd.Email) cmd.Login = strings.TrimSpace(cmd.Login) - if setting.AuthProxyEnabled { - if setting.AuthProxyHeaderProperty == "email" && cmd.Email != c.Email { + if hs.Cfg.AuthProxyEnabled { + if hs.Cfg.AuthProxyHeaderProperty == "email" && cmd.Email != c.Email { return response.Error(400, "Not allowed to change email when auth proxy is using email property", nil) } - if setting.AuthProxyHeaderProperty == "username" && cmd.Login != c.Login { + if hs.Cfg.AuthProxyHeaderProperty == "username" && cmd.Login != c.Login { return response.Error(400, "Not allowed to change username when auth proxy is using username property", nil) } } diff --git a/pkg/services/authn/authnimpl/service.go b/pkg/services/authn/authnimpl/service.go index 67a26a0937a..1da25ae0320 100644 --- a/pkg/services/authn/authnimpl/service.go +++ b/pkg/services/authn/authnimpl/service.go @@ -106,8 +106,8 @@ func ProvideService( if s.cfg.BasicAuthEnabled { s.RegisterClient(clients.ProvideBasic(passwordClient)) } - // FIXME (kalleep): Remove the global variable and stick it into cfg - if !setting.DisableLoginForm { + + if !s.cfg.DisableLoginForm { s.RegisterClient(clients.ProvideForm(passwordClient)) } } diff --git a/pkg/services/navtree/navtreeimpl/navtree.go b/pkg/services/navtree/navtreeimpl/navtree.go index 8508e284f02..316d9f24cd3 100644 --- a/pkg/services/navtree/navtreeimpl/navtree.go +++ b/pkg/services/navtree/navtreeimpl/navtree.go @@ -297,7 +297,7 @@ func (s *ServiceImpl) getProfileNode(c *contextmodel.ReqContext) *navtree.NavLin Text: "Notification history", Id: "profile/notifications", Url: s.cfg.AppSubURL + "/profile/notifications", Icon: "bell", }) - if setting.AddChangePasswordLink() { + if s.cfg.AddChangePasswordLink() { children = append(children, &navtree.NavLink{ Text: "Change password", Id: "profile/password", Url: s.cfg.AppSubURL + "/profile/password", Icon: "lock", diff --git a/pkg/setting/setting.go b/pkg/setting/setting.go index 86ae820e7d2..1686bf1e5aa 100644 --- a/pkg/setting/setting.go +++ b/pkg/setting/setting.go @@ -97,28 +97,17 @@ var ( VerifyEmailEnabled bool LoginHint string PasswordHint string - DisableLoginForm bool DisableSignoutMenu bool SignoutRedirectUrl string ExternalUserMngLinkUrl string ExternalUserMngLinkName string ExternalUserMngInfo string - OAuthAutoLogin bool ViewersCanEdit bool // HTTP auth SigV4AuthEnabled bool AzureAuthEnabled bool - AnonymousEnabled bool - - // Auth proxy settings - AuthProxyEnabled bool - AuthProxyHeaderProperty string - - // Basic Auth - BasicAuthEnabled bool - // Global setting objects. Raw *ini.File @@ -154,12 +143,6 @@ var ( ImageUploadProvider string ) -// AddChangePasswordLink returns if login form is disabled or not since -// the same intention can be used to hide both features. -func AddChangePasswordLink() bool { - return !DisableLoginForm -} - // TODO move all global vars to this struct type Cfg struct { Raw *ini.File @@ -286,6 +269,7 @@ type Cfg struct { DisableLogin bool AdminEmail string DisableSyncLock bool + DisableLoginForm bool // AWS Plugin Auth AWSAllowedAuthProviders []string @@ -307,6 +291,7 @@ type Cfg struct { AuthProxySyncTTL int // OAuth + OAuthAutoLogin bool OAuthCookieMaxAge int // JWT Auth @@ -518,6 +503,12 @@ type Cfg struct { CustomResponseHeaders map[string]string } +// AddChangePasswordLink returns if login form is disabled or not since +// the same intention can be used to hide both features. +func (cfg *Cfg) AddChangePasswordLink() bool { + return !cfg.DisableLoginForm +} + type CommandLineArgs struct { Config string HomePath string @@ -1439,12 +1430,12 @@ func readAuthSettings(iniFile *ini.File, cfg *Cfg) (err error) { // Debug setting unlocking frontend auth sync lock. Users will still be reset on their next login. cfg.DisableSyncLock = auth.Key("disable_sync_lock").MustBool(false) - DisableLoginForm = auth.Key("disable_login_form").MustBool(false) + cfg.DisableLoginForm = auth.Key("disable_login_form").MustBool(false) DisableSignoutMenu = auth.Key("disable_signout_menu").MustBool(false) // Deprecated - OAuthAutoLogin = auth.Key("oauth_auto_login").MustBool(false) - if OAuthAutoLogin { + cfg.OAuthAutoLogin = auth.Key("oauth_auto_login").MustBool(false) + if cfg.OAuthAutoLogin { cfg.Logger.Warn("[Deprecated] The oauth_auto_login configuration setting is deprecated. Please use auto_login inside auth provider section instead.") } @@ -1481,16 +1472,14 @@ func readAuthSettings(iniFile *ini.File, cfg *Cfg) (err error) { readAuthOktaSettings(iniFile, cfg) // anonymous access - AnonymousEnabled = iniFile.Section("auth.anonymous").Key("enabled").MustBool(false) - cfg.AnonymousEnabled = AnonymousEnabled + cfg.AnonymousEnabled = iniFile.Section("auth.anonymous").Key("enabled").MustBool(false) cfg.AnonymousOrgName = valueAsString(iniFile.Section("auth.anonymous"), "org_name", "") cfg.AnonymousOrgRole = valueAsString(iniFile.Section("auth.anonymous"), "org_role", "") cfg.AnonymousHideVersion = iniFile.Section("auth.anonymous").Key("hide_version").MustBool(false) // basic auth authBasic := iniFile.Section("auth.basic") - BasicAuthEnabled = authBasic.Key("enabled").MustBool(true) - cfg.BasicAuthEnabled = BasicAuthEnabled + cfg.BasicAuthEnabled = authBasic.Key("enabled").MustBool(true) // JWT auth authJWT := iniFile.Section("auth.jwt") @@ -1511,12 +1500,10 @@ func readAuthSettings(iniFile *ini.File, cfg *Cfg) (err error) { cfg.JWTAuthSkipOrgRoleSync = authJWT.Key("skip_org_role_sync").MustBool(false) authProxy := iniFile.Section("auth.proxy") - AuthProxyEnabled = authProxy.Key("enabled").MustBool(false) - cfg.AuthProxyEnabled = AuthProxyEnabled + cfg.AuthProxyEnabled = authProxy.Key("enabled").MustBool(false) cfg.AuthProxyHeaderName = valueAsString(authProxy, "header_name", "") - AuthProxyHeaderProperty = valueAsString(authProxy, "header_property", "") - cfg.AuthProxyHeaderProperty = AuthProxyHeaderProperty + cfg.AuthProxyHeaderProperty = valueAsString(authProxy, "header_property", "") cfg.AuthProxyAutoSignUp = authProxy.Key("auto_sign_up").MustBool(true) cfg.AuthProxyEnableLoginToken = authProxy.Key("enable_login_token").MustBool(false)