Showme
Dynamic APIs are integral to how users interact with data. GraphGrid Showmes allow developers to create their own APIs using only Geequel. In this tutorial you will learn the basics of Showmes using ONgDB's movie dataset. We recommend completing the Movie Database tutorial before moving on to this one. The Movie Database tutorial teaches you how to make your own graph using ONgDB's movie dataset, and how to visualize it in the Dashboard. We'll be using those basics in this tutorial.
Showme Module Tutorial Overview
/getMoviesByYear
Showme- Create a Showme called
getMoviesByYear
. - Execute the
/getMoviesByYear
Showme.
- Create a Showme called
/shortestPath
Showme- Create a Showme called
shortestPath
- Execute the
shortestPath
Showme.
- Create a Showme called
- Add a Showme to the Dashboard.
Create a Showme
/getMoviesByYear
Let's make a Showme that will create an endpoint that will allow a user to return a list of movies released in a certain year. Now that we have defined what we want our endpoint to do, we need to answer the following questions:
What query will need to be run to access the data that we need?
We know that we'll need to query nodes with a
Movie
label that match the value of the parameterreleased
. We can pass in this Geequel into our request:
MATCH (m:Movie {released:$released}) RETURN m
What is the method of this request?
Since we are retrieving information from the database the method for this endpoint will be a
GET
request.
What do we want to name our path?
/getMoviesByYear
sounds good!
What parameters will we need to include and/or require in this request?
In order for this request to be successful we need to include in our params
released
as a key.
The entire /createShowme
request including the body we created will look like this:
You can use either the /createShowme
and /updateShowme
to create a Showme. Just note that for /updateShowme
has slightly different parameters.
Instead of nodeTypeGrns
and params
/updateShowme
uses addNodeTypeGrns
and addParams
.
curl --location --request POST "${API_BASE}/1.0/showme/createShowme" \
--header "Authorization: Bearer ${BEARER_TOKEN}" \
--header 'Content-Type: application/json' \
--data-raw '
{
"cypher": "MATCH (m:Movie {released:$released}) RETURN m",
"showmeMethod": "GET",
"showmePath": "/getMoviesByYear",
"showmeDisplayValue": "getMoviesByYear",
"showmeDefinition": "Returns a list of movies released in a specific year",
"showmePopulatorDisplayValue": "getMoviesByYear",
"showmePopulatorDefinition": "getMoviesByYear",
"nodeTypeGrns": [],
"params": {
"released": ""
},
"requiredParams": [],
"cypherOrder": 0,
"overrideCypherOrder": false
}'
And the response will look like this:
{
"showme": {
"id": 66,
"labels": [],
"enver": 0,
"createdAt": "2021-04-27T16:43:33.164Z",
"updatedAt": "2021-04-27T16:43:33.164Z",
"createdBy": "graphgrid",
"lastModifiedBy": "graphgrid",
"grn": "grn:gg:graphgridshowme:HrT9QxjdnnVoV0owQODCnD00zrPHuyul4cTjmXypWWp1",
"key": "GET /getMoviesByYear",
"method": "GET",
"path": "/getMoviesByYear",
"definition": "Returns a list of movies released in a specific year",
"displayValue": "getMoviesByYear",
"order": null,
"disableUserRoleRequirement": null,
"nodeTypes": [],
"showmePopulator": {
"id": 65,
"labels": [],
"enver": 0,
"createdAt": "2021-04-27T16:43:33.152Z",
"updatedAt": "2021-04-27T16:43:33.179Z",
"createdBy": "graphgrid",
"lastModifiedBy": "graphgrid",
"grn":"grn:gg:graphgridshowmepopulator:3Bb7MPFpJ5xtHh6nsYL2YMjVAJQsRfwxjSIz820WWRKI",
"cypher": "MATCH (m:Movie {released:$released}) RETURN m",
"displayValue": "getMoviesByYear",
"definition": "getMoviesByYear",
"requiredParameters": [],
"searchQuery": null,
"successRoutes": [],
"failureRoutes": [],
"conditionalSuccessRoutes": [],
"conditionalFailureRoutes": [],
"parameters": [
{
"id": 305,
"labels": [],
"enver": 0,
"createdAt": "2021-04-27T16:43:33.154Z",
"updatedAt": "2021-04-27T16:43:33.154Z",
"createdBy": "graphgrid",
"lastModifiedBy": "graphgrid",
"grn": "grn:gg:graphgridshowmeparameter:sizHGDyypOprw1pkn3UccpdqAzhJyzjM07NyGY5wMIAA",
"type": "java.util.LinkedHashMap",
"key": "released",
"value": "{}",
"encryption": null,
"grnType": "graphgridshowmeparameter",
"label": "GraphGridShowmeParameter"
}
],
"snippets": [],
"snippetImpls": null,
"cypherOrder": 0,
"grnType": "graphgridshowmepopulator",
"label": "GraphGridShowmePopulator"
},
"securityRules": null,
"grnType": "graphgridshowme",
"label": "GraphGridShowme"
},
"showmePopulator": {
"id": 65,
"labels": [],
"enver": 0,
"createdAt": "2021-04-27T16:43:33.152Z",
"updatedAt": "2021-04-27T16:43:33.179Z",
"createdBy": "graphgrid",
"lastModifiedBy": "graphgrid",
"grn": "grn:gg:graphgridshowmepopulator:3Bb7MPFpJ5xtHh6nsYL2YMjVAJQsRfwxjSIz820WWRKI",
"cypher": "MATCH (m:Movie {released:$released}) RETURN m",
"displayValue": "getMoviesByYear",
"definition": "getMoviesByYear",
"requiredParameters": [],
"searchQuery": null,
"successRoutes": [],
"failureRoutes": [],
"conditionalSuccessRoutes": [],
"conditionalFailureRoutes": [],
"parameters": [
{
"id": 305,
"labels": [],
"enver": 0,
"createdAt": "2021-04-27T16:43:33.154Z",
"updatedAt": "2021-04-27T16:43:33.154Z",
"createdBy": "graphgrid",
"lastModifiedBy": "graphgrid",
"grn": "grn:gg:graphgridshowmeparameter:sizHGDyypOprw1pkn3UccpdqAzhJyzjM07NyGY5wMIAA",
"type": "java.util.LinkedHashMap",
"key": "released",
"value": "{}",
"encryption": null,
"grnType": "graphgridshowmeparameter",
"label": "GraphGridShowmeParameter"
}
],
"snippets": [],
"snippetImpls": null,
"cypherOrder": 0,
"grnType": "graphgridshowmepopulator",
"label": "GraphGridShowmePopulator"
}
}
/executeShowme/getMoviesByYear
Now we can see our newly created endpoint in action by executing the Showme.
Run this request passing in the path of our Showme /getMoviesByYear
and our params {"released":1999}
. This /executeShowme
request
should return the results for the key "released" that has a value of 1999.
Parameters must be URL encoded for GET
requests.
curl --location --request GET "${API_BASE}/1.0/showme/executeShowme/getMoviesByYear?params=%7B%22released%22%3A1999%7D" \
--header "Authorization: Bearer ${BEARER_TOKEN}"
Our response shows a list of movies that were released in 1999:
{
"results": [
{
"m": {
"labels": [
"Resource",
"Movie",
"GraphGridResource"
],
"id": 18,
"properties": {
"createdAt": "2021-04-26T20:19:55+00:00",
"grn": "grn:gg:movie:HCzJLaDkzJL3EvkGHMBIwDHxmb6xKPSshu9DLihqNuaI",
"lastSearchIndexedAt": "0",
"tagline": "One robot's 200 year journey to become an ordinary man.",
"title": "Bicentennial Man",
"released": 1999,
"updatedAt": "2021-04-26T20:19:55+00:00"
}
}
},
{
"m": {
"labels": [
"Resource",
"Movie",
"GraphGridResource"
],
"id": 46,
"properties": {
"createdAt": "2021-04-26T20:19:55+00:00",
"grn": "grn:gg:movie:ryRIh16x7oMFrkf9IX9Xx70HLyR8unhm8cXOvEDbZIBY",
"lastSearchIndexedAt": "0",
"tagline": "Walk a mile you'll never forget.",
"title": "The Green Mile",
"released": 1999,
"updatedAt": "2021-04-26T20:19:55+00:00"
}
}
},
{
"m": {
"labels": [
"Resource",
"Movie",
"GraphGridResource"
],
"id": 103,
"properties": {
"createdAt": "2021-04-26T20:19:55+00:00",
"grn": "grn:gg:movie:pHwiHrVucvcsifSO2A58X6QiCYdvkiA4SSaFSdCXFD1d",
"lastSearchIndexedAt": "0",
"tagline": "Welcome to the Real World",
"title": "The Matrix",
"released": 1999,
"updatedAt": "2021-04-26T20:19:55+00:00"
}
}
},
{
"m": {
"labels": [
"Resource",
"Movie",
"GraphGridResource"
],
"id": 165,
"properties": {
"createdAt": "2021-04-26T20:19:55+00:00",
"grn": "grn:gg:movie:0mTK8k4FJ6Nrl9sPNVVTbdHIqPQgyOynYUX9Tr727VH7",
"lastSearchIndexedAt": "0",
"tagline": "First loves last. Forever.",
"title": "Snow Falling on Cedars",
"released": 1999,
"updatedAt": "2021-04-26T20:19:55+00:00"
}
}
}
],
"bookmark": "neo4j:bookmark:v1:tx2175",
"errors": []
}
/shortestPath
This Showme example is a bit more advanced, but presents just how much Showmes can be customized to handle your data to get interesting
insights! The /shortestPath
Showme will take in two parameters of two person nodes. The Showme will return the shortest path through
edgeType relationships between them.
The Geequel query we need to run to get the shortest path between two nodes will looks like this:
MATCH (p1:Person) WHERE p1.grn = {firstPersonGrn} MATCH (p2:Person) WHERE p2.grn = {secondPersonGrn} MATCH p=allShortestPaths((p1)-[*]-(p2)) WHERE NONE(n IN nodes(p) WHERE n:Version) WITH nodes(p) AS shortestPathNodes UNWIND shortestPathNodes AS shortestPathNode RETURN COLLECT(shortestPathNode.grn) AS nodeIds
This query sets two parameters: firstPersonGrn
and secondPersonGrn
and uses all edgeTypes to find the shortest path between them.
Here's the full create Showme request:
curl --location --request PUT "${API_BASE}/1.0/showme/updateShowme/shortestPath" \
--header 'Content-Type: application/json' \
--header "Authorization: Bearer ${BEARER_TOKEN}" \
--data-raw '{
"cypher": "MATCH (p1:Person) WHERE p1.grn = {firstPersonGrn} MATCH (p2:Person) WHERE p2.grn = {secondPersonGrn} MATCH p=allShortestPaths((p1)-[*]-(p2)) WHERE NONE(n IN nodes(p) WHERE n:Version) WITH nodes(p) AS shortestPathNodes UNWIND shortestPathNodes AS shortestPathNode RETURN COLLECT(shortestPathNode.grn) AS nodeIds",
"showmeMethod": "GET",
"showmePath": "/shortestPath",
"showmeDisplayValue": "shortestPath",
"showmeDefinition": "shortest path between two people",
"showmePopulatorDisplayValue": "shortestPath",
"showmePopulatorDefinition": "shortestPath",
"addNodeTypeGrns": [],
"addParams": {
"firstPersonGrn": "",
"secondPersonGrn": ""
},
"requiredParams": ["firstPersonGrn","secondPersonGrn"],
"cypherOrder": 0,
"overrideCypherOrder": false
}
'
/executeShowme/shortestPath
Let's see our Showme in action! Run the /executeShowme request with URL encoded params for firstPersonGrn
and secondPersonGrn
. This
request queries the shortest path between Keanu Reeves and Al Pacino.
curl --location --request GET "${API_BASE}/1.0/showme/executeShowme/shortestPath?params=%7B%22firstPersonGrn%22%3A%22grn%3Agg%3Aperson%3AVd0D6CdJ4T3RmkYhyCAneDFEX5WJWU9H1P450TsPXhT9%22%2C%20%22secondPersonGrn%22%3A%22grn%3Agg%3Aperson%3ApKMmKbKTseEGadwaM3EYOBrvKlTJpr5ICctdnfNYv4DP%22%7D" \
--header "Authorization: Bearer ${BEARER_TOKEN}"
Response:
{
"results": [{
"shortestPathNodes": [{
"labels": [
"Resource",
"Person",
"GraphGridResource"
],
"id": 355,
"properties": {
"createdAt": "2021-04-28T21:52:29+00:00",
"grn":"grn:gg:person:Vd0D6CdJ4T3RmkYhyCAneDFEX5WJWU9H1P450TsPXhT9",
"lastSearchIndexedAt": "0",
"born": 1940,
"name": "Al Pacino",
"updatedAt": "2021-04-28T21:52:29+00:00"
}
},
{
"labels": [
"Resource",
"Movie",
"GraphGridResource"
],
"id": 353,
"properties": {
"createdAt": "2021-04-28T21:52:29+00:00",
"grn": "grn:gg:movie:pO3MA539rBvsA4LXU26G0tFHm1vUDfznq1P3gksl6YeI",
"lastSearchIndexedAt": "0",
"tagline": "Evil has its winning ways",
"title": "The Devil's Advocate",
"released": 1997,
"updatedAt": "2021-04-28T21:52:29+00:00"
}
},
{
"labels": [
"Resource",
"Person",
"GraphGridResource"
],
"id": 343,
"properties": {
"createdAt": "2021-04-28T21:52:29+00:00",
"grn":
"grn:gg:person:pKMmKbKTseEGadwaM3EYOBrvKlTJpr5ICctdnfNYv4DP",
"lastSearchIndexedAt": "0",
"born": 1964,
"name": "Keanu Reeves",
"updatedAt": "2021-04-28T21:52:29+00:00"
}
}
]
}],
"bookmark": "neo4j:bookmark:v1:tx6495",
"errors": []
}
The response returns the shortest path between our two person nodes, which is that they both acted in "The Devil's Advocate." We can see and use our Showmes through the GraphGrid Dashboard. Now that we know more about the API calls, let's get a Showme working in the dashboard!
Showmes in The Dashboard
Getting Showmes to appear in the GraphGrid Dashboard takes some setup through GraphGrid Manager Models. A manager model shows what nodes, relationships, and properties are allowed and how they can be structured.
Setup Steps
These are the steps required to display a Showme in the dashboard:
Generate a Manager Model Policy
Get Manager Grn
Generate a Manager Model Graph
Create getNodeTypeGrns Showme
Execute getNodeTypeGrns Showme
Create your custom Showme
Generate a Manager Model Policy
A ManagerModelPolicy (MMP) is a JSON policy which is used to generate the NodeType, EdgeType, Property, PropertyImpl, and versioning
nodes of a manager model.
For our Movie Database we want to include the Movie and Person node labels.
curl --location --request POST "${API_BASE}/1.0/manager/model/policy/default/generateManagerPolicy/default-manager-model-policy" \
--header 'Content-Type: application/json' \
--header "Authorization: Bearer ${BEARER_TOKEN}" \
--data-raw '{
"includeLabels":
[
"Person",
"Movie"
],
"excludeRelationships":[]
}'
Generate a Manager Model Graph
Using our manager model policy and our manager node, we need to generate a manager model graph. This request essentially prepares our
manager model policy to set up parameters that are required for the graph to recognize our nodetypes. The name of our manager model
policy and our manager grn are required parameters for this request. This request requires the manager node grn. The default manager node grn is grn:gg:manager:default
If you are using a different manager version with a different node, you can retrieve its grn by using this Manager endpoint to retrieve it by its name.
curl --location --request POST "${API_BASE}/1.0/manager/model/policy/generateManagerModelGraph/default/default-manager-model-policy/grn:gg:manager:default' \
--header 'Content-Type: application/json" \
--header "Authorization: Bearer ${BEARER_TOKEN}"
Add NodeType Grns to a Showme
Next we'll need to grab the nodeTypeGrns
for both Person
and Movie
nodes. To do this we can run these this query in ONgDB (remember that ONgDB can be acces in the browser at port 7474
):
MATCH (a:NodeType {key:"Person"}) MATCH (b:NodeType {key: "Movie"}) RETURN a.grn, b.grn
Next we'll need to copy these two grns. These can be added to any custom Showme in the request body under the nodeTypeGrns
key. For this tutorial we'll add it to the /shortestPath
Showme.
This is what the request looks like with the nodeTypeGrns
added to the Showme:
curl --location --request PUT "${API_BASE}/1.0/showme/updateShowme/shortestPath" \
--header 'Content-Type: application/json' \
--header "Authorization: Bearer ${BEARER_TOKEN}" \
--data-raw '{
"cypher": "MATCH (p1:Person) WHERE p1.grn = {firstPersonGrn} MATCH (p2:Person) WHERE p2.grn = {secondPersonGrn} MATCH p=allShortestPaths((p1)-[*]-(p2)) WHERE NONE(n IN nodes(p) WHERE n:Version) WITH nodes(p) AS shortestPathNodes UNWIND shortestPathNodes AS shortestPathNode RETURN COLLECT(shortestPathNode.grn) AS nodeIds",
"showmeMethod": "GET",
"showmePath": "/shortestPath",
"showmeDisplayValue": "shortestPath",
"showmeDefinition": "shortest path between two people",
"showmePopulatorDisplayValue": "shortestPath",
"showmePopulatorDefinition": "shortestPath",
"addNodeTypeGrns": ["grn:gg:graphgridnodetype:p5m6SZLuqp5rTILpu1zOkVYFPY4x9FzjKIgAbgMPlS18","grn:gg:graphgridnodetype:hRl8GplVHixGMQM1a4B6obNoOT00bhHVzpdOp59cgqDO"],
"addParams": {
"firstPersonGrn": "",
"secondPersonGrn": ""
},
"requiredParams": ["firstPersonGrn","secondPersonGrn"],
"cypherOrder": 0,
"overrideCypherOrder": false
}
'
Run the above request to update the /shortestPath
Showme with the proper nodeTypeGrns
.
Create Your Custom Showme
Let's see our /shortestPath
Showme that we already created in action in the dashboard!
Viewing Showmes in the Dashboard
Head into the GraphGrid Dashboard and create a new project to display our Showme. In the query editor, run a query for 1 person node and add it to the graph. We used the "Al Pacino" node. Select the node and click the Showme button.
And the Showmes tab will appear:
From here you can edit the Showme in order to add parameters and run it.
The shortestPath Showme takes two parameters, firstPersonGrn
and secondPersonGrn
. Let's use a different grn from our original
shortestPath
request. Let's setfirstPersonGrn
to Carrie-Anne Moss and keep Al Pacino for the secondPersonGrn
. These parameters
will return the shortest path between these two actors who (according to the data we're using) have not acted in any movies together.
Copy this Geequel query to return the nodes' grn
:
MATCH (a:Person {name: "Carrie-Anne Moss"}) MATCH (b:Person {name: "Al Pacino"}) RETURN a.grn, b.grn
Copy and place these grn
values in the Showme. Once the parameters are set we can click the "Update Showme" button which will save our parameter values. Making sure our Al Pacino node is still selected, click the plus sign next to the name of the Showme.
Clicking this button will execute our Showme with our set parameters and will then appear in the graph.
Our Showme returned the shortest path between Al Pacino and Carrie-Anne Moss! Carrie-Anne starred in the "Matrix" Trilogy with Keanu Reeves who acted in "The Devil's Advocate" with Al Pacino.
Showme functionality within the UI is still a work in progress. In order to get the cleanest results from a Showme it's recommended to create a new project. If multiple Showmes are executed on the same project graph the results are added to the Showme nodes already displayed on the graph.
Setting Security Rules
It may be necessary to restrict data access for certain roles within your organization. This section of the tutorial will guide you through setting up a secured showme that performs an authorization and authentication check.
Security protocols are defined under the showmeSecurityRules
parameter as a Geequel query in the request body. The security rules set up in a showme are an
added layer of security to ensure that only users with the right credentials have access to the information returned by the showme.
To define a showme security rule, a Geequel query will need to return a true
or false
value. The showme security rule takes in a Geequel query that
returns true
or false
. If the value returns true
then the user will be granted access, if it is false
access will be denied.
An example of a query that would work as a security rule would be the one below:
OPTIONAL MATCH rel=(principal)-[:HAS_ROLE]->({name:'admin'}) RETURN rel IS NOT NULL
This query looks for a relationship called HAS_ROLE
the name
"admin". This query will either return true or false.
Another example would be to use the properties passed into the showme itself:
OPTIONAL MATCH (u2:User {grn: $userGrn2})<-[:SECURITY_SPEC]-(principal) WITH u2, principal CALL apoc.util.validate(u2 IS NULL, 'resource cannot be found for ' + $userGrn2 + ' or is not authorized for the user', []) OPTIONAL MATCH (p:SecurityPermission {name: 'Admin'}) RETURN shortestPath((principal)-[*..3]->(p)) IS NOT NULL
The query above uses the properties set in the showme to look for validation within the security parameters set and returns a message if the user is not authorized.
You may have noticed the principal
in the example Geequel queries. The principal
is
defined from the user's OAuth Token metadata. The principal
value will be defined by
the user that is making the API call.
The Geequel query is included within the JSON body of the showme upon creation. The
property is called showMeSecurityRules
. Its key is "cypherQuery" and the value is the
Geequel query that returns true or false.
"showMeSecurityRules": {
"spelExpression": "permitAll",
"cypherQuery": "WITH principal.name AS name RETURN true"
The above query would permit all users/roles access to the data retrieved by the showme.
Next let's set a security rule that only allows showme access to certain users. First we will create a property on the user node(s) that we want to allow access
and set its value to true
. This will be the property that the showme API reads in order to authenticate the request.
One way we could do this is to set a property called isAdmin
on the user node and give it a value of true
. The following query finds a user node by its grn
and sets a property called isAdmin
to true
.
MATCH (principal:User {grn: "grn:gg:user:EeTO5wqULpuk1Xr8T8JQ2VcT5075cTvAWdmpjEDXnl9W"}) SET principal.isAdmin = true
Next we need to write a Geequel query to add to the showme request body that defines the security rules:
"showmeSecurityRules": {
"cypherQuery": "RETURN principal.isAdmin = true"
A showme with these defined security rules would only allow access to user nodes that have the property isAdmin
with the value set to true
.
An unauthorized user would get the following message when attempting to access the showme:
{
"timestamp": "2023-09-20T19:30:52.938Z",
"status": 403,
"type": null,
"code": null,
"error": "Forbidden",
"message": "Access is denied; invalid security rule",
"localizedMessage": "Access is denied; invalid security rule",
"path": "/1.0/showme/executeShowme/getMoviesByYear",
"cause": null,
"stacktrace": "org.springframework.security.access.AccessDeniedException: Access is denied; invalid security rule\n\tat com.graphgrid.boot.security.showme.service.ShowmeAuthorizeServiceImpl.checkAuthorized(ShowmeAuthorizeServiceImpl.java:96)\n\tat com.graphgrid.boot.manager.service.ShowmeServiceImpl.executeShowme(ShowmeServiceImpl.java:765)\n\tat com.graphgrid.boot.manager.service.ShowmeServiceImpl$$FastClassBySpringCGLIB$$e05dba31.invoke(<generated>)\n\tat org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)\n\tat org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:684)\n\tat com.graphgrid.boot.manager.service.ShowmeServiceImpl$$EnhancerBySpringCGLIB$$b99c3914.executeShowme(<generated>)\n\tat com.graphgrid.boot.manager.controller.ShowmeController.lambda$executeShowme$0(ShowmeController.java:261)\n\tat org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBodyReturnValueHandler$StreamingResponseBodyTask.call(StreamingResponseBodyReturnValueHandler.java:110)\n\tat org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBodyReturnValueHandler$StreamingResponseBodyTask.call(StreamingResponseBodyReturnValueHandler.java:97)\n\tat org.springframework.web.context.request.async.WebAsyncManager.lambda$startCallableProcessing$4(WebAsyncManager.java:326)\n\tat java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)\n\tat java.util.concurrent.FutureTask.run(FutureTask.java:266)\n\tat java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)\n\tat java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)\n\tat java.lang.Thread.run(Thread.java:750)\n"
}
The message returns as access denied due to invalid security rule. User nodes that do not have the isAdmin
property set to true
are not authorized to access
this showme.
When setting the value of the property defined in the showmeSecurityRules
query, the query must return a valid boolean value of true
. Anything other than
true would result in denied access. When setting these properties on user nodes ensure that the value is set to true
and not a string "true".