Fayland 林 > Catalyst-Authentication-Store-FromSub > Catalyst::Authentication::Store::FromSub

Download:
Catalyst-Authentication-Store-FromSub-0.01.tar.gz

Dependencies

Annotate this POD

View/Report Bugs
Module Version: 0.01   Source  

NAME ^

Catalyst::Authentication::Store::FromSub - A storage class for Catalyst Authentication using one Catalyst Model class

VERSION ^

version 0.01

SYNOPSIS ^

    use Catalyst qw/Authentication/;

    __PACKAGE__->config->{authentication} = {  
        default_realm => 'members',
        realms => {
            members => {
            credential => {
                class => 'Password',
                password_field => 'password',
                password_type => 'clear'
            },
            store => {
                class => 'FromSub', # or 'Object'
                user_type => 'Hash',
                model_class => 'UserAuth',
                id_field => 'user_id',
            }
        }
    } };

    # Log a user in:
    sub login : Global {
        my ( $self, $c ) = @_;

        $c->authenticate( {  
            username => $c->req->params->username,
            password => $c->req->params->password,
        } );
    }

    package MyApp::Model::UserAuth; # map with model_class in config above
    use base qw/Catalyst::Model/;
    use strict;

    sub auth { # sub name needs to be 'auth'
        my ($self, $c, $userinfo) = @_;

        my $where;
        if (exists $userinfo->{user_id}) { # restore from session (id_field => 'user_id')
            $where = { user_id => $userinfo->{user_id} };
        } elsif (exists $userinfo->{username}) { # from authenticate
            $where = { username => $userinfo->{username} };
        } else { return; }

        # deal with cache
        # if (my $val = $c->cache->get($key) {
        #     return $val;
        # } else {
            my $user = $c->model('TestApp')->resultset('User')->search( $where )->first;
            $user = $user->{_column_data}; # hash
        #     $c->cache->set($key, $user);
        # }

        return $user;
    }

DESCRIPTION ^

Catalyst::Authentication::Store::FromSub class provides access to authentication information by using a Catalyst Model sub auth.

In sub auth of the Catalyst model, we can use cache there (or do some complicated code). it would avoid the hit of db every request.

CONFIGURATION

The FromSub authentication store is activated by setting the store config class element to 'FromSub'. See the Catalyst::Plugin::Authentication documentation for more details on configuring the store.

The FromSub storage module has several configuration options

    __PACKAGE__->config->{authentication} = {  
        default_realm => 'members',
        realms => {
            members => {
                credential => {
                    # ...
                },
                store => {
                    class => 'FromSub',
                    user_type => 'Object',
                    model_class => 'UserAuth',
                    id_field => 'user_id',
                }
            }
        }
    };

    authentication:
      default_realm: 'members'
      realms:
        members:
          credential:
            class: 'Password'
          store:
            class: 'FromSub'
            user_type: 'Object'
            model_class: "UserAuth"
class

Class is part of the core Catalyst::Authentication::Plugin module, it contains the class name of the store to be used. it must be 'FromSub' here.

user_type

'Hash' or 'Object', depends on the return value in sub auth, REQUIRED.

model_class

Contains the class name (as passed to $c->model()) of Catalyst. This config item is REQUIRED.

id_field

For restore from session, we pass { $id_field => $c->session->{__user}->{$id_field} } to sub auth, so be sure you deal with this $userinfo in sub auth like

    sub auth { # sub name needs to be 'auth'
        my ($self, $c, $userinfo) = @_;

        my $where;
        if (exists $userinfo->{user_id}) { # restore from session (id_field => 'user_id')
            $where = { user_id => $userinfo->{user_id} };
        } elsif (exists $userinfo->{username}) { # from authenticate
            $where = { username => $userinfo->{username} };
        } else { return; }

It is a primary key return by sub auth. Default as 'id'

USAGE

The Catalyst::Authentication::Store::FromSub storage module is not called directly from application code. You interface with it through the $c->authenticate() call.

EXAMPLES

Adv.

    # for login
    sub login : Global {
        my ( $self, $c ) = @_;

        $c->authenticate( {  
            username => $c->req->params->username,
            password => $c->req->params->password,
            status => [ 'active', 'registered' ],
        } );
    }

    sub is_admin : Global {
        my ( $self, $c ) = @_;

        # use Set::Object in C::P::A::Roles
        eval {
            if ( $c->assert_user_roles( qw/admin/ ) ) {
                $c->res->body( 'ok' );
            }
        };
        if ($@) {
            $c->res->body( 'failed' );
        }
    }

    package MyApp::Model::UserAuth; # map with model_class in config above
    use base qw/Catalyst::Model/;
    use strict;

    sub auth {
        my ($self, $c, $userinfo) = @_;

        my ($where, $cache_key);
        if (exists $userinfo->{user_id}) {
            $where = { user_id => $userinfo->{user_id} };
            $cache_key = 'global|user|user_id=' . $userinfo->{user_id};
        } elsif (exists $userinfo->{username}) {
            $where = { username => $userinfo->{username} };
            $cache_key = 'global|user|username=' . $userinfo->{username};
        } else { return; }

        my $user;
        if (my $val = $c->cache->get($cache_key) {
            $user = $val;
        } else {
            $user = $c->model('TestApp')->resultset('User')->search( $where )->first;
            $user = $user->{_column_data}; # hash to cache
            # get user roles
            my $role_rs = $c->model('TestApp')->resultset('UserRole')->search( {
                user => $user->{id}
            } );
            while (my $r = $role_rs->next) {
                my $role = $c->model('TestApp')->resultset('Role')->find( {
                    id => $r->roleid
                } );
                push @{$user->{roles}}, $role->role;
            }
            # $user = {
            #     'roles' => [
            #         'admin',
            #         'user'
            #     ],
            #    'status' => 'active',
            #    'session_data' => undef,
            #    'username' => 'jayk',
            #    'email' => 'j@cpants.org',
            #    'password' => 'letmein',
            #    'id' => '3'
            #}
            $c->cache->set($cache_key, $user);
        }

        # validate status
        if ( exists $userinfo->{status} and ref $userinfo->{status} eq 'ARRAY') {
            unless (grep { $_ eq $user->{status} } @{$userinfo->{status}}) {
                return;
            }
        }

        return $user;
    }

SEE ALSO

Catalyst::Plugin::Authentication, Catalyst::Plugin::Authentication::Internals, Catalyst::Plugin::Authorization::Roles

AUTHOR ^

  Fayland Lam <fayland@gmail.com>

COPYRIGHT AND LICENSE ^

This software is copyright (c) 2009 by Fayland Lam.

This is free software; you can redistribute it and/or modify it under the same terms as perl itself.

syntax highlighting: