Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 9f51b61

Browse files
scoping query using rls (#194)
* scoping query using rls * fixed log
1 parent f633be4 commit 9f51b61

File tree

1 file changed

+71
-0
lines changed

1 file changed

+71
-0
lines changed

‎pkg/services/query/query.go

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ const (
3636
HeaderPanelPluginId = "X-Panel-Plugin-Id"
3737
HeaderQueryGroupID = "X-Query-Group-Id" // mainly useful for finding related queries with query chunking
3838
HeaderFromExpression = "X-Grafana-From-Expr" // used by datasources to identify expression queries
39+
headerCodeRabbitOrg = "X-CodeRabbit-Org-Id" // used by CodeRabbit Org Id use to set Row Level Security to scope queries to org
3940
)
4041

4142
func ProvideService(
@@ -259,6 +260,46 @@ func (s *ServiceImpl) handleQuerySingleDatasource(ctx context.Context, user iden
259260
if err != nil {
260261
return nil, err
261262
}
263+
264+
codeRabbitOrgId := ""
265+
reqCtx := contexthandler.FromContext(ctx)
266+
if reqCtx != nil && reqCtx.Req != nil {
267+
codeRabbitOrgId = reqCtx.Req.Header.Get(headerCodeRabbitOrg)
268+
}
269+
270+
if codeRabbitOrgId != "" {
271+
s.log.Info("CodeRabbitOrgID found in header")
272+
setQuery := s.createScopeToOrgQuery(codeRabbitOrgId, ds, true)
273+
resetQuery := s.createScopeToOrgQuery(codeRabbitOrgId, ds, false)
274+
275+
setQueryReq := &backend.QueryDataRequest{
276+
PluginContext: pCtx,
277+
Headers: map[string]string{},
278+
Queries: []backend.DataQuery{},
279+
}
280+
setQueryReq.Queries = append(setQueryReq.Queries, setQuery)
281+
_, err := s.pluginClient.QueryData(ctx, setQueryReq)
282+
if err != nil {
283+
s.log.Error("Error querying data", "error", err)
284+
return nil, err
285+
} else {
286+
s.log.Info("Applied RLS Query: ")
287+
}
288+
289+
defer func() {
290+
resetQueryReq := &backend.QueryDataRequest{
291+
PluginContext: pCtx,
292+
Headers: map[string]string{},
293+
Queries: []backend.DataQuery{},
294+
}
295+
resetQueryReq.Queries = append(resetQueryReq.Queries, resetQuery)
296+
_, err := s.pluginClient.QueryData(ctx, resetQueryReq)
297+
if err != nil {
298+
s.log.Error("Error querying data", "error", err)
299+
}
300+
}()
301+
}
302+
262303
req := &backend.QueryDataRequest{
263304
PluginContext: pCtx,
264305
Headers: map[string]string{},
@@ -341,6 +382,36 @@ func (s *ServiceImpl) parseMetricRequest(ctx context.Context, user identity.Requ
341382
return req, req.validateRequest(ctx)
342383
}
343384

385+
func (s *ServiceImpl) createScopeToOrgQuery(codeRabbitOrgId string, ds *datasources.DataSource, setOrg bool) backend.DataQuery {
386+
setOrgID := fmt.Sprintf("SET app.current_org_id = '%s'", codeRabbitOrgId)
387+
resetOrgID := "RESET app.current_org_id"
388+
389+
rawSql := ""
390+
if setOrg {
391+
rawSql = setOrgID
392+
} else {
393+
rawSql = resetOrgID
394+
}
395+
396+
return backend.DataQuery{
397+
TimeRange: backend.TimeRange{
398+
From: time.Now().Add(-time.Hour),
399+
To: time.Now(),
400+
},
401+
RefID: "rls_setup",
402+
MaxDataPoints: 100,
403+
Interval: 1000 * time.Millisecond,
404+
QueryType: rawSql,
405+
JSON: []byte(`{
406+
"datasource": {"uid": "` + ds.UID + `"},
407+
"intervalMs": 1000,
408+
"maxDataPoints": 100,
409+
"rawSql": "` + rawSql + `",
410+
"format": "table",
411+
"refId": "rls_setup"}`),
412+
}
413+
}
414+
344415
func (s *ServiceImpl) getDataSourceFromQuery(ctx context.Context, user identity.Requester, skipDSCache bool, query *simplejson.Json, history map[string]*datasources.DataSource) (*datasources.DataSource, error) {
345416
var err error
346417
uid := query.Get("datasource").Get("uid").MustString()

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /