Google-Ads-AdWords-Client
view release on metacpan or search on metacpan
lib/Google/Ads/Common/OAuth2BaseHandler.pm view on Meta::CPAN
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
package Google::Ads::Common::OAuth2BaseHandler;
use strict;
use warnings;
use version;
use base qw(Google::Ads::Common::AuthHandlerInterface);
# The following needs to be on one line because CPAN uses a particularly hacky
# eval() to determine module versions.
use Google::Ads::Common::Constants; our $VERSION = ${Google::Ads::Common::Constants::VERSION};
use Class::Std::Fast;
use HTTP::Request::Common;
use LWP::UserAgent;
use URI::Escape;
use constant OAUTH2_TOKEN_INFO_URL =>
"https://www.googleapis.com/oauth2/v1/tokeninfo";
# Class::Std-style attributes. Need to be kept in the same line.
# These need to go in the same line for older Perl interpreters to understand.
my %api_client_of : ATTR(:name<api_client> :default<>);
my %client_id_of : ATTR(:name<client_id> :default<>);
my %access_token_of : ATTR(:init_arg<access_token> :default<>);
my %access_token_expires_of : ATTR(:name<access_token_expires> :default<>);
my %__user_agent_of : ATTR(:name<__user_agent> :default<>);
# Constructor
sub START {
my ($self, $ident) = @_;
$__user_agent_of{$ident} ||= LWP::UserAgent->new();
}
# Methods from Google::Ads::Common::AuthHandlerInterface
sub initialize : CUMULATIVE(BASE FIRST) {
my ($self, $api_client, $properties) = @_;
my $ident = ident $self;
$api_client_of{$ident} = $api_client;
$client_id_of{$ident} = $properties->{oAuth2ClientId}
|| $client_id_of{$ident};
$access_token_of{$ident} = $properties->{oAuth2AccessToken}
|| $access_token_of{$ident};
}
sub prepare_request {
my ($self, $endpoint, $http_headers, $envelope) = @_;
my $access_token = $self->get_access_token();
if (!$access_token) {
my $api_client = $self->get_api_client();
my $err_msg =
"Unable to prepare a request, authorization info is " .
"incomplete or invalid.";
$api_client->get_die_on_faults() ? die($err_msg) : warn($err_msg);
return;
}
push @{$http_headers}, ("Authorization", "Bearer ${access_token}");
return HTTP::Request->new('POST', $endpoint, $http_headers, $envelope);
}
sub is_auth_enabled {
my ($self) = @_;
return $self->get_access_token();
}
# Custom getters and setters for the access token with logic to auto-refresh.
sub get_access_token {
my $self = shift;
my $ident = ident $self;
if (!$self->_is_access_token_valid()) {
if (!$self->_refresh_access_token()) {
return undef;
}
return $access_token_of{$ident};
}
return $access_token_of{$ident};
}
sub set_access_token {
my ($self, $token) = @_;
$access_token_of{ident $self} = $token;
$access_token_expires_of{ident $self} = undef;
}
# Internal methods
# Checks if:
# - the access token is set
# - if the token has no expiration set then assumes it was manually set and:
# - checks the token info, if it is valid then set its expiration
# - checks the token scopes
# - checks the token has not expired
sub _is_access_token_valid {
my $self = shift;
my $ident = ident $self;
my $access_token = $access_token_of{$ident};
if (!$access_token) {
return 0;
}
if (!$self->get_access_token_expires()) {
my $url =
OAUTH2_TOKEN_INFO_URL . "?access_token=" . uri_escape($access_token);
my $res = $self->get___user_agent()->request(GET $url);
if (!$res->is_success()) {
my $err_msg = $res->decoded_content();
$self->get_api_client()->get_die_on_faults()
? die($err_msg)
: warn($err_msg);
return 0;
}
my $content_hash = $self->__parse_auth_response($res->decoded_content());
( run in 0.834 second using v1.01-cache-2.11-cpan-39bf76dae61 )