From 2e81653b685d8c195faf1ed6246d229187ed4086 Mon Sep 17 00:00:00 2001 From: "grafana-delivery-bot[bot]" <132647405+grafana-delivery-bot[bot]@users.noreply.github.com> Date: Tue, 22 Oct 2024 09:26:00 -0300 Subject: [PATCH] [v11.3.x] Anonymous User: Adds validator service for anonymous users (#94994) Anonymous User: Adds validator service for anonymous users (#94700) (cherry picked from commit 343819601075d9dbad474b7c044845a8730ab9bb) Co-authored-by: lean.dev <34773040+leandro-deveikis@users.noreply.github.com> --- pkg/server/wireexts_oss.go | 3 ++ pkg/services/anonymous/anonimpl/impl.go | 32 ++++++++++++-------- pkg/services/anonymous/anonimpl/impl_test.go | 8 +++-- pkg/services/anonymous/validator/fake.go | 12 ++++++++ pkg/services/anonymous/validator/service.go | 23 ++++++++++++++ 5 files changed, 63 insertions(+), 15 deletions(-) create mode 100644 pkg/services/anonymous/validator/fake.go create mode 100644 pkg/services/anonymous/validator/service.go diff --git a/pkg/server/wireexts_oss.go b/pkg/server/wireexts_oss.go index 3d97c42aafd..7f9b5756da8 100644 --- a/pkg/server/wireexts_oss.go +++ b/pkg/server/wireexts_oss.go @@ -18,6 +18,7 @@ import ( "github.com/grafana/grafana/pkg/services/accesscontrol/ossaccesscontrol" "github.com/grafana/grafana/pkg/services/anonymous" "github.com/grafana/grafana/pkg/services/anonymous/anonimpl" + "github.com/grafana/grafana/pkg/services/anonymous/validator" "github.com/grafana/grafana/pkg/services/apiserver/standalone" "github.com/grafana/grafana/pkg/services/auth" "github.com/grafana/grafana/pkg/services/auth/authimpl" @@ -54,6 +55,8 @@ var wireExtsBasicSet = wire.NewSet( authimpl.ProvideUserAuthTokenService, wire.Bind(new(auth.UserTokenService), new(*authimpl.UserAuthTokenService)), wire.Bind(new(auth.UserTokenBackgroundService), new(*authimpl.UserAuthTokenService)), + validator.ProvideAnonUserLimitValidator, + wire.Bind(new(validator.AnonUserLimitValidator), new(*validator.AnonUserLimitValidatorImpl)), anonimpl.ProvideAnonymousDeviceService, wire.Bind(new(anonymous.Service), new(*anonimpl.AnonDeviceService)), licensing.ProvideService, diff --git a/pkg/services/anonymous/anonimpl/impl.go b/pkg/services/anonymous/anonimpl/impl.go index c0105441d62..1ddc6b19942 100644 --- a/pkg/services/anonymous/anonimpl/impl.go +++ b/pkg/services/anonymous/anonimpl/impl.go @@ -17,6 +17,7 @@ import ( "github.com/grafana/grafana/pkg/services/anonymous" "github.com/grafana/grafana/pkg/services/anonymous/anonimpl/anonstore" "github.com/grafana/grafana/pkg/services/anonymous/anonimpl/api" + "github.com/grafana/grafana/pkg/services/anonymous/validator" "github.com/grafana/grafana/pkg/services/authn" "github.com/grafana/grafana/pkg/services/org" "github.com/grafana/grafana/pkg/setting" @@ -28,23 +29,26 @@ const deviceIDHeader = "X-Grafana-Device-Id" const keepFor = time.Hour * 24 * 61 type AnonDeviceService struct { - log log.Logger - localCache *localcache.CacheService - anonStore anonstore.AnonStore - serverLock *serverlock.ServerLockService - cfg *setting.Cfg + log log.Logger + localCache *localcache.CacheService + anonStore anonstore.AnonStore + serverLock *serverlock.ServerLockService + cfg *setting.Cfg + limitValidator validator.AnonUserLimitValidator } func ProvideAnonymousDeviceService(usageStats usagestats.Service, authBroker authn.Service, sqlStore db.DB, cfg *setting.Cfg, orgService org.Service, serverLockService *serverlock.ServerLockService, accesscontrol accesscontrol.AccessControl, routeRegister routing.RouteRegister, + validator validator.AnonUserLimitValidator, ) *AnonDeviceService { a := &AnonDeviceService{ - log: log.New("anonymous-session-service"), - localCache: localcache.New(29*time.Minute, 15*time.Minute), - anonStore: anonstore.ProvideAnonDBStore(sqlStore, cfg.AnonymousDeviceLimit), - serverLock: serverLockService, - cfg: cfg, + log: log.New("anonymous-session-service"), + localCache: localcache.New(29*time.Minute, 15*time.Minute), + anonStore: anonstore.ProvideAnonDBStore(sqlStore, cfg.AnonymousDeviceLimit), + serverLock: serverLockService, + cfg: cfg, + limitValidator: validator, } usageStats.RegisterMetricsFunc(a.usageStatFn) @@ -81,6 +85,11 @@ func (a *AnonDeviceService) usageStatFn(ctx context.Context) (map[string]any, er } func (a *AnonDeviceService) tagDeviceUI(ctx context.Context, device *anonstore.Device) error { + err := a.limitValidator.Validate(ctx) + if err != nil { + return err + } + key := device.CacheKey() if val, ok := a.localCache.Get(key); ok { @@ -109,8 +118,7 @@ func (a *AnonDeviceService) tagDeviceUI(ctx context.Context, device *anonstore.D return nil } -func (a *AnonDeviceService) untagDevice(ctx context.Context, - identity *authn.Identity, r *authn.Request, err error) { +func (a *AnonDeviceService) untagDevice(ctx context.Context, _ *authn.Identity, r *authn.Request, err error) { if err != nil { return } diff --git a/pkg/services/anonymous/anonimpl/impl_test.go b/pkg/services/anonymous/anonimpl/impl_test.go index b193d22edb6..d60a9345874 100644 --- a/pkg/services/anonymous/anonimpl/impl_test.go +++ b/pkg/services/anonymous/anonimpl/impl_test.go @@ -15,6 +15,7 @@ import ( "github.com/grafana/grafana/pkg/services/accesscontrol/actest" "github.com/grafana/grafana/pkg/services/anonymous" "github.com/grafana/grafana/pkg/services/anonymous/anonimpl/anonstore" + "github.com/grafana/grafana/pkg/services/anonymous/validator" "github.com/grafana/grafana/pkg/services/authn/authntest" "github.com/grafana/grafana/pkg/services/org/orgtest" "github.com/grafana/grafana/pkg/setting" @@ -123,7 +124,7 @@ func TestIntegrationDeviceService_tag(t *testing.T) { t.Run(tc.name, func(t *testing.T) { store := db.InitTestDB(t) anonService := ProvideAnonymousDeviceService(&usagestats.UsageStatsMock{}, - &authntest.FakeService{}, store, setting.NewCfg(), orgtest.NewOrgServiceFake(), nil, actest.FakeAccessControl{}, &routing.RouteRegisterImpl{}) + &authntest.FakeService{}, store, setting.NewCfg(), orgtest.NewOrgServiceFake(), nil, actest.FakeAccessControl{}, &routing.RouteRegisterImpl{}, validator.FakeAnonUserLimitValidator{}) for _, req := range tc.req { err := anonService.TagDevice(context.Background(), req.httpReq, req.kind) @@ -161,7 +162,7 @@ func TestIntegrationAnonDeviceService_localCacheSafety(t *testing.T) { } store := db.InitTestDB(t) anonService := ProvideAnonymousDeviceService(&usagestats.UsageStatsMock{}, - &authntest.FakeService{}, store, setting.NewCfg(), orgtest.NewOrgServiceFake(), nil, actest.FakeAccessControl{}, &routing.RouteRegisterImpl{}) + &authntest.FakeService{}, store, setting.NewCfg(), orgtest.NewOrgServiceFake(), nil, actest.FakeAccessControl{}, &routing.RouteRegisterImpl{}, validator.FakeAnonUserLimitValidator{}) req := &http.Request{ Header: http.Header{ @@ -259,7 +260,7 @@ func TestIntegrationDeviceService_SearchDevice(t *testing.T) { store := db.InitTestDB(t) cfg := setting.NewCfg() cfg.AnonymousEnabled = true - anonService := ProvideAnonymousDeviceService(&usagestats.UsageStatsMock{}, &authntest.FakeService{}, store, cfg, orgtest.NewOrgServiceFake(), nil, actest.FakeAccessControl{}, &routing.RouteRegisterImpl{}) + anonService := ProvideAnonymousDeviceService(&usagestats.UsageStatsMock{}, &authntest.FakeService{}, store, cfg, orgtest.NewOrgServiceFake(), nil, actest.FakeAccessControl{}, &routing.RouteRegisterImpl{}, validator.FakeAnonUserLimitValidator{}) for _, tc := range testCases { err := store.Reset() @@ -300,6 +301,7 @@ func TestIntegrationAnonDeviceService_DeviceLimitWithCache(t *testing.T) { nil, actest.FakeAccessControl{}, &routing.RouteRegisterImpl{}, + validator.FakeAnonUserLimitValidator{}, ) // Define test cases diff --git a/pkg/services/anonymous/validator/fake.go b/pkg/services/anonymous/validator/fake.go new file mode 100644 index 00000000000..c6a90a8b50b --- /dev/null +++ b/pkg/services/anonymous/validator/fake.go @@ -0,0 +1,12 @@ +package validator + +import "context" + +type FakeAnonUserLimitValidator struct { +} + +var _ AnonUserLimitValidator = (*FakeAnonUserLimitValidator)(nil) + +func (f FakeAnonUserLimitValidator) Validate(_ context.Context) error { + return nil +} diff --git a/pkg/services/anonymous/validator/service.go b/pkg/services/anonymous/validator/service.go new file mode 100644 index 00000000000..ea312288920 --- /dev/null +++ b/pkg/services/anonymous/validator/service.go @@ -0,0 +1,23 @@ +package validator + +import ( + "context" +) + +type AnonUserLimitValidator interface { + Validate(ctx context.Context) error +} + +// AnonUserLimitValidatorImpl is used to validate the limit of Anonymous user +type AnonUserLimitValidatorImpl struct { +} + +var _ AnonUserLimitValidator = (*AnonUserLimitValidatorImpl)(nil) + +func ProvideAnonUserLimitValidator() *AnonUserLimitValidatorImpl { + return &AnonUserLimitValidatorImpl{} +} + +func (a AnonUserLimitValidatorImpl) Validate(_ context.Context) error { + return nil +}