Backend: Remove more globals (#29644)

Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>
This commit is contained in:
Arve Knudsen
2020-12-15 19:09:04 +01:00
committed by GitHub
parent aa8fb1ae98
commit dd2d206d99
35 changed files with 526 additions and 484 deletions
@@ -81,7 +81,7 @@ type Options struct {
OrgID int64
}
// New instance of the AuthProxy
// New instance of the AuthProxy.
func New(cfg *setting.Cfg, options *Options) *AuthProxy {
header := options.Ctx.Req.Header.Get(cfg.AuthProxyHeaderName)
return &AuthProxy{
@@ -93,7 +93,7 @@ func New(cfg *setting.Cfg, options *Options) *AuthProxy {
}
}
// IsEnabled checks if the proxy auth is enabled
// IsEnabled checks if the auth proxy is enabled.
func (auth *AuthProxy) IsEnabled() bool {
// Bail if the setting is not enabled
return auth.cfg.AuthProxyEnabled
@@ -350,13 +350,13 @@ func logUserIn(auth *authproxy.AuthProxy, username string, logger log.Logger, ig
return id, nil
}
func handleError(ctx *models.ReqContext, err error, statusCode int, cb func(error)) {
func (h *ContextHandler) handleError(ctx *models.ReqContext, err error, statusCode int, cb func(error)) {
details := err
var e authproxy.Error
if errors.As(err, &e) {
details = e.DetailsError
}
ctx.Handle(statusCode, err.Error(), details)
ctx.Handle(h.Cfg, statusCode, err.Error(), details)
if cb != nil {
cb(details)
@@ -385,7 +385,7 @@ func (h *ContextHandler) initContextWithAuthProxy(ctx *models.ReqContext, orgID
// Check if allowed to continue with this IP
if err := auth.IsAllowedIP(); err != nil {
handleError(ctx, err, 407, func(details error) {
h.handleError(ctx, err, 407, func(details error) {
logger.Error("Failed to check whitelisted IP addresses", "message", err.Error(), "error", details)
})
return true
@@ -393,7 +393,7 @@ func (h *ContextHandler) initContextWithAuthProxy(ctx *models.ReqContext, orgID
id, err := logUserIn(auth, username, logger, false)
if err != nil {
handleError(ctx, err, 407, nil)
h.handleError(ctx, err, 407, nil)
return true
}
@@ -414,13 +414,13 @@ func (h *ContextHandler) initContextWithAuthProxy(ctx *models.ReqContext, orgID
}
id, err = logUserIn(auth, username, logger, true)
if err != nil {
handleError(ctx, err, 407, nil)
h.handleError(ctx, err, 407, nil)
return true
}
user, err = auth.GetSignedInUser(id)
if err != nil {
handleError(ctx, err, 407, nil)
h.handleError(ctx, err, 407, nil)
return true
}
}
@@ -433,7 +433,7 @@ func (h *ContextHandler) initContextWithAuthProxy(ctx *models.ReqContext, orgID
// Remember user data in cache
if err := auth.Remember(id); err != nil {
handleError(ctx, err, 500, func(details error) {
h.handleError(ctx, err, 500, func(details error) {
logger.Error(
"Failed to store user in cache",
"username", username,
@@ -11,7 +11,6 @@ import (
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/auth"
"github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/util"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@@ -22,7 +21,7 @@ func TestDontRotateTokensOnCancelledRequests(t *testing.T) {
ctxHdlr := getContextHandler(t)
ctx, cancel := context.WithCancel(context.Background())
reqContext, _, err := initTokenRotationScenario(ctx, t)
reqContext, _, err := initTokenRotationScenario(ctx, t, ctxHdlr)
require.NoError(t, err)
tryRotateCallCount := 0
@@ -46,7 +45,7 @@ func TestDontRotateTokensOnCancelledRequests(t *testing.T) {
func TestTokenRotationAtEndOfRequest(t *testing.T) {
ctxHdlr := getContextHandler(t)
reqContext, rr, err := initTokenRotationScenario(context.Background(), t)
reqContext, rr, err := initTokenRotationScenario(context.Background(), t, ctxHdlr)
require.NoError(t, err)
uts := &auth.FakeUserAuthTokenService{
@@ -80,18 +79,13 @@ func TestTokenRotationAtEndOfRequest(t *testing.T) {
assert.True(t, foundLoginCookie, "Could not find cookie")
}
func initTokenRotationScenario(ctx context.Context, t *testing.T) (*models.ReqContext, *httptest.ResponseRecorder, error) {
func initTokenRotationScenario(ctx context.Context, t *testing.T, ctxHdlr *ContextHandler) (
*models.ReqContext, *httptest.ResponseRecorder, error) {
t.Helper()
origLoginCookieName := setting.LoginCookieName
origLoginMaxLifetime := setting.LoginMaxLifetime
t.Cleanup(func() {
setting.LoginCookieName = origLoginCookieName
setting.LoginMaxLifetime = origLoginMaxLifetime
})
setting.LoginCookieName = "login_token"
ctxHdlr.Cfg.LoginCookieName = "login_token"
var err error
setting.LoginMaxLifetime, err = gtime.ParseDuration("7d")
ctxHdlr.Cfg.LoginMaxLifetime, err = gtime.ParseDuration("7d")
if err != nil {
return nil, nil, err
}
+51 -2
View File
@@ -1,18 +1,23 @@
package quota
import (
"errors"
"github.com/grafana/grafana/pkg/bus"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/registry"
"github.com/grafana/grafana/pkg/setting"
)
var ErrInvalidQuotaTarget = errors.New("invalid quota target")
func init() {
registry.RegisterService(&QuotaService{})
}
type QuotaService struct {
AuthTokenService models.UserTokenService `inject:""`
Cfg *setting.Cfg `inject:""`
}
func (qs *QuotaService) Init() error {
@@ -20,7 +25,7 @@ func (qs *QuotaService) Init() error {
}
func (qs *QuotaService) QuotaReached(c *models.ReqContext, target string) (bool, error) {
if !setting.Quota.Enabled {
if !qs.Cfg.Quota.Enabled {
return false, nil
}
// No request context means this is a background service, like LDAP Background Sync.
@@ -29,8 +34,9 @@ func (qs *QuotaService) QuotaReached(c *models.ReqContext, target string) (bool,
if c == nil {
return false, nil
}
// get the list of scopes that this target is valid for. Org, User, Global
scopes, err := models.GetQuotaScopes(target)
scopes, err := qs.getQuotaScopes(target)
if err != nil {
return false, err
}
@@ -106,3 +112,46 @@ func (qs *QuotaService) QuotaReached(c *models.ReqContext, target string) (bool,
return false, nil
}
func (qs *QuotaService) getQuotaScopes(target string) ([]models.QuotaScope, error) {
scopes := make([]models.QuotaScope, 0)
switch target {
case "user":
scopes = append(scopes,
models.QuotaScope{Name: "global", Target: target, DefaultLimit: qs.Cfg.Quota.Global.User},
models.QuotaScope{Name: "org", Target: "org_user", DefaultLimit: qs.Cfg.Quota.Org.User},
)
return scopes, nil
case "org":
scopes = append(scopes,
models.QuotaScope{Name: "global", Target: target, DefaultLimit: qs.Cfg.Quota.Global.Org},
models.QuotaScope{Name: "user", Target: "org_user", DefaultLimit: qs.Cfg.Quota.User.Org},
)
return scopes, nil
case "dashboard":
scopes = append(scopes,
models.QuotaScope{Name: "global", Target: target, DefaultLimit: qs.Cfg.Quota.Global.Dashboard},
models.QuotaScope{Name: "org", Target: target, DefaultLimit: qs.Cfg.Quota.Org.Dashboard},
)
return scopes, nil
case "data_source":
scopes = append(scopes,
models.QuotaScope{Name: "global", Target: target, DefaultLimit: qs.Cfg.Quota.Global.DataSource},
models.QuotaScope{Name: "org", Target: target, DefaultLimit: qs.Cfg.Quota.Org.DataSource},
)
return scopes, nil
case "api_key":
scopes = append(scopes,
models.QuotaScope{Name: "global", Target: target, DefaultLimit: qs.Cfg.Quota.Global.ApiKey},
models.QuotaScope{Name: "org", Target: target, DefaultLimit: qs.Cfg.Quota.Org.ApiKey},
)
return scopes, nil
case "session":
scopes = append(scopes,
models.QuotaScope{Name: "global", Target: target, DefaultLimit: qs.Cfg.Quota.Global.Session},
)
return scopes, nil
default:
return scopes, ErrInvalidQuotaTarget
}
}
-12
View File
@@ -1,7 +1,6 @@
package sqlstore
import (
"context"
"fmt"
"time"
@@ -275,14 +274,3 @@ func getOrCreateOrg(sess *DBSession, orgName string) (int64, error) {
return org.Id, nil
}
func createDefaultOrg(ctx context.Context) error {
return inTransactionCtx(ctx, func(sess *DBSession) error {
_, err := getOrCreateOrg(sess, mainOrgName)
if err != nil {
return err
}
return nil
})
}
+19 -12
View File
@@ -118,10 +118,13 @@ func (ss *SQLStore) Init() error {
func (ss *SQLStore) ensureMainOrgAndAdminUser() error {
err := ss.InTransaction(context.Background(), func(ctx context.Context) error {
ss.log.Debug("Ensuring main org and admin user exist")
var stats models.SystemUserCountStats
err := ss.WithDbSession(ctx, func(sess *DBSession) error {
var rawSql = `SELECT COUNT(id) AS Count FROM ` + dialect.Quote("user")
if _, err := sess.SQL(rawSql).Get(&stats); err != nil {
// TODO: Should be able to rename "Count" to "count", for more standard SQL style
// Just have to make sure it gets deserialized properly into models.SystemUserCountStats
rawSQL := `SELECT COUNT(id) AS Count FROM ` + dialect.Quote("user")
if _, err := sess.SQL(rawSQL).Get(&stats); err != nil {
return fmt.Errorf("could not determine if admin user exists: %w", err)
}
@@ -137,23 +140,27 @@ func (ss *SQLStore) ensureMainOrgAndAdminUser() error {
// ensure admin user
if !ss.Cfg.DisableInitAdminCreation {
cmd := models.CreateUserCommand{}
cmd.Login = setting.AdminUser
cmd.Email = setting.AdminUser + "@localhost"
cmd.Password = setting.AdminPassword
cmd.IsAdmin = true
ss.log.Debug("Creating default admin user")
cmd := models.CreateUserCommand{
Login: ss.Cfg.AdminUser,
Email: ss.Cfg.AdminUser + "@localhost",
Password: ss.Cfg.AdminPassword,
IsAdmin: true,
}
if err := bus.DispatchCtx(ctx, &cmd); err != nil {
return fmt.Errorf("failed to create admin user: %s", err)
}
ss.log.Info("Created default admin", "user", setting.AdminUser)
ss.log.Info("Created default admin", "user", ss.Cfg.AdminUser)
return nil
}
// ensure default org if default admin user is disabled
if err := createDefaultOrg(ctx); err != nil {
return errutil.Wrap("Failed to create default organization", err)
// ensure default org even if default admin user is disabled
if err := inTransactionCtx(ctx, func(sess *DBSession) error {
_, err := getOrCreateOrg(sess, mainOrgName)
return err
}); err != nil {
return fmt.Errorf("failed to create default organization: %w", err)
}
ss.log.Info("Created default organization")