Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Allow Firebase Storage Bucket to be accessed only by some users

I have a main "folder" in my storage directory called users-projects and then I create folders for every users' projects. I want to allow the users to access only their projects and the projects they are invited in, like a Dropbox or Google Drive folder with collaborators.

In the Documentation they says:

Include group information (such as a group ID or list of authorized uids) in the file metadata

So here is my questions:

  • Can I do this directly with the folder?
  • How can I store the list of authorized uids?

I am programming an iOS app in Swift.

Here is my actual code for the Rules:

service firebase.storage {
  match /b/on-team.appspot.com/o {
    match /{allPaths=**} {
      allow read, write: if request.auth != null;
    }
    match /users-projects {
        match /{projectId} {
        allow read, write: if ?????
      }
    }
  }
}

Here is the official documentation: https://firebase.google.com/docs/storage/security/user-security .

like image 284
alessionossa Avatar asked Mar 12 '23 06:03

alessionossa


2 Answers

I think the correct static rule would be :

allow read, write: if request.auth.uid == 'a-user-id' || request.auth.uid == 'another-user-id' || ...

But I guess you are looking for dynamic rules :)

For the owners it's quite simple to setup a dynamic rule with the folder name :

match /users-projects/{projectId}/{userId} {
    allow read, write: if request.auth.uid == userId 

For more complex cases like invited users, you can try using the custom metadata to store invited uids in the file, and match them against user id accessing that ressource, example rule:

allow read: if resource.metadata.invited.matches(request.auth.uid);

The custom metadata values can only be strings, so I suggest you store them as coma-separated value so you can edit them easily, and at the same time use a simple match in the access rule.

Note: this is only scalable while invitedUids.join(',') length is shorter than maximum length of custom metadata values. (I don't know that value). If your app is not built to accept hundreds of invited users, it should be ok, otherwise you might need to setup a server-side access mecanism which build a unique download link for each invited user, instead of relying on simple rules.

Also, I don't think you can use token groupId value to enforce access security in your case (as depicted in the docs), because you have a many-to-many relationship between users and folders/files. (users will not belong to only one group)

So, to answer your questions:

  • The resource object in the rules only apply to files, if using metadata to enforce access, they need to be updated on each file in the folder if they share the same access rules
  • The metadata is just a string->string key-value store, you just need to store user ids as a string in a arbitrary non-reserved key, as explained above.
like image 135
Pandaiolo Avatar answered May 09 '23 06:05

Pandaiolo


Store individual project in a directory using their userid

  • /users-projects/user_id/project1
  • /users-projects/user_id/project2


     service firebase.storage {
         match /b/on-team.appspot.com/o {
           match /{allPaths=**} {
             allow read, write: if request.auth != null;
           }
         match /users-projects/{user_id} {
             allow read, write: if request.auth.uid == user_id 
         }
      }
    }
like image 27
Sunday G Akinsete Avatar answered May 09 '23 05:05

Sunday G Akinsete