[Catalyst] Advanced role-based authorization

J. Shirley jshirley at gmail.com
Tue May 20 19:30:32 BST 2008


On Mon, May 19, 2008 at 10:56 PM, jakac <jakac at iprom.si> wrote:
> Hello!
>
> Yes, I am also pretty sure that I will not be able to achieve something like
> this using
> one of the common plugins. So I was wondering if anybody has a simple
> solution
> for this kind of problem?
>
> Since my application will be used by a limited number of users (about
> 100-200) I am
> not afraid that users_pages_roles table would grow too big but I still need
> some
> kind of solution..
>
> Thanx.
>
> sindharta_tanuwijaya at yahoo.co.jp wrote:
>
> Hi,
>
> I don't think you can achieve that by Catalyst::Plugin::Authorization but
> please correct me if I am wrong.
>
> On a side note though, I also had an idea that is similar to yours some time
> ago, but I scrapped it because the number of records in
> users_pages_roles tables will increase exponentially as the number of users
> and pages increase.
> I wonder how the sharing function is implemented in Google Docs though.
>
> Sindharta
>
> jakac <jakac at iprom.si> wrote:
>
> Hello!
>
> I am new to Catalyst and I am developing my first web application using this
> really
> great framework. I really like the way Catalyst allows me to build my
> application but
> now I have a problem which I can not resolve by myself.
>
> I studied the tutorial and I understand the whole concept of "role based"
> authorization
> where we have three tables:
>
> - users (list of users with primary key user_id)
> - roles (list of roles with primary key role_id)
> - users_roles (with user_id - role_id relations)
>
> but for my application I need a bit more advanced system than that because
> every
> user has also multiple pages and different roles for each page (he can edit
> some,
> only view the others etc.). One user has different permissions for each of
> the pages and
> also more users have access (and different permissions) to the same page.
> So I need 4 tables:
>
> - users (list of users with primary key user_id)
> - roles (list of roles with primary key role_id)
> - pages (list of pages with primary key page_id)
> - users_pages_roles (with user_id - page_id - role_id relations)
>
> e.g.:
> user1 | page1 | edit
> user1 | page2 | edit
> user2 | page2 | view
> user3 | page1 | edit
> user3 | page2 | view
> etc.
>
> How can I make this kind of authorization using Catalyst? How to build a
> model
> and configure "roles" plugin?
>
> Also with simple role based system I can check if user has permission to use
> that part
> of application using:
>
> $c->assert_user_roles( qw/rolename/ );
>
> What about with this kind of "advanced" authorization?
>
> Thank you all!
>
> JakaC.
>

The way that I tend to do this is a Util controller that contains
actions that have these rules configured.

So, in a public action that requires admin for view and edit, or
regular user for view only, once you know if that action is viewing or
editing, forward that way:

$c->forward('/util/action_acl', [ 'view', 'edit' ]);

Then, in the private action:
sub action_acl : Private {
    my ( $self, $c, @permissions ) = @_;
    # Do check here
    unless ( $has_access ) {
        $c->detach('/errors/permission_denied');
}


The way that you do the actual check is really specific to your
application.  In one application I'm working with, I have a huge
config hash (and this action is in a separate ACL controller, rather
than a generic Util controller)

so I have:
package MyApp::Controller::ACL;

__PACKAGE__->config(
    rolename => {
       '/action/root' => [ 'view', 'edit', 'delete' ]
    }
);

Then it is very easy to just look at $c->action->reverse and look if
they have that in the array ref.

The -really- nice thing about this is that I can use the ACL as a base
class and inherit it and config things separately down the chain,
since config is merged in as you would expect.

(PS., this is all just simplified, really.  I don't have
view,edit,delete style permissions in my app; I actually have
different levels of "view" based on the permission and level of the
user since I work with sensitive personal data... but it works well,
in testing anyway)



More information about the Catalyst mailing list