Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Authorization rules in bolt #50

Open
tirsen opened this issue Mar 11, 2016 · 5 comments
Open

Authorization rules in bolt #50

tirsen opened this issue Mar 11, 2016 · 5 comments

Comments

@tirsen
Copy link

tirsen commented Mar 11, 2016

We're using the bolt compiler for our authorization rules. Can we get a port of the authorization rules to bolt please?

@wconnorwalsh
Copy link

+1

@pandaiolo
Copy link

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

@leblancmeneses
Copy link

Thoughts on why firebase-queue should not exist in our bolt rules

  • You don't own the type so upgrades of this third party lib would seem error prone. I would recommend to not specify an [is Type] rule.
  • authorization rules only should be specified on the '/queue' path.
    read() { auth.canAdministerQueue || auth.canProcessQueue }
    write() { auth.canAdministerQueue || auth.canProcessQueue }
  • specs - is a devops 1 time migration script using a custom firebase token with canAdministerQueue claim.
  • tasks - should not be exposed to the browser client. This is an ongoing backend process that watches a path and writes to a given queue/task using canAdministerQueue claim.

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?

@mckoss
Copy link

mckoss commented Aug 4, 2016

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()"
    }
  }
}

@leblancmeneses
Copy link

leblancmeneses commented Oct 18, 2016

@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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants