npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

cancan-backbone

v0.0.1

Published

A library with Javascript bindings for the Ruby access control library CanCan

Downloads

10

Readme

CanCan for Backbone.js

Real-world web applications often rely on a combination of server-side and client-side code. If you're building a Rails application, you're probably relying on an access control library like CanCan, and a JS framework like Backbone.js for client side rendering.

This library makes it possible to export your CanCan abilities from Ruby to JS, and do the same access checks on the client side. This is great for doing UI-specific functionality, but should of course be backed by an API with tight access control.

The JS code was adapted directly from the CanCan Ruby code, but without Ruby-specific functionality like blocks, etc.

Coverage

See the tests for coverage. Most of the CanCan functionality has been implemented, although only the action, subject and conditions will be used in the JS library. Your ability blocks will not work.

Model associations will work, if you return the data in the main model response. This means that this rule:

ability.set_can("read", Comment, { user: { id: 1 }});

Will only work if your API json response for that comment model looks like this:

{
	"body" : "This is a comment",
	"user" : {
		"id" : 1
	}
}

On the API side, this will probably be way too slow for larger sets of associations, but that's just how it is right now. If I had time, I would probably try to implement some type of lazy-loading of associations.

Setup

First drop the cancan-backbone.js file into your assets folder.

Then in your Backbone models, add a backboneClass class property, make sure you define it in the object that is the second parameter to Backbone.Model.extend. The second object is for classProperties:

var Comment = Backbone.Model.extend({}, {backboneClass:"Comment"});

In your controller/helper, implement a method that exports you abilities to JSON. This looks something like this:

def ability_to_array(a)
  a.instance_variable_get("@rules").collect do |rule| 
    rule.instance_eval do
      {
        :base_behavior => @base_behavior,
        :subjects => @subjects.map(&:to_s),
        :actions => @actions.map(&:to_s),
        :conditions => @conditions
      }
    end
  end
end

... and can be used like this:

@js_abilities = ability_to_array(current_ability)

In your view, you can now pass the abilities into js:

var ability = new Ability({rules : <%= @js_abilities.to_json.html_safe %>});

Usage

If you already loaded your abilities into your model, you're all ready to check for access:

ability.can("read", Comment);
ability.can("read", "custom");
ability.can("read", new Comment());

If you want to set abilities from JS, you need to use the set_ functions:

ability.set_can("read", Comment, {id:1});
ability.set_can("read", "somethingelse");

It's also possible to pass the name of your Backbone models as strings. It will still work:

ability.set_can("index", "Comment");
ability.can("index", Comment)  // => true
ability.can("index", "Comment")  // => true

ability.set_can("index", Post);
ability.can("index", Post)  // => true
ability.can("index", "Post")  // => true

Obviously, you need the backboneClass of your backbone models to correspond to your Rails models.

Contributors

  • @runemadsen
  • @bogn