title: Matching one of multiple paths (ACL)
body: <p>I'm trying to re-implement an ACL system for a web app using Neo4j.</p>
  
  <p>The application has a hierarchical Organization, the leaf nodes of which can own Tasks.</p>
  
  <p>There are Roles, which have Permissions. Users can be assigned to a Role within an Organization or Task. Doing so should give them the permissions assigned to the Role within that Organization, any descendants, and any owned Tasks.</p>
  
  <p>Additionally, some Users are assigned one-off Permissions on Organizations that are not part of a role.</p>
  
  <p>I have setup the graph using hyper edges to model the User x Role x Organization and User x Permission x Organization intersections.</p>
  
  <p><a href="https://i.stack.imgur.com/uKB1L.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/uKB1L.png" alt="Current data model"></a></p>
  
  <p>I am trying to ask "Does the User have a given Permission on a given Task or Organization (whether through a Role or Permission assigned directly to a node)?"</p>
  
  <p>I have partially answered it using:</p>
  
  <pre><code>MATCH (user:User)-[:MEMBER_OF]-&gt;(hyperedge:UserGroupRestriction)
          WHERE user.userId = 1
  MATCH (hyperedge)-[:ON]-&gt;(restriction)-[:OWNS|:PARENT_OF*0..3]-&gt;(t:Task { id:2 }),
  (hyperedge)-[:ROLE]-&gt;(role:Role)-[:CAN]-&gt;(p:Permission { name: 'tasks.edit' })
  RETURN count(restriction) &gt; 0 AS `allowed`
  </code></pre>
  
  <p>However this only works for the Role restriction, because I am only looking at the <code>MEMBER_OF</code> relation, which connects a User to a group restriction hyper edge. How do I modify the query so that I get a true result if they have the permission either trough a role membership or an assigned permission? The node Label for one-off permission hyper edges is <code>:UserPermissionRestriction</code>.</p>
  
  <p>Thanks for any insight, I'm open to restructuring the graph if that makes sense since this is just early proof of concept.</p>