110 lines
2.9 KiB
Perl
110 lines
2.9 KiB
Perl
package YTMusicAPI::Auth::OAuth::OAuthCredentials;
|
|
|
|
use strict;
|
|
use warnings;
|
|
|
|
use JSON;
|
|
use LWP::UserAgent;
|
|
use Data::Dumper;
|
|
|
|
use YTMusicAPI::Constants qw(
|
|
OAUTH_CLIENT_ID
|
|
OAUTH_CLIENT_SECRET
|
|
OAUTH_CODE_URL
|
|
OAUTH_SCOPE
|
|
OAUTH_TOKEN_URL
|
|
OAUTH_USER_AGENT
|
|
);
|
|
|
|
sub new {
|
|
my ( $class, $args ) = @_;
|
|
|
|
unless ( defined $args->{client_id} == defined $args->{client_secret} ) {
|
|
die "OAuthCredential init failure. "
|
|
. "Provide both client_id and client_secret or neither.";
|
|
}
|
|
|
|
my $self = {};
|
|
bless $self, $class;
|
|
|
|
$self->{client_id} =
|
|
$args->{client_id} ? $args->{client_id} : OAUTH_CLIENT_ID;
|
|
$self->{client_secret} =
|
|
$args->{client_secret} ? $args->{client_secret} : OAUTH_CLIENT_SECRET;
|
|
|
|
$self->{_session} =
|
|
$args->{session} ? $args->{session} : LWP::UserAgent->new;
|
|
|
|
if ( $args->{proxies} ) {
|
|
@$self->{_session}{ keys %{ $args->{proxies} } } =
|
|
values %{ $args->{proxies} };
|
|
}
|
|
|
|
return $self;
|
|
}
|
|
|
|
sub get_code {
|
|
my ($self) = @_;
|
|
my $code_response =
|
|
$self->_send_request( OAUTH_CODE_URL, { "scope" => OAUTH_SCOPE } );
|
|
return decode_json( $code_response->decoded_content );
|
|
}
|
|
|
|
sub _send_request {
|
|
my ( $self, $url, $data ) = @_;
|
|
|
|
$data->{"client_id"} = $self->{client_id};
|
|
my $request = HTTP::Request->new( POST => $url );
|
|
$request->header( "User-Agent" => OAUTH_USER_AGENT );
|
|
$request->content( encode_json($data) );
|
|
my $response = $self->{_session}->request($request);
|
|
|
|
if ( $response->code == 401 ) {
|
|
my $data = $response->decode_json;
|
|
my $issue = $data->{"error"};
|
|
if ( $issue eq "unauthorized_client" ) {
|
|
die "Token refresh error. Most likely client/token mismatch.";
|
|
}
|
|
elsif ( $issue eq "invalid_client" ) {
|
|
die "OAuth client failure. Most likely client_id and client_secret "
|
|
. "mismatch or YouTubeData API is not enabled.";
|
|
}
|
|
else {
|
|
die "OAuth request error. status_code: "
|
|
. $response->code
|
|
. ", url: $url, content: "
|
|
. Dumper($data);
|
|
}
|
|
}
|
|
|
|
return $response;
|
|
}
|
|
|
|
sub token_from_code {
|
|
my ( $self, $device_code ) = @_;
|
|
my $response = $self->_send_request(
|
|
OAUTH_TOKEN_URL,
|
|
{
|
|
"client_secret" => $self->{client_secret},
|
|
"grant_type" => "http://oauth.net/grant_type/device/1.0",
|
|
"code" => $device_code,
|
|
}
|
|
);
|
|
return decode_json( $response->decoded_content );
|
|
}
|
|
|
|
sub refresh_token {
|
|
my ( $self, $refresh_token ) = @_;
|
|
my $response = $self->_send_request(
|
|
OAUTH_TOKEN_URL,
|
|
{
|
|
"client_secret" => $self->{client_secret},
|
|
"grant_type" => "refresh_token",
|
|
"refresh_token" => $refresh_token,
|
|
}
|
|
);
|
|
return decode_json( $response->decoded_content );
|
|
}
|
|
|
|
1;
|