WWW-Google-Cloud-Auth-ServiceAccount

 view release on metacpan or  search on metacpan

lib/WWW/Google/Cloud/Auth/ServiceAccount.pm  view on Meta::CPAN


# so that the token doesn't expire after checking it but before the request
# is processed on the other side.
has token_expiry_shift => (
    isa      => 'Str',
    required => 0,
    default  => 10,
);

has clock => (
    isa     => 'CodeRef',
    default => sub {sub {time}}
);

has ua_string => (
    isa     => 'Str',
    default => "WWW-Google-Cloud-Auth/$VERSION",
);

has _token => (
    is       => 'rw',
    isa      => 'Maybe[Str]',
    default  => undef,
    init_arg => undef,
);

has _token_expiry => (
    is       => 'rw',
    isa      => 'Int',
    default  => 0,
    init_arg => undef,
);

has _ua => (
    isa      => 'LWP::UserAgent',
    builder  => '_build_ua',
    lazy     => 1,
    init_arg => undef,
);

sub _build_ua {
    my $self = shift;
    my $ua = LWP::UserAgent->new(
        agent => $self->ua_string,
    );
    return $ua;
}

sub _generate_jwt {
    my $self = shift;
    open (my $fh, '<', $self->credentials_path) or die("Can't open credentials file: $!");
    my $creds_json = do {local $/; <$fh>};
    my $creds      = JSON::decode_json($creds_json);
    my $payload = {
        iss => $creds->{client_email},
        scope => $self->scope,
        aud => 'https://www.googleapis.com/oauth2/v4/token',
        exp => $self->clock->() + 600,
        iat => $self->clock->(),
    };
    my $key = $creds->{private_key};
    return encode_jwt(alg => 'RS256', payload => $payload, key => \$key);
}

sub get_token {
    my $self = shift;
    return $self->_token if($self->_token && $self->clock->() < $self->_token_expiry);

    my $jwt = $self->_generate_jwt();
    my $response = $self->_ua->post(
        $self->auth_url,
        {
            grant_type => $self->grant_type,
            assertion  => $jwt,
        }
    );

    if ($response->is_success) {
        my $r = decode_json($response->decoded_content);
        $self->_token($r->{access_token});
        $self->_token_expiry($self->clock->() + $r->{expires_in} - $self->token_expiry_shift);
        return $self->_token;
    } else {
        my @err = ($response->code, $response->message, $response->decoded_content);
        croak "@err";
    }
}

__PACKAGE__->meta->make_immutable;

1;

=pod

=encoding utf8

=head1 NAME

WWW::Google::Cloud::Auth::ServiceAccount - Service account based OAuth authentication for Google Cloud APIs

=head1 SYNOPSIS

    my $auth = WWW::Google::Cloud::Auth::ServiceAccount>new(
        credentials_path => '/home/myapp/priv/google_some_service.json',
    );

    my $response = $ua->post(
		 $some_google_cloud_api_endpoint,
		'Content-Type' => 'application/json; charset=utf-8',
		'Authorization' => 'Bearer ' . $auth->get_token,
		 Content => $arguments,
	);

=head1 DESCRIPTION

This is a library for service account based OAuth authentication with Google Cloud API endpoints for server to server applications.
See: L<https://developers.google.com/identity/protocols/OAuth2ServiceAccount>

=head1 FUNCTIONS

=head2 WWW::Google::Cloud::Auth::ServiceAccount->new(credentials_path => $credentials_path);

 view all matches for this distribution
 view release on metacpan -  search on metacpan

( run in 0.859 second using v1.00-cache-2.02-grep-82fe00e-cpan-f73e49a70403 )