FastPrepACL Inheritance with Local-Only Deny Rules
Problem · Graph

ACL Inheritance with Local-Only Deny Rules

Learn this problem
MediumSnowflake logoSnowflakeFULLTIMEPHONE SCREEN
See Snowflake hiring insights

Problem statement

There are n = allows.length access-control nodes numbered from 0 through n - 1. A permission is one lowercase English letter.

  • allows[v] lists the permissions directly allowed at node v.
  • denies[v] lists the permissions directly denied at node v.
  • Each directed edge [parent, child] means that the child inherits allow declarations from that parent and all of its ancestors. The graph is acyclic.

A query asks whether node queryNodes[i] may use permission permissions[i]. Return one boolean per query in order.

The answer is true exactly when the queried node or at least one of its ancestors directly allows the permission, and the queried node itself does not directly deny it.

  • Deny rules apply only at the node that declares them. They never propagate to descendants.
  • A local deny overrides both local and inherited allows for that node.
  • A local deny does not remove the underlying allow declaration from inheritance. An allow can pass through a node that locally denies it and still reach a descendant.
  • If no local or inherited allow exists, access is false.

Edges, declarations and queries are valid. Queries do not change the graph or rules. Empty allow and deny strings are permitted, and their letter order is irrelevant.

Function

canAccess(allows: String[], denies: String[], edges: int[][], queryNodes: int[], permissions: String) → boolean[]

Examples

Example 1

allows = ["a","",""]denies = ["","a",""]edges = [[0,1],[1,2]]queryNodes = [0,1,2]permissions = "aaa"return = [true,false,true]

Permission a is allowed at node 0. Node 1 denies it locally, but that deny does not reach node 2 or stop the inherited allow. The three answers are true, false and true.

Example 2

allows = ["a","b","","c"]denies = ["","","b","a"]edges = [[0,2],[1,2],[2,3]]queryNodes = [2,2,3,3,3]permissions = "ababc"return = [true,false,false,true,true]

Node 2 inherits a and b, then denies only its own access to b. Node 3 inherits both underlying allows, adds c and locally denies a.

Constraints

  • 1 <= allows.length = denies.length <= 100.
  • Each allow or deny string contains unique lowercase English letters and has length from 0 through 26. A letter may appear in both lists for the same node.
  • 0 <= edges.length <= 500; every edge has distinct valid endpoints, no directed edge is repeated, and the graph is a DAG.
  • 0 <= queryNodes.length = permissions.length <= 200.
  • Each queried node is valid, and each queried permission is a lowercase English letter.

More Snowflake problems

drafts saved locally
public boolean[] canAccess(String[] allows, String[] denies, int[][] edges, int[] queryNodes, String permissions) {
    // Write your code here
}
allows["a","",""]
denies["","a",""]
edges[[0,1],[1,2]]
queryNodes[0,1,2]
permissions"aaa"
expected[true,false,true]
checking account