Subject: | update_access_token doesn't handle when a refresh token changes during a ->refresh() |
Date: | Sun, 23 Mar 2014 11:19:30 -0400 |
To: | bug-Net-OAuth2 [...] rt.cpan.org |
From: | Joe Papperello <antipasta [...] cpan.org> |
Some OAuth2 providers issue a new refresh token when requesting a new
access token.
Net::OAuth2 's update_access_token does not save the new refresh_token in
this scenario, so what happens is:
1. Get an access/refresh token
2. $token->refresh
3. Server returns new access token AND new refresh token
4. Net::OAuth2 saves access token only
... Some time passes ...
4. $token->refresh
5. Request fails since we still have the old refresh token saved
Below is a patch that supports saving the refresh token if it changed,
along with some tests for the feature.
Thanks,
Joe Papperello
diff -Naur Net-OAuth2-0.55/lib/Net/OAuth2/AccessToken.pm
/share/code/Net-OAuth2-0.55/lib/Net/OAuth2/AccessToken.pm
--- Net-OAuth2-0.55/lib/Net/OAuth2/AccessToken.pm 2013-04-02
10:13:41.000000000 -0400
+++ /share/code/Net-OAuth2-0.55/lib/Net/OAuth2/AccessToken.pm 2014-03-23
10:51:40.083495949 -0400
@@ -114,11 +114,16 @@
}
-sub update_token($$$)
-{ my ($self, $token, $type, $exp) = @_;
+sub update_token($$$;$)
+{ my ($self, $token, $type, $exp, $refresh_token) = @_;
$self->{NOA_access_token} = $token;
$self->{NOA_token_type} = $type if $type;
$self->{NOA_expires_at} = $exp;
+
+ $self->{NOA_refresh_token} = $refresh_token
+ if ( $refresh_token
+ && $self->refresh_token
+ && $self->refresh_token ne $refresh_token );
$token;
}
diff -Naur Net-OAuth2-0.55/lib/Net/OAuth2/Profile/WebServer.pm
/share/code/Net-OAuth2-0.55/lib/Net/OAuth2/Profile/WebServer.pm
--- Net-OAuth2-0.55/lib/Net/OAuth2/Profile/WebServer.pm 2013-04-02
10:13:41.000000000 -0400
+++ /share/code/Net-OAuth2-0.55/lib/Net/OAuth2/Profile/WebServer.pm
2014-03-23 10:42:20.337289744 -0400
@@ -121,7 +121,9 @@
my $exp = $data{expires_in}
or die "no expires_in found in refresh data";
- $access->update_token($token, $type, $exp+time());
+ my $refresh_token = $data{refresh_token};
+
+ $access->update_token( $token, $type, $exp + time(), $refresh_token );
}
sub authorize_params(%)
diff -Naur Net-OAuth2-0.55/t/30refresh.t
/share/code/Net-OAuth2-0.55/t/30refresh.t
--- Net-OAuth2-0.55/t/30refresh.t 2013-03-28 05:58:17.000000000 -0400
+++ /share/code/Net-OAuth2-0.55/t/30refresh.t 2014-03-23
11:15:05.874804526 -0400
@@ -17,7 +17,7 @@
plan skip_all => "Test::Mock::LWP::Dispatch not installed" if $@;
Test::Mock::LWP::Dispatch->import;
- plan tests => 4;
+ plan tests => 7;
}
my $at_response = {
@@ -67,3 +67,9 @@
ok $access_token->refresh, 'access_token->refresh';
is $access_token->access_token, $at_response->{access_token},
'response access token has been set';
+is $access_token->refresh_token, $refresh_token_str, 'refresh token
remains unchanged';
+
+$at_response->{refresh_token} = 'new-refresh-token';
+ok $access_token->refresh, 'access_token->refresh';
+is $access_token->refresh_token, $at_response->{refresh_token},
+ 'new response refresh token has been set';