Changeset 5275

Show
Ignore:
Timestamp:
01/22/08 16:35:40 (5 years ago)
Author:
lyokato
Message:

lang/perl/OAuth-Lite: added functionality for OAuth Discovery 1.0 and OAuth Consumer Request 1.0

Location:
lang/perl/OAuth-Lite/trunk
Files:
6 added
5 modified

Legend:

Unmodified
Added
Removed
  • lang/perl/OAuth-Lite/trunk/Makefile.PL

    r4675 r5275  
    1414requires 'List::MoreUtils'        => '0.21'; 
    1515requires 'MIME::Base64'           => '3.07'; 
     16requires 'Net::Yadis'             => '1.00'; 
     17requires 'HTML::RelExtor'         => '0.01'; 
    1618auto_include; 
    1719WriteAll; 
  • lang/perl/OAuth-Lite/trunk/lib/OAuth/Lite.pm

    r5043 r5275  
    44use warnings; 
    55 
    6 our $VERSION = "1.07"; 
     6our $VERSION = "1.08"; 
    77our $OAUTH_DEFAULT_VERSION = "1.0"; 
    88 
  • lang/perl/OAuth-Lite/trunk/lib/OAuth/Lite/AuthMethod.pm

    r4759 r5275  
    1111our @EXPORT_OK = map { @$_ } values %EXPORT_TAGS; 
    1212 
    13 use constant AUTH_HEADER => 'auth_header'; 
    14 use constant POST_BODY   => 'post_body'; 
    15 use constant URL_QUERY   => 'url_query'; 
     13use constant AUTH_HEADER => 'AUTH-HEADER'; 
     14use constant POST_BODY   => 'POST-BODY'; 
     15use constant URL_QUERY   => 'URL-QUERY'; 
    1616 
    1717sub validate_method { 
     
    2525=head1 NAME 
    2626 
    27 OAuth::Lite::AuthMethod - auth method constants. 
     27OAuth::Lite::AuthMethod - OBSOLUTE use ParamMethod instead of this. 
    2828 
    2929=head1 SYNOPSIS 
  • lang/perl/OAuth-Lite/trunk/lib/OAuth/Lite/Consumer.pm

    r5043 r5275  
    2626use HTTP::Request; 
    2727use HTTP::Headers; 
     28use Net::Yadis; 
     29use HTML::RelExtor; 
    2830use UNIVERSAL::require; 
    2931use List::MoreUtils qw(any); 
     
    3436use OAuth::Lite::Util qw(:all); 
    3537use OAuth::Lite::AuthMethod qw(:all); 
     38use OAuth::Lite::RealmDifinition; 
    3639 
    3740=head1 NAME 
     
    8386 
    8487    unless ($res->is_success) { 
    85         if ($res->status == 400 || $res->status == 401) { 
     88        if ($res->code == 400 || $res->code == 401) { 
    8689            my $auth_header = $res->header('WWW-Authenticate'); 
    8790            if ($auth_header && $auth_header =~ /^OAuth/) { 
     
    128131HTTP method (GET or POST) when the request is for request token or access token. (optional, 'POST' is set by default) 
    129132 
     133=item param_method 
     134 
     135L<OAuth::Lite::AuthMethod>'s value you can choose from AUTH_HEADER, POST_BODY and URL_QUERY (optional, AUTH_HEADER is set by default) 
     136 
    130137=item auth_method 
    131138 
    132 L<OAuth::Lite::AuthMethod>'s value you can choose from AUTH_HEADER, POST_BODY and URL_QUERY (optional, AUTH_HEADER is set by default) 
     139OBSOLUTE - use param method instead of this 
    133140 
    134141=item realm 
     
    236243    my %args_for_parent = %args; 
    237244    delete $args_for_parent{$_} 
    238         for qw/consumer_key consumer_secret signature_method http_method auth_method realm 
    239         site request_token_path access_token_path authorize_path 
    240         callback_url/; 
     245        for qw/consumer_key consumer_secret signature_method http_method auth_method param_method 
     246        realm site request_token_path access_token_path authorize_path callback_url/; 
    241247    my $self = $class->SUPER::new(%args_for_parent); 
    242248    $self = bless $self, $class; 
     
    266272    $self->{consumer_secret} = $args{consumer_secret} || ''; 
    267273    $self->{http_method} = $args{http_method} || 'POST'; 
    268     $self->{auth_method} = $args{auth_method} || AUTH_HEADER; 
    269     unless ( OAuth::Lite::AuthMethod->validate_method( $self->{auth_method} ) ) { 
     274    $self->{param_method} = $args{param_method} || $args{auth_method} || AUTH_HEADER; 
     275    unless ( OAuth::Lite::AuthMethod->validate_method( $self->{param_method} ) ) { 
    270276        Carp::croak( sprintf 
    271             qq/Invalid auth method "%s"./, $self->{auth_method} ); 
     277            qq/Invalid auth method "%s"./, $self->{param_method} ); 
    272278    } 
    273279    $self->{signature_method} = $signature_method_class; 
     
    518524    } 
    519525 
    520     my $auth_method = $self->{auth_method}; 
     526    my $param_method = $self->{param_method}; 
    521527    if (any { $method eq $_ } @non_send_data_methods) { 
    522         $auth_method = AUTH_HEADER 
    523             unless $auth_method eq URL_QUERY;  
     528        $param_method = AUTH_HEADER 
     529            unless $param_method eq URL_QUERY;  
    524530    } else { # POST or PUT 
    525         $auth_method = AUTH_HEADER 
    526             unless $auth_method eq POST_BODY;  
    527     } 
    528  
    529     if ($auth_method eq URL_QUERY) { 
     531        $param_method = AUTH_HEADER 
     532            unless $param_method eq POST_BODY;  
     533    } 
     534 
     535    if ($param_method eq URL_QUERY) { 
    530536        my $query = $self->gen_auth_query($method, $url, $token, $extra); 
    531537        $url = sprintf q{%s?%s}, $url, $query; 
    532     } elsif ($auth_method eq POST_BODY) { 
     538    } elsif ($param_method eq POST_BODY) { 
    533539        my $query = $self->gen_auth_query($method, $url, $token, $extra); 
    534540        $content = $query; 
     
    604610    my ($self, %args) = @_; 
    605611    $args{token} ||= $self->access_token; 
    606     $self->__request(%args); 
     612    my $res = $self->__request(%args); 
     613    $res; 
     614} 
     615 
     616=head2 discover 
     617 
     618Discover realm-definition using last response. 
     619 
     620    my $difinition = $consumer->discover(); 
     621    unless ($difinition) { 
     622        die "Discovery failed"; 
     623    } 
     624 
     625=cut 
     626 
     627sub discover { 
     628        my ($self, $finders) = @_; 
     629    my $res = $self->oauth_response; 
     630    my $difinition; 
     631    if ($res->code == 400 || $res->code == 401) { 
     632        my $auth_header = $res->header('WWW-Authenticate'); 
     633        if ($auth_header && $auth_header =~ /^OAuth/) { 
     634            my ($realm, $params) = parse_auth_header($auth_header); 
     635            $difinition = $self->__discover([ 
     636                sub { 
     637                    return exists $params->{xoauth_realm} 
     638                        ? $params->{xoauth_realm} : undef;  
     639                }, 
     640                sub { 
     641                    return $realm; 
     642                }, 
     643                sub { 
     644                    for my $pair (split /&/, $res->content) { 
     645                        my ($key, $value) = split /=/, $pair; 
     646                        if ($key && $key eq 'xoauth_realm') { 
     647                            return decode_param($value); 
     648                        } 
     649                    } 
     650                    return; 
     651                }, 
     652                sub { 
     653                    my $parser = HTML::RelExtor->new; 
     654                    $parser->parse($res->content); 
     655                    for my $link ($parser->links) { 
     656                        if ($link->has_rel('auth')) { 
     657                            my $attr = $link->attr; 
     658                            if ( exists $attr->{type} 
     659                              && $attr->{type} eq q{application/xrds+xml}) { 
     660                                return $link->href; 
     661                            } 
     662                        } 
     663                    } 
     664                    return; 
     665                }, 
     666            ]); 
     667                    } 
     668    } 
     669    $difinition; 
     670} 
     671 
     672sub __discover { 
     673    my ($self, $url_finders) = @_; 
     674    for my $finder ( @$url_finders ) { 
     675        my $url = $finder->() or next; 
     676        my $yadis; 
     677        eval { $yadis = Net::Yadis->discover($url); }; 
     678        next if $@; 
     679        my $difinition = OAuth::Lite::RealmDifinition->parse($yadis); 
     680        next unless $difinition; 
     681        return $difinition; 
     682    } 
     683    return; 
    607684} 
    608685 
     
    746823 
    747824    my $req_token = $consumer->get_request_token(...); 
    748     say $consumer->oauth_response->status; 
     825    say $consumer->oauth_response->code; 
    749826 
    750827    my $req_token = $consumer->get_access_token(...); 
    751     say $consumer->oauth_response->status; 
     828    say $consumer->oauth_response->code; 
    752829 
    753830=head2 oauth_clear 
  • lang/perl/OAuth-Lite/trunk/lib/OAuth/Lite/Server/mod_perl2.pm

    r4677 r5275  
    3030use constant ACCESS_TOKEN       => 'ACCESS_TOKEN'; 
    3131 
    32 __PACKAGE__->mk_accessors(qw/request realm oauth/); 
     32__PACKAGE__->mk_accessors(qw/request realm xrealm oauth/); 
    3333 
    3434=head1 NAME 
     
    291291The realm value you set in httpd.conf by PerlSetVar. 
    292292 
     293=head2 xrealm 
     294 
     295 
     296This value should be the url of Discovery Difinition Document. 
     297See OAuth Discovery 1.0 spec. 
     298 
     299And in authentication header, this is put in as xoauth_realm. 
     300 
     301To use this, you have to set XRealm on httpd.conf 
     302 
     303  SetParVar XRealm "http://api.example.com/realm" 
     304 
    293305=head2 oauth 
    294306 
     
    319331 
    320332Set proper 'WWW-Authentication' response header 
     333 
     334=head2 is_requied_request_token 
     335 
     336Check if current request requires request-token. 
     337 
     338=head2 is_requied_access_token 
     339 
     340Check if current request requires access-token. 
     341 
     342=head2 is_requied_protected_resource 
     343 
     344Check if current request requires protected-resource. 
     345 
     346=head2 accepts_consumer_request 
     347 
     348You can adopt OAuth Consumer Request 1.0. 
     349 
     350See http://oauth.googlecode.com/svn/spec/ext/consumer_request/1.0/drafts/1/spec.html 
     351 
     352To adopt this spec, you have to set var 'AcceptConsumerRequest' on httpd.conf 
     353 
     354        <Location /resource> 
     355        PerlSetVar Mode PROTECTED_RESOURCE 
     356        PerlSetVar AcceptConsumerRequest 1 
     357        PerlResponseHandler MyServiceWithOAuth 
     358        </Location> 
     359 
     360Then override service method for protected resource. 
     361 
     362        sub service { 
     363                my ($self, $params) = @_; 
     364 
     365                my $resource_owner_id; 
     366 
     367                if (exists $params->{oauth_token}) { 
     368 
     369                        my $access_token_value = $params->{oauth_token}; 
     370                        $resource_owner_id = $self->get_user_id_of_access_token($access_token_value); 
     371 
     372                } else { 
     373 
     374                        my $consumer_key = $params->{oauth_consumer_key}; 
     375                        $resource_owner_id = $self->get_user_id_of_consumer_developer($consumer_key); 
     376 
     377                } 
     378 
     379                my @resources = MyDB::Scheme->resultset('SomeResource')->search({ 
     380                                user_id => $resource_owner_id,   
     381                }); 
     382 
     383                # output resource data in the manner your api defines. 
     384                ... 
     385 
     386                return Apache2::Const::OK; 
     387 
     388        } 
    321389 
    322390=head2 error 
     
    380448        oauth   => OAuth::Lite::ServerUtil->new, 
    381449        realm   => undef, 
     450        xrealm  => undef, 
    382451        secure  => 0, 
    383452        mode    => PROTECTED_RESOURCE, 
     453                                accepts_consumer_request => 0, 
    384454    }, $class; 
    385455    my $realm = $self->request->dir_config('Realm'); 
    386456    $self->{realm} = $realm if $realm; 
     457    my $xrealm = $self->request->dir_config('XRealm'); 
     458    $self->{xrealm} = $xrealm if $xrealm; 
     459                my $accept = $self->request->dir_config('AcceptConsumerRequest'); 
     460                $self->{accepts_consumer_request} = $accept if $accept; 
    387461    my $mode = $self->request->dir_config('Mode'); 
     462                my @valid_modes = (PROTECTED_RESOURCE, REQUEST_TOKEN, ACCESS_TOKEN); 
    388463    if ($mode) { 
    389         if (none { $mode eq $_ } (PROTECTED_RESOURCE, REQUEST_TOKEN, ACCESS_TOKEN)) { 
     464        if (none { $mode eq $_ } @valid_modes) { 
    390465            die "Invalid mode.";  
    391466        } else { 
     
    439514    } 
    440515 
    441     my $needs_to_check_token =  $self->__is_required_request_token 
     516    my $needs_to_check_token =  ( $self->is_required_request_token 
     517                                         || ( $self->is_required_protected_resource && $self->accepts_consumer_request ) ) 
    442518                             ? 0 
    443519                             : 1; 
     
    467543    my $request_uri = $uri->as_string; 
    468544 
    469     if ($self->__is_required_request_token) { 
     545    if ($self->is_required_request_token) { 
    470546 
    471547        $self->oauth->verify_signature( 
     
    479555        return $self->__output_token($request_token); 
    480556 
    481     } elsif ($self->__is_required_access_token) { 
     557    } elsif ($self->is_required_access_token) { 
    482558 
    483559        my $token_value = $params->{oauth_token}; 
     
    499575    } else { 
    500576 
    501         my $token_value = $params->{oauth_token}; 
    502         my $token_secret = $self->get_access_token_secret($token_value); 
    503         unless (defined $token_secret) { 
    504             return $self->errout(401, q{Invalid token}); 
    505         } 
     577                                my $token_secret = ''; 
     578                                if (exists $params->{oauth_token}) { 
     579                                        my $token_value = $params->{oauth_token}; 
     580                                        $token_secret = $self->get_access_token_secret($token_value); 
     581                                        unless (defined $token_secret) { 
     582                                                        return $self->errout(401, q{Invalid token}); 
     583                                        } 
     584                                } 
    506585 
    507586        $self->oauth->verify_signature( 
     
    510589            url             => $request_uri, 
    511590            consumer_secret => $consumer_secret || '', 
    512             token_secret    => $token_secret || '', 
     591            token_secret    => $token_secret, 
    513592        ) or return $self->errout(401, q{Invalid signature}); 
    514593 
     
    528607} 
    529608 
    530 sub __is_required_request_token { 
     609sub is_required_request_token { 
    531610    my $self = shift; 
    532611    return ($self->{mode} eq REQUEST_TOKEN) ? 1 : 0; 
    533612} 
    534613 
    535 sub __is_required_access_token { 
     614sub is_required_access_token { 
    536615    my $self = shift; 
    537616    return ($self->{mode} eq ACCESS_TOKEN) ? 1 : 0; 
     617} 
     618 
     619sub is_required_protected_resource { 
     620    my $self = shift; 
     621    return ($self->{mode} eq PROTECTED_RESOURCE) ? 1 : 0; 
     622} 
     623 
     624sub accepts_consumer_request { 
     625                my $self = shift; 
     626                return $self->{accepts_consumer_request}; 
    538627} 
    539628 
     
    585674sub set_authenticate_header { 
    586675    my $self = shift; 
    587     $self->request->err_headers_out->add( 'WWW-Authenticate', 
    588         sprintf(q{OAuth realm="%s"}, $self->realm)); 
     676    my $header = $self->{xrealm} 
     677      ? sprintf(q{OAuth realm="%s", xoauth_realm="%s"}, $self->realm, $self->xrealm) 
     678      : sprintf(q{OAuth realm="%s"}, $self->realm); 
     679    $self->request->err_headers_out->add( 'WWW-Authenticate', $header ); 
    589680} 
    590681