Open tirsen opened 8 years ago
+1
Here is my attempt, seem to work. Customize to your own needs. Not sure about the ErrorDetail
type, has it is not validated in the original format of the queue rules.
//
//
// Rules for the workers queue
//
//
path /queue/tasks {
read() { auth.canProcessTasks }
write() { auth.canAddTasks || auth.canProcessTasks }
index() { ['_state'] }
/{taskId} is Task {
validate() {
// Customize to your needs the following line
this.hasChildren(['_property_1', ..., '_property_n']) ||
(auth.canProcessTasks &&
this.hasChildren(['_state', '_state_changed', '_progress']))
}
}
}
path /queue/specs {
read() { auth.canAddSpecs || auth.canProcessTasks }
write() { auth.canAddSpecs }
/{specId} is Spec
}
type Task {
_state: String | Null,
_state_changed: InitialTimestamp | Null,
_owner: String | Null,
_progress: Percent | Null,
_error_details: ErrorDetail | Null,
_id: String | Null,
_property_1: XXX, // Change with custom properties validation
... // Change with custom properties validation
_property_n: XXX, // Change with custom properties validation
}
type Spec {
start_state: String | Null,
in_progress_state: String,
finished_state: String | Null,
error_state: String | Null,
timeout: PositiveNumber | Null,
}
type ErrorDetail {
error: String | Null,
error_stack: String | Null,
previous_state: String | Null,
original_task: Anything | Null,
attempts: PositiveNumber | Null
}
type InitialTimestamp extends Number {
validate() { noChange(this) || withInitialCondition(this, this == now) }
}
type PositiveNumber extends Number {
validate() { this >= 0 }
}
type Percent extends Number {
validate() { this <= 100 }
}
// Type `Any` has a bug, this is a workaround
// see https://github.com/firebase/bolt/issues/111
type Anything {
validate() {
this.isString() || this.isNumber() || this.isBoolean() || this.hasChildren()
}
}
withInitialCondition(ref, exp) { isNew(ref) && exp }
isNew(ref) { prior(ref) == null }
noChange(ref) { ref == prior(ref) }
Thoughts on why firebase-queue should not exist in our bolt rules
read() { auth.canAdministerQueue || auth.canProcessQueue }
write() { auth.canAdministerQueue || auth.canProcessQueue }
What I am having problems with is the last list item. How can I make it atomic? Ideally, I would want firebase to support a trigger so as a collection is appended I could auto append the task queue. Until then, it seems we may need firebase-queue-watcherâ„¢ to watch a collection and append the queue task collection. Is there a project that already mirrors an existing collection, recovers on restarts where it left off?
I fixed the Any bug in the Bolt repo yesterday if you want to try it out (I will release it via npm along with other bug fixes in the next day or so - probably as version 0.8.1).
BTW - while it currently works to call methods like hasChildren() and isBoolean() in your own validate methods, it's more idiomatic to use type statements.
// This Bolt definition ...
type Anything extends String | Number | Boolean | Object;
path /x is Anything;
// ... produces this JSON output:
{
"rules": {
"x": {
".validate": "newData.isString() || newData.isNumber() || newData.isBoolean() || newData.hasChildren()"
}
}
}
@mckoss Is there a way to get "$other": to be replaced with a custom expression?
"$other":{ '.validate': "auth != null && auth.uid == 'feature-worker'" }
benefits: 1) Forces the web client to match the Type specified on the path. 2) My Type doesn't care about firebase-queue internal data structures. 3) Allows my firebase queue worker to be able to write other queue specific properties when limiting write access with databaseAuthVariableOverride: { uid: "feature-worker" } to the rest of my database.
We're using the bolt compiler for our authorization rules. Can we get a port of the authorization rules to bolt please?