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 )