Skip to content

Support JsonPath union operator #4914

@lsmor

Description

@lsmor

Problem

The current implementation of JsonPath does not allow for union operator [,] in its full form: only array indices are allowed. Such operator is part of the RFC9535. The idea is that you can specify different keys in you jwt-role-claim-key and pick the first match.

Here there is an example in the JSONPath Online Evaluator. The example shows the syntax and the results

What's the use case?

If you have multiple Identity providers, they could send the role in different claims. It is not clear to me how you handle such a situation. Currently I was able to put a custom claim in both IdP's because I have permissions to do so, but that's not true always.

Solution

For example, in your config file you could have

# proposed syntax
jwt-role-claim-key=".[role,userinfo.role]" 

That will search for role claim, and if fails will search for useinfo.role. I am bearly familiar with Pgrst codebase, but I think the implementation should be something in the line of:

-- module PostgREST.Config.JSPath
-- Completely untested code
type JSPath = [JSPathExp]

data JSPathExp
  = JSPKey Text                      -- .property or ."property-dash"
  | JSPIdx Int                       -- [0]
  | JSPSlice (Maybe Int) (Maybe Int) -- [0:5] or [0:] or [:5] or [:]
  | JSPFilter FilterExp              -- [?(@ == "match")]
  | JSPUnion [JSPath]   -- <<<NEW>>> An union is a list of JSPaths (notice the nested list because of JSPath)


-- <<<NEW>>> Parser for the union case
pJSPUnion :: P.Parser JSPathExp
pJSPUnion = do
  P.char '['
  inner <- P.many1 pJSPKey `P.sepBy` ','
  P.char ']'
  return (JSPUnion inner ) <?> "pJSPUnion: JSPath union operator"

-- <<NEW>> the walk for the new case. Something tells me is a simple usage of the Alternative instance of Maybe
walkJSPath jsonObj (JSPUnion jpaths:rest) = asum $  fmap (walkJSPath jsonObj)  jpaths -- apply walkJSPath to all and take the first Just value

-- Other things should be implemented as well

The above is far from a real implementation, but moreless you can have an idea.

Metadata

Metadata

Assignees

Labels

breaking changeA bug fix or enhancement that would cause a breaking changeconfigrelated to the configuration options
No fields configured for Feature.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions