File Coverage

blib/lib/Amon2/Auth/Site/Google.pm
Criterion Covered Total %
statement 15 47 31.9
branch 0 10 0.0
condition n/a
subroutine 5 8 62.5
pod 1 3 33.3
total 21 68 30.8


line stmt bran cond sub pod time code
1             package Amon2::Auth::Site::Google;
2 1     1   1542 use Mouse;
  1         33244  
  1         5  
3              
4 1     1   303 use JSON;
  1         2  
  1         10  
5 1     1   1564 use LWP::UserAgent;
  1         52400  
  1         31  
6 1     1   11 use URI;
  1         1  
  1         236  
7              
8             our $VERSION = "0.03";
9              
10             has client_id => (
11             is => 'ro',
12             isa => 'Str',
13             required => 1,
14             );
15              
16             has client_secret => (
17             is => 'ro',
18             isa => 'Str',
19             required => 1,
20             );
21              
22             has redirect_url => (
23             is => 'ro',
24             isa => 'Str',
25             );
26              
27             has scope => (
28             is => 'ro',
29             isa => 'ArrayRef',
30             default => sub { [qw(https://www.googleapis.com/auth/userinfo.profile)] },
31             );
32              
33             has user_info => (
34             is => 'rw',
35             isa => 'Bool',
36             default => 1,
37             );
38              
39             has authorize_url => (
40             is => 'ro',
41             isa => 'Str',
42             default => 'https://accounts.google.com/o/oauth2/auth',
43             );
44              
45             has token_url => (
46             is => 'ro',
47             isa => 'Str',
48             default => 'https://accounts.google.com/o/oauth2/token',
49             );
50              
51             has token_info_url => (
52             is => 'ro',
53             isa => 'Str',
54             default => 'https://www.googleapis.com/oauth2/v1/tokeninfo',
55             );
56              
57             has user_info_url => (
58             is => 'ro',
59             isa => 'Str',
60             default => 'https://www.googleapis.com/oauth2/v1/userinfo',
61             );
62              
63             has ua => (
64             is => 'ro',
65             isa => 'LWP::UserAgent',
66             lazy => 1,
67             default => sub {
68             LWP::UserAgent->new(agent => "Amon2::Auth::Site::Google/$VERSION");
69             },
70             );
71              
72 1     1   7 no Mouse;
  1         2  
  1         12  
73             __PACKAGE__->meta->make_immutable;
74              
75 0     0 0   sub moniker { 'google' }
76              
77             sub auth_uri {
78 0     0 0   my ($self, $c, $callback_uri) = @_;
79              
80 0           my $uri = URI->new($self->authorize_url);
81 0           $uri->query_form(+{
82             client_id => $self->client_id,
83             scope => $self->scope,
84             redirect_uri => $callback_uri,
85             response_type => 'code',
86             access_type => 'offline',
87             approval_prompt => 'force',
88             });
89 0           return $uri->as_string;
90             }
91              
92             sub callback {
93 0     0 1   my ($self, $c, $callback) = @_;
94              
95 0           my $res = $self->ua->post($self->token_url, +{
96             client_id => $self->client_id,
97             client_secret => $self->client_secret,
98             code => $c->req->param('code'),
99             redirect_uri => $self->redirect_url,
100             grant_type => 'authorization_code',
101             });
102 0 0         $res->is_success or do {
103 0           warn $res->decoded_content;
104 0           return $callback->{on_error}->($res->decoded_content);
105             };
106 0           my $token = decode_json $res->content;
107              
108 0           my $uri = URI->new($self->token_info_url);
109 0           $uri->query_form(+{ access_token => $token->{access_token} });
110 0           $res = $self->ua->get($uri->as_string);
111 0           my $token_info = decode_json $res->content;
112 0 0         $res->is_success or do {
113 0           warn $res->decoded_content;
114 0           return $callback->{on_error}->($res->decoded_content);
115             };
116 0 0         $token_info->{audience} eq $self->client_id or do {
117 0           warn 'invalid token';
118 0           return $callback->{on_error}->('invalid token');
119             };
120 0           my @args = ($token->{access_token}, $token->{refresh_token});
121              
122 0 0         if ($self->user_info) {
123 0           my $uri = URI->new($self->user_info_url);
124 0           $uri->query_form(+{ access_token => $token->{access_token} });
125 0           my $res = $self->ua->get($uri->as_string);
126 0 0         $res->is_success or do {
127 0           warn $res->decoded_content;
128 0           return $callback->{on_error}->($res->decoded_content);
129             };
130 0           my $user = decode_json $res->content;
131 0           push @args, $user;
132             }
133              
134 0           $callback->{on_finished}->(@args);
135             }
136              
137             1;
138             __END__