组的Firebase数据库规则

时间:2017-06-25 15:32:16

标签: json firebase firebase-realtime-database firebase-security

我有这个Firebase DB,必要时可以更改:

DB

该DB的JSON是:

{
  "groups": {
    "1": {
      "name": "G1",

      "points": {
        "1": {
            "name": "p1"
        }
      },
      "visits": {
        "1": {
            "name": "v1"
        }
      },
      "areas": {
        "1": {
            "name": "a1"
        }
      },
      "waypoints": {
        "1": {
            "name": "w1"
        }
      },
      "interests": {
        "1": {
            "name": "i1"
        }
      }
    },
    "2": {
      "name": "G2",

      "points": {
        "2": {
            "name": "p2"
        }
      },
      "visits": {
        "2": {
            "name": "v2"
        }
      },
      "areas": {
        "2": {
            "name": "a2"
        }
      },
      "waypoints": {
        "2": {
            "name": "w2"
        }
      },
      "interests": {
        "2": {
            "name": "i2"
        }
      }
    }
  },
  "users": {
    "qdRw1khg1ZO1s52YioYCdM4WrD02": {
      "firstName": "AAAA",
      "lastName": "BBB",
      "email": "sdf@sdfs.com"     
    },
    "h3KYDXkPQrY246w6Y6NXIanVoNS2": {
      "firstName": "FF",
      "lastName": "RR",
      "email": "wwf@jjuzhz.com"
    }
  },
  "userGroups": {
    "qdRw1khg1ZO1s52YioYCdM4WrD02": {
      "1": "admin",
      "2": "readwrite"
    },
    "h3KYDXkPQrY246w6Y6NXIanVoNS2": {
      "1": "admin",
      "2": "readonly"     
    }
  }
}

我想定义规则来完成以下任务:

  • 每个人都可以创建一个新组
  • 只有群组的用户才能阅读群组数据
  • 只有组的“管理员”可以将数据写入组本身,添加用户并更改组数据的子级别
    • “readwrite”组用户可以写入子级别“points”和“visits”
    • “readonly”群组用户根本无法写入

我有:

"groups": {          
  "$groupId": {
    ".read": "root.child('userGroups').child(auth.uid).child($groupId).exists()",
    ".write": "! root.child('userGroups').child(auth.uid).child($groupId).exists() || 
                          (data.parent().val() === 'points' && root.child('userGroups').child(auth.uid).child($groupId).val() != 'readonly') ||
                        (data.parent().val() === 'visits' && root.child('userGroups').child(auth.uid).child($groupId).val() === 'readonly') ||
                        (data.parent().val() != 'points' && data.parent().val() != 'visits' && root.child('userGroups').child(auth.uid).child($groupId).val() === 'admin')"
  }
},
"users": {
  "$userId": {
    ".read": "auth != null",
    ".write": "auth != null && 
              $userId === auth.uid && 
              newData.val() != null"
  }
},
"userGroups": {
  "$userId": {
    ".read": "auth != null",
    ".write": "auth != null && 
               data.child(auth.uid).val() === 'admin' && 
               newData.val() != null"          
  }
}

但是,由于

,这不起作用
data.parent().val()

不返回父级的名称字符串。所以我做不到

data.parent().val() != 'points'

如何解决这个问题?问题是根据指定的规则将数据写入组。

2 个答案:

答案 0 :(得分:5)

Firebaser在这里。我希望这个答案能够随着时间的推移而更新。

我的第一步是将特定子节点的规则移动到该特定子节点。这消除了您遇到的parent()问题。第一次迭代是:

  "groups": {          
    "$groupId": {
      ".read": "root.child('userGroups').child(auth.uid).child($groupId).exists()",
      "points": {
        ".write": "root.child('userGroups').child(auth.uid).child($groupId).val() !== 'readonly'"
      }
    }
  },

这允许用户h3KYDXkPQrY246w6Y6NXIanVoNS2写入/groups/1/points(用户是管理员),但不能写入/groups/2/points(用户只能访问该帐户)。

下一步是使规则更通用。为此,我引入了一个$child变量,它匹配组下的任何节点:

  "groups": {          
    "$groupId": {
      ".read": "root.child('userGroups').child(auth.uid).child($groupId).exists()",
      "$child": {
        ".write": "root.child('userGroups').child(auth.uid).child($groupId).val() !== 'readonly'
                   || ($child !== 'points' && $child !== 'visits')"
      }
    }

这允许用户h3KYDXkPQrY246w6Y6NXIanVoNS2写入/groups/2/name(可由任何组成员写入),但不能写入/groups/2/points(用户只能读取访问权限)。

更新:显然我把你的逻辑颠倒过来,所以这是我最后的决定:

  "groups": {          
    "$groupId": {
      ".read": "root.child('userGroups').child(auth.uid).child($groupId).exists()",
      ".write": "root.child('userGroups').child(auth.uid).child($groupId).val() == 'admin'",
      "$child": {
        ".write": "root.child('userGroups').child(auth.uid).child($groupId).val() === 'readwrite'
                   && ($child !== 'points' || $child !== 'visits')"
      }
    }

使用此用户h3KYDXkPQrY246w6Y6NXIanVoNS2

  • 可以写信给/groups/1/name,因为他们是第1组的管理员
  • 可以写信给/groups/2/points,因为他们是第1组的管理员
  • 无法写信给/groups/2/name因为他们不是第2组的管理员
  • 可以写信给/groups/2/points,因为他们是第2组的读写成员

答案 1 :(得分:2)

如果您尝试“点”和“访问”级别的嵌套规则该怎么办:

System.setProperty("webdriver.chrome.driver", "./exe/chromedriver.exe");
    WebDriver driver = new ChromeDriver();
    driver.get("https://demo.actitime.com");
    driver.manage().timeouts().implicitlyWait(15, TimeUnit.SECONDS);
    driver.findElement(By.name("username")).sendKeys("admin");
    driver.findElement(By.name("pwd")).sendKeys("manager");
    driver.findElement(By.id("loginButton")).click();
    Thread.sleep(3000);
    WebDriverWait wait = new WebDriverWait(driver, 15);
    wait.until(ExpectedConditions.numberOfElementsToBe(By.xpath("//div[contains(text(), 'TASKS')]"), 1));
    driver.findElement(By.id("logoutLink")).click();
    driver.quit();