diff --git a/pkg/api/api.go b/pkg/api/api.go index 3f10f3565fe..3153312966e 100644 --- a/pkg/api/api.go +++ b/pkg/api/api.go @@ -154,7 +154,7 @@ func (hs *HTTPServer) registerRoutes() { teamsRoute.Post("/", bind(models.CreateTeamCommand{}), Wrap(hs.CreateTeam)) teamsRoute.Put("/:teamId", bind(models.UpdateTeamCommand{}), Wrap(hs.UpdateTeam)) teamsRoute.Delete("/:teamId", Wrap(hs.DeleteTeamByID)) - teamsRoute.Get("/:teamId/members", Wrap(GetTeamMembers)) + teamsRoute.Get("/:teamId/members", Wrap(hs.GetTeamMembers)) teamsRoute.Post("/:teamId/members", bind(models.AddTeamMemberCommand{}), Wrap(hs.AddTeamMember)) teamsRoute.Put("/:teamId/members/:userId", bind(models.UpdateTeamMemberCommand{}), Wrap(hs.UpdateTeamMember)) teamsRoute.Delete("/:teamId/members/:userId", Wrap(hs.RemoveTeamMember)) diff --git a/pkg/api/frontendsettings.go b/pkg/api/frontendsettings.go index 9919a0aa10e..72c38900b43 100644 --- a/pkg/api/frontendsettings.go +++ b/pkg/api/frontendsettings.go @@ -196,7 +196,11 @@ func (hs *HTTPServer) getFrontendSettingsMap(c *m.ReqContext) (map[string]interf "latestVersion": plugins.GrafanaLatestVersion, "hasUpdate": plugins.GrafanaHasUpdate, "env": setting.Env, - "isEnterprise": setting.IsEnterprise, + "isEnterprise": hs.License.HasValidLicense(), + }, + "licenseInfo": map[string]interface{}{ + "hasLicense": hs.License.HasLicense(), + "expiry": hs.License.Expiry(), }, "featureToggles": hs.Cfg.FeatureToggles, } diff --git a/pkg/api/http_server.go b/pkg/api/http_server.go index 4be0c249fbf..dd3cd771bbb 100644 --- a/pkg/api/http_server.go +++ b/pkg/api/http_server.go @@ -69,6 +69,7 @@ type HTTPServer struct { RemoteCacheService *remotecache.RemoteCache `inject:""` ProvisioningService ProvisioningService `inject:""` Login *login.LoginService `inject:""` + License models.Licensing `inject:""` } func (hs *HTTPServer) Init() error { diff --git a/pkg/api/index.go b/pkg/api/index.go index 1c87b0d84fa..69ac9d60a46 100644 --- a/pkg/api/index.go +++ b/pkg/api/index.go @@ -83,7 +83,7 @@ func (hs *HTTPServer) setIndexViewData(c *m.ReqContext) (*dtos.IndexViewData, er NewGrafanaVersion: plugins.GrafanaLatestVersion, NewGrafanaVersionExists: plugins.GrafanaHasUpdate, AppName: setting.ApplicationName, - AppNameBodyClass: getAppNameBodyClass(setting.ApplicationName), + AppNameBodyClass: getAppNameBodyClass(hs.License.HasValidLicense()), } if setting.DisableGravatar { @@ -372,13 +372,10 @@ func (hs *HTTPServer) NotFoundHandler(c *m.ReqContext) { c.HTML(404, "index", data) } -func getAppNameBodyClass(name string) string { - switch name { - case setting.APP_NAME: - return "app-grafana" - case setting.APP_NAME_ENTERPRISE: +func getAppNameBodyClass(validLicense bool) string { + if validLicense { return "app-enterprise" - default: - return "" } + + return "app-grafana" } diff --git a/pkg/api/login.go b/pkg/api/login.go index 8009e474f4b..01a59df18f4 100644 --- a/pkg/api/login.go +++ b/pkg/api/login.go @@ -40,7 +40,7 @@ func (hs *HTTPServer) LoginView(c *models.ReqContext) { } viewData.Settings["oauth"] = enabledOAuths - viewData.Settings["samlEnabled"] = setting.IsEnterprise && hs.Cfg.SAMLEnabled + viewData.Settings["samlEnabled"] = hs.License.HasValidLicense() && hs.Cfg.SAMLEnabled if loginError, ok := tryGetEncryptedCookie(c, LoginErrorCookieName); ok { //this cookie is only set whenever an OAuth login fails diff --git a/pkg/api/login_test.go b/pkg/api/login_test.go index fd27bd3f656..adfe97f7bc5 100644 --- a/pkg/api/login_test.go +++ b/pkg/api/login_test.go @@ -60,7 +60,8 @@ func TestLoginErrorCookieApiEndpoint(t *testing.T) { sc := setupScenarioContext("/login") hs := &HTTPServer{ - Cfg: setting.NewCfg(), + Cfg: setting.NewCfg(), + License: models.OSSLicensingService{}, } sc.defaultHandler = Wrap(func(w http.ResponseWriter, c *models.ReqContext) { @@ -109,7 +110,8 @@ func TestLoginOAuthRedirect(t *testing.T) { sc := setupScenarioContext("/login") hs := &HTTPServer{ - Cfg: setting.NewCfg(), + Cfg: setting.NewCfg(), + License: models.OSSLicensingService{}, } sc.defaultHandler = Wrap(func(c *models.ReqContext) { diff --git a/pkg/api/team_members.go b/pkg/api/team_members.go index 0d8139e4e5c..ed63c72ef91 100644 --- a/pkg/api/team_members.go +++ b/pkg/api/team_members.go @@ -5,12 +5,11 @@ import ( "github.com/grafana/grafana/pkg/bus" m "github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/services/teamguardian" - "github.com/grafana/grafana/pkg/setting" "github.com/grafana/grafana/pkg/util" ) // GET /api/teams/:teamId/members -func GetTeamMembers(c *m.ReqContext) Response { +func (hs *HTTPServer) GetTeamMembers(c *m.ReqContext) Response { query := m.GetTeamMembersQuery{OrgId: c.OrgId, TeamId: c.ParamsInt64(":teamId")} if err := bus.Dispatch(&query); err != nil { @@ -21,7 +20,7 @@ func GetTeamMembers(c *m.ReqContext) Response { member.AvatarUrl = dtos.GetGravatarUrl(member.Email) member.Labels = []string{} - if setting.IsEnterprise && member.External { + if hs.License.HasValidLicense() && member.External { authProvider := GetAuthProviderLabel(member.AuthModule) member.Labels = append(member.Labels, authProvider) } diff --git a/pkg/extensions/main.go b/pkg/extensions/main.go index df996d4597c..785f9b4212b 100644 --- a/pkg/extensions/main.go +++ b/pkg/extensions/main.go @@ -6,6 +6,8 @@ import ( _ "github.com/crewjam/saml" _ "github.com/gobwas/glob" + "github.com/grafana/grafana/pkg/models" + "github.com/grafana/grafana/pkg/registry" _ "github.com/jung-kurt/gofpdf" _ "github.com/robfig/cron" _ "github.com/robfig/cron/v3" @@ -13,4 +15,8 @@ import ( _ "gopkg.in/square/go-jose.v2" ) +func init() { + registry.RegisterService(&models.OSSLicensingService{}) +} + var IsEnterprise bool = false diff --git a/pkg/infra/usagestats/service.go b/pkg/infra/usagestats/service.go index 7cda2cbef4b..186c51648f6 100644 --- a/pkg/infra/usagestats/service.go +++ b/pkg/infra/usagestats/service.go @@ -6,6 +6,7 @@ import ( "github.com/grafana/grafana/pkg/bus" "github.com/grafana/grafana/pkg/login/social" + "github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/services/sqlstore" "github.com/grafana/grafana/pkg/infra/log" @@ -23,6 +24,7 @@ type UsageStatsService struct { Cfg *setting.Cfg `inject:""` Bus bus.Bus `inject:""` SQLStore *sqlstore.SqlStore `inject:""` + License models.Licensing `inject:""` oauthProviders map[string]bool } diff --git a/pkg/infra/usagestats/usage_stats.go b/pkg/infra/usagestats/usage_stats.go index 1c732ea3514..6670df60e30 100644 --- a/pkg/infra/usagestats/usage_stats.go +++ b/pkg/infra/usagestats/usage_stats.go @@ -32,7 +32,7 @@ func (uss *UsageStatsService) sendUsageStats(oauthProviders map[string]bool) { "metrics": metrics, "os": runtime.GOOS, "arch": runtime.GOARCH, - "edition": getEdition(), + "edition": getEdition(uss.License.HasValidLicense()), "packaging": setting.Packaging, } @@ -182,8 +182,8 @@ func (uss *UsageStatsService) updateTotalStats() { metrics.StatsTotalActiveAdmins.Set(float64(statsQuery.Result.ActiveAdmins)) } -func getEdition() string { - if setting.IsEnterprise { +func getEdition(validLicense bool) string { + if validLicense { return "enterprise" } return "oss" diff --git a/pkg/infra/usagestats/usage_stats_test.go b/pkg/infra/usagestats/usage_stats_test.go index 45876fa304e..39e44332b9f 100644 --- a/pkg/infra/usagestats/usage_stats_test.go +++ b/pkg/infra/usagestats/usage_stats_test.go @@ -25,6 +25,7 @@ func TestMetrics(t *testing.T) { uss := &UsageStatsService{ Bus: bus.New(), SQLStore: sqlstore.InitTestDB(t), + License: models.OSSLicensingService{}, } var getSystemStatsQuery *models.GetSystemStatsQuery diff --git a/pkg/models/licensing.go b/pkg/models/licensing.go new file mode 100644 index 00000000000..691b48c101a --- /dev/null +++ b/pkg/models/licensing.go @@ -0,0 +1,30 @@ +package models + +type Licensing interface { + // HasValidLicense is true if a valid license exists + HasValidLicense() bool + + // HasLicense is true if there is a license provided + HasLicense() bool + + // Expiry returns the unix epoch timestamp when the license expires, or 0 if no valid license is provided + Expiry() int64 +} + +type OSSLicensingService struct{} + +func (OSSLicensingService) HasLicense() bool { + return false +} + +func (OSSLicensingService) Expiry() int64 { + return 0 +} + +func (OSSLicensingService) Init() error { + return nil +} + +func (OSSLicensingService) HasValidLicense() bool { + return false +}