File Coverage

blib/lib/Hatena/API/Auth.pm
Criterion Covered Total %
statement 66 71 92.9
branch 13 24 54.1
condition n/a
subroutine 15 15 100.0
pod 4 4 100.0
total 98 114 85.9


line stmt bran cond sub pod time code
1             package Hatena::API::Auth;
2 2     2   54057 use strict;
  2         6  
  2         77  
3 2     2   12 use warnings;
  2         5  
  2         108  
4             our $VERSION = 0.05;
5              
6 2     2   11 use base qw (Class::Accessor::Fast Class::ErrorHandler);
  2         8  
  2         1780  
7              
8 2     2   11506 use URI;
  2         14109  
  2         53  
9 2     2   2010 use LWP::UserAgent;
  2         80170  
  2         78  
10 2     2   23 use Digest::MD5 qw(md5_hex);
  2         4  
  2         1025  
11              
12             BEGIN {
13 2     2   12 use Carp;
  2         5  
  2         397  
14 2     2   5 our $HAVE_JSON_SYCK;
15 2         5 eval { require JSON::Syck; $HAVE_JSON_SYCK = 1 };
  2         834  
  0         0  
16 2 50       15 eval { require JSON } unless $HAVE_JSON_SYCK;
  2         2155  
17 2 50       25448 Carp::croak("JSON::Syck or JSON required to use " . __PACKAGE__) if $@;
18             *_parse_json =
19 0         0 $HAVE_JSON_SYCK ? sub { JSON::Syck::Load($_[1]) }
20 2 50   2   999 : sub { JSON::jsonToObj($_[1]) };
  2         11  
21             }
22              
23             __PACKAGE__->mk_accessors(qw(api_key secret));
24              
25             sub uri_to_login {
26 7     7 1 2498 my $self = shift;
27 7 50       32 my %parameters = ref $_[0] eq 'HASH' ? %{$_[0]} : @_;
  0         0  
28 7         27 my $uri = URI->new('http://auth.hatena.ne.jp/auth');
29 7         8547 my $request = {
30             api_key => $self->api_key,
31             %parameters,
32             };
33 7         60 $uri->query_form(
34             %$request,
35             api_sig => $self->api_sig($request),
36             );
37 7         684 return $uri;
38             }
39              
40             sub api_sig {
41 9     9 1 50 my $self = shift;
42 9         11 my $args = shift;
43 9         24 my $sig = $self->secret;
44 9         47 for my $key (sort {$a cmp $b} keys %{$args}) {
  11         23  
  9         30  
45 18 50       38 my $value = $args->{$key} ? $args->{$key} : '';
46 18         40 $sig .= $key . $value;
47             }
48 9         65 return Digest::MD5::md5_hex($sig);
49             }
50              
51             sub ua {
52 2     2 1 539 my $self = shift;
53 2 50       7 if (@_) {
54 0         0 $self->{_ua} = shift;
55             } else {
56 2 100       21 $self->{_ua} and return $self->{_ua};
57 1         11 $self->{_ua} = LWP::UserAgent->new;
58 1         2926 $self->{_ua}->agent(join '/', __PACKAGE__, __PACKAGE__->VERSION);
59             }
60 1         61 $self->{_ua};
61             }
62              
63             sub _get_auth_as_json {
64 1     1   2 my $self = shift;
65 1 50       5 my $cert = shift or croak "You must specify your cert as an argument.";
66 1         6 my $uri = URI->new('http://auth.hatena.ne.jp/api/auth.json');
67 1         75 my $request = {
68             api_key => $self->api_key,
69             cert => $cert,
70             };
71 1         12 $uri->query_form(
72             %$request,
73             api_sig => $self->api_sig($request),
74             );
75 1         87 my $res = $self->ua->get($uri->as_string);
76 1 50       634057 $res->is_success ? $res->content : $self->error($res->status_line);
77             }
78              
79             sub login {
80 2     2 1 1340 my $self = shift;
81 2 50       38 my $cert = shift or croak "Invalid argumet (no cert)";
82 2 50       10 my $auth = $self->_get_auth_as_json($cert)
83             or return $self->error($self->errstr);
84 2         64 my $json = $self->_parse_json($auth);
85 1 50       679 if ($json->{has_error}) {
86 1         22 return $self->error($json->{error}->{message});
87             } else {
88 0           return Hatena::API::Auth::User->new($json->{user});
89             }
90             }
91              
92             package Hatena::API::Auth::User;
93 2     2   23 use base qw(Class::Accessor::Fast);
  2         5  
  2         256  
94              
95             __PACKAGE__->mk_accessors(qw(name image_url thumbnail_url));
96              
97             1;
98              
99             __END__