root/branches/release-38/extlib/Net/OAuth/Request.pm @ 2229

Revision 2229, 5.6 kB (checked in by fumiakiy, 19 months ago)

Adding Net::OAuth modules in MT distribution. BugId:69893

Line 
1package Net::OAuth::Request;
2use warnings;
3use strict;
4use base qw/Class::Data::Inheritable Class::Accessor/;
5use URI::Escape;
6use UNIVERSAL::require;
7
8our $VERSION = '0.06';
9
10__PACKAGE__->mk_classdata(required_request_params => [qw/
11    consumer_key
12    signature_method
13    timestamp
14    nonce
15    /]);
16
17__PACKAGE__->mk_classdata(optional_request_params => [qw/
18    version
19    /]);
20
21__PACKAGE__->mk_classdata(required_api_params => [qw/
22    request_method
23    request_url
24    consumer_secret
25    /]);
26
27__PACKAGE__->mk_classdata(signature_elements => [qw/
28    request_method
29    request_url
30    normalized_request_parameters
31    /]);
32   
33__PACKAGE__->mk_accessors(
34    @{__PACKAGE__->required_request_params}, 
35    @{__PACKAGE__->optional_request_params},
36    @{__PACKAGE__->required_api_params},
37    qw/extra_params signature signature_key token_secret/
38    );
39
40sub add_required_request_params {
41    my $class = shift;
42    $class->required_request_params([@{$class->required_request_params}, @_]);
43    $class->mk_accessors(@_);
44}
45
46sub add_optional_request_params {
47    my $class = shift;
48    $class->optional_request_params([@{$class->optional_request_params}, @_]);
49    $class->mk_accessors(@_);
50}
51
52sub add_required_api_params {
53    my $class = shift;
54    $class->required_api_params([@{$class->required_api_params}, @_]);
55    $class->mk_accessors(@_);
56}
57
58sub add_to_signature {
59    my $class = shift;
60    $class->signature_elements([@{$class->signature_elements}, @_]);
61}
62
63sub new {
64    my $proto = shift;
65    my $class = ref $proto || $proto;
66    my %params = @_;
67    $params{version} = '1.0' unless defined $params{version};
68    my $req = bless \%params, $class;
69    $req->check;
70    return $req;
71}
72
73sub check {
74    my $self = shift;
75    foreach my $k (@{$self->required_request_params}, @{$self->required_api_params}) {
76        if (not defined $self->{$k}) {
77            die "Missing required parameter '$k'";
78        }
79    }
80    if ($self->{extra_params} and $self->allow_extra_params) {
81        foreach my $k (keys %{$self->{extra_params}}) {
82            if ($k =~ /^oauth_/) {
83                die "Parameter '$k' not allowed in arbitrary params"
84            }
85        }
86    }
87}
88
89sub encode {
90    my $str = shift;
91    $str = "" unless defined $str;
92    return URI::Escape::uri_escape_utf8($str,'^\w.~-');
93}
94
95sub decode {
96    my $str = shift;
97    return uri_unescape($str);
98}
99
100sub allow_extra_params {1}
101
102sub gather_request_parameters {
103    my $self = shift;
104    my %opts = @_;
105    $opts{quote} = "" unless defined $opts{quote};
106    $opts{params} ||= [];
107    my %params;
108    foreach my $k (@{$self->required_request_params}, @{$self->optional_request_params}, @{$opts{add}}) {
109        $params{"oauth_$k"} = $self->$k; 
110    }
111    if ($self->{extra_params} and !$opts{no_extra} and $self->allow_extra_params) {
112        foreach my $k (keys %{$self->{extra_params}}) {
113            $params{$k} = $self->{extra_params}{$k};
114        }
115    }
116    if ($opts{hash}) {
117        return \%params;
118    }
119    my @pairs;
120    while (my ($k,$v) = each %params) {
121        push @pairs, join('=', encode($k), $opts{quote} . encode($v) . $opts{quote});
122    }
123    return sort(@pairs); # sort not required here but makes module more testable
124}
125
126sub normalized_request_parameters {
127    my $self = shift;
128    return join('&',  $self->gather_request_parameters);
129}
130
131sub signature_base_string {
132    my $self = shift;
133    return join('&', map(encode($self->$_), @{$self->signature_elements}));
134}
135
136sub signature_key {
137    my $self = shift;
138    # For some sig methods (I.e. RSA), users will pass in their own key
139    my $key = $self->get('signature_key'); 
140    unless (defined $key) {
141        $key = encode($self->consumer_secret) . '&';
142        $key .= encode($self->token_secret) if $self->can('token_secret');
143    }
144    return $key;
145}
146
147sub sign {
148    my $self = shift;
149    my $class = $self->_signature_method_class;
150    $self->signature($class->sign($self, @_));
151}
152
153sub verify {
154    my $self = shift;
155    my $class = $self->_signature_method_class;
156    return $class->verify($self, @_);
157}
158
159sub _signature_method_class {
160    my $self = shift;
161    (my $signature_method = $self->signature_method) =~ s/\W+/_/g;
162    my $klass = 'Net::OAuth::SignatureMethod::' . $signature_method;
163    $klass->require or die "Unable to load $signature_method plugin";
164    return $klass;
165}
166
167sub to_authorization_header {
168    my $self = shift;
169    my $realm = shift;
170    my $sep = shift || ",";
171    return join($sep, "OAuth realm=\"$realm\"", 
172        $self->gather_request_parameters(quote => '"', add => [qw/signature/], no_extra => 1));
173}
174
175sub from_authorization_header {
176    my $proto = shift;
177    my $class = ref $proto || $proto;
178    my $header = shift;
179    my %extra_params = @_;
180    my @header = split /[\s]*,[\s]*/, $header;
181    shift @header;
182    my %params;
183    foreach my $pair (@header) {
184        my ($k,$v) = split /=/, $pair;
185        if (defined $k and defined $v) {
186            $v =~ s/(^"|"$)//g;
187            ($k,$v) = map decode($_), $k, $v;
188            $k =~ s/^oauth_//;
189            $params{$k} = $v;
190        }
191    }
192    return $class->new(%params, %extra_params);
193}
194
195sub to_post_body {
196    my $self = shift;
197    return join('&', $self->gather_request_parameters(add => [qw/signature/]));
198}
199
200sub to_hash {
201    my $self = shift;
202    return $self->gather_request_parameters(hash => 1, add => [qw/signature/]);
203}
204
205=head1 NAME
206
207Net::OAuth::Request - base class for OAuth requests
208
209=head1 SEE ALSO
210
211L<http://oauth.net>
212
213=head1 AUTHOR
214
215Keith Grennan, C<< <kgrennan at cpan.org> >>
216
217=head1 COPYRIGHT & LICENSE
218
219Copyright 2007 Keith Grennan, all rights reserved.
220
221This program is free software; you can redistribute it and/or modify it
222under the same terms as Perl itself.
223
224=cut
225
2261;
Note: See TracBrowser for help on using the browser.