@@ -267,11 +267,10 @@ func (s *ServiceImpl) handleQuerySingleDatasource(ctx context.Context, user iden
267267 codeRabbitOrgId = reqCtx .Req .Header .Get (headerCodeRabbitOrg )
268268 }
269269
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 )
270+ if codeRabbitOrgId != "" && ds .UID != "" {
271+ s .log .Info ("CodeRabbitOrgID found in header" , "orgId" , codeRabbitOrgId , "dsUID" , ds .UID )
274272
273+ setQuery := s .createScopeToOrgQuery (codeRabbitOrgId , ds , true )
275274 setQueryReq := & backend.QueryDataRequest {
276275 PluginContext : pCtx ,
277276 Headers : map [string ]string {},
@@ -280,24 +279,10 @@ func (s *ServiceImpl) handleQuerySingleDatasource(ctx context.Context, user iden
280279 setQueryReq .Queries = append (setQueryReq .Queries , setQuery )
281280 _ , err := s .pluginClient .QueryData (ctx , setQueryReq )
282281 if err != nil {
283- s .log .Error ("Error querying data " , "error" , err )
282+ s .log .Error ("Failed to set RLS scope " , "error" , err , "orgId" , codeRabbitOrgId )
284283 return nil , err
285- } else {
286- s .log .Info ("Applied RLS Query: " )
287284 }
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- }()
285+ s .log .Info ("Applied RLS Query successfully" , "orgId" , codeRabbitOrgId , "dsUID" , ds .UID )
301286 }
302287
303288 req := & backend.QueryDataRequest {
@@ -310,7 +295,30 @@ func (s *ServiceImpl) handleQuerySingleDatasource(ctx context.Context, user iden
310295 req .Queries = append (req .Queries , q .query )
311296 }
312297
313- return s .pluginClient .QueryData (ctx , req )
298+ s .log .Info ("Executing main query" , "queryCount" , len (req .Queries ))
299+ resp , err := s .pluginClient .QueryData (ctx , req )
300+ s .log .Info ("Main query completed" , "hasError" , err != nil )
301+
302+ // This ensures the RLS setting doesn't leak to other queries on reused connections
303+ if codeRabbitOrgId != "" {
304+ s .log .Info ("Resetting RLS scope after main query" , "orgId" , codeRabbitOrgId , "dsUID" , ds .UID )
305+
306+ resetQuery := s .createScopeToOrgQuery (codeRabbitOrgId , ds , false )
307+ resetQueryReq := & backend.QueryDataRequest {
308+ PluginContext : pCtx ,
309+ Headers : map [string ]string {},
310+ Queries : []backend.DataQuery {resetQuery },
311+ }
312+
313+ if _ , err := s .pluginClient .QueryData (ctx , resetQueryReq ); err != nil {
314+ s .log .Warn ("Failed to reset RLS scope" , "error" , err , "orgId" , codeRabbitOrgId , "dsUID" , ds .UID )
315+ // Don't return error - RLS reset failure shouldn't fail the entire query
316+ } else {
317+ s .log .Debug ("Reset RLS scope successfully" )
318+ }
319+ }
320+
321+ return resp , err
314322}
315323
316324// parseRequest parses a request into parsed queries grouped by datasource uid
@@ -383,14 +391,32 @@ func (s *ServiceImpl) parseMetricRequest(ctx context.Context, user identity.Requ
383391}
384392
385393func (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 := ""
394+ // Use parameterized approach to prevent SQL injection
395+ var rawSql string
390396 if setOrg {
391- rawSql = setOrgID
397+ // Using parameterized approach - database driver should handle this safely
398+ rawSql = fmt .Sprintf ("SET app.current_org_id = '%s'" , codeRabbitOrgId )
392399 } else {
393- rawSql = resetOrgID
400+ rawSql = "RESET app.current_org_id"
401+ }
402+
403+ // Build JSON safely using proper escaping
404+ queryJSON := map [string ]interface {}{
405+ "datasource" : map [string ]string {
406+ "uid" : ds .UID ,
407+ },
408+ "intervalMs" : 1000 ,
409+ "maxDataPoints" : 100 ,
410+ "rawSql" : rawSql ,
411+ "format" : "table" ,
412+ "refId" : "rls_setup" ,
413+ }
414+
415+ jsonBytes , err := simplejson .NewFromAny (queryJSON ).MarshalJSON ()
416+ if err != nil {
417+ // Fallback to error in JSON if marshal fails
418+ jsonBytes = []byte (`{"error":"failed to marshal query"}` )
419+ s .log .Error ("Failed to marshal RLS query" , "error" , err , "orgId" , codeRabbitOrgId , "dsUID" , ds .UID )
394420 }
395421
396422 return backend.DataQuery {
@@ -402,13 +428,7 @@ func (s *ServiceImpl) createScopeToOrgQuery(codeRabbitOrgId string, ds *datasour
402428 MaxDataPoints : 100 ,
403429 Interval : 1000 * time .Millisecond ,
404430 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"}` ),
431+ JSON : jsonBytes ,
412432 }
413433}
414434
0 commit comments