DEV Community

Discussion on: Help: Security per record - is it possible to make optimal solution ?

Collapse
 
phlash profile image
Phil Ashby

Nice analogy - thanks, and glad you aren't trying to solve a non-existent problem :)

As @tonymet suggests, this does feel like a file system in some ways. Perhaps you can use the graphDB primarily as the permissions management system though appropriate use of relationships from a node to nodes that represent users, so you can express the 'room access' you describe and build searches that apply the stated permissions (by requiring the edges back to the user(s)), then collecting related attributes from the 'pile' once you have filtered down the nodes?

Thread Thread
 
_hs_ profile image
HS

I'm actually working towards it. Thanks. Also the thing with this one was performance concern, where I have additional call to access management API, or even if I kind of "monolith it" I still need that extra call to filter out data not allowed for specific users. I'll look into options for my framework and how not to redesign whole architecture because of this but still maintain some performance. Anyways I think it's safe to say I'm using Neo4j sa graph db and Spring (for now) as framework so there might be a way. Just not here yet.

But more importantly I value your answer as it gave me some encouragement that there's just no way around "user per resource" as it's a requirement, but it might be not that bad as I think.

Just want to share latest experiment in Cypher

RETURN EXISTS((s)-[*0..]->()<-[:HAS_ACCESS]-()<-[:HAS_ROLE*0..1]-(u))

So this would work for both User having direct access to a certain object or Role having access to it. It's also relying on a fact that only parents point to children not the other way around. So if I have two options:
(SuperParent)->(Parent)->(Child)->(Edge)
(SuperParent)->(Parent2)->(Child2)
where User - has access -> child2 but Role -> has access -> child 1
I can get true for

MATCH (c:Child) WHERE c.name = 'Child' OR c.name = 'Child2'
MATCH (u:User {name: "user1"})
RETURN EXISTS((s)-[*0..]->()<-[:HAS_ACCESS]-()<-[:HAS_ROLE*0..1]-(u))

so it either uses Role if it can or ignores it. And it's quite fast to my surprise, however it's just a sample cypher on sample DB. But also I can ask for Super parent in same query and get true. But it does go through Role as it's using most of the relationships or it might be that role access relationship was made first so it hits it first.

So I discovered that I can have optional relationships and mandatory ones in query with Neo4j. Might write post about this one as I find it interesting what can you do with cypher regardless of what I use in the project.