Add OAuth
This commit is contained in:
109
YTMusicAPI/Auth/OAuth/OAuthCredentials.pm
Normal file
109
YTMusicAPI/Auth/OAuth/OAuthCredentials.pm
Normal file
@@ -0,0 +1,109 @@
|
||||
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;
|
||||
Reference in New Issue
Block a user