Reputation: 147
The question is about the ships branch expanded below. Everywhere only authenticated users are allowed to write their OWN data everywhere. However, there is one exception. ANY authenticated user may read data out of the ships branch.
So far I had no trouble but here is one special rule:
ANY authenticated user may delete a child under any uid in the ships branch provided that the timestamp is 10 seconds or older.
I want any user to be able to call:
firebase.database().ref('/ships/gp3tJa3tgThukt39EejqJpZq12L2/granit').remove();
uid: gp3tJa3tgThukt39EejqJpZq12L2
shipid: granit
And be granted the rights to delete only.
In order to check the age of the record I store a firebase.database.ServerValue.TIMESTAMP
in the perf
array at index 0
(I am using an array here because this record is frequently updated and I want to keep data to a minimum).
On the client side, the program can see when a record is likely to have expired and only then call remove. This in order to avoid wasteful failed calls.
I need some help to define the correct rule. The line in question is highlighted in the second example where I attempted to define this rule.
{
"ships": {
"EnBawzb0CjZVgAKrMZD4HE3k5rW2": {
"oasisoftheseas": {
"param": {
"scale": 0.33075936163570846,
"type": "cruise/royalcaribbean/oasisoftheseas"
},
"perf": {
"0": 1,
"1": 1.11014724E7,
"2": 1.70473256E7,
"3": 115.7,
"timeStamp": 1475144447302
}
}
},
"gp3tJa3tgThukt39EejqJpZq12L2": {
"granit": {
"param": {
"scale": 0.12235531736978282,
"type": "riverbarge/granit"
},
"perf": {
"0": 5,
"1": 2.05622392E7,
"2": 13154087,
"3": 285.9,
"timeStamp": 1475144450086
}
}
}
}
}
Below the rules. It is the write rule for $shipid that I am interested in defining correctly.
{
"rules": {
"anchors": {
"$uid":{
".read": "auth.uid === $uid",
".write": "auth.uid === $uid"
}
},
"completed": {
"$uid":{
".read": "auth.uid === $uid",
".write": "auth.uid == $uid"
}
},
"ships": {
".read": "auth !== null",
"$uid":{
".write": "auth.uid === $uid",
"$shipid":{
".write": "((auth !== null) &&
(now - data.child('perf').child('timeStamp').val() >= 10000))"
}
}
},
"shipslog": {
"$uid":{
".read": "auth.uid === $uid",
".write": "auth.uid === $uid"
}
}
}
}
Upvotes: 0
Views: 708
Reputation: 147
Well, I figured it out as confirmed by Frank. The solution edited in the question is correct, secure and working.
"ships": {
".read": "auth !== null",
"$uid":{
".write": "auth.uid === $uid",
"$shipid":{
".write": "((auth !== null) &&
(now - data.child('perf').child('timeStamp').val() >= 10000))"
}
}
},...
Any data can be written to the ships branch by the owner of the record. At a deeper level I use the uid wildcard and shipid wildcard to get to the data that can expire and needs to be removed.
The timestamp is secure as it is provided by the server on the server side. Deleting a ship can only happen by any authenticated user AND provided the difference between now and the timestamp is greater then 10000 milliseconds.
This is probably a nice clean generic way to let client apps cleanup old data without the need for serverside business logic.
Upvotes: 1