Amon2-Auth-Site-LINE
view release on metacpan or search on metacpan
lib/Amon2/Auth/Site/LINE.pm view on Meta::CPAN
# required parameters
my $redirect_uri = $self->redirect_uri || $callback_uri;
my %params = (
response_type => 'code',
client_id => $self->client_id,
scope => join(' ', @{$self->scope}),
redirect_uri => $redirect_uri,
state => $self->get_state($c),
);
# optional parameters
$params{nonce} = $self->get_nonce($c);
for my $key (qw(prompt max_age ui_locales bot_prompt)) {
my $value = $self->$key;
if (defined $value) {
$params{$key} = $value;
}
}
my $auth_uri = URI->new($self->authorize_url);
$auth_uri->query_form(%params);
return $auth_uri->as_string;
}
sub callback {
my($self, $c, $callback) = @_;
# state mismatch
if ($c->req->param('state') ne $self->get_state($c)) {
return $callback->{on_error}->('state parameter mismatch');
}
# access denied
if ($c->req->param('error')) {
return $callback->{on_error}->($c->req->param('error_description'));
}
my @args = ();
my %api_response = ();
# getting an access token
my $token_data;
{
my $redirect_uri = $self->redirect_uri || do { # it should be me
my $current_uri = $c->req->uri;
$current_uri->query(undef);
$current_uri->as_string;
};
my $res = $self->ua->post($self->access_token_url => +{
grant_type => 'authorization_code',
code => $c->req->param('code'),
redirect_uri => $redirect_uri,
client_id => $self->client_id,
client_secret => $self->client_secret,
});
unless ($res->is_success) {
warn $res->decoded_content;
return $callback->{on_error}->($res->status_line);
}
$token_data = decode_json($res->content);
%api_response = (%api_response, %$token_data);
}
# verify access token
my $verify_data;
{
my $uri = URI->new($self->verify_url);
$uri->query_form(access_token => $token_data->{access_token});
my $res = $self->ua->get($uri->as_string);
unless ($res->is_success) {
warn $res->decoded_content;
return $callback->{on_error}->($res->status_line);
}
$verify_data = decode_json($res->content);
if ($verify_data->{client_id} ne $self->client_id) {
return $callback->{on_error}->('client_id mismatch');
}
push @args, $token_data->{access_token};
%api_response = (%api_response, %$verify_data);
}
# get user profile
if ($self->user_info && $verify_data->{scope} =~ /\bprofile\b/) {
my $uri = URI->new($self->profile_url);
my $res = $self->ua->get(
$uri->as_string,
Authorization => 'Bearer ' . $token_data->{access_token},
);
$res->is_success or do {
warn $res->decoded_content;
return $callback->{on_error}->($res->decoded_content);
};
my $user = decode_json($res->content);
%api_response = (%api_response, %$user);
}
push @args, \%api_response;
$self->clear_state($c);
$self->clear_nonce($c);
$callback->{on_finished}->(@args);
}
sub get_state {
my($self, $c) = @_;
my $state = $self->state || $c->session->get($self->state_session_key) || do {
require Crypt::URandom::Token;
Crypt::URandom::Token::urandom_token(16)
};
$self->set_state($c, $state);
return $state;
}
sub set_state {
my($self, $c, $state) = @_;
return $c->session->set($self->state_session_key => $state);
}
sub clear_state {
my($self, $c) = @_;
return $c->session->remove($self->state_session_key);
}
sub get_nonce {
my($self, $c) = @_;
my $nonce = $self->nonce || $c->session->get($self->nonce_session_key) || do {
require Crypt::URandom::Token;
Crypt::URandom::Token::urandom_token(16)
};
$self->set_nonce($c, $nonce);
return $nonce;
}
sub set_nonce {
my($self, $c, $nonce) = @_;
return $c->session->set($self->nonce_session_key => $nonce);
}
sub clear_nonce {
my($self, $c) = @_;
return $c->session->remove($self->nonce_session_key);
}
1;
__END__
=head1 NAME
Amon2::Auth::Site::LINE - LINE integration for Amon2
=head1 SYNOPSIS
( run in 1.189 second using v1.01-cache-2.11-cpan-d7f47b0818f )