-1

-- UPDATE --

It turns out the below should have worked, but didn't due to a bug, so this was recommended by Firebase Support as a workaround, and it worked for me:

request.auth.token.permissions.toSet().hasAll([0])

-----------------------------

I have an array/list of with a single integer on my custom claims like this:

someList: [0] 

I want to check if a number exists in the list in my storage security rules. I can't seem to get the hasAll rule to work that is mentioned in the documentation: https://firebase.google.com/docs/reference/security/storage#hasall

Some rules work when referencing the list so I know for sure that the property is there in my custom claims, but I can't seem to get it to work with hasAll or using tricks with strings.

Example -

rules_version = '2';
service firebase.storage {
  match /b/{bucket}/o {
    match /clients/{clientId}/{allPaths=**} {      
      // These work - 
      allow read, write: if request.auth.token.someList.join('').size() > 0
      allow read, write: if request.auth.token.someList != null

      // These do not -
      allow read, write: if request.auth.token.someList.hasAll([0])
      allow read, write: if request.auth.token.someList.join('').matches('0')
    }
  }
}

‍♂️ ?

chevin99
  • 4,946
  • 7
  • 24
  • 32
  • The rules that work dont actually check for the integer. Are you sure your custom claims is properly set? – l1b3rty Mar 14 '23 at 08:41
  • Can your try: `allow read, write: if request.auth.token.someList is list` – l1b3rty Mar 14 '23 at 08:41
  • And `allow read, write: if request.auth.token.someList.size() == 1` – l1b3rty Mar 14 '23 at 08:42
  • @l1b3rty I tried both `is list` and `size() == 1` and those work fine, but still not `hasAll([0])` ☹️ – chevin99 Mar 14 '23 at 19:37
  • and I did `admin().auth().getUser()` in a firebase function and I for sure have `someList: [0]` in my customClaims. – chevin99 Mar 14 '23 at 19:41
  • Have you write any data to `someList` before you write `0` to it? – flutroid Mar 16 '23 at 08:02
  • Could you try re login your app? – flutroid Mar 16 '23 at 08:12
  • @flutroid I have tried re-setting the custom claims and also re-logging in and no luck. – chevin99 Mar 16 '23 at 15:03
  • Try `allow read, write: if 0 in request.auth.token.someList` – l1b3rty Mar 16 '23 at 15:08
  • @chevin99 Ok, But beware that when you update custom claims it won't also update data in rules immdetely see this [Firebase custom claims are not update in rules](https://stackoverflow.com/questions/58280361/firebase-custom-claims-are-not-update-in-rules) – flutroid Mar 16 '23 at 15:10
  • @l1b3rty `allow read, write: if 0 in request.auth.token.someList` didn't work either – chevin99 Mar 16 '23 at 15:23
  • @flutroid I had made sure to force the token refresh client-side, but still no luck ☹️. – chevin99 Mar 16 '23 at 15:24
  • In your client, can you try calling `getidtoken` with `forceRefresh` set to true before making the call? And still in the client, log the token you get back https://firebase.google.com/docs/reference/js/v8/firebase.User#getidtoken – l1b3rty Mar 17 '23 at 14:50
  • @l1b3rty thanks, yes, I've done that and the values are there on the claims. I should also point out I've been using that same `someList: [0]` for firestore rules for quite some time and they work, but haven't gotten it to work with storage rules yet. – chevin99 Mar 17 '23 at 23:34

1 Answers1

0

Some things you can do:

  1. Confirm custom claims are properly set and refreshed: in your client, try calling getidtoken with forceRefresh set to true before making the call, log the data you get back.

  2. Check if the following rules pass:

    allow read, write: if request.auth.token.someList is list;
    allow read, write: if request.auth.token.someList.size() == 1;
    allow read, write: if 0 in request.auth.token.someList;
    
l1b3rty
  • 3,333
  • 14
  • 32