Review permissions implementation and endpoints
pepoospina opened this issue · comments
-
Review the
finDelegateTo
property so that it always points to the element whose permissions are the effective permissions of an element, including whendelegate = false
, in which casefinDelegateTo
should be the sameelementId
. Once this is done, remove all logic of the typeif (delegate) { ... }
that is not needed (for example here, here, and here ). Make sure current tests pass. -
Add new tests to
uprtcl.test.ts
that changes thedelegate
property of an element. Consider all possible cases:-
delegate
of perspective A passes fromfalse
totrue
and newdelegateTo
is perspective C who hasdelegate = false
. Perspectve B hasdelegate = true
anddelegateTo = perspective A
. -
delegate
of perspective A passes fromfalse
totrue
and newdelegateTo
is perspective C who hasdelegate = true
anddelegateTo = perspective D
. Perspectve B hasdelegate = true
anddelegateTo = perspective A
. -
delegate
of perspective A passes fromtrue
tofalse
and delegateTo wasperspective C
. Perspectve B hasdelegate = true
anddelegateTo = perspective A
.
-
-
Review the endpoints related to permissions and remove the generic ones
-
path: "/uprtcl/1/accessConfig/:elementId"
-
path: "/uprtcl/1/permissions/:elementId"
Replace them with task-specific endpoints as follows:
path: "/uprtcl/1/accessConfig/:elementId/delegate?delegate=value&delegateTo=value"
Which will receive two query parameters
delegate
anddelegateTo
. The endpoint will setdelegate
property of the accessConfig ofelementId
totrue
orfalse
. Iftrue
, thedelegateTo
query parameter is checked and used to set or update thedelegateTo
property.
- check why cascade is needed and cant filter by delegateTo
Got error: Attribute delegateTo is not valid scalar type while running:
(forum credentials). - why adding ~delegateTo to the "C" level, hides C2 and shows C1 and D1? it seems its because C2 don't have children (no one
delegateTo
to it). Maybe related to @cascade? - How can we use this query as an alias to set all the
finDelegatedTo
of the elements found by the query? even if not recursive. Using upsert - Can we do the @recursive query? (so that all children
finDelegateTo
are set with one upsert mutation) - If we cant, which is probably the case, because of multiple level query. Is it possible to change the data schema so that @recurse can be used? for example, remove the
accessConfig
node, setaccessConfig
asPerspective
properties directly and usedelegateTo
pointing to auid
So, this is the query that I worked around regarding the first point:
delegatingFromAccessConfigs as var(func: eq(xid, "${elementId}")) { accessConfig : ~delegateTo { uid } }
~delegateTo
, is not an index, which doesn't allow us to perform a direct search as we do with the xid
property. The nature of the ~delegateTo
property it is that is referenced at a whole element through its uid
, because that's how the design should be. The data type that is specified as uid
is not allowed to behave as index
, which won't let us have a direct function calling it.
So in order to avoid using @cascade
and @filter
directives, which would pull from us the opportunity to increase efficiency using a reverse edge, I implemented the following logic:
-
The reverse edge
~delegateTo
, is designed to return allaccessConfig
elements that point to a specific perspective, that explains the use of the aliasaccessConfig
in the previously shown query. -
Regarding the reverse edge
~accessConfig
, it is designed to return all perspectives that are pointing to a specificaccessConfig
element.
This obfuscates to my understanding, point 2, which indicates recursivity. It would be good to try it out with the new query.
However, I already tried the following query that implements hardcoded recursivity:
{ q(func: eq(xid, "zb2wwycfp1ML7DFZRBv4UhP8iKDmUy5wPNCpyrnx57QTiCGxL")) { accessConfig : ~delegateTo { uid perspectives: ~accessConfig { xid accessConfig: ~delegateTo { uid perspectives: ~accessConfig { xid } } } } } }
It makes sense!
Now that this is solved and after reviewing a little better the dgraph documentation, I think its time to get rid of the AccessControl type, and just put all its properties (delegate
, delegateTo
, finDelegatedTo
and permissions
to the Perspective object itself).
Once done I would make sure we get the @recurse query working
Hello there!, working around the dgraph documentation, I finally found how to perform recursivity and it is pretty easy, we should only have in mind one rule:
You can specify only one level of predicates after root. These would be traversed recursively. Both scalar and entity-nodes are treated similarly.
Which means that we should avoid wrapping when specifying the data that we need, and these requires us to provide a pattern, which is the one that is going to repeat and form the tree.
Here is a an example of how a hardcoded recursive query would be:
- The query is based on a parent perspective, "PerspectiveA", which has a lot of children and it is the final delegated of all the related nodes.
This query gives us the following result:
It can be easily noticed that the result returned four (4) UIDs
, which are the children of the perspective of reference (note the green nodes in the graph above). If we do the same implementing recursivity, we can notice that we match the same result, but instead we will also receive more perspectives, which are the ones that point to the accessConfig
we needed to get, being this a result of the pattern specified in the recursive query.
The following is an example following the recursive practice:
Notice that the depth
parameter is set to a crazy number "100". According to the documentation, the parameter won't throw any error through the number specification, it will only throw an error if the depth limit is exceeded by the results, which I still can't figure it out in the docs.
This query gives us the following result:
We can easily notice in the above picture our four (4) accessConfig
, the same received in the hardcoded query.
We can also notice it in the graph result.
So if we want to make an upsert, in which we take only the UIDs
coming from our accessConfig
, we will only need to identify something like this:
a as ~accessConfig: ~delegateTo
.
But first, I would like to be sure about this recursive query, in order to follow up the pattern and achieve to properly identify the accessConfig
variables and have them ready to perform the perfect mutation!.
I closed the issue by mistake, thanks for reopening it. Your summary is super useful and clear @sotous.
It's interesting that you can use @recurse and ask for properties that will be available in some nodes, and not in others and vice-versa. The problem, as you say, is that you get the uids of the access configs and of the perspectives.
It seems that removing the distinction between the AccessConfig
and the Perspective
types and combining them into a single Perspective
type that includes the access confgi properties should result in the recursive query only having one ~delegateTo
and getting the uids of the child perspectives which can then be used to set their finDelegateTo
.
I closed the issue by mistake, thanks for reopening it. Your summary is super useful and clear @sotous.
It's interesting that you can use @recurse and ask for properties that will be available in some nodes, and not in others and vice-versa. The problem, as you say, is that you get the uids of the access configs and of the perspectives.
It seems that removing the distinction between the
AccessConfig
and thePerspective
types and combining them into a singlePerspective
type that includes the access confgi properties should result in the recursive query only having one~delegateTo
and getting the uids of the child perspectives which can then be used to set theirfinDelegateTo
.
Well, regarding your comment it seems like I achieved to make the mutation, I am working on tests to completely proof that is working out.
This one seems to be our winner. Here what I am performing is to set delegate
to false in PerspectiveB
, that's why both XIDs
are the same in the upsert query.
Before this upsert was done, all the child nodes pointing to the PerspectiveB
had as a finDelegatedTo
the PerspectiveA
.
After running this upsert, since now PerspectiveB
don't have any delegateTo
, all child nodes have as a finDelegatedTo
the PerspectiveB
.
Here you can notice the difference:
- Before the upsert
- After the upsert
The logic that I am understanding is that when you set a variable for an attribute of the @recurse
operation, the function will save the result into it, without caring about the type, which in this case can be an array or just a single element.
The upsert use the variable identifier a
, applied later in the mutation. So, depending on what is inside a
, the mutation will run n
times:
uid(result1) <finDelegatedTo> uid(finDelegatedTo) .
uid(result2) <finDelegatedTo> uid(finDelegatedTo) .
uid(result3) <finDelegatedTo> uid(finDelegatedTo) .
Being each result an element inside the variable a
, the loop will perform automatically.
Having this in mind, now I am working on tests to try out all the different scenarios and make sure that our practice is good enough. :)
Ok, perfect @sotous . It seems the case when delegate
passes from true
to false
is ready then.
Now we can focus on the case when it passes from false
to true
.
In that case:
- the
delegate
property must be set to true, - the
delegateTo
property must be set to thedelegateTo
element id provided as input. - the
finDelegateTo
property must be set to thefinDelegateTo
of thedelegateTo
element. - the
finDelegateTo
of all the elements that havefinDelegateTo
to the current element must be changed to the newfinDelegateTo
too. Looks like the job for a~finDelegateTo
query and upsert.