Well Back on The Moose Track

So after my little crash yesterday I had to revisit my decision to use 'MooseX::AuthorizedMethods' as I was using it totally wrong. It seems to have been defaulted to use a 'User' class of some sort that has a roles method on it which is checked against a passed in array-ref of roles.

Here I was thinking it was checking for 'Moose::Role' classes applied to the calling class and doing all sorts of neat Mossey stuff when in fact this is more 'Instance/Application' code rather than foundation code. Well looking at Daniel's other CPAN offerings I could see how this could be a very very useful default for him. Anyway my bad I should of looked at it closer.

So what to do?

Well after much trial and a whole lot of error I finally got the 'verifier' to work (an example in the POD and or a test would of helped, hint, hint, nudge, nudge, wink wink).

So what I eventually did was to create a 'Product::BRULE::Authorize' class that implements the 'authorized_do' method that is called for. I had to actually look at the source for CheckRoles.pm more than a few time to figure this out. Again a little help from the pod would be nice.

So in the end looked something like this

 
package Product::BRULE::Authorize;

use Moose;
use Moose::Util;

sub authorized_do {
my $self = shift;
my ( $method,$roles,$code,$instance) = @_;

foreach my $role (@{$roles}){
return $code->(@_)
if (Moose::Util::does_role($instance,$role));
}

die ...


So in the above the '$self 'is the instance of my 'Product::BRULE::Authorize' class, the '$method' is the Meta of the originating class 'Product::Moves', the '$roles' is my array ref of 'Moose::Roles', the '$code' is my code reference that 'bin_swap' will invoke and '$instance' is the current instance of the calling class.

So all I do with this is loop though the roles array ref and with my handy 'Moose::Util::does_role' I check if the instance has that role and if it does it fires the code and returns. If no roles are present it then die's with a nice pretty error message that I won't bother to repeat.

Now in my class code I had to make this change all over the place;

 
package Product::Moves;
use MooseX::AuthorizedMethods;
use Product::BRULE::Authorize;
...
authorized bin_swap => [qw(Product::BRULE::Bin ], sub {
...
},(verifier=>Product::BRULE::Authorize->new())

...



and things all worked out correctly. I even ran my tests with differing users and they all worked so I did manage to 'fix' it sort of.

I still have second thoughts as this code was not really written for what I am warping it into and in the end I still had to write more code and some of it is ugly as I am now having an extra 'use' on all my classed and a I really do not like all those ->new on each method call. That will quickly become a very large amount of rarely used instances hanging about. I could just use one instance of 'Product::BRULE::Authorize' but then again would be introducing a global app var then which is a whole other kettle of fish.


USST-Thanksgiving-012-768x1024.jpg

Leave a comment

About byterock

user-pic Long time Perl guy, a few CPAN mods allot of work on DBD::Oracle and a few YAPC presentations