cube icon indicating copy to clipboard operation
cube copied to clipboard

Add ability to look at cube meta during queryRewrite

Open rccoe opened this issue 4 years ago • 10 comments

Is your feature request related to a problem? Please describe. When setting up row-level permissions, I want to make sure that any query on a cube with a tenant id dimension is re-written to filter for that tenant ID

Describe the solution you'd like The queryRewrite function should be passed a parameter that lists out all cubes and allows to inspect the dimensions + measures on those cubes

Describe alternatives you've considered The alternative is maintaining a list of cubes manually. This gets tedious especially when extending cubes.

rccoe avatar Feb 17 '22 21:02 rccoe

Hi @rccoe ! Could you add an example that should work better for your case, please? I'd love to take a look at how you have right now and what will be an ideal implementation.

ivan-vdovin avatar Mar 30 '22 18:03 ivan-vdovin

For example, 50% of my cubes have a field tenantId dimension that needs to always be filtered by the security context. Not all cubes have tenantId.

What I would like is to be able to, at query time, determine if any cubes being queried have a tenantId dimension and, if so, add a filter for it to match the tenant-id coming from the JWT/headers.

Example cubes

cube(`Product`, {
  sql: `
    SELECT * FROM product
  `,
  refreshKey: {
  },
  preAggregations: {},
  joins: {
    },
  },
  measures: {},
  dimensions: {
    productId: {
      sql: `product_id`,
      type: `number`,
    },
    tenantId: {
      sql: `tenant_id`,
      type: `number`,
    },
  },
});
cube(`Label`, {
  sql: `
    SELECT * FROM label
  `,
  refreshKey: {
  },
  preAggregations: {},
  joins: {
    },
  },
  measures: {},
  dimensions: {
    labelId: {
      sql: `label_id`,
      type: `number`,
    },
    tenantId: {
      sql: `tenant_id`,
      type: `number`,
    },
  },
});
// Doesn't have tenantId
cube(`Building`, {
  sql: `
    SELECT * FROM building
  `,
  refreshKey: {
  },
  preAggregations: {},
  joins: {
    },
  },
  measures: {},
  dimensions: {
    buildingId: {
      sql: `building_id`,
      type: `number`,
    },
  },
});

For the above cubes, there's no way that I can determine which ones to add a tenantId filter to without hardcoding them in the queryRewrite code

rccoe avatar Mar 31 '22 19:03 rccoe

Another example: I'd like to look at the dataSource field for cubes for the dimensions, measures, and filters that are passed at query time to manipulate the query

rccoe avatar Apr 27 '22 00:04 rccoe

If you are interested in working on this issue, please leave a comment below and we will be happy to assign the issue to you. If this is the first time you are contributing a Pull Request to Cube.js, please check our contribution guidelines. You can also post any questions while contributing in the #contributors channel in the Cube.js Slack.

github-actions[bot] avatar Apr 28 '22 09:04 github-actions[bot]

Yes, has anyone found a solution to this yet?

jinyung-tan avatar Jul 11 '24 09:07 jinyung-tan

Also trying to figure this out. What I tried so far was to write a js function like, that looks at the models defined on the models folder and checks if a certain dimension exists within a cube (this is quite hacky though I hope there is a better way of doing this)

// Checks if a certain cube contains a given dimension. Returns a boolean
// folder is the folder where all the models are
function checkIfDimensionExists(cubeName, dimension, folder) {
  for (const file of fs.readdirSync(folder).filter(f => f.endsWith(".yml"))) {

    // Load yaml file
    const yamlCubes = yaml.load(fs.readFileSync(path.join(folder, file), 'utf8'))['cubes']

    // Check if the dimension exists
    for (const cube of yamlCubes) {

      if ((cube.name === cubeName) && cube.dimensions.filter(d => d.name === dimension).length > 0) {
        return true
      }
    }
  }
  return false
}

djrmarques avatar Aug 29 '24 13:08 djrmarques

@rccoe since this is an older issue, did you end up finding a solution for this? We are dealing with a situation that is very similar to what you described. Thanks :)

djrmarques avatar Aug 29 '24 14:08 djrmarques

No, never got it fixed and never got attention from the Cube team. Instead we decided to stop using cube :)

On Thu, Aug 29, 2024 at 10:26 djrmarques @.***> wrote:

@rccoe https://github.com/rccoe since this is an older issue, did you end up finding a solution for this? We are dealing with a situation that is very similar to what you described. Thanks :)

— Reply to this email directly, view it on GitHub https://github.com/cube-js/cube/issues/4118#issuecomment-2317870387, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAOE6D7F4E4K6FL7LNQ52J3ZT4VSRAVCNFSM6AAAAABKWQ3CISVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDGMJXHA3TAMZYG4 . You are receiving this because you were mentioned.Message ID: @.***>

rccoe avatar Aug 29 '24 14:08 rccoe

@djrmarques This is a valid use case and a feature proposal, however, it's not currently on the roadmap.

There are many ways to implement this in your own configuration. One of them would be, instead of running those checkIfDimensionExists checks in runtime, just inspect your data model once and generate a query_rewrite function (or a configuration that your query rewrite function would use).

In the end, you can probably just fetch from the /meta endpoint when Cube starts up and use the metadata for your checks. It would do exactly what you want.

igorlukanin avatar Aug 29 '24 14:08 igorlukanin

Thank you for the response :). I was looking through the api docs, somehow I missed this /meta endpoint. But maybe your first suggestion makes even more sense, I will try it out. Once again thanks.

djrmarques avatar Aug 29 '24 15:08 djrmarques

No, never got it fixed and never got attention from the Cube team. Instead we decided to stop using cube :) … On Thu, Aug 29, 2024 at 10:26 djrmarques @.> wrote: @rccoe https://github.com/rccoe since this is an older issue, did you end up finding a solution for this? We are dealing with a situation that is very similar to what you described. Thanks :) — Reply to this email directly, view it on GitHub <#4118 (comment)>, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAOE6D7F4E4K6FL7LNQ52J3ZT4VSRAVCNFSM6AAAAABKWQ3CISVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDGMJXHA3TAMZYG4 . You are receiving this because you were mentioned.Message ID: @.>

What alternative you started using instead of cube?

kunalfermat avatar Dec 23 '24 13:12 kunalfermat