[Maypole] Maypole::Plugin::Authorization

Dave Howorth dhoworth@mrc-lmb.cam.ac.uk
Thu, 27 Jan 2005 11:33:45 +0000


Peter Speltz wrote:
> while we're on subject. here's some subs useful for making the addnew
> permission form with select boxes. I added these to M::P::Authorization.pm. 

Hi Peter,

Thanks for the subs. I'm not sure their natural home is 
M::P::Authorization.pm though?

> # pjs -- ok_model_classes() -- turns ok tables into a list of classes
> sub ok_model_classes {
>     my ($r) = @_;
>     map { $r->config->model->class_of($r, $_) } keys %{$r->config->ok_tables};
> }

This is using ok_tables to decide what classes it's possible for the 
authorization system to manage. I would rather use the authorization 
system to determine what's possible and allowed and deduce an 
appropriate value for display_tables and ok_tables for a particular 
request from that.

But in any event I think this sub would belong in the model rather than 
the authorization subsystem.

> # returns list of public actions for model class
> sub model_actions {
>     my ($r, $model) = @_;
>     #$model ||= $r->model_class;
>     die "No model to get actions for." unless $model;
>     use Class::Inspector;
>     my $methods = Class::Inspector->methods($model);
>     my @actions = ();
>     for my $meth (@$methods) {
>          push @actions, $meth if  $model->is_public($meth);
>     }
>     @actions;
> }

Again, I think this method properly belongs in the model class. I 
originally put it in the driver class out of laziness! I find it's 
easier to prototype things like that.

> To use them i have this huge ugly sub prep_form_input in my permission class.
> It's like an AsForm but just for this one class. It be cool if this could be
> built into M:P:Authorization.pm somehow as its a lot of work to use it. I may
> try moving it to there and see what i come up with.
> 
> # call this in pages that have addnew, edit, search forms
> # Permissions->prep_form_input($r);
> sub prep_form_input{
>     my ($self, $r) = @_;
>     my $params = $r->params;
>     warn "params are " . Dumper($params);
>     my $targs = $r->template_args;
>     $targs->{classmetadata} ||= {};
>     my $cgi = $targs->{classmetadata}->{cgi} = {}; # clean cgi input slate
> 
>     # get ready to make 3 inputs -- role and model class and method select box
>     my $model = $params->{model_class};
>     my @actions = $model ? $r->model_actions($model) : ();
>     unshift @actions, '*' if @actions;
>     my @ok_classes = $r->ok_model_classes;
> 
>     # make the input html elements
>     my $role = $self->to_field('auth_role_id');
>     warn Dumper($role);
>     my $class= $self->a_select_box('model_class', \@ok_classes, $model);
>     my $meth = $self->a_select_box('method', \@actions) ;
>     $class->attr('onChange' => "do_reload()");
> 
>     # put in template args cgi slot
>     $cgi->{auth_role} = $role;
>     $cgi->{model_class} = $class;
>     $cgi->{method} = $meth;
>     $targs->{classmetadata}{columns} = ['auth_role', 'model_class', 'method'];
> }

I think this is view-specific? It's setting up template arguments, it's 
making use of particular methods of dealing with cgi parameters and 
X/HTML output elements etc. There isn't really anywhere for 
class-specific view-related code that comes to mind (rereading that, 
perhaps a TT plugin is the obvious place?), so I guess the model class 
where you've got it is probably best. It's an action, or a large part of 
one. Some (all?) of the view-related code could be moved to the template 
itself to achieve better separation.

It's good stuff, though. I want to automate the field population. So 
I'll try adding these concepts to my app and see what flavour it turns 
out :)

Cheers, Dave