Anonymous User: Adds validator service for anonymous users (#94700)

This commit is contained in:
lean.dev 2024-10-18 13:10:41 -03:00 committed by GitHub
parent fd5f351a6f
commit 3438196010
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 63 additions and 15 deletions

View File

@ -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,

View File

@ -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
}

View File

@ -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

View File

@ -0,0 +1,12 @@
package validator
import "context"
type FakeAnonUserLimitValidator struct {
}
var _ AnonUserLimitValidator = (*FakeAnonUserLimitValidator)(nil)
func (f FakeAnonUserLimitValidator) Validate(_ context.Context) error {
return nil
}

View File

@ -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
}