Commit 80e9546c by Emil Tullstedt Committed by GitHub

Settings: Add setting for hiding version number for anonymous users (#24919)

* Settings: Add setting for hiding version number for anonymous users

Fixes #12925

* Hide version string from footer when unavailable

* Settings: Test frontend settings with hide version for anonymous users

* Settings: Add hide version variable to frontend settings

* Make AnonymousHideVersion non-global

Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>

* Settings: Improve test neighbor friendliness, reset state before and after

* Settings: Use T.Cleanup

Co-authored-by: Arve Knudsen <arve.knudsen@gmail.com>
parent 370791d5
...@@ -315,6 +315,9 @@ org_name = Main Org. ...@@ -315,6 +315,9 @@ org_name = Main Org.
# specify role for unauthenticated users # specify role for unauthenticated users
org_role = Viewer org_role = Viewer
# mask the Grafana version number for unauthenticated users
hide_version = false
#################################### Github Auth ######################### #################################### Github Auth #########################
[auth.github] [auth.github]
enabled = false enabled = false
......
...@@ -314,6 +314,9 @@ ...@@ -314,6 +314,9 @@
# specify role for unauthenticated users # specify role for unauthenticated users
;org_role = Viewer ;org_role = Viewer
# mask the Grafana version number for unauthenticated users
;hide_version = false
#################################### Github Auth ########################## #################################### Github Auth ##########################
[auth.github] [auth.github]
;enabled = false ;enabled = false
......
...@@ -20,6 +20,7 @@ export interface BuildInfo { ...@@ -20,6 +20,7 @@ export interface BuildInfo {
edition: string; edition: string;
latestVersion: string; latestVersion: string;
hasUpdate: boolean; hasUpdate: boolean;
hideVersion: boolean;
} }
/** /**
......
...@@ -167,6 +167,17 @@ func (hs *HTTPServer) getFrontendSettingsMap(c *models.ReqContext) (map[string]i ...@@ -167,6 +167,17 @@ func (hs *HTTPServer) getFrontendSettingsMap(c *models.ReqContext) (map[string]i
} }
} }
hideVersion := hs.Cfg.AnonymousHideVersion && !c.IsSignedIn
version := setting.BuildVersion
commit := setting.BuildCommit
buildstamp := setting.BuildStamp
if hideVersion {
version = ""
commit = ""
buildstamp = 0
}
jsonObj := map[string]interface{}{ jsonObj := map[string]interface{}{
"defaultDatasource": defaultDatasource, "defaultDatasource": defaultDatasource,
"datasources": datasources, "datasources": datasources,
...@@ -197,9 +208,10 @@ func (hs *HTTPServer) getFrontendSettingsMap(c *models.ReqContext) (map[string]i ...@@ -197,9 +208,10 @@ func (hs *HTTPServer) getFrontendSettingsMap(c *models.ReqContext) (map[string]i
"disableSanitizeHtml": hs.Cfg.DisableSanitizeHtml, "disableSanitizeHtml": hs.Cfg.DisableSanitizeHtml,
"pluginsToPreload": pluginsToPreload, "pluginsToPreload": pluginsToPreload,
"buildInfo": map[string]interface{}{ "buildInfo": map[string]interface{}{
"version": setting.BuildVersion, "hideVersion": hideVersion,
"commit": setting.BuildCommit, "version": version,
"buildstamp": setting.BuildStamp, "commit": commit,
"buildstamp": buildstamp,
"edition": hs.License.Edition(), "edition": hs.License.Edition(),
"latestVersion": plugins.GrafanaLatestVersion, "latestVersion": plugins.GrafanaLatestVersion,
"hasUpdate": plugins.GrafanaHasUpdate, "hasUpdate": plugins.GrafanaHasUpdate,
......
package api
import (
"encoding/json"
"net/http"
"net/http/httptest"
"path"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/grafana/grafana/pkg/services/rendering"
"github.com/grafana/grafana/pkg/services/licensing"
"github.com/grafana/grafana/pkg/bus"
"github.com/grafana/grafana/pkg/services/sqlstore"
"github.com/grafana/grafana/pkg/middleware"
"gopkg.in/macaron.v1"
"github.com/grafana/grafana/pkg/setting"
)
func setupTestEnvironment(t *testing.T, cfg *setting.Cfg) (*macaron.Macaron, *HTTPServer) {
t.Helper()
sqlstore.InitTestDB(t)
{
oldVersion := setting.BuildVersion
oldCommit := setting.BuildCommit
oldEnv := setting.Env
t.Cleanup(func() {
setting.BuildVersion = oldVersion
setting.BuildCommit = oldCommit
setting.Env = oldEnv
})
}
bus.ClearBusHandlers()
bus.AddHandler("sql", sqlstore.GetPluginSettings)
t.Cleanup(bus.ClearBusHandlers)
r := &rendering.RenderingService{Cfg: cfg}
hs := &HTTPServer{
Cfg: cfg,
Bus: bus.GetBus(),
License: &licensing.OSSLicensingService{},
RenderService: r,
}
m := macaron.New()
m.Use(middleware.GetContextHandler(nil, nil, nil))
m.Use(macaron.Renderer(macaron.RenderOptions{
Directory: path.Join(setting.StaticRootPath, "views"),
IndentJSON: true,
Delims: macaron.Delims{Left: "[[", Right: "]]"},
}))
m.Get("/api/frontend/settings/", hs.GetFrontendSettings)
return m, hs
}
func TestHTTPServer_GetFrontendSettings_hideVersionAnonyomus(t *testing.T) {
type buildInfo struct {
Version string `json:"version"`
Commit string `json:"commit"`
Env string `json:"env"`
}
type settings struct {
BuildInfo buildInfo `json:"buildInfo"`
}
cfg := setting.NewCfg()
m, hs := setupTestEnvironment(t, cfg)
req := httptest.NewRequest(http.MethodGet, "/api/frontend/settings", nil)
setting.BuildVersion = "7.8.9"
setting.BuildCommit = "01234567"
setting.Env = "testing"
tests := []struct {
hideVersion bool
expected settings
}{
{
hideVersion: false,
expected: settings{
BuildInfo: buildInfo{
Version: setting.BuildVersion,
Commit: setting.BuildCommit,
Env: setting.Env,
},
},
},
{
hideVersion: true,
expected: settings{
BuildInfo: buildInfo{
Version: "",
Commit: "",
Env: setting.Env,
},
},
},
}
for _, test := range tests {
hs.Cfg.AnonymousHideVersion = test.hideVersion
expected := test.expected
recorder := httptest.NewRecorder()
m.ServeHTTP(recorder, req)
got := settings{}
err := json.Unmarshal(recorder.Body.Bytes(), &got)
require.NoError(t, err)
require.GreaterOrEqual(t, 400, recorder.Code, "status codes higher than 400 indicates a failure")
assert.EqualValues(t, expected, got)
}
}
...@@ -4,13 +4,14 @@ import ( ...@@ -4,13 +4,14 @@ import (
"context" "context"
"crypto/tls" "crypto/tls"
"fmt" "fmt"
"github.com/grafana/grafana/pkg/services/search"
"net" "net"
"net/http" "net/http"
"os" "os"
"path" "path"
"sync" "sync"
"github.com/grafana/grafana/pkg/services/search"
"github.com/grafana/grafana/pkg/plugins/backendplugin" "github.com/grafana/grafana/pkg/plugins/backendplugin"
"github.com/grafana/grafana/pkg/api/live" "github.com/grafana/grafana/pkg/api/live"
...@@ -351,8 +352,10 @@ func (hs *HTTPServer) healthHandler(ctx *macaron.Context) { ...@@ -351,8 +352,10 @@ func (hs *HTTPServer) healthHandler(ctx *macaron.Context) {
data := simplejson.New() data := simplejson.New()
data.Set("database", "ok") data.Set("database", "ok")
data.Set("version", setting.BuildVersion) if !hs.Cfg.AnonymousHideVersion {
data.Set("commit", setting.BuildCommit) data.Set("version", setting.BuildVersion)
data.Set("commit", setting.BuildCommit)
}
if err := bus.Dispatch(&models.GetDBHealthQuery{}); err != nil { if err := bus.Dispatch(&models.GetDBHealthQuery{}); err != nil {
data.Set("database", "failing") data.Set("database", "failing")
......
...@@ -360,9 +360,14 @@ func (hs *HTTPServer) setIndexViewData(c *models.ReqContext) (*dtos.IndexViewDat ...@@ -360,9 +360,14 @@ func (hs *HTTPServer) setIndexViewData(c *models.ReqContext) (*dtos.IndexViewDat
}) })
} }
helpVersion := fmt.Sprintf(`%s v%s (%s)`, setting.ApplicationName, setting.BuildVersion, setting.BuildCommit)
if hs.Cfg.AnonymousHideVersion && !c.IsSignedIn {
helpVersion = setting.ApplicationName
}
data.NavTree = append(data.NavTree, &dtos.NavLink{ data.NavTree = append(data.NavTree, &dtos.NavLink{
Text: "Help", Text: "Help",
SubTitle: fmt.Sprintf(`%s v%s (%s)`, setting.ApplicationName, setting.BuildVersion, setting.BuildCommit), SubTitle: helpVersion,
Id: "help", Id: "help",
Url: "#", Url: "#",
Icon: "question-circle", Icon: "question-circle",
......
...@@ -296,6 +296,8 @@ type Cfg struct { ...@@ -296,6 +296,8 @@ type Cfg struct {
// Use to enable new features which may still be in alpha/beta stage. // Use to enable new features which may still be in alpha/beta stage.
FeatureToggles map[string]bool FeatureToggles map[string]bool
AnonymousHideVersion bool
} }
// IsExpressionsEnabled returns whether the expressions feature is enabled. // IsExpressionsEnabled returns whether the expressions feature is enabled.
...@@ -873,6 +875,7 @@ func (cfg *Cfg) Load(args *CommandLineArgs) error { ...@@ -873,6 +875,7 @@ func (cfg *Cfg) Load(args *CommandLineArgs) error {
if err != nil { if err != nil {
return err return err
} }
cfg.AnonymousHideVersion = iniFile.Section("auth.anonymous").Key("hide_version").MustBool(false)
// auth proxy // auth proxy
authProxy := iniFile.Section("auth.proxy") authProxy := iniFile.Section("auth.proxy")
......
...@@ -38,6 +38,11 @@ export let getVersionLinks = (): FooterLink[] => { ...@@ -38,6 +38,11 @@ export let getVersionLinks = (): FooterLink[] => {
const stateInfo = licenseInfo.stateInfo ? ` (${licenseInfo.stateInfo})` : ''; const stateInfo = licenseInfo.stateInfo ? ` (${licenseInfo.stateInfo})` : '';
links.push({ text: `${buildInfo.edition}${stateInfo}`, url: licenseInfo.licenseUrl }); links.push({ text: `${buildInfo.edition}${stateInfo}`, url: licenseInfo.licenseUrl });
if (buildInfo.hideVersion) {
return links;
}
links.push({ text: `v${buildInfo.version} (${buildInfo.commit})` }); links.push({ text: `v${buildInfo.version} (${buildInfo.commit})` });
if (buildInfo.hasUpdate) { if (buildInfo.hasUpdate) {
......
...@@ -70,13 +70,10 @@ export const HomeLink: FC<HomeLinkProps> = ({ title, url, target, icon }) => { ...@@ -70,13 +70,10 @@ export const HomeLink: FC<HomeLinkProps> = ({ title, url, target, icon }) => {
export const VersionFooter: FC = () => { export const VersionFooter: FC = () => {
const styles = getStyles(); const styles = getStyles();
const { version, commit } = config.buildInfo; const { hideVersion, version, commit } = config.buildInfo;
const versionString = hideVersion ? '' : `Version ${version} (${commit})`;
return ( return <div className={styles.footer}>{versionString}</div>;
<div className={styles.footer}>
Version {version} ({commit})
</div>
);
}; };
export const getStyles = stylesFactory(() => { export const getStyles = stylesFactory(() => {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment