mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Auth: Separate anonymous settings to its own struct (#97791)
separate anonymous settings to its own struct
This commit is contained in:
parent
fc7805957e
commit
40d3b02648
@ -157,7 +157,7 @@ func (hs *HTTPServer) getFrontendSettings(c *contextmodel.ReqContext) (*dtos.Fro
|
||||
}
|
||||
}
|
||||
|
||||
hideVersion := hs.Cfg.AnonymousHideVersion && !c.IsSignedIn
|
||||
hideVersion := hs.Cfg.Anonymous.HideVersion && !c.IsSignedIn
|
||||
version := setting.BuildVersion
|
||||
commit := setting.BuildCommit
|
||||
commitShort := getShortCommitHash(setting.BuildCommit, 10)
|
||||
@ -266,8 +266,8 @@ func (hs *HTTPServer) getFrontendSettings(c *contextmodel.ReqContext) (*dtos.Fro
|
||||
},
|
||||
|
||||
FeatureToggles: featureToggles,
|
||||
AnonymousEnabled: hs.Cfg.AnonymousEnabled,
|
||||
AnonymousDeviceLimit: hs.Cfg.AnonymousDeviceLimit,
|
||||
AnonymousEnabled: hs.Cfg.Anonymous.Enabled,
|
||||
AnonymousDeviceLimit: hs.Cfg.Anonymous.DeviceLimit,
|
||||
RendererAvailable: hs.RenderService.IsAvailable(c.Req.Context()),
|
||||
RendererVersion: hs.RenderService.Version(),
|
||||
RendererDefaultImageWidth: hs.Cfg.RendererDefaultImageWidth,
|
||||
|
@ -160,7 +160,7 @@ func TestHTTPServer_GetFrontendSettings_hideVersionAnonymous(t *testing.T) {
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.desc, func(t *testing.T) {
|
||||
hs.Cfg.AnonymousHideVersion = test.hideVersion
|
||||
hs.Cfg.Anonymous.HideVersion = test.hideVersion
|
||||
expected := test.expected
|
||||
|
||||
recorder := httptest.NewRecorder()
|
||||
|
@ -61,7 +61,7 @@ func TestHealthAPI_VersionEnterprise(t *testing.T) {
|
||||
|
||||
func TestHealthAPI_AnonymousHideVersion(t *testing.T) {
|
||||
m, hs := setupHealthAPITestEnvironment(t)
|
||||
hs.Cfg.AnonymousHideVersion = true
|
||||
hs.Cfg.Anonymous.HideVersion = true
|
||||
|
||||
req := httptest.NewRequest(http.MethodGet, "/api/health", nil)
|
||||
rec := httptest.NewRecorder()
|
||||
@ -80,7 +80,7 @@ func TestHealthAPI_DatabaseHealthy(t *testing.T) {
|
||||
const cacheKey = "db-healthy"
|
||||
|
||||
m, hs := setupHealthAPITestEnvironment(t)
|
||||
hs.Cfg.AnonymousHideVersion = true
|
||||
hs.Cfg.Anonymous.HideVersion = true
|
||||
|
||||
healthy, found := hs.CacheService.Get(cacheKey)
|
||||
require.False(t, found)
|
||||
@ -107,7 +107,7 @@ func TestHealthAPI_DatabaseUnhealthy(t *testing.T) {
|
||||
const cacheKey = "db-healthy"
|
||||
|
||||
m, hs := setupHealthAPITestEnvironment(t)
|
||||
hs.Cfg.AnonymousHideVersion = true
|
||||
hs.Cfg.Anonymous.HideVersion = true
|
||||
hs.SQLStore.(*dbtest.FakeDB).ExpectedError = errors.New("bad")
|
||||
|
||||
healthy, found := hs.CacheService.Get(cacheKey)
|
||||
@ -135,7 +135,7 @@ func TestHealthAPI_DatabaseHealthCached(t *testing.T) {
|
||||
const cacheKey = "db-healthy"
|
||||
|
||||
m, hs := setupHealthAPITestEnvironment(t)
|
||||
hs.Cfg.AnonymousHideVersion = true
|
||||
hs.Cfg.Anonymous.HideVersion = true
|
||||
|
||||
// Mock unhealthy database in cache.
|
||||
hs.CacheService.Set(cacheKey, false, 5*time.Minute)
|
||||
|
@ -716,7 +716,7 @@ func (hs *HTTPServer) apiHealthHandler(ctx *web.Context) {
|
||||
data := healthResponse{
|
||||
Database: "ok",
|
||||
}
|
||||
if !hs.Cfg.AnonymousHideVersion {
|
||||
if !hs.Cfg.Anonymous.HideVersion {
|
||||
data.Version = hs.Cfg.BuildVersion
|
||||
data.Commit = hs.Cfg.BuildCommit
|
||||
if hs.Cfg.EnterpriseBuildCommit != "NA" && hs.Cfg.EnterpriseBuildCommit != "" {
|
||||
|
@ -84,7 +84,7 @@ func TestMetrics(t *testing.T) {
|
||||
uss.Cfg = &setting.Cfg{
|
||||
ReportingEnabled: true,
|
||||
BuildVersion: "5.0.0",
|
||||
AnonymousEnabled: true,
|
||||
Anonymous: setting.AnonymousSettings{Enabled: true},
|
||||
BasicAuthEnabled: true,
|
||||
LDAPAuthEnabled: true,
|
||||
AuthProxy: setting.AuthProxySettings{Enabled: true},
|
||||
|
@ -139,7 +139,7 @@ func TestCollectingUsageStats(t *testing.T) {
|
||||
s := createService(t, &setting.Cfg{
|
||||
ReportingEnabled: true,
|
||||
BuildVersion: "5.0.0",
|
||||
AnonymousEnabled: true,
|
||||
Anonymous: setting.AnonymousSettings{Enabled: true},
|
||||
BasicAuthEnabled: true,
|
||||
LDAPAuthEnabled: true,
|
||||
AuthProxy: setting.AuthProxySettings{Enabled: true},
|
||||
|
@ -182,5 +182,5 @@ func getQuotaHandler(reached bool, target string) web.Handler {
|
||||
}
|
||||
|
||||
func configure(cfg *setting.Cfg) {
|
||||
cfg.AnonymousEnabled = false
|
||||
cfg.Anonymous.Enabled = false
|
||||
}
|
||||
|
@ -399,11 +399,11 @@ func rolePermissionsCollector(store db.DB) legacyTupleCollector {
|
||||
func anonymousRoleBindingsCollector(cfg *setting.Cfg, store db.DB) legacyTupleCollector {
|
||||
return func(ctx context.Context, orgID int64) (map[string]map[string]*openfgav1.TupleKey, error) {
|
||||
tuples := make(map[string]map[string]*openfgav1.TupleKey)
|
||||
object := zanzana.NewTupleEntry(zanzana.TypeRole, zanzana.TranslateBasicRole(cfg.AnonymousOrgRole), "")
|
||||
object := zanzana.NewTupleEntry(zanzana.TypeRole, zanzana.TranslateBasicRole(cfg.Anonymous.OrgRole), "")
|
||||
// Object should be set to delete obsolete permissions
|
||||
tuples[object] = make(map[string]*openfgav1.TupleKey)
|
||||
|
||||
o, err := getOrgByName(ctx, store, cfg.AnonymousOrgName)
|
||||
o, err := getOrgByName(ctx, store, cfg.Anonymous.OrgName)
|
||||
if err != nil {
|
||||
return tuples, nil
|
||||
}
|
||||
|
@ -93,7 +93,7 @@ func NewZanzanaReconciler(cfg *setting.Cfg, client zanzana.Client, store db.DB,
|
||||
},
|
||||
}
|
||||
|
||||
if cfg.AnonymousEnabled {
|
||||
if cfg.Anonymous.Enabled {
|
||||
zanzanaReconciler.reconcilers = append(zanzanaReconciler.reconcilers,
|
||||
newResourceReconciler(
|
||||
"anonymous role binding",
|
||||
|
@ -39,9 +39,9 @@ func (a *Anonymous) Name() string {
|
||||
}
|
||||
|
||||
func (a *Anonymous) Authenticate(ctx context.Context, r *authn.Request) (*authn.Identity, error) {
|
||||
o, err := a.orgService.GetByName(ctx, &org.GetOrgByNameQuery{Name: a.cfg.AnonymousOrgName})
|
||||
o, err := a.orgService.GetByName(ctx, &org.GetOrgByNameQuery{Name: a.cfg.Anonymous.OrgName})
|
||||
if err != nil {
|
||||
a.log.FromContext(ctx).Error("Failed to find organization", "name", a.cfg.AnonymousOrgName, "error", err)
|
||||
a.log.FromContext(ctx).Error("Failed to find organization", "name", a.cfg.Anonymous.OrgName, "error", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@ -64,7 +64,7 @@ func (a *Anonymous) Authenticate(ctx context.Context, r *authn.Request) (*authn.
|
||||
}
|
||||
|
||||
func (a *Anonymous) IsEnabled() bool {
|
||||
return a.cfg.AnonymousEnabled
|
||||
return a.cfg.Anonymous.Enabled
|
||||
}
|
||||
|
||||
func (a *Anonymous) Test(ctx context.Context, r *authn.Request) bool {
|
||||
@ -77,7 +77,7 @@ func (a *Anonymous) IdentityType() claims.IdentityType {
|
||||
}
|
||||
|
||||
func (a *Anonymous) ResolveIdentity(ctx context.Context, orgID int64, typ claims.IdentityType, id string) (*authn.Identity, error) {
|
||||
o, err := a.orgService.GetByName(ctx, &org.GetOrgByNameQuery{Name: a.cfg.AnonymousOrgName})
|
||||
o, err := a.orgService.GetByName(ctx, &org.GetOrgByNameQuery{Name: a.cfg.Anonymous.OrgName})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -99,7 +99,7 @@ func (a *Anonymous) UsageStatFn(ctx context.Context) (map[string]any, error) {
|
||||
|
||||
// Add stats about anonymous auth
|
||||
m["stats.anonymous.customized_role.count"] = 0
|
||||
if !strings.EqualFold(a.cfg.AnonymousOrgRole, "Viewer") {
|
||||
if !strings.EqualFold(a.cfg.Anonymous.OrgRole, "Viewer") {
|
||||
m["stats.anonymous.customized_role.count"] = 1
|
||||
}
|
||||
|
||||
@ -116,7 +116,7 @@ func (a *Anonymous) newAnonymousIdentity(o *org.Org) *authn.Identity {
|
||||
Type: claims.TypeAnonymous,
|
||||
OrgID: o.ID,
|
||||
OrgName: o.Name,
|
||||
OrgRoles: map[int64]org.RoleType{o.ID: org.RoleType(a.cfg.AnonymousOrgRole)},
|
||||
OrgRoles: map[int64]org.RoleType{o.ID: org.RoleType(a.cfg.Anonymous.OrgRole)},
|
||||
ClientParams: authn.ClientParams{SyncPermissions: true},
|
||||
}
|
||||
}
|
||||
|
@ -30,16 +30,20 @@ func TestAnonymous_Authenticate(t *testing.T) {
|
||||
desc: "should success with valid org configured",
|
||||
org: &org.Org{ID: 1, Name: "some org"},
|
||||
cfg: &setting.Cfg{
|
||||
AnonymousOrgName: "some org",
|
||||
AnonymousOrgRole: "Viewer",
|
||||
Anonymous: setting.AnonymousSettings{
|
||||
OrgRole: "Viewer",
|
||||
OrgName: "some org",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "should return error if any error occurs during org lookup",
|
||||
err: fmt.Errorf("some error"),
|
||||
cfg: &setting.Cfg{
|
||||
AnonymousOrgName: "some org",
|
||||
AnonymousOrgRole: "Viewer",
|
||||
Anonymous: setting.AnonymousSettings{
|
||||
OrgRole: "Viewer",
|
||||
OrgName: "some org",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
@ -63,7 +67,7 @@ func TestAnonymous_Authenticate(t *testing.T) {
|
||||
assert.Equal(t, "anonymous:0", user.GetID())
|
||||
assert.Equal(t, tt.org.ID, user.OrgID)
|
||||
assert.Equal(t, tt.org.Name, user.OrgName)
|
||||
assert.Equal(t, tt.cfg.AnonymousOrgRole, string(user.GetOrgRole()))
|
||||
assert.Equal(t, tt.cfg.Anonymous.OrgRole, string(user.GetOrgRole()))
|
||||
}
|
||||
})
|
||||
}
|
||||
@ -86,7 +90,9 @@ func TestAnonymous_ResolveIdentity(t *testing.T) {
|
||||
desc: "should return error when org id is not the configured one",
|
||||
org: &org.Org{ID: 2, Name: "some org"},
|
||||
cfg: &setting.Cfg{
|
||||
AnonymousOrgName: "some org",
|
||||
Anonymous: setting.AnonymousSettings{
|
||||
OrgName: "some org",
|
||||
},
|
||||
},
|
||||
orgID: 1,
|
||||
typ: claims.TypeAnonymous,
|
||||
@ -97,7 +103,9 @@ func TestAnonymous_ResolveIdentity(t *testing.T) {
|
||||
desc: "should return error when namespace id does not match anonymous namespace id",
|
||||
org: &org.Org{ID: 1, Name: "some org"},
|
||||
cfg: &setting.Cfg{
|
||||
AnonymousOrgName: "some org",
|
||||
Anonymous: setting.AnonymousSettings{
|
||||
OrgName: "some org",
|
||||
},
|
||||
},
|
||||
orgID: 1,
|
||||
typ: claims.TypeAnonymous,
|
||||
@ -108,7 +116,9 @@ func TestAnonymous_ResolveIdentity(t *testing.T) {
|
||||
desc: "should resolve identity",
|
||||
org: &org.Org{ID: 1, Name: "some org"},
|
||||
cfg: &setting.Cfg{
|
||||
AnonymousOrgName: "some org",
|
||||
Anonymous: setting.AnonymousSettings{
|
||||
OrgName: "some org",
|
||||
},
|
||||
},
|
||||
orgID: 1,
|
||||
typ: claims.TypeAnonymous,
|
||||
|
@ -45,7 +45,7 @@ func ProvideAnonymousDeviceService(usageStats usagestats.Service, authBroker aut
|
||||
a := &AnonDeviceService{
|
||||
log: log.New("anonymous-session-service"),
|
||||
localCache: localcache.New(29*time.Minute, 15*time.Minute),
|
||||
anonStore: anonstore.ProvideAnonDBStore(sqlStore, cfg.AnonymousDeviceLimit),
|
||||
anonStore: anonstore.ProvideAnonDBStore(sqlStore, cfg.Anonymous.DeviceLimit),
|
||||
serverLock: serverLockService,
|
||||
cfg: cfg,
|
||||
limitValidator: validator,
|
||||
@ -60,7 +60,7 @@ func ProvideAnonymousDeviceService(usageStats usagestats.Service, authBroker aut
|
||||
anonDeviceService: a,
|
||||
}
|
||||
|
||||
if cfg.AnonymousEnabled {
|
||||
if cfg.Anonymous.Enabled {
|
||||
authBroker.RegisterClient(anonClient)
|
||||
authBroker.RegisterPostLoginHook(a.untagDevice, 100)
|
||||
}
|
||||
@ -171,7 +171,7 @@ func (a *AnonDeviceService) TagDevice(ctx context.Context, httpReq *http.Request
|
||||
|
||||
// ListDevices returns all devices that have been updated between the given times.
|
||||
func (a *AnonDeviceService) ListDevices(ctx context.Context, from *time.Time, to *time.Time) ([]*anonstore.Device, error) {
|
||||
if !a.cfg.AnonymousEnabled {
|
||||
if !a.cfg.Anonymous.Enabled {
|
||||
a.log.Debug("Anonymous access is disabled, returning empty result")
|
||||
return []*anonstore.Device{}, nil
|
||||
}
|
||||
@ -181,7 +181,7 @@ func (a *AnonDeviceService) ListDevices(ctx context.Context, from *time.Time, to
|
||||
|
||||
// CountDevices returns the number of devices that have been updated between the given times.
|
||||
func (a *AnonDeviceService) CountDevices(ctx context.Context, from time.Time, to time.Time) (int64, error) {
|
||||
if !a.cfg.AnonymousEnabled {
|
||||
if !a.cfg.Anonymous.Enabled {
|
||||
a.log.Debug("Anonymous access is disabled, returning empty result")
|
||||
return 0, nil
|
||||
}
|
||||
@ -190,7 +190,7 @@ func (a *AnonDeviceService) CountDevices(ctx context.Context, from time.Time, to
|
||||
}
|
||||
|
||||
func (a *AnonDeviceService) SearchDevices(ctx context.Context, query *anonstore.SearchDeviceQuery) (*anonstore.SearchDeviceQueryResult, error) {
|
||||
if !a.cfg.AnonymousEnabled {
|
||||
if !a.cfg.Anonymous.Enabled {
|
||||
a.log.Debug("Anonymous access is disabled, returning empty result")
|
||||
return nil, nil
|
||||
}
|
||||
|
@ -259,7 +259,7 @@ func TestIntegrationDeviceService_SearchDevice(t *testing.T) {
|
||||
}
|
||||
store := db.InitTestDB(t)
|
||||
cfg := setting.NewCfg()
|
||||
cfg.AnonymousEnabled = true
|
||||
cfg.Anonymous.Enabled = true
|
||||
anonService := ProvideAnonymousDeviceService(&usagestats.UsageStatsMock{}, &authntest.FakeService{}, store, cfg, orgtest.NewOrgServiceFake(), nil, actest.FakeAccessControl{}, &routing.RouteRegisterImpl{}, validator.FakeAnonUserLimitValidator{})
|
||||
|
||||
for _, tc := range testCases {
|
||||
@ -291,7 +291,7 @@ func TestIntegrationAnonDeviceService_DeviceLimitWithCache(t *testing.T) {
|
||||
// Setup test environment
|
||||
store := db.InitTestDB(t)
|
||||
cfg := setting.NewCfg()
|
||||
cfg.AnonymousDeviceLimit = 1 // Set device limit to 1 for testing
|
||||
cfg.Anonymous.DeviceLimit = 1 // Set device limit to 1 for testing
|
||||
anonService := ProvideAnonymousDeviceService(
|
||||
&usagestats.UsageStatsMock{},
|
||||
&authntest.FakeService{},
|
||||
|
@ -14,7 +14,7 @@ func (s *Service) getUsageStats(ctx context.Context) (map[string]any, error) {
|
||||
authTypes["basic_auth"] = s.cfg.BasicAuthEnabled
|
||||
authTypes["ldap"] = s.cfg.LDAPAuthEnabled
|
||||
authTypes["auth_proxy"] = s.cfg.AuthProxy.Enabled
|
||||
authTypes["anonymous"] = s.cfg.AnonymousEnabled
|
||||
authTypes["anonymous"] = s.cfg.Anonymous.Enabled
|
||||
authTypes["jwt"] = s.cfg.JWTAuth.Enabled
|
||||
authTypes["grafana_password"] = !s.cfg.DisableLogin
|
||||
authTypes["login_form"] = !s.cfg.DisableLoginForm
|
||||
|
@ -189,7 +189,7 @@ func (s *ServiceImpl) GetNavTree(c *contextmodel.ReqContext, prefs *pref.Prefere
|
||||
|
||||
func (s *ServiceImpl) getHomeNode(c *contextmodel.ReqContext, prefs *pref.Preference) *navtree.NavLink {
|
||||
homeUrl := s.cfg.AppSubURL + "/"
|
||||
if !c.IsSignedIn && !s.cfg.AnonymousEnabled {
|
||||
if !c.IsSignedIn && !s.cfg.Anonymous.Enabled {
|
||||
homeUrl = s.cfg.AppSubURL + "/login"
|
||||
} else {
|
||||
homePage := s.cfg.HomePage
|
||||
|
@ -155,18 +155,18 @@ func (s *StandardSearchService) getUser(ctx context.Context, backendUser *backen
|
||||
// TODO: get user & user's permissions from the request context
|
||||
|
||||
var usr *user.SignedInUser
|
||||
if s.cfg.AnonymousEnabled && backendUser.Email == "" && backendUser.Login == "" {
|
||||
getOrg := org.GetOrgByNameQuery{Name: s.cfg.AnonymousOrgName}
|
||||
if s.cfg.Anonymous.Enabled && backendUser.Email == "" && backendUser.Login == "" {
|
||||
getOrg := org.GetOrgByNameQuery{Name: s.cfg.Anonymous.OrgName}
|
||||
orga, err := s.orgService.GetByName(ctx, &getOrg)
|
||||
if err != nil {
|
||||
s.logger.Error("Anonymous access organization error.", "org_name", s.cfg.AnonymousOrgName, "error", err)
|
||||
s.logger.Error("Anonymous access organization error.", "org_name", s.cfg.Anonymous.OrgName, "error", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
usr = &user.SignedInUser{
|
||||
OrgID: orga.ID,
|
||||
OrgName: orga.Name,
|
||||
OrgRole: org.RoleType(s.cfg.AnonymousOrgRole),
|
||||
OrgRole: org.RoleType(s.cfg.Anonymous.OrgRole),
|
||||
IsAnonymous: true,
|
||||
}
|
||||
} else {
|
||||
|
@ -302,11 +302,7 @@ type Cfg struct {
|
||||
// Deprecated: use featuremgmt.FeatureFlags
|
||||
IsFeatureToggleEnabled func(key string) bool // filled in dynamically
|
||||
|
||||
AnonymousEnabled bool
|
||||
AnonymousOrgName string
|
||||
AnonymousOrgRole string
|
||||
AnonymousHideVersion bool
|
||||
AnonymousDeviceLimit int64
|
||||
Anonymous AnonymousSettings
|
||||
|
||||
DateFormats DateFormats
|
||||
|
||||
@ -1654,12 +1650,7 @@ func readAuthSettings(iniFile *ini.File, cfg *Cfg) (err error) {
|
||||
}
|
||||
|
||||
// anonymous access
|
||||
anonSection := iniFile.Section("auth.anonymous")
|
||||
cfg.AnonymousEnabled = anonSection.Key("enabled").MustBool(false)
|
||||
cfg.AnonymousOrgName = valueAsString(anonSection, "org_name", "")
|
||||
cfg.AnonymousOrgRole = valueAsString(anonSection, "org_role", "")
|
||||
cfg.AnonymousHideVersion = anonSection.Key("hide_version").MustBool(false)
|
||||
cfg.AnonymousDeviceLimit = anonSection.Key("device_limit").MustInt64(0)
|
||||
cfg.readAnonymousSettings()
|
||||
|
||||
// basic auth
|
||||
authBasic := iniFile.Section("auth.basic")
|
||||
|
21
pkg/setting/setting_anonymous.go
Normal file
21
pkg/setting/setting_anonymous.go
Normal file
@ -0,0 +1,21 @@
|
||||
package setting
|
||||
|
||||
type AnonymousSettings struct {
|
||||
Enabled bool
|
||||
OrgName string
|
||||
OrgRole string
|
||||
HideVersion bool
|
||||
DeviceLimit int64
|
||||
}
|
||||
|
||||
func (cfg *Cfg) readAnonymousSettings() {
|
||||
anonSection := cfg.Raw.Section("auth.anonymous")
|
||||
|
||||
anonSettings := AnonymousSettings{}
|
||||
anonSettings.Enabled = anonSection.Key("enabled").MustBool(false)
|
||||
anonSettings.OrgName = valueAsString(anonSection, "org_name", "")
|
||||
anonSettings.OrgRole = valueAsString(anonSection, "org_role", "")
|
||||
anonSettings.HideVersion = anonSection.Key("hide_version").MustBool(false)
|
||||
anonSettings.DeviceLimit = anonSection.Key("device_limit").MustInt64(0)
|
||||
cfg.Anonymous = anonSettings
|
||||
}
|
Loading…
Reference in New Issue
Block a user