Untitled

mail@pastecode.io avatarunknown
plain_text
a month ago
3.8 kB
4
Indexable
Never
rules_version = '2';

service cloud.firestore {
  match /databases/{database}/documents {
    match /Organizations/{orgID} {
      allow get: if getRole(database, orgID, request.auth.uid) in ['Admin', 'Editor', 'Viewer'];
      allow list, write, delete: if false;


      // Only allow a user to read/write/delete the documents in the 'Materials' collection
      // if their uid is equal to the orgID
      match /Materials/{materialID} {
      	// Allows read if the resource is public or the user is an org admin, editor, or reader
        allow read: if resource.data.visibility == 'public' || getRole(database, orgID, request.auth.uid) in ['Admin', 'Editor', 'Viewer'];
        allow create: if getRole(database, orgID, request.auth.uid) in ['Admin', 'Editor'] &&
                          getMaterial(database, orgID, materialID) == null &&
                          (request.resource.data.glyphIDs == null || 
                          request.resource.data.glyphIDs.size() == 0);
        // Allows writes if the user is an org admin or editor, and if glyphIDs are included in the request, the org must own them all
        allow update: if getRole(database, orgID, request.auth.uid) in ['Admin', 'Editor'] &&
                          getMaterial(database, orgID, materialID) != null &&
                          (request.resource.data.glyphIDs == null || 
                          request.resource.data.glyphIDs.size() == 0 || 
                          request.resource.data.glyphIDs.hasOnly(getOrgGlyphIDs(database, orgID)));
        allow delete: if getRole(database, orgID, request.auth.uid) in ['Admin', 'Editor'] && getMaterial(database, orgID, materialID) != null;
      }
      // Only allow a user to read/write/delete the documents in the 'Glyphs' collection
      // if their uid is equal to the orgID
      match /Glyphs/{glyphID} {
        allow get: if true; // if getRole(database, orgID, request.auth.uid) in ['Admin', 'Editor', 'Viewer'];
        allow list: if getRole(database, orgID, request.auth.uid) in ['Admin', 'Editor', 'Viewer'];
        allow create: if false;  // Created in via admin sdk
        allow update, delete: if getRole(database, orgID, request.auth.uid) in ['Admin', 'Editor'] && getGlyph(database, orgID, glyphID) != null;
      }
      // Only organiation admin can manage roles
      match /Roles/{roleID} {
        allow read: if roleID == request.auth.uid || getRole(database, orgID, request.auth.uid) == 'Admin';
        allow write, delete: if false;  // should be serverside only
      }

      // Only organiation admin can manage roles
      match /Users/{userID} {
        allow read: if userID == request.auth.uid || getRole(database, orgID, request.auth.uid) == 'Admin';
        allow write, delete: if false;
      }
    }
    match /GlyphHashes/{glyphHashID} {
      // Allow read access to a specific document
      allow get: if true;
      // Disallow listing all documents in the collection & writing/deleting
      allow list, write, delete: if false;
    }
  }
  // Allow users to fetch their own role via collectionGroup query
  match /{document=**}/Roles/{roleID} {
    allow read: if request.auth.uid == resource.data.id;
    allow write, delete: if false;
  }

  function getRole(db, orgId, userId) {
    return get(/databases/$(db)/documents/Organizations/$(orgId)/Roles/$(userId)).data.role;
  }
  function getOrgGlyphIDs(db, orgId) {
    return get(/databases/$(db)/documents/Organizations/$(orgId)).data.allGlyphIDs;
  }
  function getGlyph(db, organizationId, glyphId) {
    return get(/databases/$(db)/documents/Organizations/$(organizationId)/Glyphs/$(glyphId));
  }
  function getMaterial(db, organizationId, materialId) {
    return get(/databases/$(db)/documents/Organizations/$(organizationId)/Materials/$(materialId));
  }
}