Tuesday, 31 March 2009

State of authentication

We're using restful_authentication for login - because it's a good standard set of tools. However, we didn't want activation for our system, as it's just a slow-down on the path to user kick-ass-ness, and we wanted out users up and running with a minimum of fuss. However what we *did* want, was statefulness (so we could suspend users).

When I ran the usual generator without the --include-activation flag, I figured that would be the trick...

Unfortunately, AR doesn't seem to grasp that you can have statefulness without activation - so the authentication/authorisation sections have an activation state (and set up an activation code and require that you provide it and activate your user... etc) regardless of your choice of --include-activation.

This is a bit annoying - especially because the Authorization module is now also hidden deep in the bowels of the AR plugin itself (rather than in the user model), which means I can't just delete the bits I don't want.

The plugin itself is not clear about how to go about setting up your own set of states (eg removing activation, or adding a "locked" state), so this is a quickie guide.

Setting up your own states

To begin with, to override your states, you need to copy the appropriate Authorization file into your lib directory eg:
cp vendor/plugins/restful_authentication/lib/authorization/stateful_roles.rb lib/my_stateful_roles.rb

Then require this file at the top of your user model eg:
require 'lib/my_stateful_roles.rb'

Open up this file and change the module name so you don't clash (in the bizarre case you need to use the standard set of states in some other model) eg:

module Authorization
  module MyStatefulRoles

Your user model will then have a reference to this module that you need to update from Authorization::StatefulRoles to Authorization::MyStatefulRoles

You now have a file that you can alter to your heart's content.

Coming soon: how to successfully remove the activation state from this file...

Monday, 30 March 2009

acts_as_state_machine 2.0

I spun up a new rails project and downloaded my favourite authentication plugin restful_authentication, only to find that all out-of-the-box tests break (oh noez!)

Clearly, I thought, restful_authentication is now just a millisecond behind edge rails... and therefore doesn't work properly anymore.

I quickly realised that no, it's just that the old-standard install (via svn) is no longer maintained - you have to move over to the github version.

This solves most of the problems, but I was still having a problem with one of the tests. It seems that acts_as_state_machine is similarly non-Rails 2.0 compliant.

Luckily, acts_as_state_machine has just a one-line fix to get it back up to scratch. It seems that the write_attribute method has been deprecated, and this causes a little bit of internal havoc for the state? style of methods (eg passive?, active? etc as used by restful_authentication).

The test cases kept giving me:

NoMethodError: You have a nil object when you didn't expect it!
The error occurred while evaluating nil.to_sym

To fix it, search for the string: "def set_initial_state", then replace the line (just below it):
write_attribute self.class.state_column, self.class.initial_state.to_s
with:
self.send "#{self.class.state_column}=", self.class.initial_state.to_s

I just want a toaster...

I was buying all my basic housey stuff at Tesco today (it's *that* kind of supermarket/superstore), but feeling overwhelmed... Being in a foreign country means all the brands mean nothing to you, so you don't know which ones do what, and you find there are many brands that do things you've never even heard of.

So you have two options. You can either pick things at random and hope you aren't going to end up with your washing machine spilling a river of frothy soap suds across the floor, or check every single item to make sure it does what you expect it to do.

When you have to read the back of every bottle of washing liquid and read all the dodgy manufacturers claims that mean nothing to you to decide whether you want "unscented" or "hypoallergenic" or "automatic" or "non-biological"... and whether that actually means anything or just another manufacturer's claim (like "full of wholesome goodness")... for every single item in the shopping trolley you find it's quite easy to take several hours just to do a normal shop.

By the end of that you come to a shining wall of toasters and find yourself weighing the benefits of "hi-lift" vs "variable-browning" and whether it's better to have "sneak peek" or "cool wall" technology and you get to the stage where you just want to scream "I want something that takes bread and spits out toast, that's *all* I want!"... :P

...and since when did toasters all become so *huge*. I'm missing the toaster I had in Sydney even despite having a dodgy Singapore plug that required a plug-adapter to use. It took four slices of toast and fit into nearly the same space as my new two-slice toaster that's tall and fat and looks like some kind of shiny metal alien pod. :P

and in case you ask "well why didn't I choose one that doesn't look like that - they all do, of course. Apart from the ones that are even *bigger* and look like some kind of industrial machine that will take your bread and throw it clear across the factory floor to the industrial jam-spreader...

...in the end, of course, I went with the one that had all of the above. Because I can't be sure I won't suddenly need "cool wall" technology (whatever that is)... I can always google it when I get home.