File Coverage

blib/lib/WWW/LinkedIn.pm
Criterion Covered Total %
statement 27 75 36.0
branch 0 18 0.0
condition 0 9 0.0
subroutine 9 17 52.9
pod 0 8 0.0
total 36 127 28.3


line stmt bran cond sub pod time code
1              
2             package WWW::LinkedIn;
3              
4 1     1   912 use strict;
  1         2  
  1         40  
5 1     1   6 use warnings 'all';
  1         1  
  1         46  
6 1     1   15 use Carp 'confess';
  1         2  
  1         62  
7 1     1   951 use Net::OAuth;
  1         673  
  1         29  
8 1     1   25516 use LWP::UserAgent;
  1         227796  
  1         133  
9 1     1   31655 use HTTP::Request::Common;
  1         5060  
  1         202  
10 1     1   10 use Digest::MD5 'md5_hex';
  1         2  
  1         60  
11 1     1   1314 use Digest::HMAC_SHA1;
  1         47124  
  1         53  
12 1     1   994 use MIME::Base64;
  1         2610  
  1         4092  
13              
14             our $VERSION = '0.004';
15              
16              
17             sub new
18             {
19 0     0 0   my ($class, %args) = @_;
20            
21 0           foreach(qw( consumer_key consumer_secret ))
22             {
23 0 0         confess "Required param '$_' was not provided"
24             unless $args{$_};
25             }# end foreach()
26            
27 0           return bless \%args, $class;
28             }# end new()
29              
30 0     0 0   sub consumer_key { shift->{consumer_key} }
31 0     0 0   sub consumer_secret { shift->{consumer_secret} }
32 0 0   0 0   sub access_token { @_ > 1 ? $_[0]->{access_token} = $_[1] : $_[0]->{access_token} }
33 0 0   0 0   sub access_token_secret { @_ > 1 ? $_[0]->{access_token_secret} = $_[1] : $_[0]->{access_token_secret} }
34              
35              
36             sub get_request_token
37             {
38 0     0 0   my ($s, %args) = @_;
39              
40 0           foreach(qw( callback ))
41             {
42 0 0         confess "Required param '$_' was not provided"
43             unless $args{$_};
44             }# end foreach()
45            
46 0           $Net::OAuth::PROTOCOL_VERSION = Net::OAuth::PROTOCOL_VERSION_1_0A;
47              
48 0           my $nonce = md5_hex(time() * rand());
49 0           my $timestamp = time();
50 0           my $request = Net::OAuth->request("request token")->new(
51             consumer_key => $s->consumer_key,
52             consumer_secret => $s->consumer_secret,
53             request_url => 'https://api.linkedin.com/uas/oauth/requestToken',
54             request_method => 'POST',
55             signature_method => 'HMAC-SHA1',
56             timestamp => $timestamp,
57             nonce => $nonce,
58             callback => $args{callback},
59             );
60 0           $request->sign;
61 0           my $res = LWP::UserAgent->new()->request(POST $request->to_url);
62 0 0         my ($token) = $res->content =~ m{token\=([^&]+)}
63             or confess "LinkedIn's API did not return a request token. Instead, it returned this:\n" . $res->as_string;
64 0 0         my ($token_secret) = $res->content =~ m{oauth_token_secret\=([^&]+)}
65             or confess "LinkedIn's API did not return a request token secret. Instead, it returned this:\n" . $res->as_string;
66            
67             return {
68 0           token => $token,
69             secret => $token_secret,
70             url => "https://www.linkedin.com/uas/oauth/authorize?oauth_token=$token",
71             };
72             }# end get_request_token()
73              
74              
75             sub get_access_token
76             {
77 0     0 0   my ($s, %args) = @_;
78            
79 0           foreach(qw( request_token request_token_secret verifier ))
80             {
81 0 0         confess "Required param '$_' was not provided"
82             unless $args{$_};
83             }# end foreach()
84              
85 0           $Net::OAuth::PROTOCOL_VERSION = Net::OAuth::PROTOCOL_VERSION_1_0A;
86 0           my $nonce = md5_hex(time() * rand());
87 0           my $timestamp = time();
88 0           my $request = Net::OAuth->request("access token")->new(
89             consumer_key => $s->consumer_key,
90             consumer_secret => $s->consumer_secret,
91             request_method => 'POST',
92             signature_method => 'HMAC-SHA1',
93             timestamp => $timestamp,
94             nonce => $nonce,
95             request_url => 'https://api.linkedin.com/uas/oauth/accessToken',
96             token => $args{request_token},
97             token_secret => $args{request_token_secret},
98             verifier => $args{verifier},
99             );
100 0           $request->sign;
101 0           my $req = POST 'https://api.linkedin.com/uas/oauth/accessToken';
102 0           $req->header( Authorization => $request->to_authorization_header );
103 0           my $res = LWP::UserAgent->new->request( $req );
104 0           my ($access_token) = $res->content =~ m{oauth_token\=([^&]+)};
105 0           my ($access_token_secret) = $res->content =~ m{oauth_token_secret\=([^&]+)};
106            
107             return {
108 0           token => $access_token,
109             secret => $access_token_secret,
110             };
111             }# end get_access_token()
112              
113              
114             sub request
115             {
116 0     0 0   my ($s, %args) = @_;
117            
118 0           foreach(qw( request_url ))
119             {
120 0 0         confess "Required param '$_' was not provided"
121             unless $args{$_};
122             }# end foreach()
123 0           foreach(qw( access_token access_token_secret ))
124             {
125 0 0 0       confess "Required param '$_' not provided and not set manually"
126             unless $args{$_} || exists $s->{$_};
127             }# end foreach()
128              
129 0           $Net::OAuth::PROTOCOL_VERSION = Net::OAuth::PROTOCOL_VERSION_1_0A;
130 0           my $nonce = md5_hex(time() * rand());
131 0           my $timestamp = time();
132 0   0       my $request = Net::OAuth->request("protected resource")->new(
      0        
133             signature_method => 'HMAC-SHA1',
134             timestamp => $timestamp,
135             nonce => $nonce,
136             consumer_key => $s->consumer_key,
137             consumer_secret => $s->consumer_secret,
138             token => $args{access_token} || $s->access_token,
139             token_secret => $args{access_token_secret} || $s->access_token_secret,
140             request_method => 'GET',
141             request_url => $args{request_url},
142             );
143 0           $request->sign;
144 0           my $req = GET $args{request_url};
145 0           $req->header( Authorization => $request->to_authorization_header );
146 0           my $res = LWP::UserAgent->new->request( $req );
147 0           return $res->content;
148             }# end request()
149              
150             1;# return true:
151              
152             =pod
153              
154             =head1 NAME
155              
156             WWW::LinkedIn - Simple interface to the LinkedIn OAuth API
157              
158             =head1 SYNOPSIS
159              
160             =head2 Step 1
161              
162             Get the Request Token and Request Token Secret
163              
164             <%
165             use WWW::LinkedIn;
166             my $li = WWW::LinkedIn->new(
167             consumer_key => $consumer_key, # Your 'API Key'
168             consumer_secret => $consumer_secret, # Your 'Secret Key'
169             );
170             my $token = $li->get_request_token(
171             callback => "http://www.example.com/v1/login/linkedin/"
172             );
173            
174             # Save $token->{token} and $token->{secret} for later:
175             $Session->{request_token} = $token->{token};
176             $Session->{request_token_secret} = $token->{secret};
177             %>
178            
179            
180             Login to LinkedIn
181              
182             =head2 Step 2
183              
184             After the user has authorized your app to have access to their account, they will be
185             redirected to the URL you specified in the C parameter from Step 1.
186              
187             The URL will be given the parameter C which you will need.
188              
189             Perform the following in the URL that they are redirected to:
190              
191             use WWW::LinkedIn;
192            
193             my $li = WWW::LinkedIn->new(
194             consumer_key => $consumer_key,
195             consumer_secret => $consumer_secret,
196             );
197             my $access_token = $li->get_access_token(
198             verifier => $Form->{oauth_verifier}, # <--- This is passed to us in the querystring:
199             request_token => $Session->{request_token}, # <--- From step 1.
200             request_token_secret => $Session->{request_token_secret}, # <--- From step 1.
201             );
202              
203             =head2 Step 3
204              
205             Now you can use the C method to make 'protected resource' requests like this:
206              
207             # Get the user's own profile:
208             my $profile_xml = $li->request(
209             request_url => 'https://api.linkedin.com/v1/people/~:(id,first-name,last-name,headline)',
210             access_token => $access_token->{token},
211             access_token_secret => $access_token->{secret},
212             );
213              
214             Returns something like this:
215              
216            
217            
218             XnMs6jaRm6
219             John
220             Drago
221             Master Hackologist
222            
223              
224             # Get a specific user's profile:
225             my $profile_xml = $li->request(
226             request_url => 'https://api.linkedin.com/v1/people/id=XnMs6jaRm6:(id,first-name,last-name,headline)',
227             access_token => $access_token->{token},
228             access_token_secret => $access_token->{secret},
229             );
230              
231             =head1 DESCRIPTION
232              
233             This module provides a simple interface to the LinkedIn OAuth API.
234              
235             The documentation on LinkedIn's website was unclear and required a couple days
236             of trial-and-error to make it all work.
237              
238             =head1 ACKNOWLEDGEMENTS
239              
240             Special thanks to:
241              
242             =over 4
243              
244             =item * Taylor Singletary who put together this SlideShare presentation:
245             L
246              
247             =item * The authors of L, L, L and L without which this module would not be possible.
248              
249             =head1 AUTHOR
250              
251             John Drago C<< >>
252              
253             Copyright 2011 - All rights reserved.
254              
255             =head1 LICENSE
256              
257             This software is Free software and may be used and redistributed under the same
258             terms as any version of perl itself.
259              
260             =cut
261              
262