您如何为安全的多用户共享对象访问建模 Parse 数据库?

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

我正在尝试为我的 Parse 数据库建模以使用角色进行 ACL 访问。角色将包含许多用户,以便用户可以拥有与其共享数据的组。我还 100% 锁定所有 CLP。只有用户拥有 public 登录和创建的 find() 和 write() 访问权限。

我还没有看到任何对此进行解释的确切情况。我见过许多关系、指针和 ACL 角色访问的示例,但 none 用于共享的安全数据库。到目前为止,我无法理解或推断我如何锁定 CLP(没有 find())和基于角色的 ACL 访问。指针或关系能否以某种方式实现这一点?

当前获取颜色 returns 所有具有主密钥的对象(显然与我想要的相反)或拒绝访问。

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;
  });

正在将用户添加到角色

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. 当前角色指向用户,这可以很好地按照上面的方式添加用户。
  2. 我的颜色 class 具有基于角色的 ACL 访问权限,并且适用于单个用户。
  3. 所有 CPL 目前都已锁定,我想保持这种状态。

有人可以帮我指明正确的方向吗?指向正确的方向或与我联系 ;)

在 Parse Server 安全工作的方式中,对于特定用户访问特定对象,对象的 ACL 规则和对象的 CLP 规则都必须通过 class。这意味着,如果您删除某个 class 对 CLP 的所有权限,则该 class 的所有对象将只能通过主密钥访问,这看起来像您的行为。

由于每个对象都有 ACL 规则,我将 CLP 设置为仅允许经过身份验证的用户,您应该通过这种方式实现您的需要。

我让这件事完全按照我的意图发生,尽管是以一种迂回的方式,而不是直接使用关系或指针。我敢肯定有一种更简单的方法可以做到这一点,但我不知道。

在我的简单演示项目中,我有一个代表简单数据的颜色 class,class 包括一个颜色和一个 groupOwner。组所有者 属性 是与每个新对象一起保存的角色名称。在查询所有颜色时,我正在检查用户的角色并将其与用户有权访问的颜色进行引用。这样根据用户的角色只返回授权对象。

在我的项目中,除了登录和注册之外,所有 CLP 都是 100% 锁定的,即使是这些我也在考虑锁定以通过云代码调用。我想要尽可能多的服务器控制和尽可能多的隐藏代码。

如果有人有意见或更好的方法请分享:)

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;
  });