FAQ
Question: when a user logs in to our Catalyst app, he/she should only see
the items he/she is allowed to see. But the only way we can figure how to do
this is to pass $c->user either to the ResultSet methods or to the
FormHandler methods, making the app more and more interdependent... Is there
a better paradigm in the context of a Catalyst app?

Right now we're working this via DBIC ResultSet like so:

package Incident::Schema::DB::ResultSet::Incident;
use base 'DBIx::Class::ResultSet';

sub *security* {
my $rs = shift;
my $user = shift;

$user = $user->obj
if ( $user->can('obj') );
if ( $user->is_admin ) {
return $rs; # everything is visible to admins
}

my %visible_teams = map { $_ => 1 }
$user->corp_team_ids; # method from Incident::User schema
$rs = $rs->search(
{ 'me.team' =>
{ -in => [ keys %visible_teams ] }
},
{ order_by => ['created'] }
);

return $rs;
}

Then...

package Incident::Web::Controller::Ticket;
BEGIN { extends 'Catalyst::Controller'; }

sub base : Chained('/auth') PathPart('ticket') CaptureArgs(0) {
my ( $self, $c ) = @_;
my $rs = $c->model('Incident::Ticket')->security( *$c->user* );
$c->stash( incident_rs => $rs );
}

Is this Kosher? In this context it's a DBIC resultset depending on another
DBIC object, so it may not be as big an issue as, say, when we have
HTML::FormHandler popup menus that should only show the user options based
on the user's role and/or organization.

Is there a canonical way to approach this both in ResultSets and in
FormHandler forms?

--
"The very nucleus of Character: to do what you know you should do, when you
don't want to do it." Stephen Covey
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.scsys.co.uk/pipermail/catalyst/attachments/20111012/952b908d/attachment.htm

Search Discussions

  • Eden Cardim at Oct 18, 2011 at 10:00 am
    "will" == will trillich writes:
    will> Question: when a user logs in to our Catalyst app, he/she
    will> should only see the items he/she is allowed to see. But the
    will> only way we can figure how to do this is to pass $c->user
    will> either to the ResultSet methods or to the FormHandler methods,
    will> making the app more and more interdependent... Is there a
    will> better paradigm in the context of a Catalyst app?

    That is perfectly fine as long as you define an API for user and stick
    to it so you can replace it via duck typing afterwards.

    will> Right now we're working this via DBIC ResultSet like so:

    will> package Incident::Schema::DB::ResultSet::Incident;
    will> use base 'DBIx::Class::ResultSet';

    will> sub security {
    will> ? ? my $rs ? ? ?= shift;
    will> ? ? my $user ? ?= shift;

    will> ? ? $user = $user->obj
    will> ? ? ? ? if ( $user->can('obj') );
    will> ? ? if ( $user->is_admin ) {
    will> ? ? ? ? return $rs; # everything is visible to admins
    will> ? ? }

    will> ? ? my %visible_teams = map { $_ => 1 }
    will> ? ? ? ? $user->corp_team_ids; # method from Incident::User schema
    will> ? ? $rs = $rs->search(
    will> ? ? ? ? { 'me.team' =>
    will> ? ? ? ? ? ? { -in => [ keys %visible_teams ] }
    will> ? ? ? ? },
    will> ? ? ? ? { order_by => ['created'] }
    will> ? ? );

    will> ? ? return $rs;
    will> }

    will> Then...

    will> package Incident::Web::Controller::Ticket;
    will> BEGIN { extends 'Catalyst::Controller'; }

    will> sub base : Chained('/auth') PathPart('ticket') CaptureArgs(0) {
    will> ? ? my ( $self, $c ) = @_;
    will> ? ? my $rs = $c->model('Incident::Ticket')->security( $c->user );
    will> ? ? $c->stash( incident_rs => $rs );
    will> }

    will> Is this Kosher? In this context it's a DBIC resultset
    will> depending on another DBIC object, so it may not be as big an
    will> issue as, say, when we have HTML::FormHandler popup menus that
    will> should only show the user options based on the user's role
    will> and/or organization.

    will> Is there a canonical way to approach this both in ResultSets
    will> and in FormHandler forms?

    You might want to look at Catalyst::TraitFor::Model::DBIC::Schema::WithCurrentUser

    --
    Eden Cardim
    Code Monkey http://www.shadowcat.co.uk/catalyst/
    Shadowcat Systems Ltd. Want a managed development or deployment platform?
    http://blog.edencardim.com/ http://www.shadowcat.co.uk/servers/
    http://twitter.com/#!/edenc
  • Tomas Doran at Oct 21, 2011 at 6:35 pm

    On 11 Oct 2011, at 17:57, will trillich wrote:
    Is this Kosher?
    Yes, this is entirely fine!

    You may however want to look at
    Catalyst::TraitFor::Model::DBIC::Schema::WithCurrentUser, which will
    help your DBIC schema 'magically' get hold of the user if available,
    and DBIx::Class::Schema::RestrictWithObject, which will allow you to
    use that user to restrict your resultsets to the stuff that user can
    see...

    So basically, you're on completely the right lines - the 'right' thing
    to do is to just handle this at the DBIC layer (so that you tell DBIC
    your user, and then all resultsets you get back are things that user
    is allowed to see)..

    Hope this helps!

    Cheers
    t0m

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupcatalyst @
categoriescatalyst, perl
postedOct 12, '11 at 12:57a
activeOct 21, '11 at 6:35p
posts3
users3
websitecatalystframework.org
irc#catalyst

People

Translate

site design / logo © 2021 Grokbase