5

I am trying to create a security rule that allows any user in a group to read the information of any other user in the same group. In other words a user should be able to read the user information of any user that belongs to a common group.

This is what I have:

{
  "rules": {
    "users": {
      "$user_id": {
        // Any user beloging to at least one group in common should be able to read
        ".read": "$user_id === auth.uid || root.child('users/' + $user_id + '/groups').hasAny(root.child('users/' + auth.uid + '/groups'))",
        ".write": "$user_id === auth.uid",

        "groups": {
          "$group_id": {
            ".validate": "root.child('groups/' + $group_id).exists() && newData.isBoolean()"
          }
        }  
      }
    },

    "groups": {
      "$group_id": {
        "name": { ".validate": "newData.isString() && newData.val().length > 0 && newData.val().length < 50" }
      }
    },

    "members": {
      "$group_id": {
        ".read": "root.child('members/' + $group_id + '/' + auth.uid).exists()",
        ".validate": "root.child('groups/' + $group_id).exists()",
        "$user_id": {
          ".write": true, // Skipped for brevity
          ".validate": "root.child('users/' + $user_id).exists() && newData.isBoolean()"
        }
      }
    },
    }
  }
}

Of course, the hasAny function is not part of the API. Is there any way to do this with the existing API? Are there any plans to add something like this?

Alejandro
  • 3,726
  • 1
  • 23
  • 29
  • Can you talk a bit more about the underlying use case we're trying to resolve? hasAny isn't likely to be developed soon. – Kato Aug 19 '14 at 19:24
  • I'm trying to create a place where users can interact. If you join a group you can see everybody's profile in that group. Simple as that. – Alejandro Aug 20 '14 at 06:20
  • Can you just place the public info into a separate path and make it available to everyone, or copy the public portion into the group? – Kato Aug 20 '14 at 17:57
  • There is going to be a lot of redundancy, but I guess that's the only option... – Alejandro Aug 21 '14 at 18:39
  • You could also maintain an index of which members are allowed to view the user in the user record itself, and update that list when users are added/removed from groups. You could also maintain a master list with something like /friends/$userid/$friendid/$groupid, where $friendid is a collection of groups that allow access. When the last group is removed, $friendid will be null and access denied. – Kato Aug 22 '14 at 01:38
  • the answer is this here: [http://stackoverflow.com/questions/14491496/granting-access-to-firebase-locations-to-a-group-of-users][1] [1]: http://stackoverflow.com/questions/14491496/granting-access-to-firebase-locations-to-a-group-of-users – Seb May 04 '15 at 19:34

2 Answers2

0

To maintain user's friends list.

You'll have to keep reference of the user's friends list. When a user join a group, add group member's auth.uid to the user's friends list. Then, only his friends can read his profile.

{"rules":{
  // $user_id == current user's auth.uid
  // $friend_id == his friend's auth.uid
  // $member_id == group member's auth.uid
  "users":{"$user_id":{
    "friends":{"$friend_id":{
    }},

    // readable by my friends:
    ".read":"auth =! null && data.child('friends').hasChild(auth.uid)"

  }},
  "groups":{"$group_id":{
    "members":{"$member_id":{
    }}
  }}
}}
Nik
  • 709
  • 4
  • 22
0

To maintain multiple profiles.

The following answer creates multiple profile copies / views for each group the user join. Much like multiple resume you send about your self to different companies. So, members of the company may know you differently depending on the resume you have sent to them.

Each of user's profile is view-able only to members of the designated group.

When the viewer auth.uid is a member of barney group, the viewer can view any users who has profile/barney written in his account.

{"rules":{
  // $user_id == current user's auth.uid
  // $friend_id == his friend's auth.uid
  // $member_id == group member's auth.uid
  "users":{"$user_id":{
    "profile":{"$group_id":{
        // readable by group members:
        ".read":"auth =! null && root.child('groups').child($group_id).child('members').hasChild(auth.uid)"
    }}
  }},
  "groups":{"$group_id":{
    "members":{"$member_id":{
    }}
  }}
}}
Nik
  • 709
  • 4
  • 22