From 01b3000b093f721ab5bbe445e1c88438f0e35ac6 Mon Sep 17 00:00:00 2001 From: Alexander Zobnin Date: Tue, 3 Sep 2024 13:27:24 +0200 Subject: [PATCH] Search with check --- pkg/services/dashboards/service/zanzana.go | 72 +++++++++++++++++++++- pkg/setting/settings_zanzana.go | 3 + 2 files changed, 74 insertions(+), 1 deletion(-) diff --git a/pkg/services/dashboards/service/zanzana.go b/pkg/services/dashboards/service/zanzana.go index 9a3f45a2e50..fb43b97ef04 100644 --- a/pkg/services/dashboards/service/zanzana.go +++ b/pkg/services/dashboards/service/zanzana.go @@ -3,7 +3,9 @@ package service import ( "context" "fmt" + "strconv" "strings" + "sync" "time" openfgav1 "github.com/openfga/api/proto/openfga/v1" @@ -67,7 +69,14 @@ func (dr *DashboardServiceImpl) FindDashboardsZanzanaCompare(ctx context.Context } func (dr *DashboardServiceImpl) FindDashboardsZanzana(ctx context.Context, query *dashboards.FindPersistedDashboardsQuery) ([]dashboards.DashboardSearchProjection, error) { - ctx, span := tracer.Start(ctx, "dashboards.service.FindDashboardsZanzana") + if len(query.Title) > 8 { + return dr.FindDashboardsZanzanaCheck(ctx, query) + } + return dr.FindDashboardsZanzanaList(ctx, query) +} + +func (dr *DashboardServiceImpl) FindDashboardsZanzanaList(ctx context.Context, query *dashboards.FindPersistedDashboardsQuery) ([]dashboards.DashboardSearchProjection, error) { + ctx, span := tracer.Start(ctx, "dashboards.service.FindDashboardsZanzanaList") defer span.End() res, err := dr.acService.ListObjects(ctx, &openfgav1.ListObjectsRequest{ @@ -97,3 +106,64 @@ func (dr *DashboardServiceImpl) FindDashboardsZanzana(ctx context.Context, query query.SkipAccessControlFilter = true return dr.dashboardStore.FindDashboards(ctx, query) } + +func (dr *DashboardServiceImpl) FindDashboardsZanzanaCheck(ctx context.Context, query *dashboards.FindPersistedDashboardsQuery) ([]dashboards.DashboardSearchProjection, error) { + query.SkipAccessControlFilter = true + findRes, err := dr.dashboardStore.FindDashboards(ctx, query) + if err != nil { + return nil, err + } + + orgId := query.OrgId + if orgId == 0 && query.SignedInUser.GetOrgID() != 0 { + orgId = query.SignedInUser.GetOrgID() + } + + concurrentRequests := dr.cfg.Zanzana.ConcurrentChecks + res := make([]dashboards.DashboardSearchProjection, 0) + resToCheck := make(chan dashboards.DashboardSearchProjection, concurrentRequests) + allowedResults := make(chan dashboards.DashboardSearchProjection, len(findRes)) + errChan := make(chan error, len(findRes)) + var wg sync.WaitGroup + for i := 0; i < int(concurrentRequests); i++ { + wg.Add(1) + go func() { + defer wg.Done() + for d := range resToCheck { + objectType := zanzana.TypeDashboard + if d.IsFolder { + objectType = zanzana.TypeFolder + } + object := zanzana.NewScopedTupleEntry(objectType, d.UID, "", strconv.FormatInt(orgId, 10)) + key := &openfgav1.CheckRequestTupleKey{ + User: query.SignedInUser.GetUID(), + Relation: "read", + Object: object, + } + + checkRes, err := dr.acService.Check(ctx, &openfgav1.CheckRequest{ + TupleKey: key, + }) + if err != nil { + errChan <- err + dr.log.Error("error checking access", "error", err) + } else if checkRes.Allowed { + allowedResults <- d + } + } + }() + } + + for _, r := range findRes { + resToCheck <- r + } + close(resToCheck) + + wg.Wait() + close(allowedResults) + for r := range allowedResults { + res = append(res, r) + } + + return res, nil +} diff --git a/pkg/setting/settings_zanzana.go b/pkg/setting/settings_zanzana.go index fd692cd32b1..50a2966e3ed 100644 --- a/pkg/setting/settings_zanzana.go +++ b/pkg/setting/settings_zanzana.go @@ -20,6 +20,8 @@ type ZanzanaSettings struct { ListenHTTP bool // OpenFGA http server address which allows to connect with fga cli HttpAddr string + // Number of check requests running concurrently + ConcurrentChecks int64 } func (cfg *Cfg) readZanzanaSettings() { @@ -38,6 +40,7 @@ func (cfg *Cfg) readZanzanaSettings() { s.Addr = sec.Key("address").MustString("") s.ListenHTTP = sec.Key("listen_http").MustBool(false) s.HttpAddr = sec.Key("http_addr").MustString("127.0.0.1:8080") + s.ConcurrentChecks = sec.Key("concurrent_checks").MustInt64(10) cfg.Zanzana = s }