File Coverage

blib/lib/Amon2/Auth/Site/Github.pm
Criterion Covered Total %
statement 24 55 43.6
branch 0 20 0.0
condition n/a
subroutine 8 11 72.7
pod 0 3 0.0
total 32 89 35.9


line stmt bran cond sub pod time code
1 1     1   830 use strict;
  1         1  
  1         23  
2 1     1   3 use warnings;
  1         1  
  1         20  
3 1     1   3 use utf8;
  1         1  
  1         4  
4              
5             package Amon2::Auth::Site::Github;
6 1     1   22 use Mouse;
  1         1  
  1         9  
7              
8 1     1   276 use Amon2::Auth;
  1         1  
  1         16  
9 1     1   4 use LWP::UserAgent;
  1         1  
  1         17  
10 1     1   3 use JSON;
  1         1  
  1         6  
11 1     1   446 use Amon2::Auth::Util qw(parse_content);
  1         3  
  1         492  
12             our $VERSION = '0.07';
13              
14 0     0 0   sub moniker { 'github' }
15              
16             has client_id => (
17             is => 'ro',
18             isa => 'Str',
19             required => 1,
20             );
21             has client_secret => (
22             is => 'ro',
23             isa => 'Str',
24             required => 1,
25             );
26             has scope => (
27             is => 'ro',
28             isa => 'Str',
29             );
30              
31             has user_info => (
32             is => 'rw',
33             isa => 'Bool',
34             default => 1,
35             );
36              
37             has ua => (
38             is => 'ro',
39             isa => 'LWP::UserAgent',
40             lazy => 1,
41             default => sub {
42             my $ua = LWP::UserAgent->new(agent => "Amon2::Auth/$Amon2::Auth::VERSION");
43             },
44             );
45              
46             has authorize_url => (
47             is => 'ro',
48             isa => 'Str',
49             default => 'https://github.com/login/oauth/authorize',
50             );
51             has access_token_url => (
52             is => 'ro',
53             isa => 'Str',
54             default => 'https://github.com/login/oauth/access_token',
55             );
56             has redirect_url => (
57             is => 'ro',
58             isa => 'Str',
59             );
60              
61             sub auth_uri {
62 0     0 0   my ($self, $c, $callback_uri) = @_;
63              
64 0           my $redirect_uri = URI->new($self->authorize_url);
65 0           my %params;
66 0 0         if (defined $callback_uri) {
    0          
67 0           $params{redirect_uri} = $callback_uri;
68             } elsif (defined $self->redirect_url) {
69 0           $params{redirect_uri} = $self->redirect_url;
70             }
71 0           for (qw(client_id scope)) {
72 0 0         next unless defined $self->$_;
73 0           $params{$_} = $self->$_;
74             }
75 0           $redirect_uri->query_form(%params);
76 0           return $redirect_uri->as_string;
77             }
78              
79             sub callback {
80 0     0 0   my ($self, $c, $callback) = @_;
81              
82 0 0         my $code = $c->req->param('code') or die "Cannot get a 'code' parameter";
83 0           my %params = (code => $code);
84 0           $params{client_id} = $self->client_id;
85 0           $params{client_secret} = $self->client_secret;
86 0 0         $params{redirect_url} = $self->redirect_url if defined $self->redirect_url;
87 0           my $res = $self->ua->post($self->access_token_url, \%params);
88 0 0         $res->is_success or die "Cannot authenticate";
89 0           my $dat = parse_content($res->decoded_content);
90 0 0         if (my $err = $dat->{error}) {
91 0           return $callback->{on_error}->($err);
92             }
93 0 0         my $access_token = $dat->{access_token} or die "Cannot get a access_token";
94 0           my @args = ($access_token);
95 0 0         if ($self->user_info) {
96 0           my $res = $self->ua->get("https://api.github.com/user?oauth_token=${access_token}");
97 0 0         $res->is_success or return $callback->{on_error}->($res->status_line);
98 0           my $dat = decode_json($res->decoded_content);
99 0           push @args, $dat;
100             }
101 0           return $callback->{on_finished}->( @args );
102             }
103              
104             1;
105             __END__
106              
107             =head1 NAME
108              
109             Amon2::Auth::Site::Github - Github integration for Amon2
110              
111             =head1 SYNOPSIS
112              
113              
114             __PACKAGE__->load_plugin('Web::Auth', {
115             module => 'Github',
116             on_finished => sub {
117             my ($c, $token, $user) = @_;
118             my $name = $user->{name} || die;
119             $c->session->set('name' => $name);
120             $c->session->set('site' => 'github');
121             return $c->redirect('/');
122             }
123             });
124              
125             =head1 DESCRIPTION
126              
127             This is a github authentication module for Amon2. You can call a github APIs with this module.
128              
129             =head1 ATTRIBUTES
130              
131             =over 4
132              
133             =item client_id
134              
135             =item client_secret
136              
137             =item scope
138              
139             API scope in string.
140              
141             =item user_info(Default: true)
142              
143             Fetch user information after authenticate?
144              
145             =item ua(instance of LWP::UserAgent)
146              
147             You can replace instance of L<LWP::UserAgent>.
148              
149             =back
150              
151             =head1 METHODS
152              
153             =over 4
154              
155             =item C<< $auth->auth_uri($c:Amon2::Web, $callback_uri : Str) :Str >>
156              
157             Get a authenticate URI.
158              
159             =item C<< $auth->callback($c:Amon2::Web, $callback:HashRef) : Plack::Response >>
160              
161             Process the authentication callback dispatching.
162              
163             C<< $callback >> MUST have two keys.
164              
165             =over 4
166              
167             =item on_error
168              
169             on_error callback function is called if an error was occurred.
170              
171             The arguments are following:
172              
173             sub {
174             my ($c, $error_message) = @_;
175             ...
176             }
177              
178             =item on_finished
179              
180             on_finished callback function is called if an authentication was finished.
181              
182             The arguments are following:
183              
184             sub {
185             my ($c, $access_token, $user) = @_;
186             ...
187             }
188              
189             C<< $user >> contains user information. This code contains a information like L<https://api.github.com/users/dankogai>.
190              
191             If you set C<< $auth->user_info >> as false value, authentication engine does not pass C<< $user >>.
192              
193             =back
194              
195             =back
196