I've been kicking some ideas around for a few days and not coming up with a solution I like. So, I'm now asking for help here from the Moose community, specifically for fresh ideas for adding a permissions architecture on top of my Moose classes.
Some time back we started replacing one big, ugly monolithic web app with Catalyst. We used DBIC as the "Model" layer as is commonly done and pushed much business logic into Result and ResultSet classes. But with a dozen or so developers, some with old habits, I see our Controllers growing fat with business logic. But, we need to be able to use the "app" in more than just Catalyst (and in more than one Catalyst app, as well), so I'm working on adding a Moose-based Model layer that sits on top of our DBIC layer where that business logic can be located (and thus used by many consumers). One handy thing about Catalyst is we are able to hook into the request and see what "action" is going to run before it runs. That makes it pretty easy to do things like centralized data validation (which is why I asked about "automatically" wrapping methods) and access control before an action runs. The other thing Catalyst does is abstract out the model methods by URL. So "GET /widget/123" can read a row from the widget table if the user has access, an "PUT /widget/123/owner" might set a column on the same widget row but makes it easy to add additional access/permission checking (you have access AND be an admin or current "owner" of the widget). I don't want to reinvent Catalyst, but I now have a set of Moose classes that sit on top of DBIC (and other data sources) that mostly provides an abstraction layer to hold that code that was sitting in the fat Catalyst controllers. But, I'd like to separate out the access/permission checking from the work of fetching and updating -- a large number of methods in this new model need to test the same permissions. Access/permission control is very important -- and in our app tends to be complex and expensive to test. So, I'd like to have this live as it's own set of classes (with its own tests, and caching, etc.). Something that enforces a clean separation of concerns and is easier to maintain. And that is the architecture I'm struggling with. Anyone have suggestions how to use Moose to structure this? It's not a terribly hard problem, but again looking for something a bit more clever than just: package App::Model::Widget; use Moose; sub set_widget_owner { my ( $self, $new_owner, $current_user ) = @_; die unless $self->access_layer->widget->can_set_owner( $self, $current_user ); # update owner ... } -- Bill Moseley mose...@hank.org