Show
Ignore:
Timestamp:
06/30/08 10:47:25 (5 years ago)
Author:
hidek
Message:

merge refactoring branch to trunk

Location:
lang/perl/Catalyst-Controller-RequestToken/trunk
Files:
14 added
11 modified

Legend:

Unmodified
Added
Removed
  • lang/perl/Catalyst-Controller-RequestToken/trunk/.shipit

    r13221 r14891  
    11steps = FindVersion, ChangeVersion, CheckChangeLog, DistTest, Commit, Tag, MakeDist, UploadCPAN 
     2git.tagpattern = %v 
     3git.push_to    = origi 
    24 
    3 git.tagpattern = %v 
    4 git.push_to    = origin 
  • lang/perl/Catalyst-Controller-RequestToken/trunk/Changes

    r13249 r14891  
    1 0.01    Thu Jun  5 0:32:10 JST 2008 
     10.02    Fri Jun  6 11:37:31 JST 2008 
     2                 
     30.01    Thu Jun  5  0:32:10 JST 2008 
    24                - first release 
    35 
  • lang/perl/Catalyst-Controller-RequestToken/trunk/Makefile.PL

    r13241 r14891  
    77build_requires 'Catalyst::Plugin::Session'; 
    88test_requires 'Catalyst::Plugin::Session::State::Cookie'; 
     9test_requires 'Catalyst::Action::RenderView'; 
    910test_requires 'Test::WWW::Mechanize::Catalyst'; 
    1011test_requires 'Test::More'; 
  • lang/perl/Catalyst-Controller-RequestToken/trunk/lib/Catalyst/Controller/RequestToken.pm

    r13285 r14891  
    44use warnings; 
    55 
    6  
    76use base qw(Catalyst::Controller); 
    87 
     8use Catalyst::Exception; 
    99use Scalar::Util qw/weaken/; 
    10  
    11 our $VERSION = '0.01'; 
    12  
    13 __PACKAGE__->config( 
    14         session_name => '_token', 
    15         request_name => '_token', 
    16 ); 
     10use Class::C3; 
     11use Digest(); 
     12 
     13our $VERSION = '0.02'; 
    1714 
    1815sub ACCEPT_CONTEXT { 
     
    2320    weaken( $self->{c} ); 
    2421 
    25     return $self->NEXT::ACCEPT_CONTEXT($c, @_) || $self; 
     22    return $self->NEXT::ACCEPT_CONTEXT( $c, @_ ) || $self; 
    2623} 
    2724 
    2825sub new { 
    2926    my $class = shift; 
    30     my $self  = $class->NEXT::new(@_); 
    31  
    32     $self->_setup(@_); 
    33     return $self; 
    34 } 
    35  
    36 sub _setup { 
    37     my $self = shift; 
    38     my ($c) = @_; 
    39  
    40     $self->config(%{$self->config}, %{$c->config->{'Controller::RequestToken'}}); 
     27    my ( $c, $args ) = @_; 
     28 
     29    my $self = $class->next::method( $c, $args ); 
    4130 
    4231    Catalyst::Exception->throw("Catalyst::Plugin::Session is required") 
    4332        unless $c->isa('Catalyst::Plugin::Session'); 
     33 
     34    my $config = { 
     35        session_name => '_token', 
     36        request_name => '_token', 
     37        %{ $c->config->{'Controller::RequestToken'} }, 
     38        %{ $class->config }, 
     39        %{$args}, 
     40    }; 
     41 
     42    $self->config($config); 
     43    return $self; 
     44} 
     45 
     46sub token { 
     47    my ( $self, $arg ) = @_; 
     48    my $c = $self->{c}; 
     49 
     50    if ( defined $arg ) { 
     51        $c->session->{ $self->_ident() } = $arg; 
     52        return $arg; 
     53    } 
     54 
     55    return $c->session->{ $self->_ident() }; 
     56} 
     57 
     58sub create_token { 
     59    my ( $self, $arg ) = @_; 
     60    my $c = $self->{c}; 
     61 
     62    $c->log->debug("create token") if $c->debug; 
     63    my $digest = _find_digest(); 
     64    my $seed = join( time, rand(10000), $$, {} ); 
     65    $digest->add($seed); 
     66    my $token = $digest->hexdigest; 
     67    $c->log->debug("token is created: $token") if $c->debug; 
     68 
     69    return $self->token($token); 
     70} 
     71 
     72sub remove_token { 
     73    my ( $self, $arg ) = @_; 
     74    my $c = $self->{c}; 
     75 
     76    $c->log->debug("remove token") if $c->debug; 
     77    undef $c->session->{$self->_ident()}; 
     78    $self->token(undef); 
    4479} 
    4580 
    4681sub validate_token { 
    47     my $self = shift; 
    48  
    49     return $self->{c}->stash->{validate_token}; 
     82    my ( $self, $arg ) = @_; 
     83    my $c    = $self->{c}; 
     84    my $conf = $self->config; 
     85 
     86    $c->log->debug('validate token') if $c->debug; 
     87    my $session = $self->token; 
     88    my $request = $c->req->param( $conf->{request_name} ); 
     89 
     90    $c->log->debug("session: $session"); 
     91    $c->log->debug("request: $request"); 
     92 
     93    if ( ( $session && $request ) && $session eq $request ) { 
     94        $c->log->debug('token is valid') if $c->debug; 
     95         $c->stash->{$self->_ident()} = 1; 
     96    } 
     97    else { 
     98        $c->log->debug('token is invalid') if $c->debug; 
     99        if ( $c->isa('Catalyst::Plugin::FormValidator::Simple') ) { 
     100            $c->set_invalid_form( $conf->{request_name} => 'TOKEN' ); 
     101        } 
     102        undef $c->stash->{$self->_ident()}; 
     103    } 
     104} 
     105 
     106sub is_valid_token { 
     107    my ( $self, $arg ) = @_; 
     108    my $c    = $self->{c}; 
     109 
     110    return $c->stash->{$self->_ident()}; 
     111} 
     112 
     113sub _ident {    # secret stash key for this template' 
     114    return '__' . ref( $_[0] ) . '_token'; 
     115} 
     116 
     117# following code is from Catalyst::Plugin::Session 
     118my $usable; 
     119 
     120sub _find_digest () { 
     121    unless ($usable) { 
     122        foreach my $alg (qw/SHA-256 SHA-1 MD5/) { 
     123            if ( eval { Digest->new($alg) } ) { 
     124                $usable = $alg; 
     125                last; 
     126            } 
     127        } 
     128        Catalyst::Exception->throw( 
     129                  "Could not find a suitable Digest module. Please install " 
     130                . "Digest::SHA1, Digest::SHA, or Digest::MD5" ) 
     131            unless $usable; 
     132    } 
     133 
     134    return Digest->new($usable); 
    50135} 
    51136 
     
    53138    my ( $self, $app_class, $action_name, $vaue, $attrs ) = @_; 
    54139 
    55     return ( ActionClass => 'Catalyst::Controller::RequestToken::Action::CreateToken' ); 
     140    return ( ActionClass => 
     141            'Catalyst::Controller::RequestToken::Action::CreateToken' ); 
    56142} 
    57143 
     
    59145    my ( $self, $app_class, $action_name, $vaue, $attrs ) = @_; 
    60146 
    61     return ( ActionClass => 'Catalyst::Controller::RequestToken::Action::ValidateToken' ); 
     147    return ( ActionClass => 
     148            'Catalyst::Controller::RequestToken::Action::ValidateToken' ); 
    62149} 
    63150 
     
    65152    my ( $self, $app_class, $action_name, $vaue, $attrs ) = @_; 
    66153 
    67     return ( ActionClass => 'Catalyst::Controller::RequestToken::Action::RemoveToken' ); 
     154    return ( ActionClass => 
     155            'Catalyst::Controller::RequestToken::Action::RemoveToken' ); 
    68156} 
    69157 
     
    71159    my ( $self, $app_class, $action_name, $vaue, $attrs ) = @_; 
    72160 
    73     return ( ActionClass => 'Catalyst::Controller::RequestToken::Action::ValidateRemoveToken' ); 
     161    return ( ActionClass => 
     162            'Catalyst::Controller::RequestToken::Action::ValidateRemoveToken' 
     163    ); 
    74164} 
    75165 
     
    97187    use base qw(Catalyst::Controller::RequestToken); 
    98188     
    99     sub form :Local { 
     189    sub form :CreateToken { 
    100190        my ($self, $c) = @_; 
    101191        $c->stash->{template} = 'form.tt'; 
     
    103193    } 
    104194     
    105     sub confirm :Local :CreateToken { 
     195    sub confirm :Local :ValidateToken { 
    106196        my ($self, $c) = @_; 
    107197        $c->stash->{template} = 'confirm.tt'; 
     
    109199    } 
    110200     
    111     sub complete :Local :ValidateToken { 
     201    sub complete :Local :ValidateRemoveToken { 
    112202        my ($self, $c) = @_; 
    113203        if ($self->validate_token) { 
     
    123213    <body> 
    124214    <form action="confirm" method="post"> 
     215    <input type="hidden" name="_token" values="[% c.req.param('_token') %]"/> 
    125216    <input type="submit" name="submit" value="confirm"/> 
    126217    </form> 
     
    146237This module REQUIRES Catalyst::Plugin::Session to store server side token. 
    147238 
    148 If you add CreateToken attribute to action, token will be created and stored 
    149 into request and session. You can return a content with request token which 
    150 should be posted to server. 
    151  
    152 If you add ValidateToken attribute, this will validate request token with  
    153 sever-side session token, and remove token from session. 
    154  
    155 After ValidateToken, there is any token in session, so validation will be 
    156 failed, if user request with expired token. 
     239=head1 ATTRIBUTES 
     240 
     241=over 4 
     242 
     243=item CreateToken 
     244 
     245Creates new token and put it into request and session.  
     246You can return a content with request token which should be posted  
     247to server. 
     248 
     249=item ValidateToken 
     250 
     251After CreateToken, clients will post token request, so you need 
     252validate it correct or not. 
     253 
     254ValidateToken attribute validates request token with session token  
     255which is created by CreateToken attribute. 
     256 
     257=item RemoveToken 
     258 
     259Removes token from session, then request token will be invalid any more. 
     260 
     261= item ValidateRemoveToken  
     262Works as combination of ValidateToken and RemoveToken. 
     263This will be useful for the last part of transaction. 
     264 
     265=back 
    157266 
    158267=head1 METHODS 
    159268 
    160269=over 4 
     270 
     271=item token 
     272 
     273=item create_token 
     274 
     275=item remove_token 
    161276 
    162277=item validate_token 
     
    164279Return token is valid or not.  This will work collectlly only after 
    165280ValidateToken. 
     281 
     282=item is_valid_token 
    166283 
    167284=back 
     
    183300 
    184301=item request_name 
     302 
     303Default: _token 
     304 
     305=item validate_stash_name 
    185306 
    186307Default: _token 
  • lang/perl/Catalyst-Controller-RequestToken/trunk/lib/Catalyst/Controller/RequestToken/Action/CreateToken.pm

    r13240 r14891  
    66use base qw(Catalyst::Action); 
    77 
    8 use Catalyst::Exception; 
    9 use Digest(); 
    10  
    118sub execute { 
    129    my $self = shift; 
    1310    my ( $controller, $c, @args ) = @_; 
    1411 
    15     $c->log->debug("create token") if $c->debug; 
    16     my $digest = _find_digest(); 
    17     my $seed = join( time, rand(10000), $$, {} ); 
    18     $digest->add($seed); 
    19     my $token = $digest->hexdigest; 
    20     $c->log->debug("token is created: $token") if $c->debug; 
    21  
    22     my $conf = $controller->config; 
    23     $c->session->{ $conf->{session_name} } = $token; 
    24     $c->request->params->{ $conf->{request_name} } = $token; 
    25  
     12    $controller->create_token; 
    2613    return $self->NEXT::execute(@_); 
    2714} 
    2815 
    29 # following code is from Catalyst::Plugin::Session 
    30 my $usable; 
     161; 
    3117 
    32 sub _find_digest () { 
    33     unless ($usable) { 
    34         foreach my $alg (qw/SHA-256 SHA-1 MD5/) { 
    35             if ( eval { Digest->new($alg) } ) { 
    36                 $usable = $alg; 
    37                 last; 
    38             } 
    39         } 
    40         Catalyst::Exception->throw( 
    41                   "Could not find a suitable Digest module. Please install " 
    42                 . "Digest::SHA1, Digest::SHA, or Digest::MD5" ) 
    43             unless $usable; 
    44     } 
    45  
    46     return Digest->new($usable); 
    47 } 
     18__END__ 
    4819 
    4920=head1 NAME 
     
    8354=cut 
    8455 
    85 1; 
    8656 
  • lang/perl/Catalyst-Controller-RequestToken/trunk/lib/Catalyst/Controller/RequestToken/Action/RemoveToken.pm

    r13285 r14891  
    66use base qw(Catalyst::Action); 
    77 
    8 use Catalyst::Exception; 
    9 use Class::C3; 
    10  
    118sub execute { 
    129    my $self = shift; 
    1310    my ( $controller, $c, @args ) = @_; 
    1411 
    15     $c->log->debug("remove token") if $c->debug; 
    16     my $conf = $controller->config; 
    17     undef $c->session->{ $conf->{session_name} }; 
    18  
     12    $controller->remove_token; 
    1913    return $self->next::method(@_); 
    2014} 
  • lang/perl/Catalyst-Controller-RequestToken/trunk/lib/Catalyst/Controller/RequestToken/Action/ValidateToken.pm

    r13285 r14891  
    66use base qw(Catalyst::Action); 
    77 
    8 use Catalyst::Exception; 
    9 use Class::C3; 
    10  
    118sub execute { 
    129    my $self = shift; 
    1310    my ( $controller, $c, @args ) = @_; 
    1411 
    15     my $conf = $controller->config; 
    16  
    17     $c->log->debug('validate token') if $c->debug; 
    18     my $session = $c->session->{ $conf->{session_name} }; 
    19     my $request = $c->req->param( $conf->{request_name} ); 
    20  
    21     if ( ( $session && $request ) && $session eq $request ) { 
    22         $c->stash->{validate_token} = 1; 
    23         $c->log->debug('token is valid') if $c->debug; 
    24     } else { 
    25         $c->log->debug('token is invalid') if $c->debug; 
    26         if ( $c->isa('Catalyst::Plugin::FormValidator::Simple') ) { 
    27             $c->set_invalid_form( 
    28                 $conf->{request_name} => 'TOKEN' ); 
    29         } 
    30     } 
    31  
     12    $controller->validate_token; 
    3213    return $self->next::method(@_); 
    3314} 
  • lang/perl/Catalyst-Controller-RequestToken/trunk/t/lib/TestApp.pm

    r13285 r14891  
    55use Catalyst qw(-Debug Session Session::Store::Dummy Session::State::Cookie); 
    66#use Catalyst qw(Session Session::Store::Dummy Session::State::Cookie); 
    7  
     7__PACKAGE__->config('Controller::RequestToken' => {session_name => '__token', request_name => '__token'}); 
    88__PACKAGE__->setup; 
    99 
  • lang/perl/Catalyst-Controller-RequestToken/trunk/t/lib/TestApp/Controller/Root.pm

    r13221 r14891  
    99# your actions replace this one 
    1010sub main :Path { $_[1]->res->body('<h1>It works</h1>') } 
    11 sub end : ActionClass('RenderView'){}; 
     11sub end :Private { 
     12   my ($self, $c) = @_;  
     13    $c->response->content_type("text/html; charset=UTF-8");  
     14    } 
    12151; 
  • lang/perl/Catalyst-Controller-RequestToken/trunk/t/lib/TestApp/Controller/Simple.pm

    r13285 r14891  
    88    my ( $self, $c ) = @_; 
    99 
    10     $c->stash->{html} = <<HTML; 
     10    my $html = <<HTML; 
    1111<html> 
    1212<head></head> 
     
    1414FORM 
    1515<form action="confirm" method="post"> 
    16 <input type="hidden" name="_token" value="TOKEN"/> 
     16<input type="hidden" name="__token" value="TOKEN"/> 
    1717<input type="submit" name="submit" value="submit"/> 
    1818</form> 
     
    2121HTML 
    2222 
    23     $c->forward('parse_html'); 
     23    my $token = $self->token; 
     24    $html =~ s/TOKEN/$token/g; 
     25    $c->response->body($html); 
    2426} 
    2527 
     
    2729    my ( $self, $c ) = @_; 
    2830 
    29     $c->stash->{html} = <<HTML; 
     31    $c->detach('error') unless $self->is_valid_token; 
     32    my $html = <<HTML; 
    3033<html> 
    3134<body> 
    3235CONFIRM 
    3336<form action="complete" method="post"> 
    34 <input type="hidden" name="_token" value="TOKEN"/> 
     37<input type="hidden" name="__token" value="REQUEST"/> 
    3538<input type="submit" name="submit" value="submit"/> 
    3639</form> 
     
    3841</html> 
    3942HTML 
    40     $c->detach('error') unless $self->validate_token; 
    41     $c->forward('parse_html'); 
     43    my $token = $c->req->param('__token'); 
     44    $html =~ s/REQUEST/$token/g; 
     45    $c->response->body($html); 
    4246} 
    4347 
     
    4549    my ( $self, $c ) = @_; 
    4650 
    47     $c->stash->{html} = <<HTML; 
     51    $c->detach('error') unless $self->is_valid_token; 
     52    my $html = <<HTML; 
    4853<html><body>SUCCESS</body></html> 
    4954HTML 
    5055 
    51     $c->detach('error') unless $self->validate_token; 
    52     $c->forward('parse_html'); 
     56    $c->response->body($html); 
    5357} 
    5458 
     
    6367} 
    6468 
    65 sub parse_html : Private { 
    66     my ( $self, $c ) = @_; 
    67     my $token = $c->req->param('_token'); 
    68  
    69     my $html = $c->stash->{html}; 
    70     $html =~ s/TOKEN/$token/g; 
    71     $c->response->body($html); 
    72 } 
    73  
    74691; 
  • lang/perl/Catalyst-Controller-RequestToken/trunk/t/live-test.t

    r13285 r14891  
    33use strict; 
    44use warnings; 
    5 #use Test::More tests => 15; 
    65use Test::More qw(no_plan); 
    76 
     
    2423$mech->submit_form_ok({}, 'submit form'); 
    2524$mech->content_like(qr/CONFIRM/i, 'see if it has our text'); 
    26 $mech->content; 
    2725 
    2826$mech->submit_form_ok({}, 'submit form'); 
     
    3129$mech->reload; 
    3230$mech->content_like(qr/INVALID ACCESS/i, 'see if it has our text'); 
    33  
     31=cut 
    3432$mech->back; 
    3533$mech->content_like(qr/CONFIRM/i, 'see if it has our text'); 
     
    4644$mech->submit; 
    4745$mech->content_like(qr/SUCCESS/i, 'see if it has our text'); 
    48  
     46=cut