Chore: Remove public vars in setting package (#81018)

Removes the public variable setting.SecretKey plus some other ones. 
Introduces some new functions for creating setting.Cfg.
pull/81058/head
Marcus Efraimsson 2 years ago committed by GitHub
parent 147bf01745
commit 6768c6c059
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 5
      pkg/api/alerting.go
  2. 4
      pkg/api/annotations.go
  3. 5
      pkg/api/api.go
  4. 6
      pkg/api/avatar/avatar.go
  5. 4
      pkg/api/dashboard_permission.go
  6. 14
      pkg/api/dtos/models.go
  7. 5
      pkg/api/folder_bench_test.go
  8. 4
      pkg/api/folder_permission.go
  9. 42
      pkg/api/frontendsettings.go
  10. 9
      pkg/api/frontendsettings_test.go
  11. 14
      pkg/api/index.go
  12. 6
      pkg/api/login_test.go
  13. 2
      pkg/api/org_users.go
  14. 10
      pkg/api/pluginproxy/ds_proxy.go
  15. 1
      pkg/api/pluginproxy/pluginproxy_test.go
  16. 2
      pkg/api/short_url.go
  17. 9
      pkg/api/signup.go
  18. 4
      pkg/api/user.go
  19. 10
      pkg/api/user_test.go
  20. 5
      pkg/cmd/grafana-cli/commands/commands.go
  21. 18
      pkg/cmd/grafana-cli/commands/datamigrations/encrypt_datasource_passwords.go
  22. 13
      pkg/cmd/grafana-cli/commands/datamigrations/encrypt_datasource_passwords_test.go
  23. 2
      pkg/components/imguploader/azureblobuploader_test.go
  24. 16
      pkg/components/imguploader/imguploader.go
  25. 30
      pkg/components/imguploader/imguploader_test.go
  26. 2
      pkg/components/imguploader/s3uploader_test.go
  27. 3
      pkg/infra/metrics/settings.go
  28. 4
      pkg/infra/usagestats/service/api_test.go
  29. 2
      pkg/login/social/connectors/gitlab_oauth.go
  30. 2
      pkg/login/social/connectors/google_oauth.go
  31. 2
      pkg/middleware/recovery.go
  32. 17
      pkg/services/accesscontrol/ossaccesscontrol/permissions_services.go
  33. 10
      pkg/services/accesscontrol/resourcepermissions/api.go
  34. 4
      pkg/services/accesscontrol/resourcepermissions/api_test.go
  35. 5
      pkg/services/accesscontrol/resourcepermissions/service.go
  36. 2
      pkg/services/accesscontrol/resourcepermissions/service_test.go
  37. 14
      pkg/services/alerting/engine.go
  38. 11
      pkg/services/alerting/engine_integration_test.go
  39. 25
      pkg/services/alerting/engine_test.go
  40. 22
      pkg/services/alerting/notifier.go
  41. 13
      pkg/services/alerting/notifier_test.go
  42. 4
      pkg/services/alerting/notifiers/alertmanager.go
  43. 7
      pkg/services/alerting/notifiers/alertmanager_test.go
  44. 3
      pkg/services/alerting/notifiers/dingding.go
  45. 4
      pkg/services/alerting/notifiers/dingding_test.go
  46. 2
      pkg/services/alerting/notifiers/discord.go
  47. 4
      pkg/services/alerting/notifiers/discord_test.go
  48. 6
      pkg/services/alerting/notifiers/email.go
  49. 7
      pkg/services/alerting/notifiers/email_test.go
  50. 2
      pkg/services/alerting/notifiers/googlechat.go
  51. 4
      pkg/services/alerting/notifiers/googlechat_test.go
  52. 3
      pkg/services/alerting/notifiers/hipchat.go
  53. 6
      pkg/services/alerting/notifiers/hipchat_test.go
  54. 3
      pkg/services/alerting/notifiers/kafka.go
  55. 4
      pkg/services/alerting/notifiers/kafka_test.go
  56. 4
      pkg/services/alerting/notifiers/line.go
  57. 5
      pkg/services/alerting/notifiers/line_test.go
  58. 4
      pkg/services/alerting/notifiers/opsgenie.go
  59. 13
      pkg/services/alerting/notifiers/opsgenie_test.go
  60. 4
      pkg/services/alerting/notifiers/pagerduty.go
  61. 21
      pkg/services/alerting/notifiers/pagerduty_test.go
  62. 6
      pkg/services/alerting/notifiers/pushover.go
  63. 5
      pkg/services/alerting/notifiers/pushover_test.go
  64. 4
      pkg/services/alerting/notifiers/sensu.go
  65. 5
      pkg/services/alerting/notifiers/sensu_test.go
  66. 4
      pkg/services/alerting/notifiers/sensugo.go
  67. 5
      pkg/services/alerting/notifiers/sensugo_test.go
  68. 10
      pkg/services/alerting/notifiers/slack.go
  69. 15
      pkg/services/alerting/notifiers/slack_test.go
  70. 3
      pkg/services/alerting/notifiers/teams.go
  71. 6
      pkg/services/alerting/notifiers/teams_test.go
  72. 4
      pkg/services/alerting/notifiers/telegram.go
  73. 5
      pkg/services/alerting/notifiers/telegram_test.go
  74. 4
      pkg/services/alerting/notifiers/threema.go
  75. 11
      pkg/services/alerting/notifiers/threema_test.go
  76. 2
      pkg/services/alerting/notifiers/victorops.go
  77. 8
      pkg/services/alerting/notifiers/victorops_test.go
  78. 4
      pkg/services/alerting/notifiers/webhook.go
  79. 5
      pkg/services/alerting/notifiers/webhook_test.go
  80. 5
      pkg/services/alerting/result_handler.go
  81. 8
      pkg/services/alerting/scheduler.go
  82. 14
      pkg/services/alerting/service.go
  83. 17
      pkg/services/alerting/service_test.go
  84. 2
      pkg/services/alerting/test_notification.go
  85. 2
      pkg/services/anonymous/anonimpl/api/api.go
  86. 2
      pkg/services/anonymous/anonimpl/impl.go
  87. 16
      pkg/services/auth/authimpl/auth_token.go
  88. 4
      pkg/services/auth/authimpl/auth_token_test.go
  89. 6
      pkg/services/auth/jwt/auth_test.go
  90. 2
      pkg/services/auth/jwt/key_sets.go
  91. 38
      pkg/services/dashboards/service/dashboard_service.go
  92. 16
      pkg/services/dashboards/service/dashboard_service_test.go
  93. 9
      pkg/services/dashboardsnapshots/database/database_test.go
  94. 9
      pkg/services/dashboardsnapshots/service/service_test.go
  95. 6
      pkg/services/dashboardversion/dashverimpl/dashver.go
  96. 6
      pkg/services/dashboardversion/dashverimpl/dashver_test.go
  97. 2
      pkg/services/datasources/service/datasource.go
  98. 12
      pkg/services/datasources/service/datasource_test.go
  99. 2
      pkg/services/featuremgmt/service.go
  100. 22
      pkg/services/libraryelements/database.go
  101. Some files were not shown because too many files have changed in this diff Show More

@ -20,7 +20,6 @@ import (
"github.com/grafana/grafana/pkg/services/notifications" "github.com/grafana/grafana/pkg/services/notifications"
"github.com/grafana/grafana/pkg/services/search" "github.com/grafana/grafana/pkg/services/search"
"github.com/grafana/grafana/pkg/services/search/model" "github.com/grafana/grafana/pkg/services/search/model"
"github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/util" "github.com/grafana/grafana/pkg/util"
"github.com/grafana/grafana/pkg/web" "github.com/grafana/grafana/pkg/web"
) )
@ -522,7 +521,7 @@ func (hs *HTTPServer) fillWithSecureSettingsData(ctx context.Context, cmd *alert
return err return err
} }
secureSettings, err := hs.EncryptionService.DecryptJsonData(ctx, res.SecureSettings, setting.SecretKey) secureSettings, err := hs.EncryptionService.DecryptJsonData(ctx, res.SecureSettings, hs.Cfg.SecretKey)
if err != nil { if err != nil {
return err return err
} }
@ -551,7 +550,7 @@ func (hs *HTTPServer) fillWithSecureSettingsDataByUID(ctx context.Context, cmd *
return err return err
} }
secureSettings, err := hs.EncryptionService.DecryptJsonData(ctx, res.SecureSettings, setting.SecretKey) secureSettings, err := hs.EncryptionService.DecryptJsonData(ctx, res.SecureSettings, hs.Cfg.SecretKey)
if err != nil { if err != nil {
return err return err
} }

@ -69,7 +69,7 @@ func (hs *HTTPServer) GetAnnotations(c *contextmodel.ReqContext) response.Respon
dashboardCache := make(map[int64]*string) dashboardCache := make(map[int64]*string)
for _, item := range items { for _, item := range items {
if item.Email != "" { if item.Email != "" {
item.AvatarURL = dtos.GetGravatarUrl(item.Email) item.AvatarURL = dtos.GetGravatarUrl(hs.Cfg, item.Email)
} }
if item.DashboardID != 0 { if item.DashboardID != 0 {
@ -485,7 +485,7 @@ func (hs *HTTPServer) GetAnnotationByID(c *contextmodel.ReqContext) response.Res
} }
if annotation.Email != "" { if annotation.Email != "" {
annotation.AvatarURL = dtos.GetGravatarUrl(annotation.Email) annotation.AvatarURL = dtos.GetGravatarUrl(hs.Cfg, annotation.Email)
} }
return response.JSON(200, annotation) return response.JSON(200, annotation)

@ -46,7 +46,6 @@ import (
publicdashboardsapi "github.com/grafana/grafana/pkg/services/publicdashboards/api" publicdashboardsapi "github.com/grafana/grafana/pkg/services/publicdashboards/api"
"github.com/grafana/grafana/pkg/services/serviceaccounts" "github.com/grafana/grafana/pkg/services/serviceaccounts"
"github.com/grafana/grafana/pkg/services/user" "github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana/pkg/setting"
) )
var plog = log.New("api") var plog = log.New("api")
@ -511,7 +510,7 @@ func (hs *HTTPServer) registerRoutes() {
apiRoute.Group("/alerts", func(alertsRoute routing.RouteRegister) { apiRoute.Group("/alerts", func(alertsRoute routing.RouteRegister) {
alertsRoute.Post("/test", routing.Wrap(hs.AlertTest)) alertsRoute.Post("/test", routing.Wrap(hs.AlertTest))
alertsRoute.Post("/:alertId/pause", reqEditorRole, routing.Wrap(hs.PauseAlert(setting.AlertingEnabled))) alertsRoute.Post("/:alertId/pause", reqEditorRole, routing.Wrap(hs.PauseAlert(hs.Cfg.AlertingEnabled)))
alertsRoute.Get("/:alertId", hs.ValidateOrgAlert, routing.Wrap(hs.GetAlert)) alertsRoute.Get("/:alertId", hs.ValidateOrgAlert, routing.Wrap(hs.GetAlert))
alertsRoute.Get("/", routing.Wrap(hs.GetAlerts)) alertsRoute.Get("/", routing.Wrap(hs.GetAlerts))
alertsRoute.Get("/states-for-dashboard", routing.Wrap(hs.GetAlertStatesForDashboard)) alertsRoute.Get("/states-for-dashboard", routing.Wrap(hs.GetAlertStatesForDashboard))
@ -583,7 +582,7 @@ func (hs *HTTPServer) registerRoutes() {
adminRoute.Get("/settings", authorize(ac.EvalPermission(ac.ActionSettingsRead)), routing.Wrap(hs.AdminGetSettings)) adminRoute.Get("/settings", authorize(ac.EvalPermission(ac.ActionSettingsRead)), routing.Wrap(hs.AdminGetSettings))
adminRoute.Get("/settings-verbose", authorize(ac.EvalPermission(ac.ActionSettingsRead)), routing.Wrap(hs.AdminGetVerboseSettings)) adminRoute.Get("/settings-verbose", authorize(ac.EvalPermission(ac.ActionSettingsRead)), routing.Wrap(hs.AdminGetVerboseSettings))
adminRoute.Get("/stats", authorize(ac.EvalPermission(ac.ActionServerStatsRead)), routing.Wrap(hs.AdminGetStats)) adminRoute.Get("/stats", authorize(ac.EvalPermission(ac.ActionServerStatsRead)), routing.Wrap(hs.AdminGetStats))
adminRoute.Post("/pause-all-alerts", reqGrafanaAdmin, routing.Wrap(hs.PauseAllAlerts(setting.AlertingEnabled))) adminRoute.Post("/pause-all-alerts", reqGrafanaAdmin, routing.Wrap(hs.PauseAllAlerts(hs.Cfg.AlertingEnabled)))
adminRoute.Post("/encryption/rotate-data-keys", reqGrafanaAdmin, routing.Wrap(hs.AdminRotateDataEncryptionKeys)) adminRoute.Post("/encryption/rotate-data-keys", reqGrafanaAdmin, routing.Wrap(hs.AdminRotateDataEncryptionKeys))
adminRoute.Post("/encryption/reencrypt-data-keys", reqGrafanaAdmin, routing.Wrap(hs.AdminReEncryptEncryptionKeys)) adminRoute.Post("/encryption/reencrypt-data-keys", reqGrafanaAdmin, routing.Wrap(hs.AdminReEncryptEncryptionKeys))

@ -107,7 +107,7 @@ func (a *AvatarCacheServer) Handler(ctx *contextmodel.ReqContext) {
return return
} }
avatar := a.GetAvatarForHash(hash) avatar := a.GetAvatarForHash(a.cfg, hash)
ctx.Resp.Header().Set("Content-Type", "image/jpeg") ctx.Resp.Header().Set("Content-Type", "image/jpeg")
@ -123,8 +123,8 @@ func (a *AvatarCacheServer) Handler(ctx *contextmodel.ReqContext) {
} }
} }
func (a *AvatarCacheServer) GetAvatarForHash(hash string) *Avatar { func (a *AvatarCacheServer) GetAvatarForHash(cfg *setting.Cfg, hash string) *Avatar {
if setting.DisableGravatar { if cfg.DisableGravatar {
alog.Warn("'GetGravatarForHash' called despite gravatars being disabled; returning default profile image") alog.Warn("'GetGravatarForHash' called despite gravatars being disabled; returning default profile image")
return a.notFound return a.notFound
} }

@ -69,10 +69,10 @@ func (hs *HTTPServer) GetDashboardPermissionList(c *contextmodel.ReqContext) res
continue continue
} }
perm.UserAvatarURL = dtos.GetGravatarUrl(perm.UserEmail) perm.UserAvatarURL = dtos.GetGravatarUrl(hs.Cfg, perm.UserEmail)
if perm.TeamID > 0 { if perm.TeamID > 0 {
perm.TeamAvatarURL = dtos.GetGravatarUrlWithDefault(perm.TeamEmail, perm.Team) perm.TeamAvatarURL = dtos.GetGravatarUrlWithDefault(hs.Cfg, perm.TeamEmail, perm.Team)
} }
if perm.Slug != "" { if perm.Slug != "" {
perm.URL = dashboards.GetDashboardFolderURL(perm.IsFolder, perm.UID, perm.Slug) perm.URL = dashboards.GetDashboardFolderURL(perm.IsFolder, perm.UID, perm.Slug)

@ -108,9 +108,9 @@ func (mr *MetricRequest) CloneWithQueries(queries []*simplejson.Json) MetricRequ
} }
} }
func GetGravatarUrl(text string) string { func GetGravatarUrl(cfg *setting.Cfg, text string) string {
if setting.DisableGravatar { if cfg.DisableGravatar {
return setting.AppSubUrl + "/public/img/user_profile.png" return cfg.AppSubURL + "/public/img/user_profile.png"
} }
if text == "" { if text == "" {
@ -118,7 +118,7 @@ func GetGravatarUrl(text string) string {
} }
hash, _ := GetGravatarHash(text) hash, _ := GetGravatarHash(text)
return fmt.Sprintf(setting.AppSubUrl+"/avatar/%x", hash) return fmt.Sprintf(cfg.AppSubURL+"/avatar/%x", hash)
} }
func GetGravatarHash(text string) ([]byte, bool) { func GetGravatarHash(text string) ([]byte, bool) {
@ -133,14 +133,14 @@ func GetGravatarHash(text string) ([]byte, bool) {
return hasher.Sum(nil), true return hasher.Sum(nil), true
} }
func GetGravatarUrlWithDefault(text string, defaultText string) string { func GetGravatarUrlWithDefault(cfg *setting.Cfg, text string, defaultText string) string {
if text != "" { if text != "" {
return GetGravatarUrl(text) return GetGravatarUrl(cfg, text)
} }
text = regNonAlphaNumeric.ReplaceAllString(defaultText, "") + "@localhost" text = regNonAlphaNumeric.ReplaceAllString(defaultText, "") + "@localhost"
return GetGravatarUrl(text) return GetGravatarUrl(cfg, text)
} }
func IsHiddenUser(userLogin string, signedInUser identity.Requester, cfg *setting.Cfg) bool { func IsHiddenUser(userLogin string, signedInUser identity.Requester, cfg *setting.Cfg) bool {

@ -451,11 +451,12 @@ func setupServer(b testing.TB, sc benchScenario, features featuremgmt.FeatureTog
ac := acimpl.ProvideAccessControl(sc.cfg) ac := acimpl.ProvideAccessControl(sc.cfg)
folderServiceWithFlagOn := folderimpl.ProvideService(ac, bus.ProvideBus(tracing.InitializeTracerForTest()), sc.cfg, dashStore, folderStore, sc.db, features, nil) folderServiceWithFlagOn := folderimpl.ProvideService(ac, bus.ProvideBus(tracing.InitializeTracerForTest()), sc.cfg, dashStore, folderStore, sc.db, features, nil)
cfg := setting.NewCfg()
folderPermissions, err := ossaccesscontrol.ProvideFolderPermissions( folderPermissions, err := ossaccesscontrol.ProvideFolderPermissions(
features, routing.NewRouteRegister(), sc.db, ac, license, &dashboards.FakeDashboardStore{}, folderServiceWithFlagOn, acSvc, sc.teamSvc, sc.userSvc) cfg, features, routing.NewRouteRegister(), sc.db, ac, license, &dashboards.FakeDashboardStore{}, folderServiceWithFlagOn, acSvc, sc.teamSvc, sc.userSvc)
require.NoError(b, err) require.NoError(b, err)
dashboardPermissions, err := ossaccesscontrol.ProvideDashboardPermissions( dashboardPermissions, err := ossaccesscontrol.ProvideDashboardPermissions(
features, routing.NewRouteRegister(), sc.db, ac, license, &dashboards.FakeDashboardStore{}, folderServiceWithFlagOn, acSvc, sc.teamSvc, sc.userSvc) cfg, features, routing.NewRouteRegister(), sc.db, ac, license, &dashboards.FakeDashboardStore{}, folderServiceWithFlagOn, acSvc, sc.teamSvc, sc.userSvc)
require.NoError(b, err) require.NoError(b, err)
dashboardSvc, err := dashboardservice.ProvideDashboardServiceImpl( dashboardSvc, err := dashboardservice.ProvideDashboardServiceImpl(

@ -50,10 +50,10 @@ func (hs *HTTPServer) GetFolderPermissionList(c *contextmodel.ReqContext) respon
perm.FolderID = folder.ID perm.FolderID = folder.ID
perm.DashboardID = 0 perm.DashboardID = 0
perm.UserAvatarURL = dtos.GetGravatarUrl(perm.UserEmail) perm.UserAvatarURL = dtos.GetGravatarUrl(hs.Cfg, perm.UserEmail)
if perm.TeamID > 0 { if perm.TeamID > 0 {
perm.TeamAvatarURL = dtos.GetGravatarUrlWithDefault(perm.TeamEmail, perm.Team) perm.TeamAvatarURL = dtos.GetGravatarUrlWithDefault(hs.Cfg, perm.TeamEmail, perm.Team)
} }
if perm.Slug != "" { if perm.Slug != "" {

@ -165,29 +165,29 @@ func (hs *HTTPServer) getFrontendSettings(c *contextmodel.ReqContext) (*dtos.Fro
frontendSettings := &dtos.FrontendSettingsDTO{ frontendSettings := &dtos.FrontendSettingsDTO{
DefaultDatasource: defaultDS, DefaultDatasource: defaultDS,
Datasources: dataSources, Datasources: dataSources,
MinRefreshInterval: setting.MinRefreshInterval, MinRefreshInterval: hs.Cfg.MinRefreshInterval,
Panels: panels, Panels: panels,
Apps: apps, Apps: apps,
AppUrl: hs.Cfg.AppURL, AppUrl: hs.Cfg.AppURL,
AppSubUrl: hs.Cfg.AppSubURL, AppSubUrl: hs.Cfg.AppSubURL,
AllowOrgCreate: (setting.AllowUserOrgCreate && c.IsSignedIn) || c.IsGrafanaAdmin, AllowOrgCreate: (hs.Cfg.AllowUserOrgCreate && c.IsSignedIn) || c.IsGrafanaAdmin,
AuthProxyEnabled: hs.Cfg.AuthProxyEnabled, AuthProxyEnabled: hs.Cfg.AuthProxyEnabled,
LdapEnabled: hs.Cfg.LDAPAuthEnabled, LdapEnabled: hs.Cfg.LDAPAuthEnabled,
JwtHeaderName: hs.Cfg.JWTAuthHeaderName, JwtHeaderName: hs.Cfg.JWTAuthHeaderName,
JwtUrlLogin: hs.Cfg.JWTAuthURLLogin, JwtUrlLogin: hs.Cfg.JWTAuthURLLogin,
AlertingErrorOrTimeout: setting.AlertingErrorOrTimeout, AlertingErrorOrTimeout: hs.Cfg.AlertingErrorOrTimeout,
AlertingNoDataOrNullValues: setting.AlertingNoDataOrNullValues, AlertingNoDataOrNullValues: hs.Cfg.AlertingNoDataOrNullValues,
AlertingMinInterval: setting.AlertingMinInterval, AlertingMinInterval: hs.Cfg.AlertingMinInterval,
LiveEnabled: hs.Cfg.LiveMaxConnections != 0, LiveEnabled: hs.Cfg.LiveMaxConnections != 0,
AutoAssignOrg: hs.Cfg.AutoAssignOrg, AutoAssignOrg: hs.Cfg.AutoAssignOrg,
VerifyEmailEnabled: setting.VerifyEmailEnabled, VerifyEmailEnabled: hs.Cfg.VerifyEmailEnabled,
SigV4AuthEnabled: setting.SigV4AuthEnabled, SigV4AuthEnabled: hs.Cfg.SigV4AuthEnabled,
AzureAuthEnabled: setting.AzureAuthEnabled, AzureAuthEnabled: hs.Cfg.AzureAuthEnabled,
RbacEnabled: true, RbacEnabled: true,
ExploreEnabled: setting.ExploreEnabled, ExploreEnabled: hs.Cfg.ExploreEnabled,
HelpEnabled: setting.HelpEnabled, HelpEnabled: hs.Cfg.HelpEnabled,
ProfileEnabled: setting.ProfileEnabled, ProfileEnabled: hs.Cfg.ProfileEnabled,
NewsFeedEnabled: setting.NewsFeedEnabled, NewsFeedEnabled: hs.Cfg.NewsFeedEnabled,
QueryHistoryEnabled: hs.Cfg.QueryHistoryEnabled, QueryHistoryEnabled: hs.Cfg.QueryHistoryEnabled,
GoogleAnalyticsId: hs.Cfg.GoogleAnalyticsID, GoogleAnalyticsId: hs.Cfg.GoogleAnalyticsID,
GoogleAnalytics4Id: hs.Cfg.GoogleAnalytics4ID, GoogleAnalytics4Id: hs.Cfg.GoogleAnalytics4ID,
@ -201,12 +201,12 @@ func (hs *HTTPServer) getFrontendSettings(c *contextmodel.ReqContext) (*dtos.Fro
ApplicationInsightsConnectionString: hs.Cfg.ApplicationInsightsConnectionString, ApplicationInsightsConnectionString: hs.Cfg.ApplicationInsightsConnectionString,
ApplicationInsightsEndpointUrl: hs.Cfg.ApplicationInsightsEndpointUrl, ApplicationInsightsEndpointUrl: hs.Cfg.ApplicationInsightsEndpointUrl,
DisableLoginForm: hs.Cfg.DisableLoginForm, DisableLoginForm: hs.Cfg.DisableLoginForm,
DisableUserSignUp: !setting.AllowUserSignUp, DisableUserSignUp: !hs.Cfg.AllowUserSignUp,
LoginHint: setting.LoginHint, LoginHint: hs.Cfg.LoginHint,
PasswordHint: setting.PasswordHint, PasswordHint: hs.Cfg.PasswordHint,
ExternalUserMngInfo: setting.ExternalUserMngInfo, ExternalUserMngInfo: hs.Cfg.ExternalUserMngInfo,
ExternalUserMngLinkUrl: setting.ExternalUserMngLinkUrl, ExternalUserMngLinkUrl: hs.Cfg.ExternalUserMngLinkUrl,
ExternalUserMngLinkName: setting.ExternalUserMngLinkName, ExternalUserMngLinkName: hs.Cfg.ExternalUserMngLinkName,
ViewersCanEdit: hs.Cfg.ViewersCanEdit, ViewersCanEdit: hs.Cfg.ViewersCanEdit,
AngularSupportEnabled: hs.Cfg.AngularSupportEnabled, AngularSupportEnabled: hs.Cfg.AngularSupportEnabled,
EditorsCanAdmin: hs.Cfg.EditorsCanAdmin, EditorsCanAdmin: hs.Cfg.EditorsCanAdmin,
@ -228,7 +228,7 @@ func (hs *HTTPServer) getFrontendSettings(c *contextmodel.ReqContext) (*dtos.Fro
Edition: hs.License.Edition(), Edition: hs.License.Edition(),
LatestVersion: hs.grafanaUpdateChecker.LatestVersion(), LatestVersion: hs.grafanaUpdateChecker.LatestVersion(),
HasUpdate: hs.grafanaUpdateChecker.UpdateAvailable(), HasUpdate: hs.grafanaUpdateChecker.UpdateAvailable(),
Env: setting.Env, Env: hs.Cfg.Env,
}, },
LicenseInfo: dtos.FrontendSettingsLicenseInfoDTO{ LicenseInfo: dtos.FrontendSettingsLicenseInfoDTO{
@ -303,8 +303,8 @@ func (hs *HTTPServer) getFrontendSettings(c *contextmodel.ReqContext) (*dtos.Fro
frontendSettings.UnifiedAlertingEnabled = *hs.Cfg.UnifiedAlerting.Enabled frontendSettings.UnifiedAlertingEnabled = *hs.Cfg.UnifiedAlerting.Enabled
} }
if setting.AlertingEnabled != nil { if hs.Cfg.AlertingEnabled != nil {
frontendSettings.AlertingEnabled = *setting.AlertingEnabled frontendSettings.AlertingEnabled = *(hs.Cfg.AlertingEnabled)
} }
// It returns false if the provider is not enabled or the skip org role sync is false. // It returns false if the provider is not enabled or the skip org role sync is false.

@ -41,11 +41,9 @@ func setupTestEnvironment(t *testing.T, cfg *setting.Cfg, features featuremgmt.F
{ {
oldVersion := setting.BuildVersion oldVersion := setting.BuildVersion
oldCommit := setting.BuildCommit oldCommit := setting.BuildCommit
oldEnv := setting.Env
t.Cleanup(func() { t.Cleanup(func() {
setting.BuildVersion = oldVersion setting.BuildVersion = oldVersion
setting.BuildCommit = oldCommit setting.BuildCommit = oldCommit
setting.Env = oldEnv
}) })
} }
@ -83,7 +81,7 @@ func setupTestEnvironment(t *testing.T, cfg *setting.Cfg, features featuremgmt.F
m := web.New() m := web.New()
m.Use(getContextHandler(t, cfg).Middleware) m.Use(getContextHandler(t, cfg).Middleware)
m.UseMiddleware(web.Renderer(filepath.Join(setting.StaticRootPath, "views"), "[[", "]]")) m.UseMiddleware(web.Renderer(filepath.Join("", "views"), "[[", "]]"))
m.Get("/api/frontend/settings/", hs.GetFrontendSettings) m.Get("/api/frontend/settings/", hs.GetFrontendSettings)
return m, hs return m, hs
@ -111,7 +109,6 @@ func TestHTTPServer_GetFrontendSettings_hideVersionAnonymous(t *testing.T) {
// TODO: Remove // TODO: Remove
setting.BuildVersion = cfg.BuildVersion setting.BuildVersion = cfg.BuildVersion
setting.BuildCommit = cfg.BuildCommit setting.BuildCommit = cfg.BuildCommit
setting.Env = cfg.Env
tests := []struct { tests := []struct {
desc string desc string
@ -125,7 +122,7 @@ func TestHTTPServer_GetFrontendSettings_hideVersionAnonymous(t *testing.T) {
BuildInfo: buildInfo{ BuildInfo: buildInfo{
Version: setting.BuildVersion, Version: setting.BuildVersion,
Commit: setting.BuildCommit, Commit: setting.BuildCommit,
Env: setting.Env, Env: cfg.Env,
}, },
}, },
}, },
@ -136,7 +133,7 @@ func TestHTTPServer_GetFrontendSettings_hideVersionAnonymous(t *testing.T) {
BuildInfo: buildInfo{ BuildInfo: buildInfo{
Version: "", Version: "",
Commit: "", Commit: "",
Env: setting.Env, Env: cfg.Env,
}, },
}, },
}, },

@ -60,7 +60,7 @@ func (hs *HTTPServer) setIndexViewData(c *contextmodel.ReqContext) (*dtos.IndexV
locale = parts[0] locale = parts[0]
} }
appURL := setting.AppUrl appURL := hs.Cfg.AppURL
appSubURL := hs.Cfg.AppSubURL appSubURL := hs.Cfg.AppSubURL
// special case when doing localhost call from image renderer // special case when doing localhost call from image renderer
@ -100,7 +100,7 @@ func (hs *HTTPServer) setIndexViewData(c *contextmodel.ReqContext) (*dtos.IndexV
OrgName: c.OrgName, OrgName: c.OrgName,
OrgRole: c.SignedInUser.GetOrgRole(), OrgRole: c.SignedInUser.GetOrgRole(),
OrgCount: hs.getUserOrgCount(c, userID), OrgCount: hs.getUserOrgCount(c, userID),
GravatarUrl: dtos.GetGravatarUrl(c.SignedInUser.GetEmail()), GravatarUrl: dtos.GetGravatarUrl(hs.Cfg, c.SignedInUser.GetEmail()),
IsGrafanaAdmin: c.IsGrafanaAdmin, IsGrafanaAdmin: c.IsGrafanaAdmin,
Theme: theme.ID, Theme: theme.ID,
LightTheme: theme.Type == "light", LightTheme: theme.Type == "light",
@ -117,7 +117,7 @@ func (hs *HTTPServer) setIndexViewData(c *contextmodel.ReqContext) (*dtos.IndexV
ThemeType: theme.Type, ThemeType: theme.Type,
AppUrl: appURL, AppUrl: appURL,
AppSubUrl: appSubURL, AppSubUrl: appSubURL,
NewsFeedEnabled: setting.NewsFeedEnabled, NewsFeedEnabled: hs.Cfg.NewsFeedEnabled,
GoogleAnalyticsId: settings.GoogleAnalyticsId, GoogleAnalyticsId: settings.GoogleAnalyticsId,
GoogleAnalytics4Id: settings.GoogleAnalytics4Id, GoogleAnalytics4Id: settings.GoogleAnalytics4Id,
GoogleAnalytics4SendManualPageViews: hs.Cfg.GoogleAnalytics4SendManualPageViews, GoogleAnalytics4SendManualPageViews: hs.Cfg.GoogleAnalytics4SendManualPageViews,
@ -149,7 +149,7 @@ func (hs *HTTPServer) setIndexViewData(c *contextmodel.ReqContext) (*dtos.IndexV
data.User.Permissions = ac.BuildPermissionsMap(userPermissions) data.User.Permissions = ac.BuildPermissionsMap(userPermissions)
if setting.DisableGravatar { if hs.Cfg.DisableGravatar {
data.User.GravatarUrl = hs.Cfg.AppSubURL + "/public/img/user_profile.png" data.User.GravatarUrl = hs.Cfg.AppSubURL + "/public/img/user_profile.png"
} }
@ -170,7 +170,7 @@ func (hs *HTTPServer) buildUserAnalyticsSettings(c *contextmodel.ReqContext) dto
// Anonymous users do not have an email or auth info // Anonymous users do not have an email or auth info
if namespace != identity.NamespaceUser { if namespace != identity.NamespaceUser {
return dtos.AnalyticsSettings{Identifier: "@" + setting.AppUrl} return dtos.AnalyticsSettings{Identifier: "@" + hs.Cfg.AppURL}
} }
if !c.IsSignedIn { if !c.IsSignedIn {
@ -180,10 +180,10 @@ func (hs *HTTPServer) buildUserAnalyticsSettings(c *contextmodel.ReqContext) dto
userID, err := identity.IntIdentifier(namespace, id) userID, err := identity.IntIdentifier(namespace, id)
if err != nil { if err != nil {
hs.log.Error("Failed to parse user ID", "error", err) hs.log.Error("Failed to parse user ID", "error", err)
return dtos.AnalyticsSettings{Identifier: "@" + setting.AppUrl} return dtos.AnalyticsSettings{Identifier: "@" + hs.Cfg.AppURL}
} }
identifier := c.SignedInUser.GetEmail() + "@" + setting.AppUrl identifier := c.SignedInUser.GetEmail() + "@" + hs.Cfg.AppURL
authInfo, err := hs.authInfoService.GetAuthInfo(c.Req.Context(), &login.GetAuthInfoQuery{UserId: userID}) authInfo, err := hs.authInfoService.GetAuthInfo(c.Req.Context(), &login.GetAuthInfoQuery{UserId: userID})
if err != nil && !errors.Is(err, user.ErrUserNotFound) { if err != nil && !errors.Is(err, user.ErrUserNotFound) {

@ -122,16 +122,14 @@ func TestLoginErrorCookieAPIEndpoint(t *testing.T) {
}) })
cfg.LoginCookieName = loginCookieName cfg.LoginCookieName = loginCookieName
setting.SecretKey = "login_testing"
cfg.OAuthAutoLogin = true cfg.OAuthAutoLogin = true
oauthError := errors.New("User not a member of one of the required organizations") 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()) encryptedError, err := hs.SecretsService.Encrypt(context.Background(), []byte(oauthError.Error()), secrets.WithoutScope())
require.NoError(t, err) require.NoError(t, err)
expCookiePath := "/" expCookiePath := "/"
if len(setting.AppSubUrl) > 0 { if len(cfg.AppSubURL) > 0 {
expCookiePath = setting.AppSubUrl expCookiePath = cfg.AppSubURL
} }
cookie := http.Cookie{ cookie := http.Cookie{
Name: loginErrorCookieName, Name: loginErrorCookieName,

@ -305,7 +305,7 @@ func (hs *HTTPServer) searchOrgUsersHelper(c *contextmodel.ReqContext, query *or
if dtos.IsHiddenUser(user.Login, c.SignedInUser, hs.Cfg) { if dtos.IsHiddenUser(user.Login, c.SignedInUser, hs.Cfg) {
continue continue
} }
user.AvatarURL = dtos.GetGravatarUrl(user.Email) user.AvatarURL = dtos.GetGravatarUrl(hs.Cfg, user.Email)
userIDs[fmt.Sprint(user.UserID)] = true userIDs[fmt.Sprint(user.UserID)] = true
authLabelsUserIDs = append(authLabelsUserIDs, user.UserID) authLabelsUserIDs = append(authLabelsUserIDs, user.UserID)

@ -275,7 +275,7 @@ func (proxy *DataSourceProxy) director(req *http.Request) {
} }
func (proxy *DataSourceProxy) validateRequest() error { func (proxy *DataSourceProxy) validateRequest() error {
if !checkWhiteList(proxy.ctx, proxy.targetUrl.Host) { if !proxy.checkWhiteList() {
return errors.New("target URL is not a valid target") return errors.New("target URL is not a valid target")
} }
@ -354,10 +354,10 @@ func (proxy *DataSourceProxy) logRequest() {
"body", body) "body", body)
} }
func checkWhiteList(c *contextmodel.ReqContext, host string) bool { func (proxy *DataSourceProxy) checkWhiteList() bool {
if host != "" && len(setting.DataProxyWhiteList) > 0 { if proxy.targetUrl.Host != "" && len(proxy.cfg.DataProxyWhiteList) > 0 {
if _, exists := setting.DataProxyWhiteList[host]; !exists { if _, exists := proxy.cfg.DataProxyWhiteList[proxy.targetUrl.Host]; !exists {
c.JsonApiErr(403, "Data proxy hostname and ip are not included in whitelist", nil) proxy.ctx.JsonApiErr(403, "Data proxy hostname and ip are not included in whitelist", nil)
return false return false
} }
} }

@ -28,7 +28,6 @@ import (
) )
func TestPluginProxy(t *testing.T) { func TestPluginProxy(t *testing.T) {
setting.SecretKey = "password"
secretsService := secretsManager.SetupTestService(t, fakes.NewFakeSecretsStore()) secretsService := secretsManager.SetupTestService(t, fakes.NewFakeSecretsStore())
t.Run("When getting proxy headers", func(t *testing.T) { t.Run("When getting proxy headers", func(t *testing.T) {

@ -26,7 +26,7 @@ func (hs *HTTPServer) createShortURL(c *contextmodel.ReqContext) response.Respon
return response.Err(err) return response.Err(err)
} }
url := fmt.Sprintf("%s/goto/%s?orgId=%d", strings.TrimSuffix(setting.AppUrl, "/"), shortURL.Uid, c.SignedInUser.GetOrgID()) url := fmt.Sprintf("%s/goto/%s?orgId=%d", strings.TrimSuffix(hs.Cfg.AppURL, "/"), shortURL.Uid, c.SignedInUser.GetOrgID())
c.Logger.Debug("Created short URL", "url", url) c.Logger.Debug("Created short URL", "url", url)
dto := dtos.ShortURL{ dto := dtos.ShortURL{

@ -14,7 +14,6 @@ import (
contextmodel "github.com/grafana/grafana/pkg/services/contexthandler/model" contextmodel "github.com/grafana/grafana/pkg/services/contexthandler/model"
tempuser "github.com/grafana/grafana/pkg/services/temp_user" tempuser "github.com/grafana/grafana/pkg/services/temp_user"
"github.com/grafana/grafana/pkg/services/user" "github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/util" "github.com/grafana/grafana/pkg/util"
"github.com/grafana/grafana/pkg/web" "github.com/grafana/grafana/pkg/web"
) )
@ -22,7 +21,7 @@ import (
// GET /api/user/signup/options // GET /api/user/signup/options
func (hs *HTTPServer) GetSignUpOptions(c *contextmodel.ReqContext) response.Response { func (hs *HTTPServer) GetSignUpOptions(c *contextmodel.ReqContext) response.Response {
return response.JSON(http.StatusOK, util.DynMap{ return response.JSON(http.StatusOK, util.DynMap{
"verifyEmailEnabled": setting.VerifyEmailEnabled, "verifyEmailEnabled": hs.Cfg.VerifyEmailEnabled,
"autoAssignOrg": hs.Cfg.AutoAssignOrg, "autoAssignOrg": hs.Cfg.AutoAssignOrg,
}) })
} }
@ -34,7 +33,7 @@ func (hs *HTTPServer) SignUp(c *contextmodel.ReqContext) response.Response {
if err = web.Bind(c.Req, &form); err != nil { if err = web.Bind(c.Req, &form); err != nil {
return response.Error(http.StatusBadRequest, "bad request data", err) return response.Error(http.StatusBadRequest, "bad request data", err)
} }
if !setting.AllowUserSignUp { if !hs.Cfg.AllowUserSignUp {
return response.Error(401, "User signup is disabled", nil) return response.Error(401, "User signup is disabled", nil)
} }
@ -86,7 +85,7 @@ func (hs *HTTPServer) SignUpStep2(c *contextmodel.ReqContext) response.Response
if err := web.Bind(c.Req, &form); err != nil { if err := web.Bind(c.Req, &form); err != nil {
return response.Error(http.StatusBadRequest, "bad request data", err) return response.Error(http.StatusBadRequest, "bad request data", err)
} }
if !setting.AllowUserSignUp { if !hs.Cfg.AllowUserSignUp {
return response.Error(401, "User signup is disabled", nil) return response.Error(401, "User signup is disabled", nil)
} }
@ -102,7 +101,7 @@ func (hs *HTTPServer) SignUpStep2(c *contextmodel.ReqContext) response.Response
} }
// verify email // verify email
if setting.VerifyEmailEnabled { if hs.Cfg.VerifyEmailEnabled {
if ok, rsp := hs.verifyUserSignUpEmail(c.Req.Context(), form.Email, form.Code); !ok { if ok, rsp := hs.verifyUserSignUpEmail(c.Req.Context(), form.Email, form.Code); !ok {
return rsp return rsp
} }

@ -79,7 +79,7 @@ func (hs *HTTPServer) getUserUserProfile(c *contextmodel.ReqContext, userID int6
} }
userProfile.AccessControl = hs.getAccessControlMetadata(c, c.SignedInUser.GetOrgID(), "global.users:id:", strconv.FormatInt(userID, 10)) userProfile.AccessControl = hs.getAccessControlMetadata(c, c.SignedInUser.GetOrgID(), "global.users:id:", strconv.FormatInt(userID, 10))
userProfile.AvatarURL = dtos.GetGravatarUrl(userProfile.Email) userProfile.AvatarURL = dtos.GetGravatarUrl(hs.Cfg, userProfile.Email)
return response.JSON(http.StatusOK, userProfile) return response.JSON(http.StatusOK, userProfile)
} }
@ -324,7 +324,7 @@ func (hs *HTTPServer) getUserTeamList(c *contextmodel.ReqContext, orgID int64, u
} }
for _, team := range queryResult { for _, team := range queryResult {
team.AvatarURL = dtos.GetGravatarUrlWithDefault(team.Email, team.Name) team.AvatarURL = dtos.GetGravatarUrlWithDefault(hs.Cfg, team.Email, team.Name)
} }
return response.JSON(http.StatusOK, queryResult) return response.JSON(http.StatusOK, queryResult)
} }

@ -103,7 +103,7 @@ func TestUserAPIEndpoint_userLoggedIn(t *testing.T) {
} }
err = srv.UpdateAuthInfo(context.Background(), cmd) err = srv.UpdateAuthInfo(context.Background(), cmd)
require.NoError(t, err) require.NoError(t, err)
avatarUrl := dtos.GetGravatarUrl("@test.com") avatarUrl := dtos.GetGravatarUrl(hs.Cfg, "@test.com")
sc.fakeReqWithParams("GET", sc.url, map[string]string{"id": fmt.Sprintf("%v", usr.ID)}).exec() sc.fakeReqWithParams("GET", sc.url, map[string]string{"id": fmt.Sprintf("%v", usr.ID)}).exec()
expected := user.UserProfileDTO{ expected := user.UserProfileDTO{
@ -160,7 +160,7 @@ func TestUserAPIEndpoint_userLoggedIn(t *testing.T) {
loggedInUserScenario(t, "When calling GET on", "/api/users", "/api/users", func(sc *scenarioContext) { loggedInUserScenario(t, "When calling GET on", "/api/users", "/api/users", func(sc *scenarioContext) {
userMock.ExpectedSearchUsers = mockResult userMock.ExpectedSearchUsers = mockResult
searchUsersService := searchusers.ProvideUsersService(filters.ProvideOSSSearchUserFilter(), userMock) searchUsersService := searchusers.ProvideUsersService(sc.cfg, filters.ProvideOSSSearchUserFilter(), userMock)
sc.handlerFunc = searchUsersService.SearchUsers sc.handlerFunc = searchUsersService.SearchUsers
sc.fakeReqWithParams("GET", sc.url, map[string]string{}).exec() sc.fakeReqWithParams("GET", sc.url, map[string]string{}).exec()
@ -173,7 +173,7 @@ func TestUserAPIEndpoint_userLoggedIn(t *testing.T) {
loggedInUserScenario(t, "When calling GET with page and limit querystring parameters on", "/api/users", "/api/users", func(sc *scenarioContext) { loggedInUserScenario(t, "When calling GET with page and limit querystring parameters on", "/api/users", "/api/users", func(sc *scenarioContext) {
userMock.ExpectedSearchUsers = mockResult userMock.ExpectedSearchUsers = mockResult
searchUsersService := searchusers.ProvideUsersService(filters.ProvideOSSSearchUserFilter(), userMock) searchUsersService := searchusers.ProvideUsersService(sc.cfg, filters.ProvideOSSSearchUserFilter(), userMock)
sc.handlerFunc = searchUsersService.SearchUsers sc.handlerFunc = searchUsersService.SearchUsers
sc.fakeReqWithParams("GET", sc.url, map[string]string{"perpage": "10", "page": "2"}).exec() sc.fakeReqWithParams("GET", sc.url, map[string]string{"perpage": "10", "page": "2"}).exec()
@ -186,7 +186,7 @@ func TestUserAPIEndpoint_userLoggedIn(t *testing.T) {
loggedInUserScenario(t, "When calling GET on", "/api/users/search", "/api/users/search", func(sc *scenarioContext) { loggedInUserScenario(t, "When calling GET on", "/api/users/search", "/api/users/search", func(sc *scenarioContext) {
userMock.ExpectedSearchUsers = mockResult userMock.ExpectedSearchUsers = mockResult
searchUsersService := searchusers.ProvideUsersService(filters.ProvideOSSSearchUserFilter(), userMock) searchUsersService := searchusers.ProvideUsersService(sc.cfg, filters.ProvideOSSSearchUserFilter(), userMock)
sc.handlerFunc = searchUsersService.SearchUsersWithPaging sc.handlerFunc = searchUsersService.SearchUsersWithPaging
sc.fakeReqWithParams("GET", sc.url, map[string]string{}).exec() sc.fakeReqWithParams("GET", sc.url, map[string]string{}).exec()
@ -202,7 +202,7 @@ func TestUserAPIEndpoint_userLoggedIn(t *testing.T) {
loggedInUserScenario(t, "When calling GET with page and perpage querystring parameters on", "/api/users/search", "/api/users/search", func(sc *scenarioContext) { loggedInUserScenario(t, "When calling GET with page and perpage querystring parameters on", "/api/users/search", "/api/users/search", func(sc *scenarioContext) {
userMock.ExpectedSearchUsers = mockResult userMock.ExpectedSearchUsers = mockResult
searchUsersService := searchusers.ProvideUsersService(filters.ProvideOSSSearchUserFilter(), userMock) searchUsersService := searchusers.ProvideUsersService(sc.cfg, filters.ProvideOSSSearchUserFilter(), userMock)
sc.handlerFunc = searchUsersService.SearchUsersWithPaging sc.handlerFunc = searchUsersService.SearchUsersWithPaging
sc.fakeReqWithParams("GET", sc.url, map[string]string{"perpage": "10", "page": "2"}).exec() sc.fakeReqWithParams("GET", sc.url, map[string]string{"perpage": "10", "page": "2"}).exec()

@ -30,7 +30,7 @@ func runRunnerCommand(command func(commandLine utils.CommandLine, runner server.
} }
} }
func runDbCommand(command func(commandLine utils.CommandLine, sqlStore db.DB) error) func(context *cli.Context) error { func runDbCommand(command func(commandLine utils.CommandLine, cfg *setting.Cfg, sqlStore db.DB) error) func(context *cli.Context) error {
return func(context *cli.Context) error { return func(context *cli.Context) error {
cmd := &utils.ContextCommandLine{Context: context} cmd := &utils.ContextCommandLine{Context: context}
runner, err := initializeRunner(cmd) runner, err := initializeRunner(cmd)
@ -38,8 +38,9 @@ func runDbCommand(command func(commandLine utils.CommandLine, sqlStore db.DB) er
return fmt.Errorf("%v: %w", "failed to initialize runner", err) return fmt.Errorf("%v: %w", "failed to initialize runner", err)
} }
cfg := runner.Cfg
sqlStore := runner.SQLStore sqlStore := runner.SQLStore
if err := command(cmd, sqlStore); err != nil { if err := command(cmd, cfg, sqlStore); err != nil {
return err return err
} }

@ -27,14 +27,14 @@ var (
// EncryptDatasourcePasswords migrates unencrypted secrets on datasources // EncryptDatasourcePasswords migrates unencrypted secrets on datasources
// to the secureJson Column. // to the secureJson Column.
func EncryptDatasourcePasswords(c utils.CommandLine, sqlStore db.DB) error { func EncryptDatasourcePasswords(c utils.CommandLine, cfg *setting.Cfg, sqlStore db.DB) error {
return sqlStore.WithDbSession(context.Background(), func(session *db.Session) error { return sqlStore.WithDbSession(context.Background(), func(session *db.Session) error {
passwordsUpdated, err := migrateColumn(session, "password") passwordsUpdated, err := migrateColumn(cfg, session, "password")
if err != nil { if err != nil {
return err return err
} }
basicAuthUpdated, err := migrateColumn(session, "basic_auth_password") basicAuthUpdated, err := migrateColumn(cfg, session, "basic_auth_password")
if err != nil { if err != nil {
return err return err
} }
@ -61,7 +61,7 @@ func EncryptDatasourcePasswords(c utils.CommandLine, sqlStore db.DB) error {
}) })
} }
func migrateColumn(session *db.Session, column string) (int, error) { func migrateColumn(cfg *setting.Cfg, session *db.Session, column string) (int, error) {
var rows []map[string][]byte var rows []map[string][]byte
session.Cols("id", column, "secure_json_data") session.Cols("id", column, "secure_json_data")
@ -74,18 +74,18 @@ func migrateColumn(session *db.Session, column string) (int, error) {
return 0, fmt.Errorf("failed to select column: %s: %w", column, err) return 0, fmt.Errorf("failed to select column: %s: %w", column, err)
} }
rowsUpdated, err := updateRows(session, rows, column) rowsUpdated, err := updateRows(cfg, session, rows, column)
if err != nil { if err != nil {
return rowsUpdated, fmt.Errorf("failed to update column: %s: %w", column, err) return rowsUpdated, fmt.Errorf("failed to update column: %s: %w", column, err)
} }
return rowsUpdated, err return rowsUpdated, err
} }
func updateRows(session *db.Session, rows []map[string][]byte, passwordFieldName string) (int, error) { func updateRows(cfg *setting.Cfg, session *db.Session, rows []map[string][]byte, passwordFieldName string) (int, error) {
var rowsUpdated int var rowsUpdated int
for _, row := range rows { for _, row := range rows {
newSecureJSONData, err := getUpdatedSecureJSONData(row, passwordFieldName) newSecureJSONData, err := getUpdatedSecureJSONData(cfg.SecretKey, row, passwordFieldName)
if err != nil { if err != nil {
return 0, err return 0, err
} }
@ -111,8 +111,8 @@ func updateRows(session *db.Session, rows []map[string][]byte, passwordFieldName
return rowsUpdated, nil return rowsUpdated, nil
} }
func getUpdatedSecureJSONData(row map[string][]byte, passwordFieldName string) (map[string]any, error) { func getUpdatedSecureJSONData(secretKey string, row map[string][]byte, passwordFieldName string) (map[string]any, error) {
encryptedPassword, err := util.Encrypt(row[passwordFieldName], setting.SecretKey) encryptedPassword, err := util.Encrypt(row[passwordFieldName], secretKey)
if err != nil { if err != nil {
return nil, err return nil, err
} }

@ -38,8 +38,10 @@ func passwordMigration(t *testing.T, session *db.Session, sqlstore db.DB) {
ds.Created = time.Now() ds.Created = time.Now()
ds.Updated = time.Now() ds.Updated = time.Now()
cfg := setting.NewCfg()
if ds.Name == "elasticsearch" { if ds.Name == "elasticsearch" {
key, err := util.Encrypt([]byte("value"), setting.SecretKey) key, err := util.Encrypt([]byte("value"), cfg.SecretKey)
require.NoError(t, err) require.NoError(t, err)
ds.SecureJsonData = map[string][]byte{"key": key} ds.SecureJsonData = map[string][]byte{"key": key}
@ -58,7 +60,7 @@ func passwordMigration(t *testing.T, session *db.Session, sqlstore db.DB) {
// run migration // run migration
c, err := commandstest.NewCliContext(map[string]string{}) c, err := commandstest.NewCliContext(map[string]string{})
require.Nil(t, err) require.Nil(t, err)
err = EncryptDatasourcePasswords(c, sqlstore) err = EncryptDatasourcePasswords(c, setting.NewCfg(), sqlstore)
require.NoError(t, err) require.NoError(t, err)
// verify that no datasources still have password or basic_auth // verify that no datasources still have password or basic_auth
@ -68,7 +70,8 @@ func passwordMigration(t *testing.T, session *db.Session, sqlstore db.DB) {
assert.Equal(t, len(dss), 4) assert.Equal(t, len(dss), 4)
for _, ds := range dss { for _, ds := range dss {
sj, err := DecryptSecureJsonData(ds) cfg := setting.NewCfg()
sj, err := DecryptSecureJsonData(cfg.SecretKey, ds)
require.NoError(t, err) require.NoError(t, err)
if ds.Name == "influxdb" { if ds.Name == "influxdb" {
@ -101,10 +104,10 @@ func passwordMigration(t *testing.T, session *db.Session, sqlstore db.DB) {
} }
} }
func DecryptSecureJsonData(ds *datasources.DataSource) (map[string]string, error) { func DecryptSecureJsonData(secretKey string, ds *datasources.DataSource) (map[string]string, error) {
decrypted := make(map[string]string) decrypted := make(map[string]string)
for key, data := range ds.SecureJsonData { for key, data := range ds.SecureJsonData {
decryptedData, err := util.Decrypt(data, setting.SecretKey) decryptedData, err := util.Decrypt(data, secretKey)
if err != nil { if err != nil {
return nil, err return nil, err
} }

@ -18,7 +18,7 @@ func TestUploadToAzureBlob(t *testing.T) {
}) })
require.NoError(t, err) require.NoError(t, err)
uploader, _ := NewImageUploader() uploader, _ := NewImageUploader(cfg)
path, err := uploader.Upload(context.Background(), "../../../public/img/logo_transparent_400x.png") path, err := uploader.Upload(context.Background(), "../../../public/img/logo_transparent_400x.png")

@ -32,10 +32,10 @@ var (
logger = log.New("imguploader") logger = log.New("imguploader")
) )
func NewImageUploader() (ImageUploader, error) { func NewImageUploader(cfg *setting.Cfg) (ImageUploader, error) {
switch setting.ImageUploadProvider { switch cfg.ImageUploadProvider {
case "s3": case "s3":
s3sec, err := setting.Raw.GetSection("external_image_storage.s3") s3sec, err := cfg.Raw.GetSection("external_image_storage.s3")
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -64,7 +64,7 @@ func NewImageUploader() (ImageUploader, error) {
return NewS3Uploader(endpoint, region, bucket, path, "public-read", accessKey, secretKey, pathStyleAccess), nil return NewS3Uploader(endpoint, region, bucket, path, "public-read", accessKey, secretKey, pathStyleAccess), nil
case "webdav": case "webdav":
webdavSec, err := setting.Raw.GetSection("external_image_storage.webdav") webdavSec, err := cfg.Raw.GetSection("external_image_storage.webdav")
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -80,7 +80,7 @@ func NewImageUploader() (ImageUploader, error) {
return NewWebdavImageUploader(url, username, password, public_url) return NewWebdavImageUploader(url, username, password, public_url)
case "gcs": case "gcs":
gcssec, err := setting.Raw.GetSection("external_image_storage.gcs") gcssec, err := cfg.Raw.GetSection("external_image_storage.gcs")
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -102,7 +102,7 @@ func NewImageUploader() (ImageUploader, error) {
return gcs.NewUploader(keyFile, bucketName, path, enableSignedURLs, suExp) return gcs.NewUploader(keyFile, bucketName, path, enableSignedURLs, suExp)
case "azure_blob": case "azure_blob":
azureBlobSec, err := setting.Raw.GetSection("external_image_storage.azure_blob") azureBlobSec, err := cfg.Raw.GetSection("external_image_storage.azure_blob")
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -118,8 +118,8 @@ func NewImageUploader() (ImageUploader, error) {
return NewLocalImageUploader() return NewLocalImageUploader()
} }
if setting.ImageUploadProvider != "" { if cfg.ImageUploadProvider != "" {
logger.Error("The external image storage configuration is invalid", "unsupported provider", setting.ImageUploadProvider) logger.Error("The external image storage configuration is invalid", "unsupported provider", cfg.ImageUploadProvider)
} }
return NopImageUploader{}, nil return NopImageUploader{}, nil

@ -17,10 +17,10 @@ func TestImageUploaderFactory(t *testing.T) {
}) })
require.NoError(t, err) require.NoError(t, err)
setting.ImageUploadProvider = "s3" cfg.ImageUploadProvider = "s3"
t.Run("with bucket url https://foo.bar.baz.s3-us-east-2.amazonaws.com", func(t *testing.T) { t.Run("with bucket url https://foo.bar.baz.s3-us-east-2.amazonaws.com", func(t *testing.T) {
s3sec, err := setting.Raw.GetSection("external_image_storage.s3") s3sec, err := cfg.Raw.GetSection("external_image_storage.s3")
require.NoError(t, err) require.NoError(t, err)
_, err = s3sec.NewKey("bucket_url", "https://foo.bar.baz.s3-us-east-2.amazonaws.com") _, err = s3sec.NewKey("bucket_url", "https://foo.bar.baz.s3-us-east-2.amazonaws.com")
require.NoError(t, err) require.NoError(t, err)
@ -29,7 +29,7 @@ func TestImageUploaderFactory(t *testing.T) {
_, err = s3sec.NewKey("secret_key", "secret_key") _, err = s3sec.NewKey("secret_key", "secret_key")
require.NoError(t, err) require.NoError(t, err)
uploader, err := NewImageUploader() uploader, err := NewImageUploader(cfg)
require.NoError(t, err) require.NoError(t, err)
original, ok := uploader.(*S3Uploader) original, ok := uploader.(*S3Uploader)
@ -41,7 +41,7 @@ func TestImageUploaderFactory(t *testing.T) {
}) })
t.Run("with bucket url https://s3.amazonaws.com/mybucket", func(t *testing.T) { t.Run("with bucket url https://s3.amazonaws.com/mybucket", func(t *testing.T) {
s3sec, err := setting.Raw.GetSection("external_image_storage.s3") s3sec, err := cfg.Raw.GetSection("external_image_storage.s3")
require.NoError(t, err) require.NoError(t, err)
_, err = s3sec.NewKey("bucket_url", "https://s3.amazonaws.com/my.bucket.com") _, err = s3sec.NewKey("bucket_url", "https://s3.amazonaws.com/my.bucket.com")
require.NoError(t, err) require.NoError(t, err)
@ -50,7 +50,7 @@ func TestImageUploaderFactory(t *testing.T) {
_, err = s3sec.NewKey("secret_key", "secret_key") _, err = s3sec.NewKey("secret_key", "secret_key")
require.NoError(t, err) require.NoError(t, err)
uploader, err := NewImageUploader() uploader, err := NewImageUploader(cfg)
require.NoError(t, err) require.NoError(t, err)
original, ok := uploader.(*S3Uploader) original, ok := uploader.(*S3Uploader)
@ -62,7 +62,7 @@ func TestImageUploaderFactory(t *testing.T) {
}) })
t.Run("with bucket url https://s3-us-west-2.amazonaws.com/mybucket", func(t *testing.T) { t.Run("with bucket url https://s3-us-west-2.amazonaws.com/mybucket", func(t *testing.T) {
s3sec, err := setting.Raw.GetSection("external_image_storage.s3") s3sec, err := cfg.Raw.GetSection("external_image_storage.s3")
require.NoError(t, err) require.NoError(t, err)
_, err = s3sec.NewKey("bucket_url", "https://s3-us-west-2.amazonaws.com/my.bucket.com") _, err = s3sec.NewKey("bucket_url", "https://s3-us-west-2.amazonaws.com/my.bucket.com")
require.NoError(t, err) require.NoError(t, err)
@ -71,7 +71,7 @@ func TestImageUploaderFactory(t *testing.T) {
_, err = s3sec.NewKey("secret_key", "secret_key") _, err = s3sec.NewKey("secret_key", "secret_key")
require.NoError(t, err) require.NoError(t, err)
uploader, err := NewImageUploader() uploader, err := NewImageUploader(cfg)
require.NoError(t, err) require.NoError(t, err)
original, ok := uploader.(*S3Uploader) original, ok := uploader.(*S3Uploader)
@ -90,7 +90,7 @@ func TestImageUploaderFactory(t *testing.T) {
}) })
require.NoError(t, err) require.NoError(t, err)
setting.ImageUploadProvider = "webdav" cfg.ImageUploadProvider = "webdav"
webdavSec, err := cfg.Raw.GetSection("external_image_storage.webdav") webdavSec, err := cfg.Raw.GetSection("external_image_storage.webdav")
require.NoError(t, err) require.NoError(t, err)
@ -101,7 +101,7 @@ func TestImageUploaderFactory(t *testing.T) {
_, err = webdavSec.NewKey("password", "password") _, err = webdavSec.NewKey("password", "password")
require.NoError(t, err) require.NoError(t, err)
uploader, err := NewImageUploader() uploader, err := NewImageUploader(cfg)
require.NoError(t, err) require.NoError(t, err)
original, ok := uploader.(*WebdavUploader) original, ok := uploader.(*WebdavUploader)
@ -118,7 +118,7 @@ func TestImageUploaderFactory(t *testing.T) {
}) })
require.NoError(t, err) require.NoError(t, err)
setting.ImageUploadProvider = "gcs" cfg.ImageUploadProvider = "gcs"
gcpSec, err := cfg.Raw.GetSection("external_image_storage.gcs") gcpSec, err := cfg.Raw.GetSection("external_image_storage.gcs")
require.NoError(t, err) require.NoError(t, err)
@ -127,7 +127,7 @@ func TestImageUploaderFactory(t *testing.T) {
_, err = gcpSec.NewKey("bucket", "project-grafana-east") _, err = gcpSec.NewKey("bucket", "project-grafana-east")
require.NoError(t, err) require.NoError(t, err)
uploader, err := NewImageUploader() uploader, err := NewImageUploader(cfg)
require.NoError(t, err) require.NoError(t, err)
original, ok := uploader.(*gcs.Uploader) original, ok := uploader.(*gcs.Uploader)
@ -143,7 +143,7 @@ func TestImageUploaderFactory(t *testing.T) {
}) })
require.NoError(t, err) require.NoError(t, err)
setting.ImageUploadProvider = "azure_blob" cfg.ImageUploadProvider = "azure_blob"
t.Run("with container name", func(t *testing.T) { t.Run("with container name", func(t *testing.T) {
azureBlobSec, err := cfg.Raw.GetSection("external_image_storage.azure_blob") azureBlobSec, err := cfg.Raw.GetSection("external_image_storage.azure_blob")
@ -157,7 +157,7 @@ func TestImageUploaderFactory(t *testing.T) {
_, err = azureBlobSec.NewKey("sas_token_expiration_days", "sas_token_expiration_days") _, err = azureBlobSec.NewKey("sas_token_expiration_days", "sas_token_expiration_days")
require.NoError(t, err) require.NoError(t, err)
uploader, err := NewImageUploader() uploader, err := NewImageUploader(cfg)
require.NoError(t, err) require.NoError(t, err)
original, ok := uploader.(*AzureBlobUploader) original, ok := uploader.(*AzureBlobUploader)
@ -176,9 +176,9 @@ func TestImageUploaderFactory(t *testing.T) {
}) })
require.NoError(t, err) require.NoError(t, err)
setting.ImageUploadProvider = "local" cfg.ImageUploadProvider = "local"
uploader, err := NewImageUploader() uploader, err := NewImageUploader(cfg)
require.NoError(t, err) require.NoError(t, err)
original, ok := uploader.(*LocalUploader) original, ok := uploader.(*LocalUploader)

@ -17,7 +17,7 @@ func TestUploadToS3(t *testing.T) {
}) })
require.NoError(t, err) require.NoError(t, err)
s3Uploader, err := NewImageUploader() s3Uploader, err := NewImageUploader(cfg)
require.NoError(t, err) require.NoError(t, err)
path, err := s3Uploader.Upload(context.Background(), "../../../public/img/logo_transparent_400x.png") path, err := s3Uploader.Upload(context.Background(), "../../../public/img/logo_transparent_400x.png")

@ -8,7 +8,6 @@ import (
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus"
"github.com/grafana/grafana/pkg/infra/metrics/graphitebridge" "github.com/grafana/grafana/pkg/infra/metrics/graphitebridge"
"github.com/grafana/grafana/pkg/setting"
) )
func (im *InternalMetricsService) readSettings() error { func (im *InternalMetricsService) readSettings() error {
@ -48,7 +47,7 @@ func (im *InternalMetricsService) parseGraphiteSettings() error {
ErrorHandling: graphitebridge.ContinueOnError, ErrorHandling: graphitebridge.ContinueOnError,
} }
safeInstanceName := strings.ReplaceAll(setting.InstanceName, ".", "_") safeInstanceName := strings.ReplaceAll(im.Cfg.InstanceName, ".", "_")
prefix := graphiteSection.Key("prefix").Value() prefix := graphiteSection.Key("prefix").Value()
if prefix == "" { if prefix == "" {

@ -4,7 +4,6 @@ import (
"encoding/json" "encoding/json"
"net/http" "net/http"
"net/http/httptest" "net/http/httptest"
"path"
"testing" "testing"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
@ -15,7 +14,6 @@ import (
contextmodel "github.com/grafana/grafana/pkg/services/contexthandler/model" contextmodel "github.com/grafana/grafana/pkg/services/contexthandler/model"
"github.com/grafana/grafana/pkg/services/stats" "github.com/grafana/grafana/pkg/services/stats"
"github.com/grafana/grafana/pkg/services/user" "github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/web" "github.com/grafana/grafana/pkg/web"
) )
@ -80,7 +78,7 @@ func getUsageStats(t *testing.T, server *web.Mux) (*stats.SystemStats, *httptest
func setupTestServer(t *testing.T, user *user.SignedInUser, service *UsageStats) *web.Mux { func setupTestServer(t *testing.T, user *user.SignedInUser, service *UsageStats) *web.Mux {
server := web.New() server := web.New()
server.UseMiddleware(web.Renderer(path.Join(setting.StaticRootPath, "views"), "[[", "]]")) server.UseMiddleware(web.Renderer("views", "[[", "]]"))
server.Use(contextProvider(&testContext{user})) server.Use(contextProvider(&testContext{user}))
service.RouteRegister.Register(server) service.RouteRegister.Register(server)
return server return server

@ -255,7 +255,7 @@ func (s *SocialGitlab) extractFromAPI(ctx context.Context, client *http.Client,
idData.Role = role idData.Role = role
} }
if setting.Env == setting.Dev { if s.cfg.Env == setting.Dev {
s.log.Debug("Resolved ID", "data", fmt.Sprintf("%+v", idData)) s.log.Debug("Resolved ID", "data", fmt.Sprintf("%+v", idData))
} }

@ -216,7 +216,7 @@ func (s *SocialGoogle) extractFromToken(ctx context.Context, client *http.Client
return nil, nil return nil, nil
} }
if setting.Env == setting.Dev { if s.cfg.Env == setting.Dev {
s.log.Debug("Received id_token", "raw_json", string(rawJSON)) s.log.Debug("Received id_token", "raw_json", string(rawJSON))
} }

@ -152,7 +152,7 @@ func Recovery(cfg *setting.Cfg, license licensing.Licensing) web.Middleware {
Assets *dtos.EntryPointAssets Assets *dtos.EntryPointAssets
}{"Server Error", "Grafana", cfg.AppSubURL, cfg.DefaultTheme, "", assets} }{"Server Error", "Grafana", cfg.AppSubURL, cfg.DefaultTheme, "", assets}
if setting.Env == setting.Dev { if cfg.Env == setting.Dev {
if err, ok := r.(error); ok { if err, ok := r.(error); ok {
data.Title = err.Error() data.Title = err.Error()
} }

@ -22,6 +22,7 @@ import (
"github.com/grafana/grafana/pkg/services/team" "github.com/grafana/grafana/pkg/services/team"
"github.com/grafana/grafana/pkg/services/team/teamimpl" "github.com/grafana/grafana/pkg/services/team/teamimpl"
"github.com/grafana/grafana/pkg/services/user" "github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana/pkg/setting"
) )
type TeamPermissionsService struct { type TeamPermissionsService struct {
@ -43,7 +44,7 @@ var (
) )
func ProvideTeamPermissions( func ProvideTeamPermissions(
features featuremgmt.FeatureToggles, router routing.RouteRegister, sql db.DB, cfg *setting.Cfg, features featuremgmt.FeatureToggles, router routing.RouteRegister, sql db.DB,
ac accesscontrol.AccessControl, license licensing.Licensing, service accesscontrol.Service, ac accesscontrol.AccessControl, license licensing.Licensing, service accesscontrol.Service,
teamService team.Service, userService user.Service, teamService team.Service, userService user.Service,
) (*TeamPermissionsService, error) { ) (*TeamPermissionsService, error) {
@ -101,7 +102,7 @@ func ProvideTeamPermissions(
}, },
} }
srv, err := resourcepermissions.New(options, features, router, license, ac, service, sql, teamService, userService) srv, err := resourcepermissions.New(cfg, options, features, router, license, ac, service, sql, teamService, userService)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -117,7 +118,7 @@ var DashboardEditActions = append(DashboardViewActions, []string{dashboards.Acti
var DashboardAdminActions = append(DashboardEditActions, []string{dashboards.ActionDashboardsPermissionsRead, dashboards.ActionDashboardsPermissionsWrite}...) var DashboardAdminActions = append(DashboardEditActions, []string{dashboards.ActionDashboardsPermissionsRead, dashboards.ActionDashboardsPermissionsWrite}...)
func ProvideDashboardPermissions( func ProvideDashboardPermissions(
features featuremgmt.FeatureToggles, router routing.RouteRegister, sql db.DB, ac accesscontrol.AccessControl, cfg *setting.Cfg, features featuremgmt.FeatureToggles, router routing.RouteRegister, sql db.DB, ac accesscontrol.AccessControl,
license licensing.Licensing, dashboardStore dashboards.Store, folderService folder.Service, service accesscontrol.Service, license licensing.Licensing, dashboardStore dashboards.Store, folderService folder.Service, service accesscontrol.Service,
teamService team.Service, userService user.Service, teamService team.Service, userService user.Service,
) (*DashboardPermissionsService, error) { ) (*DashboardPermissionsService, error) {
@ -183,7 +184,7 @@ func ProvideDashboardPermissions(
RoleGroup: "Dashboards", RoleGroup: "Dashboards",
} }
srv, err := resourcepermissions.New(options, features, router, license, ac, service, sql, teamService, userService) srv, err := resourcepermissions.New(cfg, options, features, router, license, ac, service, sql, teamService, userService)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -209,7 +210,7 @@ var FolderEditActions = append(FolderViewActions, []string{
var FolderAdminActions = append(FolderEditActions, []string{dashboards.ActionFoldersPermissionsRead, dashboards.ActionFoldersPermissionsWrite}...) var FolderAdminActions = append(FolderEditActions, []string{dashboards.ActionFoldersPermissionsRead, dashboards.ActionFoldersPermissionsWrite}...)
func ProvideFolderPermissions( func ProvideFolderPermissions(
features featuremgmt.FeatureToggles, router routing.RouteRegister, sql db.DB, accesscontrol accesscontrol.AccessControl, cfg *setting.Cfg, features featuremgmt.FeatureToggles, router routing.RouteRegister, sql db.DB, accesscontrol accesscontrol.AccessControl,
license licensing.Licensing, dashboardStore dashboards.Store, folderService folder.Service, service accesscontrol.Service, license licensing.Licensing, dashboardStore dashboards.Store, folderService folder.Service, service accesscontrol.Service,
teamService team.Service, userService user.Service, teamService team.Service, userService user.Service,
) (*FolderPermissionsService, error) { ) (*FolderPermissionsService, error) {
@ -247,7 +248,7 @@ func ProvideFolderPermissions(
WriterRoleName: "Folder permission writer", WriterRoleName: "Folder permission writer",
RoleGroup: "Folders", RoleGroup: "Folders",
} }
srv, err := resourcepermissions.New(options, features, router, license, accesscontrol, service, sql, teamService, userService) srv, err := resourcepermissions.New(cfg, options, features, router, license, accesscontrol, service, sql, teamService, userService)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -309,7 +310,7 @@ type ServiceAccountPermissionsService struct {
} }
func ProvideServiceAccountPermissions( func ProvideServiceAccountPermissions(
features featuremgmt.FeatureToggles, router routing.RouteRegister, sql db.DB, ac accesscontrol.AccessControl, cfg *setting.Cfg, features featuremgmt.FeatureToggles, router routing.RouteRegister, sql db.DB, ac accesscontrol.AccessControl,
license licensing.Licensing, serviceAccountRetrieverService *retriever.Service, service accesscontrol.Service, license licensing.Licensing, serviceAccountRetrieverService *retriever.Service, service accesscontrol.Service,
teamService team.Service, userService user.Service, teamService team.Service, userService user.Service,
) (*ServiceAccountPermissionsService, error) { ) (*ServiceAccountPermissionsService, error) {
@ -338,7 +339,7 @@ func ProvideServiceAccountPermissions(
RoleGroup: "Service accounts", RoleGroup: "Service accounts",
} }
srv, err := resourcepermissions.New(options, features, router, license, ac, service, sql, teamService, userService) srv, err := resourcepermissions.New(cfg, options, features, router, license, ac, service, sql, teamService, userService)
if err != nil { if err != nil {
return nil, err return nil, err
} }

@ -11,23 +11,25 @@ import (
"github.com/grafana/grafana/pkg/services/accesscontrol" "github.com/grafana/grafana/pkg/services/accesscontrol"
contextmodel "github.com/grafana/grafana/pkg/services/contexthandler/model" contextmodel "github.com/grafana/grafana/pkg/services/contexthandler/model"
"github.com/grafana/grafana/pkg/services/org" "github.com/grafana/grafana/pkg/services/org"
"github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/web" "github.com/grafana/grafana/pkg/web"
) )
type api struct { type api struct {
cfg *setting.Cfg
ac accesscontrol.AccessControl ac accesscontrol.AccessControl
router routing.RouteRegister router routing.RouteRegister
service *Service service *Service
permissions []string permissions []string
} }
func newApi(ac accesscontrol.AccessControl, router routing.RouteRegister, manager *Service) *api { func newApi(cfg *setting.Cfg, ac accesscontrol.AccessControl, router routing.RouteRegister, manager *Service) *api {
permissions := make([]string, 0, len(manager.permissions)) permissions := make([]string, 0, len(manager.permissions))
// reverse the permissions order for display // reverse the permissions order for display
for i := len(manager.permissions) - 1; i >= 0; i-- { for i := len(manager.permissions) - 1; i >= 0; i-- {
permissions = append(permissions, manager.permissions[i]) permissions = append(permissions, manager.permissions[i])
} }
return &api{ac, router, manager, permissions} return &api{cfg, ac, router, manager, permissions}
} }
func (a *api) registerEndpoints() { func (a *api) registerEndpoints() {
@ -157,7 +159,7 @@ func (a *api) getPermissions(c *contextmodel.ReqContext) response.Response {
if permission := a.service.MapActions(p); permission != "" { if permission := a.service.MapActions(p); permission != "" {
teamAvatarUrl := "" teamAvatarUrl := ""
if p.TeamId != 0 { if p.TeamId != 0 {
teamAvatarUrl = dtos.GetGravatarUrlWithDefault(p.TeamEmail, p.Team) teamAvatarUrl = dtos.GetGravatarUrlWithDefault(a.cfg, p.TeamEmail, p.Team)
} }
dto = append(dto, resourcePermissionDTO{ dto = append(dto, resourcePermissionDTO{
@ -165,7 +167,7 @@ func (a *api) getPermissions(c *contextmodel.ReqContext) response.Response {
RoleName: p.RoleName, RoleName: p.RoleName,
UserID: p.UserId, UserID: p.UserId,
UserLogin: p.UserLogin, UserLogin: p.UserLogin,
UserAvatarUrl: dtos.GetGravatarUrl(p.UserEmail), UserAvatarUrl: dtos.GetGravatarUrl(a.cfg, p.UserEmail),
Team: p.Team, Team: p.Team,
TeamID: p.TeamId, TeamID: p.TeamId,
TeamAvatarUrl: teamAvatarUrl, TeamAvatarUrl: teamAvatarUrl,

@ -6,7 +6,6 @@ import (
"fmt" "fmt"
"net/http" "net/http"
"net/http/httptest" "net/http/httptest"
"path"
"strconv" "strconv"
"strings" "strings"
"testing" "testing"
@ -25,7 +24,6 @@ import (
"github.com/grafana/grafana/pkg/services/team/teamimpl" "github.com/grafana/grafana/pkg/services/team/teamimpl"
"github.com/grafana/grafana/pkg/services/user" "github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana/pkg/services/user/userimpl" "github.com/grafana/grafana/pkg/services/user/userimpl"
"github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/web" "github.com/grafana/grafana/pkg/web"
) )
@ -432,7 +430,7 @@ func TestApi_setUserPermission(t *testing.T) {
func setupTestServer(t *testing.T, user *user.SignedInUser, service *Service) *web.Mux { func setupTestServer(t *testing.T, user *user.SignedInUser, service *Service) *web.Mux {
server := web.New() server := web.New()
server.UseMiddleware(web.Renderer(path.Join(setting.StaticRootPath, "views"), "[[", "]]")) server.UseMiddleware(web.Renderer("views", "[[", "]]"))
server.Use(contextProvider(&testContext{user})) server.Use(contextProvider(&testContext{user}))
service.api.router.Register(server) service.api.router.Register(server)
return server return server

@ -14,6 +14,7 @@ import (
"github.com/grafana/grafana/pkg/services/org" "github.com/grafana/grafana/pkg/services/org"
"github.com/grafana/grafana/pkg/services/team" "github.com/grafana/grafana/pkg/services/team"
"github.com/grafana/grafana/pkg/services/user" "github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana/pkg/setting"
) )
type Store interface { type Store interface {
@ -52,7 +53,7 @@ type Store interface {
DeleteResourcePermissions(ctx context.Context, orgID int64, cmd *DeleteResourcePermissionsCmd) error DeleteResourcePermissions(ctx context.Context, orgID int64, cmd *DeleteResourcePermissionsCmd) error
} }
func New( func New(cfg *setting.Cfg,
options Options, features featuremgmt.FeatureToggles, router routing.RouteRegister, license licensing.Licensing, options Options, features featuremgmt.FeatureToggles, router routing.RouteRegister, license licensing.Licensing,
ac accesscontrol.AccessControl, service accesscontrol.Service, sqlStore db.DB, ac accesscontrol.AccessControl, service accesscontrol.Service, sqlStore db.DB,
teamService team.Service, userService user.Service, teamService team.Service, userService user.Service,
@ -89,7 +90,7 @@ func New(
userService: userService, userService: userService,
} }
s.api = newApi(ac, router, s) s.api = newApi(cfg, ac, router, s)
if err := s.declareFixedRoles(); err != nil { if err := s.declareFixedRoles(); err != nil {
return nil, err return nil, err

@ -245,7 +245,7 @@ func setupTestEnvironment(t *testing.T, ops Options) (*Service, *sqlstore.SQLSto
ac := acimpl.ProvideAccessControl(cfg) ac := acimpl.ProvideAccessControl(cfg)
acService := &actest.FakeService{} acService := &actest.FakeService{}
service, err := New( service, err := New(
ops, featuremgmt.WithFeatures(), routing.NewRouteRegister(), license, cfg, ops, featuremgmt.WithFeatures(), routing.NewRouteRegister(), license,
ac, acService, sql, teamSvc, userSvc, ac, acService, sql, teamSvc, userSvc,
) )
require.NoError(t, err) require.NoError(t, err)

@ -57,7 +57,7 @@ type AlertEngine struct {
// IsDisabled returns true if the alerting service is disabled for this instance. // IsDisabled returns true if the alerting service is disabled for this instance.
func (e *AlertEngine) IsDisabled() bool { func (e *AlertEngine) IsDisabled() bool {
return setting.AlertingEnabled == nil || !*setting.AlertingEnabled || !setting.ExecuteAlerts || e.Cfg.UnifiedAlerting.IsEnabled() return e.Cfg.AlertingEnabled == nil || !*(e.Cfg.AlertingEnabled) || !e.Cfg.ExecuteAlerts || e.Cfg.UnifiedAlerting.IsEnabled()
} }
// ProvideAlertEngine returns a new AlertEngine. // ProvideAlertEngine returns a new AlertEngine.
@ -80,11 +80,11 @@ func ProvideAlertEngine(renderer rendering.Service, requestValidator validations
annotationsRepo: annotationsRepo, annotationsRepo: annotationsRepo,
} }
e.execQueue = make(chan *Job, 1000) e.execQueue = make(chan *Job, 1000)
e.scheduler = newScheduler() e.scheduler = newScheduler(cfg)
e.evalHandler = NewEvalHandler(e.DataService) e.evalHandler = NewEvalHandler(e.DataService)
e.ruleReader = newRuleReader(store) e.ruleReader = newRuleReader(store)
e.log = log.New("alerting.engine") e.log = log.New("alerting.engine")
e.resultHandler = newResultHandler(e.RenderService, store, notificationService, encryptionService.GetDecryptedValue) e.resultHandler = newResultHandler(cfg, e.RenderService, store, notificationService, encryptionService.GetDecryptedValue)
e.registerUsageMetrics() e.registerUsageMetrics()
@ -153,7 +153,7 @@ func (e *AlertEngine) processJobWithRetry(grafanaCtx context.Context, job *Job)
} }
}() }()
cancelChan := make(chan context.CancelFunc, setting.AlertingMaxAttempts*2) cancelChan := make(chan context.CancelFunc, e.Cfg.AlertingMaxAttempts*2)
attemptChan := make(chan int, 1) attemptChan := make(chan int, 1)
// Initialize with first attemptID=1 // Initialize with first attemptID=1
@ -197,7 +197,7 @@ func (e *AlertEngine) processJob(attemptID int, attemptChan chan int, cancelChan
} }
}() }()
alertCtx, cancelFn := context.WithTimeout(context.Background(), setting.AlertingEvaluationTimeout) alertCtx, cancelFn := context.WithTimeout(context.Background(), e.Cfg.AlertingEvaluationTimeout)
cancelChan <- cancelFn cancelChan <- cancelFn
alertCtx, span := e.tracer.Start(alertCtx, "alert execution") alertCtx, span := e.tracer.Start(alertCtx, "alert execution")
evalContext := NewEvalContext(alertCtx, job.Rule, e.RequestValidator, e.AlertStore, e.dashboardService, e.datasourceService, e.annotationsRepo) evalContext := NewEvalContext(alertCtx, job.Rule, e.RequestValidator, e.AlertStore, e.dashboardService, e.datasourceService, e.annotationsRepo)
@ -228,7 +228,7 @@ func (e *AlertEngine) processJob(attemptID int, attemptChan chan int, cancelChan
span.SetStatus(codes.Error, "alerting execution attempt failed") span.SetStatus(codes.Error, "alerting execution attempt failed")
span.RecordError(evalContext.Error) span.RecordError(evalContext.Error)
if attemptID < setting.AlertingMaxAttempts { if attemptID < e.Cfg.AlertingMaxAttempts {
span.End() span.End()
e.log.Debug("Job Execution attempt triggered retry", "timeMs", evalContext.GetDurationMs(), "alertId", evalContext.Rule.ID, "name", evalContext.Rule.Name, "firing", evalContext.Firing, "attemptID", attemptID) e.log.Debug("Job Execution attempt triggered retry", "timeMs", evalContext.GetDurationMs(), "alertId", evalContext.Rule.ID, "name", evalContext.Rule.Name, "firing", evalContext.Firing, "attemptID", attemptID)
attemptChan <- (attemptID + 1) attemptChan <- (attemptID + 1)
@ -237,7 +237,7 @@ func (e *AlertEngine) processJob(attemptID int, attemptChan chan int, cancelChan
} }
// create new context with timeout for notifications // create new context with timeout for notifications
resultHandleCtx, resultHandleCancelFn := context.WithTimeout(context.Background(), setting.AlertingNotificationTimeout) resultHandleCtx, resultHandleCancelFn := context.WithTimeout(context.Background(), e.Cfg.AlertingNotificationTimeout)
cancelChan <- resultHandleCancelFn cancelChan <- resultHandleCancelFn
// override the context used for evaluation with a new context for notifications. // override the context used for evaluation with a new context for notifications.

@ -37,16 +37,17 @@ func TestIntegrationEngineTimeouts(t *testing.T) {
tracer := tracing.InitializeTracerForTest() tracer := tracing.InitializeTracerForTest()
dsMock := &datasources.FakeDataSourceService{} dsMock := &datasources.FakeDataSourceService{}
annotationsRepo := annotationstest.NewFakeAnnotationsRepo() annotationsRepo := annotationstest.NewFakeAnnotationsRepo()
engine := ProvideAlertEngine(nil, nil, nil, usMock, usValidatorMock, encService, nil, tracer, nil, setting.NewCfg(), nil, nil, localcache.New(time.Minute, time.Minute), dsMock, annotationsRepo) cfg := setting.NewCfg()
setting.AlertingNotificationTimeout = 30 * time.Second engine := ProvideAlertEngine(nil, nil, nil, usMock, usValidatorMock, encService, nil, tracer, nil, cfg, nil, nil, localcache.New(time.Minute, time.Minute), dsMock, annotationsRepo)
setting.AlertingMaxAttempts = 3 cfg.AlertingNotificationTimeout = 30 * time.Second
cfg.AlertingMaxAttempts = 3
engine.resultHandler = &FakeResultHandler{} engine.resultHandler = &FakeResultHandler{}
job := &Job{running: true, Rule: &Rule{}} job := &Job{running: true, Rule: &Rule{}}
t.Run("Should trigger as many retries as needed", func(t *testing.T) { t.Run("Should trigger as many retries as needed", func(t *testing.T) {
t.Run("pended alert for datasource -> result handler should be worked", func(t *testing.T) { t.Run("pended alert for datasource -> result handler should be worked", func(t *testing.T) {
// reduce alert timeout to test quickly // reduce alert timeout to test quickly
setting.AlertingEvaluationTimeout = 30 * time.Second cfg.AlertingEvaluationTimeout = 30 * time.Second
transportTimeoutInterval := 2 * time.Second transportTimeoutInterval := 2 * time.Second
serverBusySleepDuration := 1 * time.Second serverBusySleepDuration := 1 * time.Second
@ -62,7 +63,7 @@ func TestIntegrationEngineTimeouts(t *testing.T) {
require.Equal(t, true, resultHandler.ResultHandleSucceed) require.Equal(t, true, resultHandler.ResultHandleSucceed)
// initialize for other tests. // initialize for other tests.
setting.AlertingEvaluationTimeout = 2 * time.Second cfg.AlertingEvaluationTimeout = 2 * time.Second
engine.resultHandler = &FakeResultHandler{} engine.resultHandler = &FakeResultHandler{}
}) })
}) })

@ -122,7 +122,8 @@ func TestEngineProcessJob(t *testing.T) {
usValidatorMock := &validator.FakeUsageStatsValidator{} usValidatorMock := &validator.FakeUsageStatsValidator{}
encProvider := encryptionprovider.ProvideEncryptionProvider() encProvider := encryptionprovider.ProvideEncryptionProvider()
encService, err := encryptionservice.ProvideEncryptionService(encProvider, usMock, setting.NewCfg()) cfg := setting.NewCfg()
encService, err := encryptionservice.ProvideEncryptionService(encProvider, usMock, cfg)
require.NoError(t, err) require.NoError(t, err)
tracer := tracing.InitializeTracerForTest() tracer := tracing.InitializeTracerForTest()
@ -130,10 +131,10 @@ func TestEngineProcessJob(t *testing.T) {
dsMock := &fd.FakeDataSourceService{ dsMock := &fd.FakeDataSourceService{
DataSources: []*datasources.DataSource{{ID: 1, Type: datasources.DS_PROMETHEUS}}, DataSources: []*datasources.DataSource{{ID: 1, Type: datasources.DS_PROMETHEUS}},
} }
engine := ProvideAlertEngine(nil, nil, nil, usMock, usValidatorMock, encService, nil, tracer, store, setting.NewCfg(), nil, nil, localcache.New(time.Minute, time.Minute), dsMock, annotationstest.NewFakeAnnotationsRepo()) engine := ProvideAlertEngine(nil, nil, nil, usMock, usValidatorMock, encService, nil, tracer, store, cfg, nil, nil, localcache.New(time.Minute, time.Minute), dsMock, annotationstest.NewFakeAnnotationsRepo())
setting.AlertingEvaluationTimeout = 30 * time.Second cfg.AlertingEvaluationTimeout = 30 * time.Second
setting.AlertingNotificationTimeout = 30 * time.Second cfg.AlertingNotificationTimeout = 30 * time.Second
setting.AlertingMaxAttempts = 3 cfg.AlertingMaxAttempts = 3
engine.resultHandler = &FakeResultHandler{} engine.resultHandler = &FakeResultHandler{}
job := &Job{running: true, Rule: &Rule{}} job := &Job{running: true, Rule: &Rule{}}
@ -157,9 +158,9 @@ func TestEngineProcessJob(t *testing.T) {
t.Run("error + not last attempt -> retry", func(t *testing.T) { t.Run("error + not last attempt -> retry", func(t *testing.T) {
engine.evalHandler = NewFakeEvalHandler(0) engine.evalHandler = NewFakeEvalHandler(0)
for i := 1; i < setting.AlertingMaxAttempts; i++ { for i := 1; i < cfg.AlertingMaxAttempts; i++ {
attemptChan := make(chan int, 1) attemptChan := make(chan int, 1)
cancelChan := make(chan context.CancelFunc, setting.AlertingMaxAttempts) cancelChan := make(chan context.CancelFunc, cfg.AlertingMaxAttempts)
engine.processJob(i, attemptChan, cancelChan, job) engine.processJob(i, attemptChan, cancelChan, job)
nextAttemptID, more := <-attemptChan nextAttemptID, more := <-attemptChan
@ -173,9 +174,9 @@ func TestEngineProcessJob(t *testing.T) {
t.Run("error + last attempt -> no retry", func(t *testing.T) { t.Run("error + last attempt -> no retry", func(t *testing.T) {
engine.evalHandler = NewFakeEvalHandler(0) engine.evalHandler = NewFakeEvalHandler(0)
attemptChan := make(chan int, 1) attemptChan := make(chan int, 1)
cancelChan := make(chan context.CancelFunc, setting.AlertingMaxAttempts) cancelChan := make(chan context.CancelFunc, cfg.AlertingMaxAttempts)
engine.processJob(setting.AlertingMaxAttempts, attemptChan, cancelChan, job) engine.processJob(cfg.AlertingMaxAttempts, attemptChan, cancelChan, job)
nextAttemptID, more := <-attemptChan nextAttemptID, more := <-attemptChan
require.Equal(t, 0, nextAttemptID) require.Equal(t, 0, nextAttemptID)
@ -186,7 +187,7 @@ func TestEngineProcessJob(t *testing.T) {
t.Run("no error -> no retry", func(t *testing.T) { t.Run("no error -> no retry", func(t *testing.T) {
engine.evalHandler = NewFakeEvalHandler(1) engine.evalHandler = NewFakeEvalHandler(1)
attemptChan := make(chan int, 1) attemptChan := make(chan int, 1)
cancelChan := make(chan context.CancelFunc, setting.AlertingMaxAttempts) cancelChan := make(chan context.CancelFunc, cfg.AlertingMaxAttempts)
engine.processJob(1, attemptChan, cancelChan, job) engine.processJob(1, attemptChan, cancelChan, job)
nextAttemptID, more := <-attemptChan nextAttemptID, more := <-attemptChan
@ -199,7 +200,7 @@ func TestEngineProcessJob(t *testing.T) {
t.Run("Should trigger as many retries as needed", func(t *testing.T) { t.Run("Should trigger as many retries as needed", func(t *testing.T) {
t.Run("never success -> max retries number", func(t *testing.T) { t.Run("never success -> max retries number", func(t *testing.T) {
expectedAttempts := setting.AlertingMaxAttempts expectedAttempts := cfg.AlertingMaxAttempts
evalHandler := NewFakeEvalHandler(0) evalHandler := NewFakeEvalHandler(0)
engine.evalHandler = evalHandler engine.evalHandler = evalHandler
@ -219,7 +220,7 @@ func TestEngineProcessJob(t *testing.T) {
}) })
t.Run("some errors before success -> some retries", func(t *testing.T) { t.Run("some errors before success -> some retries", func(t *testing.T) {
expectedAttempts := int(math.Ceil(float64(setting.AlertingMaxAttempts) / 2)) expectedAttempts := int(math.Ceil(float64(cfg.AlertingMaxAttempts) / 2))
evalHandler := NewFakeEvalHandler(expectedAttempts) evalHandler := NewFakeEvalHandler(expectedAttempts)
engine.evalHandler = evalHandler engine.evalHandler = evalHandler

@ -20,8 +20,8 @@ import (
// for stubbing in tests // for stubbing in tests
// //
//nolint:gocritic //nolint:gocritic
var newImageUploaderProvider = func() (imguploader.ImageUploader, error) { var newImageUploaderProvider = func(cfg *setting.Cfg) (imguploader.ImageUploader, error) {
return imguploader.NewImageUploader() return imguploader.NewImageUploader(cfg)
} }
// NotifierPlugin holds meta information about a notifier. // NotifierPlugin holds meta information about a notifier.
@ -87,8 +87,9 @@ type ShowWhen struct {
Is string `json:"is"` Is string `json:"is"`
} }
func newNotificationService(renderService rendering.Service, sqlStore AlertStore, notificationSvc *notifications.NotificationService, decryptFn GetDecryptedValueFn) *notificationService { func newNotificationService(cfg *setting.Cfg, renderService rendering.Service, sqlStore AlertStore, notificationSvc *notifications.NotificationService, decryptFn GetDecryptedValueFn) *notificationService {
return &notificationService{ return &notificationService{
cfg: cfg,
log: log.New("alerting.notifier"), log: log.New("alerting.notifier"),
renderService: renderService, renderService: renderService,
sqlStore: sqlStore, sqlStore: sqlStore,
@ -98,6 +99,7 @@ func newNotificationService(renderService rendering.Service, sqlStore AlertStore
} }
type notificationService struct { type notificationService struct {
cfg *setting.Cfg
log log.Logger log log.Logger
renderService rendering.Service renderService rendering.Service
sqlStore AlertStore sqlStore AlertStore
@ -119,7 +121,7 @@ func (n *notificationService) SendIfNeeded(evalCtx *EvalContext) error {
if notifierStates.ShouldUploadImage() { if notifierStates.ShouldUploadImage() {
// Create a copy of EvalContext and give it a new, shorter, timeout context to upload the image // Create a copy of EvalContext and give it a new, shorter, timeout context to upload the image
uploadEvalCtx := *evalCtx uploadEvalCtx := *evalCtx
timeout := setting.AlertingNotificationTimeout / 2 timeout := n.cfg.AlertingNotificationTimeout / 2
var uploadCtxCancel func() var uploadCtxCancel func()
uploadEvalCtx.Ctx, uploadCtxCancel = context.WithTimeout(evalCtx.Ctx, timeout) uploadEvalCtx.Ctx, uploadCtxCancel = context.WithTimeout(evalCtx.Ctx, timeout)
@ -202,7 +204,7 @@ func (n *notificationService) sendNotifications(evalContext *EvalContext, notifi
} }
func (n *notificationService) renderAndUploadImage(evalCtx *EvalContext, timeout time.Duration) (err error) { func (n *notificationService) renderAndUploadImage(evalCtx *EvalContext, timeout time.Duration) (err error) {
uploader, err := newImageUploaderProvider() uploader, err := newImageUploaderProvider(n.cfg)
if err != nil { if err != nil {
return err return err
} }
@ -217,7 +219,7 @@ func (n *notificationService) renderAndUploadImage(evalCtx *EvalContext, timeout
}, },
Width: 1000, Width: 1000,
Height: 500, Height: 500,
ConcurrentLimit: setting.AlertingRenderLimit, ConcurrentLimit: n.cfg.AlertingRenderLimit,
Theme: models.ThemeDark, Theme: models.ThemeDark,
} }
@ -266,7 +268,7 @@ func (n *notificationService) getNeededNotifiers(orgID int64, notificationUids [
var result notifierStateSlice var result notifierStateSlice
for _, notification := range res { for _, notification := range res {
not, err := InitNotifier(notification, n.decryptFn, n.notificationService) not, err := InitNotifier(n.cfg, notification, n.decryptFn, n.notificationService)
if err != nil { if err != nil {
n.log.Error("Could not create notifier", "notifier", notification.UID, "error", err) n.log.Error("Could not create notifier", "notifier", notification.UID, "error", err)
continue continue
@ -296,13 +298,13 @@ func (n *notificationService) getNeededNotifiers(orgID int64, notificationUids [
} }
// InitNotifier instantiate a new notifier based on the model. // InitNotifier instantiate a new notifier based on the model.
func InitNotifier(model *alertmodels.AlertNotification, fn GetDecryptedValueFn, notificationService *notifications.NotificationService) (Notifier, error) { func InitNotifier(cfg *setting.Cfg, model *alertmodels.AlertNotification, fn GetDecryptedValueFn, notificationService *notifications.NotificationService) (Notifier, error) {
notifierPlugin, found := notifierFactories[model.Type] notifierPlugin, found := notifierFactories[model.Type]
if !found { if !found {
return nil, fmt.Errorf("unsupported notification type %q", model.Type) return nil, fmt.Errorf("unsupported notification type %q", model.Type)
} }
return notifierPlugin.Factory(model, fn, notificationService) return notifierPlugin.Factory(cfg, model, fn, notificationService)
} }
// GetDecryptedValueFn is a function that returns the decrypted value of // GetDecryptedValueFn is a function that returns the decrypted value of
@ -310,7 +312,7 @@ func InitNotifier(model *alertmodels.AlertNotification, fn GetDecryptedValueFn,
type GetDecryptedValueFn func(ctx context.Context, sjd map[string][]byte, key string, fallback string, secret string) string type GetDecryptedValueFn func(ctx context.Context, sjd map[string][]byte, key string, fallback string, secret string) string
// NotifierFactory is a signature for creating notifiers. // NotifierFactory is a signature for creating notifiers.
type NotifierFactory func(*alertmodels.AlertNotification, GetDecryptedValueFn, notifications.Service) (Notifier, error) type NotifierFactory func(*setting.Cfg, *alertmodels.AlertNotification, GetDecryptedValueFn, notifications.Service) (Notifier, error)
var notifierFactories = make(map[string]*NotifierPlugin) var notifierFactories = make(map[string]*NotifierPlugin)

@ -71,7 +71,7 @@ func TestNotificationService(t *testing.T) {
notificationServiceScenario(t, "Given alert rule with upload image enabled and render times out should send notification", notificationServiceScenario(t, "Given alert rule with upload image enabled and render times out should send notification",
evalCtx, true, func(sc *scenarioContext) { evalCtx, true, func(sc *scenarioContext) {
setting.AlertingNotificationTimeout = 200 * time.Millisecond sc.notificationService.cfg.AlertingNotificationTimeout = 200 * time.Millisecond
sc.renderProvider = func(ctx context.Context, opts rendering.Opts) (*rendering.RenderResult, error) { sc.renderProvider = func(ctx context.Context, opts rendering.Opts) (*rendering.RenderResult, error) {
wait := make(chan bool) wait := make(chan bool)
@ -101,7 +101,7 @@ func TestNotificationService(t *testing.T) {
notificationServiceScenario(t, "Given alert rule with upload image enabled and upload times out should send notification", notificationServiceScenario(t, "Given alert rule with upload image enabled and upload times out should send notification",
evalCtx, true, func(sc *scenarioContext) { evalCtx, true, func(sc *scenarioContext) {
setting.AlertingNotificationTimeout = 200 * time.Millisecond sc.notificationService.cfg.AlertingNotificationTimeout = 200 * time.Millisecond
sc.uploadProvider = func(ctx context.Context, path string) (string, error) { sc.uploadProvider = func(ctx context.Context, path string) (string, error) {
wait := make(chan bool) wait := make(chan bool)
@ -204,8 +204,6 @@ func notificationServiceScenario(t *testing.T, name string, evalCtx *EvalContext
}, nil }, nil
} }
setting.AlertingNotificationTimeout = 30 * time.Second
scenarioCtx := &scenarioContext{ scenarioCtx := &scenarioContext{
t: t, t: t,
evalCtx: evalCtx, evalCtx: evalCtx,
@ -229,7 +227,7 @@ func notificationServiceScenario(t *testing.T, name string, evalCtx *EvalContext
} }
origNewImageUploaderProvider := newImageUploaderProvider origNewImageUploaderProvider := newImageUploaderProvider
newImageUploaderProvider = func() (imguploader.ImageUploader, error) { newImageUploaderProvider = func(cfg *setting.Cfg) (imguploader.ImageUploader, error) {
return imageUploader, nil return imageUploader, nil
} }
defer func() { defer func() {
@ -258,7 +256,8 @@ func notificationServiceScenario(t *testing.T, name string, evalCtx *EvalContext
}, },
} }
scenarioCtx.notificationService = newNotificationService(renderService, store, nil, nil) scenarioCtx.notificationService = newNotificationService(setting.NewCfg(), renderService, store, nil, nil)
scenarioCtx.notificationService.cfg.AlertingNotificationTimeout = 30 * time.Second
fn(scenarioCtx) fn(scenarioCtx)
}) })
} }
@ -274,7 +273,7 @@ type testNotifier struct {
Frequency time.Duration Frequency time.Duration
} }
func newTestNotifier(model *alertmodels.AlertNotification, _ GetDecryptedValueFn, ns notifications.Service) (Notifier, error) { func newTestNotifier(_ *setting.Cfg, model *alertmodels.AlertNotification, _ GetDecryptedValueFn, ns notifications.Service) (Notifier, error) {
uploadImage := true uploadImage := true
value, exist := model.Settings.CheckGet("uploadImage") value, exist := model.Settings.CheckGet("uploadImage")
if exist { if exist {

@ -50,7 +50,7 @@ func init() {
} }
// NewAlertmanagerNotifier returns a new Alertmanager notifier // NewAlertmanagerNotifier returns a new Alertmanager notifier
func NewAlertmanagerNotifier(model *models.AlertNotification, fn alerting.GetDecryptedValueFn, ns notifications.Service) (alerting.Notifier, error) { func NewAlertmanagerNotifier(cfg *setting.Cfg, model *models.AlertNotification, fn alerting.GetDecryptedValueFn, ns notifications.Service) (alerting.Notifier, error) {
urlString := model.Settings.Get("url").MustString() urlString := model.Settings.Get("url").MustString()
if urlString == "" { if urlString == "" {
return nil, alerting.ValidationError{Reason: "Could not find url property in settings"} return nil, alerting.ValidationError{Reason: "Could not find url property in settings"}
@ -64,7 +64,7 @@ func NewAlertmanagerNotifier(model *models.AlertNotification, fn alerting.GetDec
} }
} }
basicAuthUser := model.Settings.Get("basicAuthUser").MustString() basicAuthUser := model.Settings.Get("basicAuthUser").MustString()
basicAuthPassword := fn(context.Background(), model.SecureSettings, "basicAuthPassword", model.Settings.Get("basicAuthPassword").MustString(), setting.SecretKey) basicAuthPassword := fn(context.Background(), model.SecureSettings, "basicAuthPassword", model.Settings.Get("basicAuthPassword").MustString(), cfg.SecretKey)
return &AlertmanagerNotifier{ return &AlertmanagerNotifier{
NotifierBase: NewNotifierBase(model, ns), NotifierBase: NewNotifierBase(model, ns),

@ -14,6 +14,7 @@ import (
"github.com/grafana/grafana/pkg/services/annotations/annotationstest" "github.com/grafana/grafana/pkg/services/annotations/annotationstest"
encryptionservice "github.com/grafana/grafana/pkg/services/encryption/service" encryptionservice "github.com/grafana/grafana/pkg/services/encryption/service"
"github.com/grafana/grafana/pkg/services/validations" "github.com/grafana/grafana/pkg/services/validations"
"github.com/grafana/grafana/pkg/setting"
) )
func TestReplaceIllegalCharswithUnderscore(t *testing.T) { func TestReplaceIllegalCharswithUnderscore(t *testing.T) {
@ -95,7 +96,7 @@ func TestAlertmanagerNotifier(t *testing.T) {
Settings: settingsJSON, Settings: settingsJSON,
} }
_, err := NewAlertmanagerNotifier(model, encryptionService.GetDecryptedValue, nil) _, err := NewAlertmanagerNotifier(setting.NewCfg(), model, encryptionService.GetDecryptedValue, nil)
require.Error(t, err) require.Error(t, err)
}) })
@ -109,7 +110,7 @@ func TestAlertmanagerNotifier(t *testing.T) {
Settings: settingsJSON, Settings: settingsJSON,
} }
not, err := NewAlertmanagerNotifier(model, encryptionService.GetDecryptedValue, nil) not, err := NewAlertmanagerNotifier(setting.NewCfg(), model, encryptionService.GetDecryptedValue, nil)
alertmanagerNotifier := not.(*AlertmanagerNotifier) alertmanagerNotifier := not.(*AlertmanagerNotifier)
require.NoError(t, err) require.NoError(t, err)
@ -128,7 +129,7 @@ func TestAlertmanagerNotifier(t *testing.T) {
Settings: settingsJSON, Settings: settingsJSON,
} }
not, err := NewAlertmanagerNotifier(model, encryptionService.GetDecryptedValue, nil) not, err := NewAlertmanagerNotifier(setting.NewCfg(), model, encryptionService.GetDecryptedValue, nil)
alertmanagerNotifier := not.(*AlertmanagerNotifier) alertmanagerNotifier := not.(*AlertmanagerNotifier)
require.NoError(t, err) require.NoError(t, err)

@ -9,6 +9,7 @@ import (
"github.com/grafana/grafana/pkg/services/alerting" "github.com/grafana/grafana/pkg/services/alerting"
"github.com/grafana/grafana/pkg/services/alerting/models" "github.com/grafana/grafana/pkg/services/alerting/models"
"github.com/grafana/grafana/pkg/services/notifications" "github.com/grafana/grafana/pkg/services/notifications"
"github.com/grafana/grafana/pkg/setting"
) )
const defaultDingdingMsgType = "link" const defaultDingdingMsgType = "link"
@ -47,7 +48,7 @@ func init() {
}) })
} }
func newDingDingNotifier(model *models.AlertNotification, _ alerting.GetDecryptedValueFn, ns notifications.Service) (alerting.Notifier, error) { func newDingDingNotifier(_ *setting.Cfg, model *models.AlertNotification, _ alerting.GetDecryptedValueFn, ns notifications.Service) (alerting.Notifier, error) {
url := model.Settings.Get("url").MustString() url := model.Settings.Get("url").MustString()
if url == "" { if url == "" {
return nil, alerting.ValidationError{Reason: "Could not find url property in settings"} return nil, alerting.ValidationError{Reason: "Could not find url property in settings"}

@ -27,7 +27,7 @@ func TestDingDingNotifier(t *testing.T) {
Settings: settingsJSON, Settings: settingsJSON,
} }
_, err := newDingDingNotifier(model, encryptionService.GetDecryptedValue, nil) _, err := newDingDingNotifier(nil, model, encryptionService.GetDecryptedValue, nil)
require.Error(t, err) require.Error(t, err)
}) })
t.Run("settings should trigger incident", func(t *testing.T) { t.Run("settings should trigger incident", func(t *testing.T) {
@ -40,7 +40,7 @@ func TestDingDingNotifier(t *testing.T) {
Settings: settingsJSON, Settings: settingsJSON,
} }
not, err := newDingDingNotifier(model, encryptionService.GetDecryptedValue, nil) not, err := newDingDingNotifier(nil, model, encryptionService.GetDecryptedValue, nil)
notifier := not.(*DingDingNotifier) notifier := not.(*DingDingNotifier)
require.Nil(t, err) require.Nil(t, err)

@ -57,7 +57,7 @@ func init() {
}) })
} }
func newDiscordNotifier(model *models.AlertNotification, _ alerting.GetDecryptedValueFn, ns notifications.Service) (alerting.Notifier, error) { func newDiscordNotifier(_ *setting.Cfg, model *models.AlertNotification, _ alerting.GetDecryptedValueFn, ns notifications.Service) (alerting.Notifier, error) {
avatar := model.Settings.Get("avatar_url").MustString() avatar := model.Settings.Get("avatar_url").MustString()
content := model.Settings.Get("content").MustString() content := model.Settings.Get("content").MustString()
url := model.Settings.Get("url").MustString() url := model.Settings.Get("url").MustString()

@ -24,7 +24,7 @@ func TestDiscordNotifier(t *testing.T) {
Settings: settingsJSON, Settings: settingsJSON,
} }
_, err := newDiscordNotifier(model, encryptionService.GetDecryptedValue, nil) _, err := newDiscordNotifier(nil, model, encryptionService.GetDecryptedValue, nil)
require.Error(t, err) require.Error(t, err)
}) })
@ -43,7 +43,7 @@ func TestDiscordNotifier(t *testing.T) {
Settings: settingsJSON, Settings: settingsJSON,
} }
not, err := newDiscordNotifier(model, encryptionService.GetDecryptedValue, nil) not, err := newDiscordNotifier(nil, model, encryptionService.GetDecryptedValue, nil)
discordNotifier := not.(*DiscordNotifier) discordNotifier := not.(*DiscordNotifier)
require.Nil(t, err) require.Nil(t, err)

@ -43,11 +43,12 @@ type EmailNotifier struct {
Addresses []string Addresses []string
SingleEmail bool SingleEmail bool
log log.Logger log log.Logger
appURL string
} }
// NewEmailNotifier is the constructor function // NewEmailNotifier is the constructor function
// for the EmailNotifier. // for the EmailNotifier.
func NewEmailNotifier(model *models.AlertNotification, _ alerting.GetDecryptedValueFn, ns notifications.Service) (alerting.Notifier, error) { func NewEmailNotifier(cfg *setting.Cfg, model *models.AlertNotification, _ alerting.GetDecryptedValueFn, ns notifications.Service) (alerting.Notifier, error) {
addressesString := model.Settings.Get("addresses").MustString() addressesString := model.Settings.Get("addresses").MustString()
singleEmail := model.Settings.Get("singleEmail").MustBool(false) singleEmail := model.Settings.Get("singleEmail").MustBool(false)
@ -63,6 +64,7 @@ func NewEmailNotifier(model *models.AlertNotification, _ alerting.GetDecryptedVa
Addresses: addresses, Addresses: addresses,
SingleEmail: singleEmail, SingleEmail: singleEmail,
log: log.New("alerting.notifier.email"), log: log.New("alerting.notifier.email"),
appURL: cfg.AppURL,
}, nil }, nil
} }
@ -94,7 +96,7 @@ func (en *EmailNotifier) Notify(evalContext *alerting.EvalContext) error {
"RuleUrl": ruleURL, "RuleUrl": ruleURL,
"ImageLink": "", "ImageLink": "",
"EmbeddedImage": "", "EmbeddedImage": "",
"AlertPageUrl": setting.AppUrl + "alerting", "AlertPageUrl": en.appURL + "alerting",
"EvalMatches": evalContext.EvalMatches, "EvalMatches": evalContext.EvalMatches,
}, },
To: en.Addresses, To: en.Addresses,

@ -8,6 +8,7 @@ import (
"github.com/grafana/grafana/pkg/components/simplejson" "github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/services/alerting/models" "github.com/grafana/grafana/pkg/services/alerting/models"
encryptionservice "github.com/grafana/grafana/pkg/services/encryption/service" encryptionservice "github.com/grafana/grafana/pkg/services/encryption/service"
"github.com/grafana/grafana/pkg/setting"
) )
func TestEmailNotifier(t *testing.T) { func TestEmailNotifier(t *testing.T) {
@ -24,7 +25,7 @@ func TestEmailNotifier(t *testing.T) {
Settings: settingsJSON, Settings: settingsJSON,
} }
_, err := NewEmailNotifier(model, encryptionService.GetDecryptedValue, nil) _, err := NewEmailNotifier(setting.NewCfg(), model, encryptionService.GetDecryptedValue, nil)
require.Error(t, err) require.Error(t, err)
}) })
@ -41,7 +42,7 @@ func TestEmailNotifier(t *testing.T) {
Settings: settingsJSON, Settings: settingsJSON,
} }
not, err := NewEmailNotifier(model, encryptionService.GetDecryptedValue, nil) not, err := NewEmailNotifier(setting.NewCfg(), model, encryptionService.GetDecryptedValue, nil)
emailNotifier := not.(*EmailNotifier) emailNotifier := not.(*EmailNotifier)
require.Nil(t, err) require.Nil(t, err)
@ -65,7 +66,7 @@ func TestEmailNotifier(t *testing.T) {
Settings: settingsJSON, Settings: settingsJSON,
} }
not, err := NewEmailNotifier(model, encryptionService.GetDecryptedValue, nil) not, err := NewEmailNotifier(setting.NewCfg(), model, encryptionService.GetDecryptedValue, nil)
emailNotifier := not.(*EmailNotifier) emailNotifier := not.(*EmailNotifier)
require.Nil(t, err) require.Nil(t, err)

@ -33,7 +33,7 @@ func init() {
}) })
} }
func newGoogleChatNotifier(model *models.AlertNotification, _ alerting.GetDecryptedValueFn, ns notifications.Service) (alerting.Notifier, error) { func newGoogleChatNotifier(_ *setting.Cfg, model *models.AlertNotification, _ alerting.GetDecryptedValueFn, ns notifications.Service) (alerting.Notifier, error) {
url := model.Settings.Get("url").MustString() url := model.Settings.Get("url").MustString()
if url == "" { if url == "" {
return nil, alerting.ValidationError{Reason: "Could not find url property in settings"} return nil, alerting.ValidationError{Reason: "Could not find url property in settings"}

@ -24,7 +24,7 @@ func TestGoogleChatNotifier(t *testing.T) {
Settings: settingsJSON, Settings: settingsJSON,
} }
_, err := newGoogleChatNotifier(model, encryptionService.GetDecryptedValue, nil) _, err := newGoogleChatNotifier(nil, model, encryptionService.GetDecryptedValue, nil)
require.Error(t, err) require.Error(t, err)
}) })
@ -41,7 +41,7 @@ func TestGoogleChatNotifier(t *testing.T) {
Settings: settingsJSON, Settings: settingsJSON,
} }
not, err := newGoogleChatNotifier(model, encryptionService.GetDecryptedValue, nil) not, err := newGoogleChatNotifier(nil, model, encryptionService.GetDecryptedValue, nil)
webhookNotifier := not.(*GoogleChatNotifier) webhookNotifier := not.(*GoogleChatNotifier)
require.Nil(t, err) require.Nil(t, err)

@ -10,6 +10,7 @@ import (
"github.com/grafana/grafana/pkg/services/alerting" "github.com/grafana/grafana/pkg/services/alerting"
"github.com/grafana/grafana/pkg/services/alerting/models" "github.com/grafana/grafana/pkg/services/alerting/models"
"github.com/grafana/grafana/pkg/services/notifications" "github.com/grafana/grafana/pkg/services/notifications"
"github.com/grafana/grafana/pkg/setting"
) )
func init() { func init() {
@ -52,7 +53,7 @@ const (
// NewHipChatNotifier is the constructor functions // NewHipChatNotifier is the constructor functions
// for the HipChatNotifier // for the HipChatNotifier
func NewHipChatNotifier(model *models.AlertNotification, _ alerting.GetDecryptedValueFn, ns notifications.Service) (alerting.Notifier, error) { func NewHipChatNotifier(_ *setting.Cfg, model *models.AlertNotification, _ alerting.GetDecryptedValueFn, ns notifications.Service) (alerting.Notifier, error) {
url := model.Settings.Get("url").MustString() url := model.Settings.Get("url").MustString()
url = strings.TrimSuffix(url, "/") url = strings.TrimSuffix(url, "/")
if url == "" { if url == "" {

@ -25,7 +25,7 @@ func TestHipChatNotifier(t *testing.T) {
Settings: settingsJSON, Settings: settingsJSON,
} }
_, err := NewHipChatNotifier(model, encryptionService.GetDecryptedValue, nil) _, err := NewHipChatNotifier(nil, model, encryptionService.GetDecryptedValue, nil)
require.Error(t, err) require.Error(t, err)
}) })
@ -41,7 +41,7 @@ func TestHipChatNotifier(t *testing.T) {
Settings: settingsJSON, Settings: settingsJSON,
} }
not, err := NewHipChatNotifier(model, encryptionService.GetDecryptedValue, nil) not, err := NewHipChatNotifier(nil, model, encryptionService.GetDecryptedValue, nil)
hipchatNotifier := not.(*HipChatNotifier) hipchatNotifier := not.(*HipChatNotifier)
require.Nil(t, err) require.Nil(t, err)
@ -67,7 +67,7 @@ func TestHipChatNotifier(t *testing.T) {
Settings: settingsJSON, Settings: settingsJSON,
} }
not, err := NewHipChatNotifier(model, encryptionService.GetDecryptedValue, nil) not, err := NewHipChatNotifier(nil, model, encryptionService.GetDecryptedValue, nil)
hipchatNotifier := not.(*HipChatNotifier) hipchatNotifier := not.(*HipChatNotifier)
require.Nil(t, err) require.Nil(t, err)

@ -9,6 +9,7 @@ import (
"github.com/grafana/grafana/pkg/services/alerting" "github.com/grafana/grafana/pkg/services/alerting"
"github.com/grafana/grafana/pkg/services/alerting/models" "github.com/grafana/grafana/pkg/services/alerting/models"
"github.com/grafana/grafana/pkg/services/notifications" "github.com/grafana/grafana/pkg/services/notifications"
"github.com/grafana/grafana/pkg/setting"
) )
func init() { func init() {
@ -40,7 +41,7 @@ func init() {
} }
// NewKafkaNotifier is the constructor function for the Kafka notifier. // NewKafkaNotifier is the constructor function for the Kafka notifier.
func NewKafkaNotifier(model *models.AlertNotification, _ alerting.GetDecryptedValueFn, ns notifications.Service) (alerting.Notifier, error) { func NewKafkaNotifier(_ *setting.Cfg, model *models.AlertNotification, _ alerting.GetDecryptedValueFn, ns notifications.Service) (alerting.Notifier, error) {
endpoint := model.Settings.Get("kafkaRestProxy").MustString() endpoint := model.Settings.Get("kafkaRestProxy").MustString()
if endpoint == "" { if endpoint == "" {
return nil, alerting.ValidationError{Reason: "Could not find kafka rest proxy endpoint property in settings"} return nil, alerting.ValidationError{Reason: "Could not find kafka rest proxy endpoint property in settings"}

@ -24,7 +24,7 @@ func TestKafkaNotifier(t *testing.T) {
Settings: settingsJSON, Settings: settingsJSON,
} }
_, err := NewKafkaNotifier(model, encryptionService.GetDecryptedValue, nil) _, err := NewKafkaNotifier(nil, model, encryptionService.GetDecryptedValue, nil)
require.Error(t, err) require.Error(t, err)
}) })
@ -42,7 +42,7 @@ func TestKafkaNotifier(t *testing.T) {
Settings: settingsJSON, Settings: settingsJSON,
} }
not, err := NewKafkaNotifier(model, encryptionService.GetDecryptedValue, nil) not, err := NewKafkaNotifier(nil, model, encryptionService.GetDecryptedValue, nil)
kafkaNotifier := not.(*KafkaNotifier) kafkaNotifier := not.(*KafkaNotifier)
require.Nil(t, err) require.Nil(t, err)

@ -37,8 +37,8 @@ const (
) )
// NewLINENotifier is the constructor for the LINE notifier // NewLINENotifier is the constructor for the LINE notifier
func NewLINENotifier(model *models.AlertNotification, fn alerting.GetDecryptedValueFn, ns notifications.Service) (alerting.Notifier, error) { func NewLINENotifier(cfg *setting.Cfg, model *models.AlertNotification, fn alerting.GetDecryptedValueFn, ns notifications.Service) (alerting.Notifier, error) {
token := fn(context.Background(), model.SecureSettings, "token", model.Settings.Get("token").MustString(), setting.SecretKey) token := fn(context.Background(), model.SecureSettings, "token", model.Settings.Get("token").MustString(), cfg.SecretKey)
if token == "" { if token == "" {
return nil, alerting.ValidationError{Reason: "Could not find token in settings"} return nil, alerting.ValidationError{Reason: "Could not find token in settings"}
} }

@ -8,6 +8,7 @@ import (
"github.com/grafana/grafana/pkg/components/simplejson" "github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/services/alerting/models" "github.com/grafana/grafana/pkg/services/alerting/models"
encryptionservice "github.com/grafana/grafana/pkg/services/encryption/service" encryptionservice "github.com/grafana/grafana/pkg/services/encryption/service"
"github.com/grafana/grafana/pkg/setting"
) )
func TestLineNotifier(t *testing.T) { func TestLineNotifier(t *testing.T) {
@ -23,7 +24,7 @@ func TestLineNotifier(t *testing.T) {
Settings: settingsJSON, Settings: settingsJSON,
} }
_, err := NewLINENotifier(model, encryptionService.GetDecryptedValue, nil) _, err := NewLINENotifier(setting.NewCfg(), model, encryptionService.GetDecryptedValue, nil)
require.Error(t, err) require.Error(t, err)
}) })
t.Run("settings should trigger incident", func(t *testing.T) { t.Run("settings should trigger incident", func(t *testing.T) {
@ -38,7 +39,7 @@ func TestLineNotifier(t *testing.T) {
Settings: settingsJSON, Settings: settingsJSON,
} }
not, err := NewLINENotifier(model, encryptionService.GetDecryptedValue, nil) not, err := NewLINENotifier(setting.NewCfg(), model, encryptionService.GetDecryptedValue, nil)
lineNotifier := not.(*LineNotifier) lineNotifier := not.(*LineNotifier)
require.Nil(t, err) require.Nil(t, err)

@ -84,10 +84,10 @@ const (
) )
// NewOpsGenieNotifier is the constructor for OpsGenie. // NewOpsGenieNotifier is the constructor for OpsGenie.
func NewOpsGenieNotifier(model *models.AlertNotification, fn alerting.GetDecryptedValueFn, ns notifications.Service) (alerting.Notifier, error) { func NewOpsGenieNotifier(cfg *setting.Cfg, model *models.AlertNotification, fn alerting.GetDecryptedValueFn, ns notifications.Service) (alerting.Notifier, error) {
autoClose := model.Settings.Get("autoClose").MustBool(true) autoClose := model.Settings.Get("autoClose").MustBool(true)
overridePriority := model.Settings.Get("overridePriority").MustBool(true) overridePriority := model.Settings.Get("overridePriority").MustBool(true)
apiKey := fn(context.Background(), model.SecureSettings, "apiKey", model.Settings.Get("apiKey").MustString(), setting.SecretKey) apiKey := fn(context.Background(), model.SecureSettings, "apiKey", model.Settings.Get("apiKey").MustString(), cfg.SecretKey)
apiURL := model.Settings.Get("apiUrl").MustString() apiURL := model.Settings.Get("apiUrl").MustString()
if apiKey == "" { if apiKey == "" {
return nil, alerting.ValidationError{Reason: "Could not find api key property in settings"} return nil, alerting.ValidationError{Reason: "Could not find api key property in settings"}

@ -16,6 +16,7 @@ import (
"github.com/grafana/grafana/pkg/services/notifications" "github.com/grafana/grafana/pkg/services/notifications"
"github.com/grafana/grafana/pkg/services/tag" "github.com/grafana/grafana/pkg/services/tag"
"github.com/grafana/grafana/pkg/services/validations" "github.com/grafana/grafana/pkg/services/validations"
"github.com/grafana/grafana/pkg/setting"
) )
func TestOpsGenieNotifier(t *testing.T) { func TestOpsGenieNotifier(t *testing.T) {
@ -32,7 +33,7 @@ func TestOpsGenieNotifier(t *testing.T) {
Settings: settingsJSON, Settings: settingsJSON,
} }
_, err := NewOpsGenieNotifier(model, encryptionService.GetDecryptedValue, nil) _, err := NewOpsGenieNotifier(setting.NewCfg(), model, encryptionService.GetDecryptedValue, nil)
require.Error(t, err) require.Error(t, err)
}) })
@ -49,7 +50,7 @@ func TestOpsGenieNotifier(t *testing.T) {
Settings: settingsJSON, Settings: settingsJSON,
} }
not, err := NewOpsGenieNotifier(model, encryptionService.GetDecryptedValue, nil) not, err := NewOpsGenieNotifier(setting.NewCfg(), model, encryptionService.GetDecryptedValue, nil)
opsgenieNotifier := not.(*OpsGenieNotifier) opsgenieNotifier := not.(*OpsGenieNotifier)
require.Nil(t, err) require.Nil(t, err)
@ -73,7 +74,7 @@ func TestOpsGenieNotifier(t *testing.T) {
Settings: settingsJSON, Settings: settingsJSON,
} }
_, err := NewOpsGenieNotifier(model, encryptionService.GetDecryptedValue, nil) _, err := NewOpsGenieNotifier(setting.NewCfg(), model, encryptionService.GetDecryptedValue, nil)
require.Error(t, err) require.Error(t, err)
require.Equal(t, reflect.TypeOf(err), reflect.TypeOf(alerting.ValidationError{})) require.Equal(t, reflect.TypeOf(err), reflect.TypeOf(alerting.ValidationError{}))
require.True(t, strings.HasSuffix(err.Error(), "Invalid value for sendTagsAs: \"not_a_valid_value\"")) require.True(t, strings.HasSuffix(err.Error(), "Invalid value for sendTagsAs: \"not_a_valid_value\""))
@ -97,7 +98,7 @@ func TestOpsGenieNotifier(t *testing.T) {
} }
notificationService := notifications.MockNotificationService() notificationService := notifications.MockNotificationService()
notifier, notifierErr := NewOpsGenieNotifier(model, encryptionService.GetDecryptedValue, notificationService) // unhandled error notifier, notifierErr := NewOpsGenieNotifier(setting.NewCfg(), model, encryptionService.GetDecryptedValue, notificationService) // unhandled error
opsgenieNotifier := notifier.(*OpsGenieNotifier) opsgenieNotifier := notifier.(*OpsGenieNotifier)
@ -146,7 +147,7 @@ func TestOpsGenieNotifier(t *testing.T) {
} }
notificationService := notifications.MockNotificationService() notificationService := notifications.MockNotificationService()
notifier, notifierErr := NewOpsGenieNotifier(model, encryptionService.GetDecryptedValue, notificationService) // unhandled error notifier, notifierErr := NewOpsGenieNotifier(setting.NewCfg(), model, encryptionService.GetDecryptedValue, notificationService) // unhandled error
opsgenieNotifier := notifier.(*OpsGenieNotifier) opsgenieNotifier := notifier.(*OpsGenieNotifier)
@ -195,7 +196,7 @@ func TestOpsGenieNotifier(t *testing.T) {
} }
notificationService := notifications.MockNotificationService() notificationService := notifications.MockNotificationService()
notifier, notifierErr := NewOpsGenieNotifier(model, encryptionService.GetDecryptedValue, notificationService) // unhandled error notifier, notifierErr := NewOpsGenieNotifier(setting.NewCfg(), model, encryptionService.GetDecryptedValue, notificationService) // unhandled error
opsgenieNotifier := notifier.(*OpsGenieNotifier) opsgenieNotifier := notifier.(*OpsGenieNotifier)

@ -76,10 +76,10 @@ var (
) )
// NewPagerdutyNotifier is the constructor for the PagerDuty notifier // NewPagerdutyNotifier is the constructor for the PagerDuty notifier
func NewPagerdutyNotifier(model *models.AlertNotification, fn alerting.GetDecryptedValueFn, ns notifications.Service) (alerting.Notifier, error) { func NewPagerdutyNotifier(cfg *setting.Cfg, model *models.AlertNotification, fn alerting.GetDecryptedValueFn, ns notifications.Service) (alerting.Notifier, error) {
severity := model.Settings.Get("severity").MustString("critical") severity := model.Settings.Get("severity").MustString("critical")
autoResolve := model.Settings.Get("autoResolve").MustBool(false) autoResolve := model.Settings.Get("autoResolve").MustBool(false)
key := fn(context.Background(), model.SecureSettings, "integrationKey", model.Settings.Get("integrationKey").MustString(), setting.SecretKey) key := fn(context.Background(), model.SecureSettings, "integrationKey", model.Settings.Get("integrationKey").MustString(), cfg.SecretKey)
messageInDetails := model.Settings.Get("messageInDetails").MustBool(false) messageInDetails := model.Settings.Get("messageInDetails").MustBool(false)
if key == "" { if key == "" {
return nil, alerting.ValidationError{Reason: "Could not find integration key property in settings"} return nil, alerting.ValidationError{Reason: "Could not find integration key property in settings"}

@ -16,6 +16,7 @@ import (
encryptionservice "github.com/grafana/grafana/pkg/services/encryption/service" encryptionservice "github.com/grafana/grafana/pkg/services/encryption/service"
"github.com/grafana/grafana/pkg/services/tag" "github.com/grafana/grafana/pkg/services/tag"
"github.com/grafana/grafana/pkg/services/validations" "github.com/grafana/grafana/pkg/services/validations"
"github.com/grafana/grafana/pkg/setting"
) )
func presenceComparer(a, b string) bool { func presenceComparer(a, b string) bool {
@ -43,7 +44,7 @@ func TestPagerdutyNotifier(t *testing.T) {
Settings: settingsJSON, Settings: settingsJSON,
} }
_, err = NewPagerdutyNotifier(model, encryptionService.GetDecryptedValue, nil) _, err = NewPagerdutyNotifier(setting.NewCfg(), model, encryptionService.GetDecryptedValue, nil)
require.Error(t, err) require.Error(t, err)
}) })
@ -59,7 +60,7 @@ func TestPagerdutyNotifier(t *testing.T) {
Settings: settingsJSON, Settings: settingsJSON,
} }
not, err := NewPagerdutyNotifier(model, encryptionService.GetDecryptedValue, nil) not, err := NewPagerdutyNotifier(setting.NewCfg(), model, encryptionService.GetDecryptedValue, nil)
pagerdutyNotifier := not.(*PagerdutyNotifier) pagerdutyNotifier := not.(*PagerdutyNotifier)
require.Nil(t, err) require.Nil(t, err)
@ -82,7 +83,7 @@ func TestPagerdutyNotifier(t *testing.T) {
Settings: settingsJSON, Settings: settingsJSON,
} }
not, err := NewPagerdutyNotifier(model, encryptionService.GetDecryptedValue, nil) not, err := NewPagerdutyNotifier(setting.NewCfg(), model, encryptionService.GetDecryptedValue, nil)
pagerdutyNotifier := not.(*PagerdutyNotifier) pagerdutyNotifier := not.(*PagerdutyNotifier)
require.Nil(t, err) require.Nil(t, err)
@ -109,7 +110,7 @@ func TestPagerdutyNotifier(t *testing.T) {
Settings: settingsJSON, Settings: settingsJSON,
} }
not, err := NewPagerdutyNotifier(model, encryptionService.GetDecryptedValue, nil) not, err := NewPagerdutyNotifier(setting.NewCfg(), model, encryptionService.GetDecryptedValue, nil)
pagerdutyNotifier := not.(*PagerdutyNotifier) pagerdutyNotifier := not.(*PagerdutyNotifier)
require.Nil(t, err) require.Nil(t, err)
@ -134,7 +135,7 @@ func TestPagerdutyNotifier(t *testing.T) {
Settings: settingsJSON, Settings: settingsJSON,
} }
not, err := NewPagerdutyNotifier(model, encryptionService.GetDecryptedValue, nil) not, err := NewPagerdutyNotifier(setting.NewCfg(), model, encryptionService.GetDecryptedValue, nil)
require.Nil(t, err) require.Nil(t, err)
pagerdutyNotifier := not.(*PagerdutyNotifier) pagerdutyNotifier := not.(*PagerdutyNotifier)
@ -191,7 +192,7 @@ func TestPagerdutyNotifier(t *testing.T) {
Settings: settingsJSON, Settings: settingsJSON,
} }
not, err := NewPagerdutyNotifier(model, encryptionService.GetDecryptedValue, nil) not, err := NewPagerdutyNotifier(setting.NewCfg(), model, encryptionService.GetDecryptedValue, nil)
require.Nil(t, err) require.Nil(t, err)
pagerdutyNotifier := not.(*PagerdutyNotifier) pagerdutyNotifier := not.(*PagerdutyNotifier)
@ -248,7 +249,7 @@ func TestPagerdutyNotifier(t *testing.T) {
Settings: settingsJSON, Settings: settingsJSON,
} }
not, err := NewPagerdutyNotifier(model, encryptionService.GetDecryptedValue, nil) not, err := NewPagerdutyNotifier(setting.NewCfg(), model, encryptionService.GetDecryptedValue, nil)
require.Nil(t, err) require.Nil(t, err)
pagerdutyNotifier := not.(*PagerdutyNotifier) pagerdutyNotifier := not.(*PagerdutyNotifier)
@ -318,7 +319,7 @@ func TestPagerdutyNotifier(t *testing.T) {
Settings: settingsJSON, Settings: settingsJSON,
} }
not, err := NewPagerdutyNotifier(model, encryptionService.GetDecryptedValue, nil) not, err := NewPagerdutyNotifier(setting.NewCfg(), model, encryptionService.GetDecryptedValue, nil)
require.NoError(t, err) require.NoError(t, err)
pagerdutyNotifier := not.(*PagerdutyNotifier) pagerdutyNotifier := not.(*PagerdutyNotifier)
@ -398,7 +399,7 @@ func TestPagerdutyNotifier(t *testing.T) {
Settings: settingsJSON, Settings: settingsJSON,
} }
not, err := NewPagerdutyNotifier(model, encryptionService.GetDecryptedValue, nil) not, err := NewPagerdutyNotifier(setting.NewCfg(), model, encryptionService.GetDecryptedValue, nil)
require.NoError(t, err) require.NoError(t, err)
pagerdutyNotifier := not.(*PagerdutyNotifier) pagerdutyNotifier := not.(*PagerdutyNotifier)
@ -477,7 +478,7 @@ func TestPagerdutyNotifier(t *testing.T) {
Settings: settingsJSON, Settings: settingsJSON,
} }
not, err := NewPagerdutyNotifier(model, encryptionService.GetDecryptedValue, nil) not, err := NewPagerdutyNotifier(setting.NewCfg(), model, encryptionService.GetDecryptedValue, nil)
require.NoError(t, err) require.NoError(t, err)
pagerdutyNotifier := not.(*PagerdutyNotifier) pagerdutyNotifier := not.(*PagerdutyNotifier)

@ -193,9 +193,9 @@ func init() {
} }
// NewPushoverNotifier is the constructor for the Pushover Notifier // NewPushoverNotifier is the constructor for the Pushover Notifier
func NewPushoverNotifier(model *models.AlertNotification, fn alerting.GetDecryptedValueFn, ns notifications.Service) (alerting.Notifier, error) { func NewPushoverNotifier(cfg *setting.Cfg, model *models.AlertNotification, fn alerting.GetDecryptedValueFn, ns notifications.Service) (alerting.Notifier, error) {
userKey := fn(context.Background(), model.SecureSettings, "userKey", model.Settings.Get("userKey").MustString(), setting.SecretKey) userKey := fn(context.Background(), model.SecureSettings, "userKey", model.Settings.Get("userKey").MustString(), cfg.SecretKey)
APIToken := fn(context.Background(), model.SecureSettings, "apiToken", model.Settings.Get("apiToken").MustString(), setting.SecretKey) APIToken := fn(context.Background(), model.SecureSettings, "apiToken", model.Settings.Get("apiToken").MustString(), cfg.SecretKey)
device := model.Settings.Get("device").MustString() device := model.Settings.Get("device").MustString()
alertingPriority, err := strconv.Atoi(model.Settings.Get("priority").MustString("0")) // default Normal alertingPriority, err := strconv.Atoi(model.Settings.Get("priority").MustString("0")) // default Normal
if err != nil { if err != nil {

@ -13,6 +13,7 @@ import (
"github.com/grafana/grafana/pkg/services/annotations/annotationstest" "github.com/grafana/grafana/pkg/services/annotations/annotationstest"
encryptionservice "github.com/grafana/grafana/pkg/services/encryption/service" encryptionservice "github.com/grafana/grafana/pkg/services/encryption/service"
"github.com/grafana/grafana/pkg/services/validations" "github.com/grafana/grafana/pkg/services/validations"
"github.com/grafana/grafana/pkg/setting"
) )
func TestPushoverNotifier(t *testing.T) { func TestPushoverNotifier(t *testing.T) {
@ -29,7 +30,7 @@ func TestPushoverNotifier(t *testing.T) {
Settings: settingsJSON, Settings: settingsJSON,
} }
_, err := NewPushoverNotifier(model, encryptionService.GetDecryptedValue, nil) _, err := NewPushoverNotifier(setting.NewCfg(), model, encryptionService.GetDecryptedValue, nil)
require.Error(t, err) require.Error(t, err)
}) })
@ -51,7 +52,7 @@ func TestPushoverNotifier(t *testing.T) {
Settings: settingsJSON, Settings: settingsJSON,
} }
not, err := NewPushoverNotifier(model, encryptionService.GetDecryptedValue, nil) not, err := NewPushoverNotifier(setting.NewCfg(), model, encryptionService.GetDecryptedValue, nil)
pushoverNotifier := not.(*PushoverNotifier) pushoverNotifier := not.(*PushoverNotifier)
require.Nil(t, err) require.Nil(t, err)

@ -61,7 +61,7 @@ func init() {
} }
// NewSensuNotifier is the constructor for the Sensu Notifier. // NewSensuNotifier is the constructor for the Sensu Notifier.
func NewSensuNotifier(model *models.AlertNotification, fn alerting.GetDecryptedValueFn, ns notifications.Service) (alerting.Notifier, error) { func NewSensuNotifier(cfg *setting.Cfg, model *models.AlertNotification, fn alerting.GetDecryptedValueFn, ns notifications.Service) (alerting.Notifier, error) {
url := model.Settings.Get("url").MustString() url := model.Settings.Get("url").MustString()
if url == "" { if url == "" {
return nil, alerting.ValidationError{Reason: "Could not find url property in settings"} return nil, alerting.ValidationError{Reason: "Could not find url property in settings"}
@ -72,7 +72,7 @@ func NewSensuNotifier(model *models.AlertNotification, fn alerting.GetDecryptedV
URL: url, URL: url,
User: model.Settings.Get("username").MustString(), User: model.Settings.Get("username").MustString(),
Source: model.Settings.Get("source").MustString(), Source: model.Settings.Get("source").MustString(),
Password: fn(context.Background(), model.SecureSettings, "password", model.Settings.Get("password").MustString(), setting.SecretKey), Password: fn(context.Background(), model.SecureSettings, "password", model.Settings.Get("password").MustString(), cfg.SecretKey),
Handler: model.Settings.Get("handler").MustString(), Handler: model.Settings.Get("handler").MustString(),
log: log.New("alerting.notifier.sensu"), log: log.New("alerting.notifier.sensu"),
}, nil }, nil

@ -8,6 +8,7 @@ import (
"github.com/grafana/grafana/pkg/components/simplejson" "github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/services/alerting/models" "github.com/grafana/grafana/pkg/services/alerting/models"
encryptionservice "github.com/grafana/grafana/pkg/services/encryption/service" encryptionservice "github.com/grafana/grafana/pkg/services/encryption/service"
"github.com/grafana/grafana/pkg/setting"
) )
func TestSensuNotifier(t *testing.T) { func TestSensuNotifier(t *testing.T) {
@ -24,7 +25,7 @@ func TestSensuNotifier(t *testing.T) {
Settings: settingsJSON, Settings: settingsJSON,
} }
_, err := NewSensuNotifier(model, encryptionService.GetDecryptedValue, nil) _, err := NewSensuNotifier(setting.NewCfg(), model, encryptionService.GetDecryptedValue, nil)
require.Error(t, err) require.Error(t, err)
}) })
@ -43,7 +44,7 @@ func TestSensuNotifier(t *testing.T) {
Settings: settingsJSON, Settings: settingsJSON,
} }
not, err := NewSensuNotifier(model, encryptionService.GetDecryptedValue, nil) not, err := NewSensuNotifier(setting.NewCfg(), model, encryptionService.GetDecryptedValue, nil)
sensuNotifier := not.(*SensuNotifier) sensuNotifier := not.(*SensuNotifier)
require.Nil(t, err) require.Nil(t, err)

@ -72,9 +72,9 @@ func init() {
} }
// NewSensuGoNotifier is the constructor for the Sensu Go Notifier. // NewSensuGoNotifier is the constructor for the Sensu Go Notifier.
func NewSensuGoNotifier(model *models.AlertNotification, fn alerting.GetDecryptedValueFn, ns notifications.Service) (alerting.Notifier, error) { func NewSensuGoNotifier(cfg *setting.Cfg, model *models.AlertNotification, fn alerting.GetDecryptedValueFn, ns notifications.Service) (alerting.Notifier, error) {
url := model.Settings.Get("url").MustString() url := model.Settings.Get("url").MustString()
apikey := fn(context.Background(), model.SecureSettings, "apikey", model.Settings.Get("apikey").MustString(), setting.SecretKey) apikey := fn(context.Background(), model.SecureSettings, "apikey", model.Settings.Get("apikey").MustString(), cfg.SecretKey)
if url == "" { if url == "" {
return nil, alerting.ValidationError{Reason: "Could not find URL property in settings"} return nil, alerting.ValidationError{Reason: "Could not find URL property in settings"}

@ -9,6 +9,7 @@ import (
"github.com/grafana/grafana/pkg/components/simplejson" "github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/services/alerting/models" "github.com/grafana/grafana/pkg/services/alerting/models"
encryptionservice "github.com/grafana/grafana/pkg/services/encryption/service" encryptionservice "github.com/grafana/grafana/pkg/services/encryption/service"
"github.com/grafana/grafana/pkg/setting"
) )
func TestSensuGoNotifier(t *testing.T) { func TestSensuGoNotifier(t *testing.T) {
@ -24,7 +25,7 @@ func TestSensuGoNotifier(t *testing.T) {
encryptionService := encryptionservice.SetupTestService(t) encryptionService := encryptionservice.SetupTestService(t)
_, err = NewSensuGoNotifier(model, encryptionService.GetDecryptedValue, nil) _, err = NewSensuGoNotifier(setting.NewCfg(), model, encryptionService.GetDecryptedValue, nil)
require.Error(t, err) require.Error(t, err)
json = ` json = `
@ -45,7 +46,7 @@ func TestSensuGoNotifier(t *testing.T) {
Settings: settingsJSON, Settings: settingsJSON,
} }
not, err := NewSensuGoNotifier(model, encryptionService.GetDecryptedValue, nil) not, err := NewSensuGoNotifier(setting.NewCfg(), model, encryptionService.GetDecryptedValue, nil)
require.NoError(t, err) require.NoError(t, err)
sensuGoNotifier := not.(*SensuGoNotifier) sensuGoNotifier := not.(*SensuGoNotifier)

@ -121,8 +121,8 @@ func init() {
const slackAPIEndpoint = "https://slack.com/api/chat.postMessage" const slackAPIEndpoint = "https://slack.com/api/chat.postMessage"
// NewSlackNotifier is the constructor for the Slack notifier. // NewSlackNotifier is the constructor for the Slack notifier.
func NewSlackNotifier(model *models.AlertNotification, fn alerting.GetDecryptedValueFn, ns notifications.Service) (alerting.Notifier, error) { func NewSlackNotifier(cfg *setting.Cfg, model *models.AlertNotification, fn alerting.GetDecryptedValueFn, ns notifications.Service) (alerting.Notifier, error) {
urlStr := fn(context.Background(), model.SecureSettings, "url", model.Settings.Get("url").MustString(), setting.SecretKey) urlStr := fn(context.Background(), model.SecureSettings, "url", model.Settings.Get("url").MustString(), cfg.SecretKey)
if urlStr == "" { if urlStr == "" {
urlStr = slackAPIEndpoint urlStr = slackAPIEndpoint
} }
@ -143,7 +143,7 @@ func NewSlackNotifier(model *models.AlertNotification, fn alerting.GetDecryptedV
mentionUsersStr := model.Settings.Get("mentionUsers").MustString() mentionUsersStr := model.Settings.Get("mentionUsers").MustString()
mentionGroupsStr := model.Settings.Get("mentionGroups").MustString() mentionGroupsStr := model.Settings.Get("mentionGroups").MustString()
mentionChannel := model.Settings.Get("mentionChannel").MustString() mentionChannel := model.Settings.Get("mentionChannel").MustString()
token := fn(context.Background(), model.SecureSettings, "token", model.Settings.Get("token").MustString(), setting.SecretKey) token := fn(context.Background(), model.SecureSettings, "token", model.Settings.Get("token").MustString(), cfg.SecretKey)
if token == "" && apiURL.String() == slackAPIEndpoint { if token == "" && apiURL.String() == slackAPIEndpoint {
return nil, alerting.ValidationError{ return nil, alerting.ValidationError{
Reason: "token must be specified when using the Slack chat API", Reason: "token must be specified when using the Slack chat API",
@ -185,6 +185,7 @@ func NewSlackNotifier(model *models.AlertNotification, fn alerting.GetDecryptedV
token: token, token: token,
upload: uploadImage, upload: uploadImage,
log: log.New("alerting.notifier.slack"), log: log.New("alerting.notifier.slack"),
homePath: cfg.HomePath,
}, nil }, nil
} }
@ -203,6 +204,7 @@ type SlackNotifier struct {
token string token string
upload bool upload bool
log log.Logger log log.Logger
homePath string
} }
// Notify sends an alert notification to Slack. // Notify sends an alert notification to Slack.
@ -408,7 +410,7 @@ func (sn *SlackNotifier) slackFileUpload(evalContext *alerting.EvalContext, log
if evalContext.ImageOnDiskPath == "" { if evalContext.ImageOnDiskPath == "" {
// nolint:gosec // nolint:gosec
// We can ignore the gosec G304 warning on this one because `setting.HomePath` comes from Grafana's configuration file. // We can ignore the gosec G304 warning on this one because `setting.HomePath` comes from Grafana's configuration file.
evalContext.ImageOnDiskPath = filepath.Join(setting.HomePath, "public/img/mixed_styles.png") evalContext.ImageOnDiskPath = filepath.Join(sn.homePath, "public/img/mixed_styles.png")
} }
log.Info("Uploading to slack via file.upload API") log.Info("Uploading to slack via file.upload API")
headers, uploadBody, err := sn.generateSlackBody(evalContext.ImageOnDiskPath, token, recipient) headers, uploadBody, err := sn.generateSlackBody(evalContext.ImageOnDiskPath, token, recipient)

@ -30,7 +30,7 @@ func TestSlackNotifier(t *testing.T) {
Settings: settingsJSON, Settings: settingsJSON,
} }
_, err = NewSlackNotifier(model, encryptionService.GetDecryptedValue, nil) _, err = NewSlackNotifier(setting.NewCfg(), model, encryptionService.GetDecryptedValue, nil)
assert.EqualError(t, err, "alert validation error: recipient must be specified when using the Slack chat API") assert.EqualError(t, err, "alert validation error: recipient must be specified when using the Slack chat API")
}) })
@ -48,7 +48,7 @@ func TestSlackNotifier(t *testing.T) {
Settings: settingsJSON, Settings: settingsJSON,
} }
not, err := NewSlackNotifier(model, encryptionService.GetDecryptedValue, nil) not, err := NewSlackNotifier(setting.NewCfg(), model, encryptionService.GetDecryptedValue, nil)
require.NoError(t, err) require.NoError(t, err)
slackNotifier := not.(*SlackNotifier) slackNotifier := not.(*SlackNotifier)
assert.Equal(t, "ops", slackNotifier.Name) assert.Equal(t, "ops", slackNotifier.Name)
@ -86,7 +86,7 @@ func TestSlackNotifier(t *testing.T) {
Settings: settingsJSON, Settings: settingsJSON,
} }
not, err := NewSlackNotifier(model, encryptionService.GetDecryptedValue, nil) not, err := NewSlackNotifier(setting.NewCfg(), model, encryptionService.GetDecryptedValue, nil)
require.NoError(t, err) require.NoError(t, err)
slackNotifier := not.(*SlackNotifier) slackNotifier := not.(*SlackNotifier)
assert.Equal(t, "ops", slackNotifier.Name) assert.Equal(t, "ops", slackNotifier.Name)
@ -120,11 +120,12 @@ func TestSlackNotifier(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
encryptionService := encryptionService encryptionService := encryptionService
cfg := setting.NewCfg()
securedSettingsJSON, err := encryptionService.EncryptJsonData( securedSettingsJSON, err := encryptionService.EncryptJsonData(
context.Background(), context.Background(),
map[string]string{ map[string]string{
"token": "xenc-XXXXXXXX-XXXXXXXX-XXXXXXXXXX", "token": "xenc-XXXXXXXX-XXXXXXXX-XXXXXXXXXX",
}, setting.SecretKey) }, cfg.SecretKey)
require.NoError(t, err) require.NoError(t, err)
model := &models.AlertNotification{ model := &models.AlertNotification{
@ -134,7 +135,7 @@ func TestSlackNotifier(t *testing.T) {
SecureSettings: securedSettingsJSON, SecureSettings: securedSettingsJSON,
} }
not, err := NewSlackNotifier(model, encryptionService.GetDecryptedValue, nil) not, err := NewSlackNotifier(cfg, model, encryptionService.GetDecryptedValue, nil)
require.NoError(t, err) require.NoError(t, err)
slackNotifier := not.(*SlackNotifier) slackNotifier := not.(*SlackNotifier)
assert.Equal(t, "ops", slackNotifier.Name) assert.Equal(t, "ops", slackNotifier.Name)
@ -165,7 +166,7 @@ func TestSlackNotifier(t *testing.T) {
Settings: settingsJSON, Settings: settingsJSON,
} }
not, err := NewSlackNotifier(model, encryptionService.GetDecryptedValue, nil) not, err := NewSlackNotifier(setting.NewCfg(), model, encryptionService.GetDecryptedValue, nil)
require.NoError(t, err) require.NoError(t, err)
slackNotifier := not.(*SlackNotifier) slackNotifier := not.(*SlackNotifier)
assert.Equal(t, "1ABCDE", slackNotifier.recipient) assert.Equal(t, "1ABCDE", slackNotifier.recipient)
@ -258,7 +259,7 @@ func TestSendSlackRequest(t *testing.T) {
encryptionService := encryptionservice.SetupTestService(t) encryptionService := encryptionservice.SetupTestService(t)
not, err := NewSlackNotifier(model, encryptionService.GetDecryptedValue, nil) not, err := NewSlackNotifier(setting.NewCfg(), model, encryptionService.GetDecryptedValue, nil)
require.NoError(t, err) require.NoError(t, err)
slackNotifier := not.(*SlackNotifier) slackNotifier := not.(*SlackNotifier)

@ -7,6 +7,7 @@ import (
"github.com/grafana/grafana/pkg/services/alerting" "github.com/grafana/grafana/pkg/services/alerting"
"github.com/grafana/grafana/pkg/services/alerting/models" "github.com/grafana/grafana/pkg/services/alerting/models"
"github.com/grafana/grafana/pkg/services/notifications" "github.com/grafana/grafana/pkg/services/notifications"
"github.com/grafana/grafana/pkg/setting"
) )
func init() { func init() {
@ -30,7 +31,7 @@ func init() {
} }
// NewTeamsNotifier is the constructor for Teams notifier. // NewTeamsNotifier is the constructor for Teams notifier.
func NewTeamsNotifier(model *models.AlertNotification, _ alerting.GetDecryptedValueFn, ns notifications.Service) (alerting.Notifier, error) { func NewTeamsNotifier(_ *setting.Cfg, model *models.AlertNotification, _ alerting.GetDecryptedValueFn, ns notifications.Service) (alerting.Notifier, error) {
url := model.Settings.Get("url").MustString() url := model.Settings.Get("url").MustString()
if url == "" { if url == "" {
return nil, alerting.ValidationError{Reason: "Could not find url property in settings"} return nil, alerting.ValidationError{Reason: "Could not find url property in settings"}

@ -24,7 +24,7 @@ func TestTeamsNotifier(t *testing.T) {
Settings: settingsJSON, Settings: settingsJSON,
} }
_, err := NewTeamsNotifier(model, encryptionService.GetDecryptedValue, nil) _, err := NewTeamsNotifier(nil, model, encryptionService.GetDecryptedValue, nil)
require.Error(t, err) require.Error(t, err)
}) })
@ -41,7 +41,7 @@ func TestTeamsNotifier(t *testing.T) {
Settings: settingsJSON, Settings: settingsJSON,
} }
not, err := NewTeamsNotifier(model, encryptionService.GetDecryptedValue, nil) not, err := NewTeamsNotifier(nil, model, encryptionService.GetDecryptedValue, nil)
teamsNotifier := not.(*TeamsNotifier) teamsNotifier := not.(*TeamsNotifier)
require.Nil(t, err) require.Nil(t, err)
@ -63,7 +63,7 @@ func TestTeamsNotifier(t *testing.T) {
Settings: settingsJSON, Settings: settingsJSON,
} }
not, err := NewTeamsNotifier(model, encryptionService.GetDecryptedValue, nil) not, err := NewTeamsNotifier(nil, model, encryptionService.GetDecryptedValue, nil)
teamsNotifier := not.(*TeamsNotifier) teamsNotifier := not.(*TeamsNotifier)
require.Nil(t, err) require.Nil(t, err)

@ -63,12 +63,12 @@ type TelegramNotifier struct {
} }
// NewTelegramNotifier is the constructor for the Telegram notifier // NewTelegramNotifier is the constructor for the Telegram notifier
func NewTelegramNotifier(model *models.AlertNotification, fn alerting.GetDecryptedValueFn, ns notifications.Service) (alerting.Notifier, error) { func NewTelegramNotifier(cfg *setting.Cfg, model *models.AlertNotification, fn alerting.GetDecryptedValueFn, ns notifications.Service) (alerting.Notifier, error) {
if model.Settings == nil { if model.Settings == nil {
return nil, alerting.ValidationError{Reason: "No Settings Supplied"} return nil, alerting.ValidationError{Reason: "No Settings Supplied"}
} }
botToken := fn(context.Background(), model.SecureSettings, "bottoken", model.Settings.Get("bottoken").MustString(), setting.SecretKey) botToken := fn(context.Background(), model.SecureSettings, "bottoken", model.Settings.Get("bottoken").MustString(), cfg.SecretKey)
chatID := model.Settings.Get("chatid").MustString() chatID := model.Settings.Get("chatid").MustString()
uploadImage := model.Settings.Get("uploadImage").MustBool() uploadImage := model.Settings.Get("uploadImage").MustBool()

@ -12,6 +12,7 @@ import (
"github.com/grafana/grafana/pkg/services/annotations/annotationstest" "github.com/grafana/grafana/pkg/services/annotations/annotationstest"
encryptionservice "github.com/grafana/grafana/pkg/services/encryption/service" encryptionservice "github.com/grafana/grafana/pkg/services/encryption/service"
"github.com/grafana/grafana/pkg/services/validations" "github.com/grafana/grafana/pkg/services/validations"
"github.com/grafana/grafana/pkg/setting"
) )
func TestTelegramNotifier(t *testing.T) { func TestTelegramNotifier(t *testing.T) {
@ -28,7 +29,7 @@ func TestTelegramNotifier(t *testing.T) {
Settings: settingsJSON, Settings: settingsJSON,
} }
_, err := NewTelegramNotifier(model, encryptionService.GetDecryptedValue, nil) _, err := NewTelegramNotifier(setting.NewCfg(), model, encryptionService.GetDecryptedValue, nil)
require.Error(t, err) require.Error(t, err)
}) })
@ -46,7 +47,7 @@ func TestTelegramNotifier(t *testing.T) {
Settings: settingsJSON, Settings: settingsJSON,
} }
not, err := NewTelegramNotifier(model, encryptionService.GetDecryptedValue, nil) not, err := NewTelegramNotifier(setting.NewCfg(), model, encryptionService.GetDecryptedValue, nil)
telegramNotifier := not.(*TelegramNotifier) telegramNotifier := not.(*TelegramNotifier)
require.Nil(t, err) require.Nil(t, err)

@ -71,14 +71,14 @@ type ThreemaNotifier struct {
} }
// NewThreemaNotifier is the constructor for the Threema notifier // NewThreemaNotifier is the constructor for the Threema notifier
func NewThreemaNotifier(model *models.AlertNotification, fn alerting.GetDecryptedValueFn, ns notifications.Service) (alerting.Notifier, error) { func NewThreemaNotifier(cfg *setting.Cfg, model *models.AlertNotification, fn alerting.GetDecryptedValueFn, ns notifications.Service) (alerting.Notifier, error) {
if model.Settings == nil { if model.Settings == nil {
return nil, alerting.ValidationError{Reason: "No Settings Supplied"} return nil, alerting.ValidationError{Reason: "No Settings Supplied"}
} }
gatewayID := model.Settings.Get("gateway_id").MustString() gatewayID := model.Settings.Get("gateway_id").MustString()
recipientID := model.Settings.Get("recipient_id").MustString() recipientID := model.Settings.Get("recipient_id").MustString()
apiSecret := fn(context.Background(), model.SecureSettings, "api_secret", model.Settings.Get("api_secret").MustString(), setting.SecretKey) apiSecret := fn(context.Background(), model.SecureSettings, "api_secret", model.Settings.Get("api_secret").MustString(), cfg.SecretKey)
// Validation // Validation
if gatewayID == "" { if gatewayID == "" {

@ -10,6 +10,7 @@ import (
"github.com/grafana/grafana/pkg/services/alerting" "github.com/grafana/grafana/pkg/services/alerting"
"github.com/grafana/grafana/pkg/services/alerting/models" "github.com/grafana/grafana/pkg/services/alerting/models"
encryptionservice "github.com/grafana/grafana/pkg/services/encryption/service" encryptionservice "github.com/grafana/grafana/pkg/services/encryption/service"
"github.com/grafana/grafana/pkg/setting"
) )
func TestThreemaNotifier(t *testing.T) { func TestThreemaNotifier(t *testing.T) {
@ -26,7 +27,7 @@ func TestThreemaNotifier(t *testing.T) {
Settings: settingsJSON, Settings: settingsJSON,
} }
_, err := NewThreemaNotifier(model, encryptionService.GetDecryptedValue, nil) _, err := NewThreemaNotifier(setting.NewCfg(), model, encryptionService.GetDecryptedValue, nil)
require.Error(t, err) require.Error(t, err)
}) })
@ -45,7 +46,7 @@ func TestThreemaNotifier(t *testing.T) {
Settings: settingsJSON, Settings: settingsJSON,
} }
not, err := NewThreemaNotifier(model, encryptionService.GetDecryptedValue, nil) not, err := NewThreemaNotifier(setting.NewCfg(), model, encryptionService.GetDecryptedValue, nil)
require.Nil(t, err) require.Nil(t, err)
threemaNotifier := not.(*ThreemaNotifier) threemaNotifier := not.(*ThreemaNotifier)
@ -72,7 +73,7 @@ func TestThreemaNotifier(t *testing.T) {
Settings: settingsJSON, Settings: settingsJSON,
} }
not, err := NewThreemaNotifier(model, encryptionService.GetDecryptedValue, nil) not, err := NewThreemaNotifier(setting.NewCfg(), model, encryptionService.GetDecryptedValue, nil)
require.Nil(t, not) require.Nil(t, not)
var valErr alerting.ValidationError var valErr alerting.ValidationError
require.True(t, errors.As(err, &valErr)) require.True(t, errors.As(err, &valErr))
@ -94,7 +95,7 @@ func TestThreemaNotifier(t *testing.T) {
Settings: settingsJSON, Settings: settingsJSON,
} }
not, err := NewThreemaNotifier(model, encryptionService.GetDecryptedValue, nil) not, err := NewThreemaNotifier(setting.NewCfg(), model, encryptionService.GetDecryptedValue, nil)
require.Nil(t, not) require.Nil(t, not)
var valErr alerting.ValidationError var valErr alerting.ValidationError
require.True(t, errors.As(err, &valErr)) require.True(t, errors.As(err, &valErr))
@ -116,7 +117,7 @@ func TestThreemaNotifier(t *testing.T) {
Settings: settingsJSON, Settings: settingsJSON,
} }
not, err := NewThreemaNotifier(model, encryptionService.GetDecryptedValue, nil) not, err := NewThreemaNotifier(setting.NewCfg(), model, encryptionService.GetDecryptedValue, nil)
require.Nil(t, not) require.Nil(t, not)
var valErr alerting.ValidationError var valErr alerting.ValidationError
require.True(t, errors.As(err, &valErr)) require.True(t, errors.As(err, &valErr))

@ -47,7 +47,7 @@ func init() {
// NewVictoropsNotifier creates an instance of VictoropsNotifier that // NewVictoropsNotifier creates an instance of VictoropsNotifier that
// handles posting notifications to Victorops REST API // handles posting notifications to Victorops REST API
func NewVictoropsNotifier(model *models.AlertNotification, _ alerting.GetDecryptedValueFn, ns notifications.Service) (alerting.Notifier, error) { func NewVictoropsNotifier(_ *setting.Cfg, model *models.AlertNotification, _ alerting.GetDecryptedValueFn, ns notifications.Service) (alerting.Notifier, error) {
autoResolve := model.Settings.Get("autoResolve").MustBool(true) autoResolve := model.Settings.Get("autoResolve").MustBool(true)
url := model.Settings.Get("url").MustString() url := model.Settings.Get("url").MustString()
if url == "" { if url == "" {

@ -39,7 +39,7 @@ func TestVictoropsNotifier(t *testing.T) {
Settings: settingsJSON, Settings: settingsJSON,
} }
_, err := NewVictoropsNotifier(model, encryptionService.GetDecryptedValue, nil) _, err := NewVictoropsNotifier(nil, model, encryptionService.GetDecryptedValue, nil)
require.Error(t, err) require.Error(t, err)
}) })
@ -56,7 +56,7 @@ func TestVictoropsNotifier(t *testing.T) {
Settings: settingsJSON, Settings: settingsJSON,
} }
not, err := NewVictoropsNotifier(model, encryptionService.GetDecryptedValue, nil) not, err := NewVictoropsNotifier(nil, model, encryptionService.GetDecryptedValue, nil)
victoropsNotifier := not.(*VictoropsNotifier) victoropsNotifier := not.(*VictoropsNotifier)
require.Nil(t, err) require.Nil(t, err)
@ -80,7 +80,7 @@ func TestVictoropsNotifier(t *testing.T) {
Settings: settingsJSON, Settings: settingsJSON,
} }
not, err := NewVictoropsNotifier(model, encryptionService.GetDecryptedValue, nil) not, err := NewVictoropsNotifier(nil, model, encryptionService.GetDecryptedValue, nil)
require.Nil(t, err) require.Nil(t, err)
victoropsNotifier := not.(*VictoropsNotifier) victoropsNotifier := not.(*VictoropsNotifier)
@ -128,7 +128,7 @@ func TestVictoropsNotifier(t *testing.T) {
Settings: settingsJSON, Settings: settingsJSON,
} }
not, err := NewVictoropsNotifier(model, encryptionService.GetDecryptedValue, nil) not, err := NewVictoropsNotifier(nil, model, encryptionService.GetDecryptedValue, nil)
require.Nil(t, err) require.Nil(t, err)
victoropsNotifier := not.(*VictoropsNotifier) victoropsNotifier := not.(*VictoropsNotifier)

@ -60,13 +60,13 @@ func init() {
// NewWebHookNotifier is the constructor for // NewWebHookNotifier is the constructor for
// the WebHook notifier. // the WebHook notifier.
func NewWebHookNotifier(model *models.AlertNotification, fn alerting.GetDecryptedValueFn, ns notifications.Service) (alerting.Notifier, error) { func NewWebHookNotifier(cfg *setting.Cfg, model *models.AlertNotification, fn alerting.GetDecryptedValueFn, ns notifications.Service) (alerting.Notifier, error) {
url := model.Settings.Get("url").MustString() url := model.Settings.Get("url").MustString()
if url == "" { if url == "" {
return nil, alerting.ValidationError{Reason: "Could not find url property in settings"} return nil, alerting.ValidationError{Reason: "Could not find url property in settings"}
} }
password := fn(context.Background(), model.SecureSettings, "password", model.Settings.Get("password").MustString(), setting.SecretKey) password := fn(context.Background(), model.SecureSettings, "password", model.Settings.Get("password").MustString(), cfg.SecretKey)
return &WebhookNotifier{ return &WebhookNotifier{
NotifierBase: NewNotifierBase(model, ns), NotifierBase: NewNotifierBase(model, ns),

@ -9,6 +9,7 @@ import (
"github.com/grafana/grafana/pkg/components/simplejson" "github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/services/alerting/models" "github.com/grafana/grafana/pkg/services/alerting/models"
encryptionservice "github.com/grafana/grafana/pkg/services/encryption/service" encryptionservice "github.com/grafana/grafana/pkg/services/encryption/service"
"github.com/grafana/grafana/pkg/setting"
) )
func TestWebhookNotifier_parsingFromSettings(t *testing.T) { func TestWebhookNotifier_parsingFromSettings(t *testing.T) {
@ -25,7 +26,7 @@ func TestWebhookNotifier_parsingFromSettings(t *testing.T) {
Settings: settingsJSON, Settings: settingsJSON,
} }
_, err = NewWebHookNotifier(model, encryptionService.GetDecryptedValue, nil) _, err = NewWebHookNotifier(nil, model, encryptionService.GetDecryptedValue, nil)
require.Error(t, err) require.Error(t, err)
}) })
@ -40,7 +41,7 @@ func TestWebhookNotifier_parsingFromSettings(t *testing.T) {
Settings: settingsJSON, Settings: settingsJSON,
} }
not, err := NewWebHookNotifier(model, encryptionService.GetDecryptedValue, nil) not, err := NewWebHookNotifier(setting.NewCfg(), model, encryptionService.GetDecryptedValue, nil)
require.NoError(t, err) require.NoError(t, err)
webhookNotifier := not.(*WebhookNotifier) webhookNotifier := not.(*WebhookNotifier)

@ -12,6 +12,7 @@ import (
"github.com/grafana/grafana/pkg/services/annotations" "github.com/grafana/grafana/pkg/services/annotations"
"github.com/grafana/grafana/pkg/services/notifications" "github.com/grafana/grafana/pkg/services/notifications"
"github.com/grafana/grafana/pkg/services/rendering" "github.com/grafana/grafana/pkg/services/rendering"
"github.com/grafana/grafana/pkg/setting"
) )
type resultHandler interface { type resultHandler interface {
@ -24,11 +25,11 @@ type defaultResultHandler struct {
log log.Logger log log.Logger
} }
func newResultHandler(renderService rendering.Service, sqlStore AlertStore, notificationService *notifications.NotificationService, decryptFn GetDecryptedValueFn) *defaultResultHandler { func newResultHandler(cfg *setting.Cfg, renderService rendering.Service, sqlStore AlertStore, notificationService *notifications.NotificationService, decryptFn GetDecryptedValueFn) *defaultResultHandler {
return &defaultResultHandler{ return &defaultResultHandler{
log: log.New("alerting.resultHandler"), log: log.New("alerting.resultHandler"),
sqlStore: sqlStore, sqlStore: sqlStore,
notifier: newNotificationService(renderService, sqlStore, notificationService, decryptFn), notifier: newNotificationService(cfg, renderService, sqlStore, notificationService, decryptFn),
} }
} }

@ -10,12 +10,14 @@ import (
) )
type schedulerImpl struct { type schedulerImpl struct {
cfg *setting.Cfg
jobs map[int64]*Job jobs map[int64]*Job
log log.Logger log log.Logger
} }
func newScheduler() scheduler { func newScheduler(cfg *setting.Cfg) scheduler {
return &schedulerImpl{ return &schedulerImpl{
cfg: cfg,
jobs: make(map[int64]*Job), jobs: make(map[int64]*Job),
log: log.New("alerting.scheduler"), log: log.New("alerting.scheduler"),
} }
@ -64,8 +66,8 @@ func (s *schedulerImpl) Tick(tickTime time.Time, execQueue chan *Job) {
// Check the job frequency against the minimum interval required // Check the job frequency against the minimum interval required
interval := job.Rule.Frequency interval := job.Rule.Frequency
if interval < setting.AlertingMinInterval { if interval < s.cfg.AlertingMinInterval {
interval = setting.AlertingMinInterval interval = s.cfg.AlertingMinInterval
} }
if now%interval == 0 { if now%interval == 0 {

@ -13,14 +13,16 @@ import (
) )
type AlertNotificationService struct { type AlertNotificationService struct {
cfg *setting.Cfg
SQLStore AlertNotificationStore SQLStore AlertNotificationStore
EncryptionService encryption.Internal EncryptionService encryption.Internal
NotificationService *notifications.NotificationService NotificationService *notifications.NotificationService
} }
func ProvideService(store db.DB, encryptionService encryption.Internal, func ProvideService(cfg *setting.Cfg, store db.DB, encryptionService encryption.Internal,
notificationService *notifications.NotificationService) *AlertNotificationService { notificationService *notifications.NotificationService) *AlertNotificationService {
s := &AlertNotificationService{ s := &AlertNotificationService{
cfg: cfg,
SQLStore: &sqlStore{db: store}, SQLStore: &sqlStore{db: store},
EncryptionService: encryptionService, EncryptionService: encryptionService,
NotificationService: notificationService, NotificationService: notificationService,
@ -38,7 +40,7 @@ func (s *AlertNotificationService) CreateAlertNotificationCommand(ctx context.Co
return nil, ValidationError{Reason: "Invalid UID: Must be 40 characters or less"} return nil, ValidationError{Reason: "Invalid UID: Must be 40 characters or less"}
} }
cmd.EncryptedSecureSettings, err = s.EncryptionService.EncryptJsonData(ctx, cmd.SecureSettings, setting.SecretKey) cmd.EncryptedSecureSettings, err = s.EncryptionService.EncryptJsonData(ctx, cmd.SecureSettings, s.cfg.SecretKey)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -61,7 +63,7 @@ func (s *AlertNotificationService) UpdateAlertNotification(ctx context.Context,
return nil, ValidationError{Reason: "Invalid UID: Must be 40 characters or less"} return nil, ValidationError{Reason: "Invalid UID: Must be 40 characters or less"}
} }
cmd.EncryptedSecureSettings, err = s.EncryptionService.EncryptJsonData(ctx, cmd.SecureSettings, setting.SecretKey) cmd.EncryptedSecureSettings, err = s.EncryptionService.EncryptJsonData(ctx, cmd.SecureSettings, s.cfg.SecretKey)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -140,7 +142,7 @@ func (s *AlertNotificationService) createNotifier(ctx context.Context, model *mo
if res.SecureSettings != nil { if res.SecureSettings != nil {
var err error var err error
secureSettingsMap, err = s.EncryptionService.DecryptJsonData(ctx, res.SecureSettings, setting.SecretKey) secureSettingsMap, err = s.EncryptionService.DecryptJsonData(ctx, res.SecureSettings, s.cfg.SecretKey)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -152,12 +154,12 @@ func (s *AlertNotificationService) createNotifier(ctx context.Context, model *mo
} }
var err error var err error
model.SecureSettings, err = s.EncryptionService.EncryptJsonData(ctx, secureSettingsMap, setting.SecretKey) model.SecureSettings, err = s.EncryptionService.EncryptJsonData(ctx, secureSettingsMap, s.cfg.SecretKey)
if err != nil { if err != nil {
return nil, err return nil, err
} }
notifier, err := InitNotifier(model, s.EncryptionService.GetDecryptedValue, s.NotificationService) notifier, err := InitNotifier(s.cfg, model, s.EncryptionService.GetDecryptedValue, s.NotificationService)
if err != nil { if err != nil {
logger.Error("Failed to create notifier", "error", err.Error()) logger.Error("Failed to create notifier", "error", err.Error())
return nil, err return nil, err

@ -33,16 +33,17 @@ func TestService(t *testing.T) {
usMock := &usagestats.UsageStatsMock{T: t} usMock := &usagestats.UsageStatsMock{T: t}
encProvider := encryptionprovider.ProvideEncryptionProvider() encProvider := encryptionprovider.ProvideEncryptionProvider()
encService, err := encryptionservice.ProvideEncryptionService(encProvider, usMock, setting.NewCfg()) cfg := setting.NewCfg()
encService, err := encryptionservice.ProvideEncryptionService(encProvider, usMock, cfg)
require.NoError(t, err) require.NoError(t, err)
s := ProvideService(sqlStore.db, encService, nil) s := ProvideService(cfg, sqlStore.db, encService, nil)
origSecret := setting.SecretKey origSecret := cfg.SecretKey
setting.SecretKey = "alert_notification_service_test" cfg.SecretKey = "alert_notification_service_test"
t.Cleanup(func() { t.Cleanup(func() {
setting.SecretKey = origSecret cfg.SecretKey = origSecret
}) })
t.Run("create alert notification should reject an invalid command", func(t *testing.T) { t.Run("create alert notification should reject an invalid command", func(t *testing.T) {
@ -64,7 +65,7 @@ func TestService(t *testing.T) {
an, err := s.CreateAlertNotificationCommand(ctx, &cmd) an, err := s.CreateAlertNotificationCommand(ctx, &cmd)
require.NoError(t, err) require.NoError(t, err)
decrypted, err := s.EncryptionService.DecryptJsonData(ctx, an.SecureSettings, setting.SecretKey) decrypted, err := s.EncryptionService.DecryptJsonData(ctx, an.SecureSettings, cfg.SecretKey)
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, ss, decrypted) require.Equal(t, ss, decrypted)
@ -116,7 +117,7 @@ func TestService(t *testing.T) {
n2, err := s.UpdateAlertNotification(ctx, &updateCmd) n2, err := s.UpdateAlertNotification(ctx, &updateCmd)
require.NoError(t, err) require.NoError(t, err)
decrypted, err := s.EncryptionService.DecryptJsonData(ctx, n2.SecureSettings, setting.SecretKey) decrypted, err := s.EncryptionService.DecryptJsonData(ctx, n2.SecureSettings, cfg.SecretKey)
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, ss, decrypted) require.Equal(t, ss, decrypted)
@ -153,7 +154,7 @@ func TestService(t *testing.T) {
func registerTestNotifier(notifierType string) { func registerTestNotifier(notifierType string) {
RegisterNotifier(&NotifierPlugin{ RegisterNotifier(&NotifierPlugin{
Type: notifierType, Type: notifierType,
Factory: func(*models.AlertNotification, GetDecryptedValueFn, notifications.Service) (Notifier, error) { Factory: func(*setting.Cfg, *models.AlertNotification, GetDecryptedValueFn, notifications.Service) (Notifier, error) {
return nil, nil return nil, nil
}, },
}) })

@ -30,7 +30,7 @@ var (
) )
func (s *AlertNotificationService) HandleNotificationTestCommand(ctx context.Context, cmd *NotificationTestCommand) error { func (s *AlertNotificationService) HandleNotificationTestCommand(ctx context.Context, cmd *NotificationTestCommand) error {
notificationSvc := newNotificationService(nil, nil, nil, nil) notificationSvc := newNotificationService(nil, nil, nil, nil, nil)
model := models.AlertNotification{ model := models.AlertNotification{
ID: cmd.ID, ID: cmd.ID,

@ -84,7 +84,7 @@ func (api *AnonDeviceServiceAPI) ListDevices(c *contextmodel.ReqContext) respons
resDevices = append(resDevices, &deviceDTO{ resDevices = append(resDevices, &deviceDTO{
Device: *device, Device: *device,
LastSeenAt: util.GetAgeString(device.UpdatedAt), LastSeenAt: util.GetAgeString(device.UpdatedAt),
AvatarUrl: dtos.GetGravatarUrl(device.DeviceID), AvatarUrl: dtos.GetGravatarUrl(api.cfg, device.DeviceID),
}) })
} }

@ -88,7 +88,7 @@ func (a *AnonDeviceService) tagDeviceUI(ctx context.Context, httpReq *http.Reque
a.localCache.SetDefault(key, struct{}{}) a.localCache.SetDefault(key, struct{}{})
if setting.Env == setting.Dev { if a.cfg.Env == setting.Dev {
a.log.Debug("Tagging device for UI", "deviceID", device.DeviceID, "device", device, "key", key) a.log.Debug("Tagging device for UI", "deviceID", device.DeviceID, "device", device, "key", key)
} }

@ -66,7 +66,7 @@ type UserAuthTokenService struct {
} }
func (s *UserAuthTokenService) CreateToken(ctx context.Context, user *user.User, clientIP net.IP, userAgent string) (*auth.UserToken, error) { func (s *UserAuthTokenService) CreateToken(ctx context.Context, user *user.User, clientIP net.IP, userAgent string) (*auth.UserToken, error) {
token, hashedToken, err := generateAndHashToken() token, hashedToken, err := generateAndHashToken(s.cfg.SecretKey)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -112,7 +112,7 @@ func (s *UserAuthTokenService) CreateToken(ctx context.Context, user *user.User,
} }
func (s *UserAuthTokenService) LookupToken(ctx context.Context, unhashedToken string) (*auth.UserToken, error) { func (s *UserAuthTokenService) LookupToken(ctx context.Context, unhashedToken string) (*auth.UserToken, error) {
hashedToken := hashToken(unhashedToken) hashedToken := hashToken(s.cfg.SecretKey, unhashedToken)
var model userAuthToken var model userAuthToken
var exists bool var exists bool
var err error var err error
@ -249,7 +249,7 @@ func (s *UserAuthTokenService) rotateToken(ctx context.Context, token *auth.User
clientIPStr = clientIP.String() clientIPStr = clientIP.String()
} }
newToken, hashedToken, err := generateAndHashToken() newToken, hashedToken, err := generateAndHashToken(s.cfg.SecretKey)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -338,7 +338,7 @@ func (s *UserAuthTokenService) TryRotateToken(ctx context.Context, token *auth.U
if err != nil { if err != nil {
return nil, err return nil, err
} }
hashedToken := hashToken(newToken) hashedToken := hashToken(s.cfg.SecretKey, newToken)
// very important that auth_token_seen is set after the prev_auth_token = case when ... for mysql to function correctly // very important that auth_token_seen is set after the prev_auth_token = case when ... for mysql to function correctly
sql := ` sql := `
@ -627,18 +627,18 @@ func createToken() (string, error) {
return token, nil return token, nil
} }
func hashToken(token string) string { func hashToken(secretKey string, token string) string {
hashBytes := sha256.Sum256([]byte(token + setting.SecretKey)) hashBytes := sha256.Sum256([]byte(token + secretKey))
return hex.EncodeToString(hashBytes[:]) return hex.EncodeToString(hashBytes[:])
} }
func generateAndHashToken() (string, string, error) { func generateAndHashToken(secretKey string) (string, string, error) {
token, err := createToken() token, err := createToken()
if err != nil { if err != nil {
return "", "", err return "", "", err
} }
return token, hashToken(token), nil return token, hashToken(secretKey, token), nil
} }
func readQuotaConfig(cfg *setting.Cfg) (*quota.Map, error) { func readQuotaConfig(cfg *setting.Cfg) (*quota.Map, error) {

@ -479,14 +479,14 @@ func TestIntegrationUserAuthToken(t *testing.T) {
token, err = ctx.tokenService.RotateToken(context.Background(), auth.RotateCommand{UnHashedToken: token.UnhashedToken}) token, err = ctx.tokenService.RotateToken(context.Background(), auth.RotateCommand{UnHashedToken: token.UnhashedToken})
require.NoError(t, err) require.NoError(t, err)
assert.True(t, token.UnhashedToken != prev) assert.True(t, token.UnhashedToken != prev)
assert.True(t, token.PrevAuthToken == hashToken(prev)) assert.True(t, token.PrevAuthToken == hashToken("", prev))
}) })
t.Run("should rotate token when called with previous", func(t *testing.T) { t.Run("should rotate token when called with previous", func(t *testing.T) {
newPrev := token.UnhashedToken newPrev := token.UnhashedToken
token, err = ctx.tokenService.RotateToken(context.Background(), auth.RotateCommand{UnHashedToken: prev}) token, err = ctx.tokenService.RotateToken(context.Background(), auth.RotateCommand{UnHashedToken: prev})
require.NoError(t, err) require.NoError(t, err)
assert.True(t, token.PrevAuthToken == hashToken(newPrev)) assert.True(t, token.PrevAuthToken == hashToken("", newPrev))
}) })
t.Run("should not rotate token when called with old previous", func(t *testing.T) { t.Run("should not rotate token when called with old previous", func(t *testing.T) {

@ -127,12 +127,8 @@ func TestVerifyUsingJWKSetURL(t *testing.T) {
}) })
require.NoError(t, err) require.NoError(t, err)
oldEnv := setting.Env
setting.Env = setting.Prod
defer func() {
setting.Env = oldEnv
}()
_, err = initAuthService(t, func(t *testing.T, cfg *setting.Cfg) { _, err = initAuthService(t, func(t *testing.T, cfg *setting.Cfg) {
cfg.Env = setting.Prod
cfg.JWTAuthJWKSetURL = "http://example.com/.well-known/jwks.json" cfg.JWTAuthJWKSetURL = "http://example.com/.well-known/jwks.json"
}) })
require.Error(t, err) require.Error(t, err)

@ -152,7 +152,7 @@ func (s *AuthService) initKeySet() error {
if err != nil { if err != nil {
return err return err
} }
if urlParsed.Scheme != "https" && setting.Env != setting.Dev { if urlParsed.Scheme != "https" && s.Cfg.Env != setting.Dev {
return ErrJWTSetURLMustHaveHTTPSScheme return ErrJWTSetURLMustHaveHTTPSScheme
} }
s.keySet = &keySetHTTP{ s.keySet = &keySetHTTP{

@ -129,7 +129,7 @@ func (dr *DashboardServiceImpl) BuildSaveDashboardCommand(ctx context.Context, d
return nil, dashboards.ErrDashboardUidTooLong return nil, dashboards.ErrDashboardUidTooLong
} }
if err := validateDashboardRefreshInterval(dash); err != nil { if err := validateDashboardRefreshInterval(dr.cfg.MinRefreshInterval, dash); err != nil {
return nil, err return nil, err
} }
@ -274,8 +274,8 @@ func getGuardianForSavePermissionCheck(ctx context.Context, d *dashboards.Dashbo
return guard, nil return guard, nil
} }
func validateDashboardRefreshInterval(dash *dashboards.Dashboard) error { func validateDashboardRefreshInterval(minRefreshInterval string, dash *dashboards.Dashboard) error {
if setting.MinRefreshInterval == "" { if minRefreshInterval == "" {
return nil return nil
} }
@ -285,16 +285,16 @@ func validateDashboardRefreshInterval(dash *dashboards.Dashboard) error {
return nil return nil
} }
minRefreshInterval, err := gtime.ParseDuration(setting.MinRefreshInterval) minRefreshIntervalDur, err := gtime.ParseDuration(minRefreshInterval)
if err != nil { if err != nil {
return fmt.Errorf("parsing min refresh interval %q failed: %w", setting.MinRefreshInterval, err) return fmt.Errorf("parsing min refresh interval %q failed: %w", minRefreshInterval, err)
} }
d, err := gtime.ParseDuration(refresh) d, err := gtime.ParseDuration(refresh)
if err != nil { if err != nil {
return fmt.Errorf("parsing refresh duration %q failed: %w", refresh, err) return fmt.Errorf("parsing refresh duration %q failed: %w", refresh, err)
} }
if d < minRefreshInterval { if d < minRefreshIntervalDur {
return dashboards.ErrDashboardRefreshIntervalTooShort return dashboards.ErrDashboardRefreshIntervalTooShort
} }
@ -303,15 +303,15 @@ func validateDashboardRefreshInterval(dash *dashboards.Dashboard) error {
func (dr *DashboardServiceImpl) SaveProvisionedDashboard(ctx context.Context, dto *dashboards.SaveDashboardDTO, func (dr *DashboardServiceImpl) SaveProvisionedDashboard(ctx context.Context, dto *dashboards.SaveDashboardDTO,
provisioning *dashboards.DashboardProvisioning) (*dashboards.Dashboard, error) { provisioning *dashboards.DashboardProvisioning) (*dashboards.Dashboard, error) {
if err := validateDashboardRefreshInterval(dto.Dashboard); err != nil { if err := validateDashboardRefreshInterval(dr.cfg.MinRefreshInterval, dto.Dashboard); err != nil {
dr.log.Warn("Changing refresh interval for provisioned dashboard to minimum refresh interval", "dashboardUid", dr.log.Warn("Changing refresh interval for provisioned dashboard to minimum refresh interval", "dashboardUid",
dto.Dashboard.UID, "dashboardTitle", dto.Dashboard.Title, "minRefreshInterval", setting.MinRefreshInterval) dto.Dashboard.UID, "dashboardTitle", dto.Dashboard.Title, "minRefreshInterval", dr.cfg.MinRefreshInterval)
dto.Dashboard.Data.Set("refresh", setting.MinRefreshInterval) dto.Dashboard.Data.Set("refresh", dr.cfg.MinRefreshInterval)
} }
dto.User = accesscontrol.BackgroundUser("dashboard_provisioning", dto.OrgID, org.RoleAdmin, provisionerPermissions) dto.User = accesscontrol.BackgroundUser("dashboard_provisioning", dto.OrgID, org.RoleAdmin, provisionerPermissions)
cmd, err := dr.BuildSaveDashboardCommand(ctx, dto, setting.IsLegacyAlertingEnabled(), false) cmd, err := dr.BuildSaveDashboardCommand(ctx, dto, dr.cfg.IsLegacyAlertingEnabled(), false)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -330,7 +330,7 @@ func (dr *DashboardServiceImpl) SaveProvisionedDashboard(ctx context.Context, dt
} }
// extract/save legacy alerts only if legacy alerting is enabled // extract/save legacy alerts only if legacy alerting is enabled
if setting.IsLegacyAlertingEnabled() { if dr.cfg.IsLegacyAlertingEnabled() {
alerts, err := dr.dashAlertExtractor.GetAlerts(ctx, dashAlertInfo) alerts, err := dr.dashAlertExtractor.GetAlerts(ctx, dashAlertInfo)
if err != nil { if err != nil {
return nil, err return nil, err
@ -364,14 +364,14 @@ func (dr *DashboardServiceImpl) SaveFolderForProvisionedDashboards(ctx context.C
func (dr *DashboardServiceImpl) SaveDashboard(ctx context.Context, dto *dashboards.SaveDashboardDTO, func (dr *DashboardServiceImpl) SaveDashboard(ctx context.Context, dto *dashboards.SaveDashboardDTO,
allowUiUpdate bool) (*dashboards.Dashboard, error) { allowUiUpdate bool) (*dashboards.Dashboard, error) {
if err := validateDashboardRefreshInterval(dto.Dashboard); err != nil { if err := validateDashboardRefreshInterval(dr.cfg.MinRefreshInterval, dto.Dashboard); err != nil {
dr.log.Warn("Changing refresh interval for imported dashboard to minimum refresh interval", dr.log.Warn("Changing refresh interval for imported dashboard to minimum refresh interval",
"dashboardUid", dto.Dashboard.UID, "dashboardTitle", dto.Dashboard.Title, "minRefreshInterval", "dashboardUid", dto.Dashboard.UID, "dashboardTitle", dto.Dashboard.Title, "minRefreshInterval",
setting.MinRefreshInterval) dr.cfg.MinRefreshInterval)
dto.Dashboard.Data.Set("refresh", setting.MinRefreshInterval) dto.Dashboard.Data.Set("refresh", dr.cfg.MinRefreshInterval)
} }
cmd, err := dr.BuildSaveDashboardCommand(ctx, dto, setting.IsLegacyAlertingEnabled(), !allowUiUpdate) cmd, err := dr.BuildSaveDashboardCommand(ctx, dto, dr.cfg.IsLegacyAlertingEnabled(), !allowUiUpdate)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -388,7 +388,7 @@ func (dr *DashboardServiceImpl) SaveDashboard(ctx context.Context, dto *dashboar
} }
// extract/save legacy alerts only if legacy alerting is enabled // extract/save legacy alerts only if legacy alerting is enabled
if setting.IsLegacyAlertingEnabled() { if dr.cfg.IsLegacyAlertingEnabled() {
alerts, err := dr.dashAlertExtractor.GetAlerts(ctx, dashAlertInfo) alerts, err := dr.dashAlertExtractor.GetAlerts(ctx, dashAlertInfo)
if err != nil { if err != nil {
return nil, err return nil, err
@ -440,11 +440,11 @@ func (dr *DashboardServiceImpl) deleteDashboard(ctx context.Context, dashboardId
func (dr *DashboardServiceImpl) ImportDashboard(ctx context.Context, dto *dashboards.SaveDashboardDTO) ( func (dr *DashboardServiceImpl) ImportDashboard(ctx context.Context, dto *dashboards.SaveDashboardDTO) (
*dashboards.Dashboard, error) { *dashboards.Dashboard, error) {
if err := validateDashboardRefreshInterval(dto.Dashboard); err != nil { if err := validateDashboardRefreshInterval(dr.cfg.MinRefreshInterval, dto.Dashboard); err != nil {
dr.log.Warn("Changing refresh interval for imported dashboard to minimum refresh interval", dr.log.Warn("Changing refresh interval for imported dashboard to minimum refresh interval",
"dashboardUid", dto.Dashboard.UID, "dashboardTitle", dto.Dashboard.Title, "dashboardUid", dto.Dashboard.UID, "dashboardTitle", dto.Dashboard.Title,
"minRefreshInterval", setting.MinRefreshInterval) "minRefreshInterval", dr.cfg.MinRefreshInterval)
dto.Dashboard.Data.Set("refresh", setting.MinRefreshInterval) dto.Dashboard.Data.Set("refresh", dr.cfg.MinRefreshInterval)
} }
cmd, err := dr.BuildSaveDashboardCommand(ctx, dto, false, true) cmd, err := dr.BuildSaveDashboardCommand(ctx, dto, false, true)

@ -118,17 +118,17 @@ func TestDashboardService(t *testing.T) {
}) })
t.Run("Should return validation error if alert data is invalid", func(t *testing.T) { t.Run("Should return validation error if alert data is invalid", func(t *testing.T) {
origAlertingEnabledSet := setting.AlertingEnabled != nil origAlertingEnabledSet := service.cfg.AlertingEnabled != nil
origAlertingEnabledVal := false origAlertingEnabledVal := false
if origAlertingEnabledSet { if origAlertingEnabledSet {
origAlertingEnabledVal = *setting.AlertingEnabled origAlertingEnabledVal = *(service.cfg.AlertingEnabled)
} }
setting.AlertingEnabled = util.Pointer(true) service.cfg.AlertingEnabled = util.Pointer(true)
t.Cleanup(func() { t.Cleanup(func() {
if !origAlertingEnabledSet { if !origAlertingEnabledSet {
setting.AlertingEnabled = nil service.cfg.AlertingEnabled = nil
} else { } else {
setting.AlertingEnabled = &origAlertingEnabledVal service.cfg.AlertingEnabled = &origAlertingEnabledVal
} }
}) })
@ -163,9 +163,9 @@ func TestDashboardService(t *testing.T) {
fakeStore.On("ValidateDashboardBeforeSave", mock.Anything, mock.Anything, mock.AnythingOfType("bool")).Return(true, nil).Once() fakeStore.On("ValidateDashboardBeforeSave", mock.Anything, mock.Anything, mock.AnythingOfType("bool")).Return(true, nil).Once()
fakeStore.On("SaveProvisionedDashboard", mock.Anything, mock.AnythingOfType("dashboards.SaveDashboardCommand"), mock.AnythingOfType("*dashboards.DashboardProvisioning")).Return(&dashboards.Dashboard{Data: simplejson.New()}, nil).Once() fakeStore.On("SaveProvisionedDashboard", mock.Anything, mock.AnythingOfType("dashboards.SaveDashboardCommand"), mock.AnythingOfType("*dashboards.DashboardProvisioning")).Return(&dashboards.Dashboard{Data: simplejson.New()}, nil).Once()
oldRefreshInterval := setting.MinRefreshInterval oldRefreshInterval := service.cfg.MinRefreshInterval
setting.MinRefreshInterval = "5m" service.cfg.MinRefreshInterval = "5m"
defer func() { setting.MinRefreshInterval = oldRefreshInterval }() defer func() { service.cfg.MinRefreshInterval = oldRefreshInterval }()
dto.Dashboard = dashboards.NewDashboard("Dash") dto.Dashboard = dashboards.NewDashboard("Dash")
dto.Dashboard.SetID(3) dto.Dashboard.SetID(3)

@ -23,12 +23,13 @@ func TestIntegrationDashboardSnapshotDBAccess(t *testing.T) {
t.Skip("skipping integration test") t.Skip("skipping integration test")
} }
sqlstore := db.InitTestDB(t) sqlstore := db.InitTestDB(t)
dashStore := ProvideStore(sqlstore, setting.NewCfg()) cfg := setting.NewCfg()
dashStore := ProvideStore(sqlstore, cfg)
origSecret := setting.SecretKey origSecret := cfg.SecretKey
setting.SecretKey = "dashboard_snapshot_testing" cfg.SecretKey = "dashboard_snapshot_testing"
t.Cleanup(func() { t.Cleanup(func() {
setting.SecretKey = origSecret cfg.SecretKey = origSecret
}) })
secretsService := fakes.NewFakeSecretsService() secretsService := fakes.NewFakeSecretsService()
dashboard := simplejson.NewFromAny(map[string]any{"hello": "mupp"}) dashboard := simplejson.NewFromAny(map[string]any{"hello": "mupp"})

@ -17,14 +17,15 @@ import (
func TestDashboardSnapshotsService(t *testing.T) { func TestDashboardSnapshotsService(t *testing.T) {
sqlStore := db.InitTestDB(t) sqlStore := db.InitTestDB(t)
dsStore := dashsnapdb.ProvideStore(sqlStore, setting.NewCfg()) cfg := setting.NewCfg()
dsStore := dashsnapdb.ProvideStore(sqlStore, cfg)
secretsService := secretsManager.SetupTestService(t, database.ProvideSecretsStore(sqlStore)) secretsService := secretsManager.SetupTestService(t, database.ProvideSecretsStore(sqlStore))
s := ProvideService(dsStore, secretsService) s := ProvideService(dsStore, secretsService)
origSecret := setting.SecretKey origSecret := cfg.SecretKey
setting.SecretKey = "dashboard_snapshot_service_test" cfg.SecretKey = "dashboard_snapshot_service_test"
t.Cleanup(func() { t.Cleanup(func() {
setting.SecretKey = origSecret cfg.SecretKey = origSecret
}) })
dashboardKey := "12345" dashboardKey := "12345"

@ -17,13 +17,15 @@ const (
) )
type Service struct { type Service struct {
cfg *setting.Cfg
store store store store
dashSvc dashboards.DashboardService dashSvc dashboards.DashboardService
log log.Logger log log.Logger
} }
func ProvideService(db db.DB, dashboardService dashboards.DashboardService) dashver.Service { func ProvideService(cfg *setting.Cfg, db db.DB, dashboardService dashboards.DashboardService) dashver.Service {
return &Service{ return &Service{
cfg: cfg,
store: &sqlStore{ store: &sqlStore{
db: db, db: db,
dialect: db.GetDialect(), dialect: db.GetDialect(),
@ -63,7 +65,7 @@ func (s *Service) Get(ctx context.Context, query *dashver.GetDashboardVersionQue
} }
func (s *Service) DeleteExpired(ctx context.Context, cmd *dashver.DeleteExpiredVersionsCommand) error { func (s *Service) DeleteExpired(ctx context.Context, cmd *dashver.DeleteExpiredVersionsCommand) error {
versionsToKeep := setting.DashboardVersionsToKeep versionsToKeep := s.cfg.DashboardVersionsToKeep
if versionsToKeep < 1 { if versionsToKeep < 1 {
versionsToKeep = 1 versionsToKeep = 1
} }

@ -36,11 +36,13 @@ func TestDashboardVersionService(t *testing.T) {
func TestDeleteExpiredVersions(t *testing.T) { func TestDeleteExpiredVersions(t *testing.T) {
versionsToKeep := 5 versionsToKeep := 5
setting.DashboardVersionsToKeep = versionsToKeep cfg := setting.NewCfg()
cfg.DashboardVersionsToKeep = versionsToKeep
dashboardVersionStore := newDashboardVersionStoreFake() dashboardVersionStore := newDashboardVersionStoreFake()
dashboardService := dashboards.NewFakeDashboardService(t) dashboardService := dashboards.NewFakeDashboardService(t)
dashboardVersionService := Service{store: dashboardVersionStore, dashSvc: dashboardService} dashboardVersionService := Service{
cfg: cfg, store: dashboardVersionStore, dashSvc: dashboardService}
t.Run("Don't delete anything if there are no expired versions", func(t *testing.T) { t.Run("Don't delete anything if there are no expired versions", func(t *testing.T) {
err := dashboardVersionService.DeleteExpired(context.Background(), &dashver.DeleteExpiredVersionsCommand{DeletedRows: 4}) err := dashboardVersionService.DeleteExpired(context.Background(), &dashver.DeleteExpiredVersionsCommand{DeletedRows: 4})

@ -554,7 +554,7 @@ func (s *Service) httpClientOptions(ctx context.Context, ds *datasources.DataSou
opts.ProxyOptions = proxyOpts opts.ProxyOptions = proxyOpts
} }
if ds.JsonData != nil && ds.JsonData.Get("sigV4Auth").MustBool(false) && setting.SigV4AuthEnabled { if ds.JsonData != nil && ds.JsonData.Get("sigV4Auth").MustBool(false) && s.cfg.SigV4AuthEnabled {
opts.SigV4 = &sdkhttpclient.SigV4Config{ opts.SigV4 = &sdkhttpclient.SigV4Config{
Service: awsServiceNamespace(ds.Type, ds.JsonData), Service: awsServiceNamespace(ds.Type, ds.JsonData),
Region: ds.JsonData.Get("sigV4Region").MustString(), Region: ds.JsonData.Get("sigV4Region").MustString(),

@ -608,7 +608,7 @@ func TestService_GetHttpTransport(t *testing.T) {
}, },
}) })
setting.SecretKey = "password" cfg.SecretKey = "password"
sjson := simplejson.New() sjson := simplejson.New()
sjson.Set("tlsAuthWithCACert", true) sjson.Set("tlsAuthWithCACert", true)
@ -659,7 +659,7 @@ func TestService_GetHttpTransport(t *testing.T) {
}, },
}) })
setting.SecretKey = "password" cfg.SecretKey = "password"
sjson := simplejson.New() sjson := simplejson.New()
sjson.Set("tlsAuth", true) sjson.Set("tlsAuth", true)
@ -706,7 +706,7 @@ func TestService_GetHttpTransport(t *testing.T) {
}, },
}) })
setting.SecretKey = "password" cfg.SecretKey = "password"
sjson := simplejson.New() sjson := simplejson.New()
sjson.Set("tlsAuthWithCACert", true) sjson.Set("tlsAuthWithCACert", true)
@ -968,10 +968,10 @@ func TestService_GetHttpTransport(t *testing.T) {
}, },
}) })
origSigV4Enabled := setting.SigV4AuthEnabled origSigV4Enabled := cfg.SigV4AuthEnabled
setting.SigV4AuthEnabled = true cfg.SigV4AuthEnabled = true
t.Cleanup(func() { t.Cleanup(func() {
setting.SigV4AuthEnabled = origSigV4Enabled cfg.SigV4AuthEnabled = origSigV4Enabled
}) })
sjson, err := simplejson.NewJson([]byte(`{ "sigV4Auth": true }`)) sjson, err := simplejson.NewJson([]byte(`{ "sigV4Auth": true }`))

@ -20,7 +20,7 @@ var (
func ProvideManagerService(cfg *setting.Cfg, licensing licensing.Licensing) (*FeatureManager, error) { func ProvideManagerService(cfg *setting.Cfg, licensing licensing.Licensing) (*FeatureManager, error) {
mgmt := &FeatureManager{ mgmt := &FeatureManager{
isDevMod: setting.Env != setting.Prod, isDevMod: cfg.Env != setting.Prod,
licensing: licensing, licensing: licensing,
flags: make(map[string]*FeatureFlag, 30), flags: make(map[string]*FeatureFlag, 30),
enabled: make(map[string]bool), enabled: make(map[string]bool),

@ -208,12 +208,12 @@ func (l *LibraryElementService) createLibraryElement(c context.Context, signedIn
CreatedBy: librarypanel.LibraryElementDTOMetaUser{ CreatedBy: librarypanel.LibraryElementDTOMetaUser{
Id: element.CreatedBy, Id: element.CreatedBy,
Name: signedInUser.GetLogin(), Name: signedInUser.GetLogin(),
AvatarUrl: dtos.GetGravatarUrl(signedInUser.GetEmail()), AvatarUrl: dtos.GetGravatarUrl(l.Cfg, signedInUser.GetEmail()),
}, },
UpdatedBy: librarypanel.LibraryElementDTOMetaUser{ UpdatedBy: librarypanel.LibraryElementDTOMetaUser{
Id: element.UpdatedBy, Id: element.UpdatedBy,
Name: signedInUser.GetLogin(), Name: signedInUser.GetLogin(),
AvatarUrl: dtos.GetGravatarUrl(signedInUser.GetEmail()), AvatarUrl: dtos.GetGravatarUrl(l.Cfg, signedInUser.GetEmail()),
}, },
}, },
} }
@ -335,12 +335,12 @@ func (l *LibraryElementService) getLibraryElements(c context.Context, store db.D
CreatedBy: librarypanel.LibraryElementDTOMetaUser{ CreatedBy: librarypanel.LibraryElementDTOMetaUser{
Id: libraryElement.CreatedBy, Id: libraryElement.CreatedBy,
Name: libraryElement.CreatedByName, Name: libraryElement.CreatedByName,
AvatarUrl: dtos.GetGravatarUrl(libraryElement.CreatedByEmail), AvatarUrl: dtos.GetGravatarUrl(l.Cfg, libraryElement.CreatedByEmail),
}, },
UpdatedBy: librarypanel.LibraryElementDTOMetaUser{ UpdatedBy: librarypanel.LibraryElementDTOMetaUser{
Id: libraryElement.UpdatedBy, Id: libraryElement.UpdatedBy,
Name: libraryElement.UpdatedByName, Name: libraryElement.UpdatedByName,
AvatarUrl: dtos.GetGravatarUrl(libraryElement.UpdatedByEmail), AvatarUrl: dtos.GetGravatarUrl(l.Cfg, libraryElement.UpdatedByEmail),
}, },
}, },
} }
@ -457,12 +457,12 @@ func (l *LibraryElementService) getAllLibraryElements(c context.Context, signedI
CreatedBy: librarypanel.LibraryElementDTOMetaUser{ CreatedBy: librarypanel.LibraryElementDTOMetaUser{
Id: element.CreatedBy, Id: element.CreatedBy,
Name: element.CreatedByName, Name: element.CreatedByName,
AvatarUrl: dtos.GetGravatarUrl(element.CreatedByEmail), AvatarUrl: dtos.GetGravatarUrl(l.Cfg, element.CreatedByEmail),
}, },
UpdatedBy: librarypanel.LibraryElementDTOMetaUser{ UpdatedBy: librarypanel.LibraryElementDTOMetaUser{
Id: element.UpdatedBy, Id: element.UpdatedBy,
Name: element.UpdatedByName, Name: element.UpdatedByName,
AvatarUrl: dtos.GetGravatarUrl(element.UpdatedByEmail), AvatarUrl: dtos.GetGravatarUrl(l.Cfg, element.UpdatedByEmail),
}, },
}, },
}) })
@ -630,12 +630,12 @@ func (l *LibraryElementService) patchLibraryElement(c context.Context, signedInU
CreatedBy: librarypanel.LibraryElementDTOMetaUser{ CreatedBy: librarypanel.LibraryElementDTOMetaUser{
Id: elementInDB.CreatedBy, Id: elementInDB.CreatedBy,
Name: elementInDB.CreatedByName, Name: elementInDB.CreatedByName,
AvatarUrl: dtos.GetGravatarUrl(elementInDB.CreatedByEmail), AvatarUrl: dtos.GetGravatarUrl(l.Cfg, elementInDB.CreatedByEmail),
}, },
UpdatedBy: librarypanel.LibraryElementDTOMetaUser{ UpdatedBy: librarypanel.LibraryElementDTOMetaUser{
Id: libraryElement.UpdatedBy, Id: libraryElement.UpdatedBy,
Name: signedInUser.GetLogin(), Name: signedInUser.GetLogin(),
AvatarUrl: dtos.GetGravatarUrl(signedInUser.GetEmail()), AvatarUrl: dtos.GetGravatarUrl(l.Cfg, signedInUser.GetEmail()),
}, },
}, },
} }
@ -683,7 +683,7 @@ func (l *LibraryElementService) getConnections(c context.Context, signedInUser i
CreatedBy: librarypanel.LibraryElementDTOMetaUser{ CreatedBy: librarypanel.LibraryElementDTOMetaUser{
Id: connection.CreatedBy, Id: connection.CreatedBy,
Name: connection.CreatedByName, Name: connection.CreatedByName,
AvatarUrl: dtos.GetGravatarUrl(connection.CreatedByEmail), AvatarUrl: dtos.GetGravatarUrl(l.Cfg, connection.CreatedByEmail),
}, },
}) })
} }
@ -732,12 +732,12 @@ func (l *LibraryElementService) getElementsForDashboardID(c context.Context, das
CreatedBy: librarypanel.LibraryElementDTOMetaUser{ CreatedBy: librarypanel.LibraryElementDTOMetaUser{
Id: element.CreatedBy, Id: element.CreatedBy,
Name: element.CreatedByName, Name: element.CreatedByName,
AvatarUrl: dtos.GetGravatarUrl(element.CreatedByEmail), AvatarUrl: dtos.GetGravatarUrl(l.Cfg, element.CreatedByEmail),
}, },
UpdatedBy: librarypanel.LibraryElementDTOMetaUser{ UpdatedBy: librarypanel.LibraryElementDTOMetaUser{
Id: element.UpdatedBy, Id: element.UpdatedBy,
Name: element.UpdatedByName, Name: element.UpdatedByName,
AvatarUrl: dtos.GetGravatarUrl(element.UpdatedByEmail), AvatarUrl: dtos.GetGravatarUrl(l.Cfg, element.UpdatedByEmail),
}, },
}, },
} }

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save