Settings: Encapsulate settings within an extensible provider (#32219)

* Encapsulate settings with a provider with support for runtime reloads

* SettingsProvider: reload is controlled by the services

* naive impl of reload handlers for settings

* working naive detection on new changes

* Trigger settings reload from API endpoint

* validation step added

* validation of settings

* Fix linting errors

* Replace DB_Varchar by DB_NVarchar

* Reduce settings columns (section, key) lenghts

* wip db update logic

* Db Settings: separate updates and removals

* Fix: removes incorrectly added code

* Minor code improvements

* Runtime settings: moved oss -> ee

* Remove no longer used setting.Cfg SAML-related fields

* Rename file setting/settings.go => setting/provider.go

* Apply suggestions from code review

Co-authored-by: Agnès Toulet <35176601+AgnesToulet@users.noreply.github.com>

* Minor code improvements on OSS settings provider

* Fix some login API tests

* Correct some GoDoc comments

* Apply suggestions from code review

Co-authored-by: Agnès Toulet <35176601+AgnesToulet@users.noreply.github.com>

Co-authored-by: Leonard Gram <leo@xlson.com>
Co-authored-by: Agnès Toulet <35176601+AgnesToulet@users.noreply.github.com>
This commit is contained in:
Joan López de la Franca Beltran
2021-04-28 11:26:58 +02:00
committed by GitHub
co-authored by Agnès Toulet Leonard Gram
parent df4181c43a
commit c41b08bd59
7 changed files with 166 additions and 18 deletions
-2
View File
@@ -5,7 +5,6 @@ import (
"time"
"github.com/go-macaron/binding"
"github.com/grafana/grafana/pkg/api/avatar"
"github.com/grafana/grafana/pkg/api/dtos"
"github.com/grafana/grafana/pkg/api/frontendlogging"
@@ -15,7 +14,6 @@ import (
"github.com/grafana/grafana/pkg/middleware"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/accesscontrol"
acmiddleware "github.com/grafana/grafana/pkg/services/accesscontrol/middleware"
)
+1
View File
@@ -73,6 +73,7 @@ type HTTPServer struct {
Bus bus.Bus `inject:""`
RenderService rendering.Service `inject:""`
Cfg *setting.Cfg `inject:""`
SettingsProvider setting.Provider `inject:""`
HooksService *hooks.HooksService `inject:""`
CacheService *localcache.CacheService `inject:""`
DatasourceCache datasources.CacheService `inject:""`
+10 -2
View File
@@ -96,7 +96,7 @@ func (hs *HTTPServer) LoginView(c *models.ReqContext) {
}
viewData.Settings["oauth"] = enabledOAuths
viewData.Settings["samlEnabled"] = hs.License.HasValidLicense() && hs.Cfg.SAMLEnabled
viewData.Settings["samlEnabled"] = hs.samlEnabled()
if loginError, ok := tryGetEncryptedCookie(c, loginErrorCookieName); ok {
// this cookie is only set whenever an OAuth login fails
@@ -278,7 +278,7 @@ func (hs *HTTPServer) loginUserWithUser(user *models.User, c *models.ReqContext)
}
func (hs *HTTPServer) Logout(c *models.ReqContext) {
if hs.Cfg.SAMLEnabled && hs.Cfg.SAMLSingleLogoutEnabled && hs.License.HasValidLicense() {
if hs.samlSingleLogoutEnabled() {
c.Redirect(hs.Cfg.AppSubURL + "/logout/saml")
return
}
@@ -342,6 +342,14 @@ func (hs *HTTPServer) RedirectResponseWithError(ctx *models.ReqContext, err erro
return response.Redirect(hs.Cfg.AppSubURL + "/login")
}
func (hs *HTTPServer) samlEnabled() bool {
return hs.SettingsProvider.KeyValue("auth.saml", "enabled").MustBool(false) && hs.License.HasValidLicense()
}
func (hs *HTTPServer) samlSingleLogoutEnabled() bool {
return hs.SettingsProvider.KeyValue("auth.saml", "single_logout").MustBool(false) && hs.samlEnabled()
}
func getLoginExternalError(err error) string {
var createTokenErr *models.CreateTokenErr
if errors.As(err, &createTokenErr) {
+12 -6
View File
@@ -94,8 +94,9 @@ func TestLoginErrorCookieAPIEndpoint(t *testing.T) {
sc := setupScenarioContext(t, "/login")
cfg := setting.NewCfg()
hs := &HTTPServer{
Cfg: cfg,
License: &licensing.OSSLicensingService{},
Cfg: cfg,
SettingsProvider: &setting.OSSImpl{Cfg: cfg},
License: &licensing.OSSLicensingService{},
}
sc.defaultHandler = routing.Wrap(func(w http.ResponseWriter, c *models.ReqContext) {
@@ -154,9 +155,11 @@ func TestLoginViewRedirect(t *testing.T) {
fakeViewIndex(t)
sc := setupScenarioContext(t, "/login")
cfg := setting.NewCfg()
hs := &HTTPServer{
Cfg: setting.NewCfg(),
License: &licensing.OSSLicensingService{},
Cfg: cfg,
SettingsProvider: &setting.OSSImpl{Cfg: cfg},
License: &licensing.OSSLicensingService{},
}
hs.Cfg.CookieSecure = true
@@ -485,9 +488,11 @@ func TestLoginOAuthRedirect(t *testing.T) {
fakeSetIndexViewData(t)
sc := setupScenarioContext(t, "/login")
cfg := setting.NewCfg()
hs := &HTTPServer{
Cfg: setting.NewCfg(),
License: &licensing.OSSLicensingService{},
Cfg: cfg,
SettingsProvider: &setting.OSSImpl{Cfg: cfg},
License: &licensing.OSSLicensingService{},
}
sc.defaultHandler = routing.Wrap(func(c *models.ReqContext) {
@@ -577,6 +582,7 @@ func setupAuthProxyLoginTest(t *testing.T, enableLoginToken bool) *scenarioConte
sc.cfg.LoginCookieName = "grafana_session"
hs := &HTTPServer{
Cfg: sc.cfg,
SettingsProvider: &setting.OSSImpl{Cfg: sc.cfg},
License: &licensing.OSSLicensingService{},
AuthTokenService: auth.NewFakeUserAuthTokenService(),
log: log.New("hello"),