0
votes

I have collections of posts with objects that contain an array names 'groupIds' that contains all the ids the post is linked to.

I perform this query, where ids is an array of all the groupIds the user is part of.

firebase
    .collectionGroup('posts')
    .where('groupIds', arrayContainsAny: [CS5GQ487VRChV9Z0N50P, 3wsvOvGZ6UOA7r5N5qjj, 3ZdEykm19nd2yMYe1FFB, pleFNwQ98ggdfyqWmAXn, 97PiIGlvoDMecJzxC38b, MaY7oJGHz2zIZ7PSLEfc])
    .orderBy('created', descending: true)
    .limit(20);

I am using these rules. (No post has more than 10 groupIds)

function hasGroupReadPermissionsMultiple(groupIds){
    return (groupIds[0] != null && groupIds[0] in request.auth.token) ||
      (groupIds[1] != null && groupIds[1] in request.auth.token) ||
      (groupIds[2] != null && groupIds[2] in request.auth.token) ||
      (groupIds[3] != null && groupIds[3] in request.auth.token) ||
      (groupIds[4] != null && groupIds[4] in request.auth.token) ||
      (groupIds[5] != null && groupIds[5] in request.auth.token) ||
      (groupIds[6] != null && groupIds[6] in request.auth.token) ||
      (groupIds[7] != null && groupIds[7] in request.auth.token) ||
      (groupIds[8] != null && groupIds[8] in request.auth.token) ||
      (groupIds[9] != null && groupIds[9] in request.auth.token);
}

match /{somePath=**}/posts/{postId}{
  allow read: if hasGroupReadPermissionsMultiple(resource.data.groupIds);
}

The user's custom claims have the id's as a key and their role as the value, directly in the claims object like so:

{CS5GQ487VRChV9Z0N50P: a, MaY7oJGHz2zIZ7PSLEfc: a, auth_time: 1599646120, 3wsvOvGZ6UOA7r5N5qjj: a, cR2j2ed4LbsCZYMib7yt: a, sub: hfn2VSqEJUMVBQLmyPa2jFhNA1Q2, user_id: hfn2VSqEJUMVBQLmyPa2jFhNA1Q2, iat: 1599719905, iss: https://securetoken.google.com/XXX, aud: XXX, het-persijntje: a, name: Jan Jansen, pleFNwQ98ggdfyqWmAXn: a, exp: 1599723505, 3ZdEykm19nd2yMYe1FFB: a, JLTmBMxPerm8BY75KEBX: a, 97PiIGlvoDMecJzxC38b: a, email_verified: true, email: [email protected], firebase: {identities: {email: [[email protected]]}, sign_in_provider: password}, het-persijntje-test-excel: a}

I want users to only access the posts if any of the groups they are part of is linked to the post. Does anybody see my mistake? Of is there a more efficient way to achieve this?

1

1 Answers

2
votes

request.auth.token refers to the entire JSON payload of custom claims. It's going to be a map object with fields for each claim, not an array as you are using it now. You will need to call out the specific property that contains the array to check again, for example request.auth.token.nameOfTheListField.

Also, you can check if an array contains items from another array with hasAny instead of indexing repeatedly into the source array.

request.auth.token.nameOfTheListField.hasAny(groupIds)