简体   繁体   中英

How could you model Parse database for secure multi-user shared object access?

I'm trying to model my Parse database for ACL access with Roles. Roles will contain many users so that users can have groups with whom they share data. I am also locking all CLPs 100%. Only User will have public find() & write() access for login and creation.

I have not yet seen an exact situation where this was explained at all. I have seen many examples of relations, pointers and ACL Role access but none for shared, secured database. So far I cannot understand or extrapolate how I can have locked CLPs (no find()) and Role based ACL access. Can pointers or relations enable this somehow?

Current get colors either returns all objects with master key (obviously the opposite of what I want) or access denied.

Parse.Cloud.define("ccGetColors", async (request) => {
    let currentUser = request.user;
    let query = new Parse.Query("Color");
    // query.equalTo("user", currentUser);
    let results = await query.find({ useMasterKey: true });
    if(results.length === 0) throw new Error('No results found!');
    let steralizedResults = [];
    for (let i = 0; i < results.length; i++) {
      let object = results[i];
      let color = object.get("color");
      steralizedResults.push(color);
    }
    return steralizedResults;
  });

Adding user to roles

Parse.Cloud.define("ccAddUserToRole", async function(request) {
    let user = request.user;
    // Get group admin ID
    let userQuery = new Parse.Query("AddUser");
    let results = await userQuery.find({ useMasterKey: true });
    let resultObject = results[0];
    let groupAdminObject = resultObject.get("groupAdmin");
    let groupAdminID = groupAdminObject.id;
    // Concatonate group name
    let groupName = "Group_" + groupAdminID;
    // Query for group role with group ID
    let roleQuery = new Parse.Query(Parse.Role);
    roleQuery.contains("name", groupName);
    roleQuery.first({ useMasterKey: true }).then(function(role) {
        console.log(role);
        role.relation("users").add(user);
        role.save(null, { useMasterKey: true });
    });
  });
  1. Currently role points to users, this is working nicely adding users as per above.
  2. My color class has Role based ACL access and works fine for a single user.
  3. All CPLs are currently locked and I want to keep it that way.

Can someone help point me in the right direction? Either pointer or relation me in the right direction;)

In the way Parse Server security works, for a certain user to have access to a certain object, BOTH ACL rule rule for the object AND CLP rule for the object's class must pass. It means that, if you remove all permissions on CLP of a certain class, all objects of that class will only be accessible via Master Key, which looks like the behavior you have.

Since you have ACL rules for each of the objects, I'd set the CLP to allow authenticated users only, and you should achieve what you need this way.

I got this to happen exactly as I intend, albeit, in a bit of a roundabout way not directly using relations or pointers. I'm sure there is an even easier way of doing this however I don't know about it.

In my simple demo project I have a color class representing simple data, the class includes a color and a groupOwner. The group owner property is the role name which is saved with each new object. On query for all colors I'm checking for user's role and referencing this against the colors the user has access to. This way only authorized objects are returned based on user's role.

In my project all CLPs are 100% locked except login and signup, and even these I'm looking at locking to call through cloud code. I want as much server control as possible and as much hidden code as possible.

If anyone has input or a better way please share:)

Parse.Cloud.define("ccSaveColor", async (request) => {
    let colorString = request.params.color;
    const query = await new Parse.Query(Parse.Role).equalTo('users', request.user).find({ useMasterKey: true })
    let role = await query[0];
    var groupACL = new Parse.ACL();
    groupACL.setRoleWriteAccess(role, true);
    groupACL.setRoleReadAccess(role, true);
    let Color = Parse.Object.extend("Color");
    let color = new Color();
    color.set("groupOwner", role.get("name"));
    color.set("color", colorString);
    color.setACL(groupACL);
    return await color.save(null, { useMasterKey: true });
  });
  
  Parse.Cloud.define("ccGetColors", async (request) => {
    const roleQuery = await new Parse.Query(Parse.Role).equalTo('users', request.user).find({ useMasterKey: true })
    let role = await roleQuery[0];
    let query = new Parse.Query("Color");
    query.equalTo("groupOwner", role.get("name"));
    let results = await query.find({ useMasterKey: true });
    if(results.length === 0) throw new Error('No results found!');
    let steralizedResults = [];
    for (let i = 0; i < results.length; i++) {
      let object = results[i];
      let color = object.get("color");
      steralizedResults.push(color);
    }
    return steralizedResults;
  });

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM