yodaisgreen
yodaisgreen

Reputation: 2310

How to use Firebase rules to only give permission to certain leaf nodes

My basic question is how do you setup Firebase rules to only allow access certain leaf nodes from their parent?

Lets say I have data that looks like this:

root: {
  posts: {
    post1: {
      user: "foo",
      post: "this is a post",
      restricted: false
    },
    post2: {
      user: "bar",
      post: "this is another post",
      restricted: true
    },
    post3: {
      user: "bar",
      post: "this is my final post",
      restricted: false
    }
  }
}

I want to $bind to the posts node and get all the posts which that user is allowed to get. I might want the admin to access all of the posts but non-admins to only be able to access post1 and post3.

Note: I'm using angularFire's $bind to synchronize nodes.

I don't believe this is possible but I would like to be able to set up my rules kinda like this:

{
  "rules": {
    "posts": {
      ".read": "auth.admin || $post.hasChild('restricted').val() !== true",
      "$post": {
      }
    }
  }
}

How are other users accomplishing this? Thanks.

Upvotes: 2

Views: 1850

Answers (2)

Titou
Titou

Reputation: 1008

I believe the canonical way to do that is to place a rule directly on the element to be read, not on the collection.

{
  "rules": {
    "posts": {
      "$post": {
        ".read": "auth.admin || data.hasChild('restricted').val() !== true"
      }
    }
  }
}

Upvotes: 0

Anant
Anant

Reputation: 7428

You can use the data.hasChild expression to achieve this:

{
  "rules": {
    "posts": {
      ".read": "auth.admin || data.hasChild('restricted').val() !== true"
    }
  }
}

However, this is not the recommended approach and won't work in practice. Security rules are not a good fit for filtering data based on access - you'll see permission denied errors in the console because angularFire will try to read all the posts from /blog and it will fail.

Instead, each user should know which posts they have access to and only fetch those directly. You can use push() (or $add in angularFire) to generate random post IDs and set the security rules such that you can access the data if you know the post ID, for example.

Upvotes: 3

Related Questions