Consent: a little firewall DSL for your Rails app

Well, it’s been a couple of months. Rest assured I’ve still been hacking away; JS.Class will be getting hashes and constants at some point in the future, I’ve got a bunch of improvements to make on Bluff, and I’ve been contributing to PDoc which is a really promising JavaScript doc engine from Tobie Langel that uses the excellent Treetop parsing engine. But enough about all that.

As a little new year present, I hacked up Consent for a friend. He was telling me he had this nice resourceful, RESTful Rails app but there was some logic, mostly permissions-style stuff, that he wasn’t sure how to do cleanly and without making his app kinda messy. I’m not sure if Consent is the answer he was after, but it’s one stab at a solution.

Consent is basically a declarative firewall for ActionController: you write a bunch of rules in a single config file, and these rules are processed on every request before the request gets to your controller. Using combinations of controller and action names, parameter matches and HTTP verbs, you can select actions from your app and use Ruby blocks to decide whether requests should be processed or whether you should be bounced to a 403 page. It’s an alternative to using verify and method-specific access control logic; you can still access the request and session data but you’ve factored your access control logic out of the controller into a separate layer.

As a quick example, here’s a rule that says all requests to SiteController#hello must be Ajax requests:

  site.hello { request.xhr? }

It’s currently reasonably well-tested and documented but needs some polish; the rule language basically works but we could do with stuff like customisable 403 responses and the like. Check it out on github, hack around, tell me if it sucks, you know the drill by now.

If you’ve enjoyed this article, you might enjoy my recently published book JavaScript Testing Recipes. It’s full of simple techniques for writing modular, maintainable JavaScript apps in the browser and on the server.