File Coverage

lib/Auth/YubiKey/Client/Web.pm
Criterion Covered Total %
statement 21 34 61.7
branch n/a
condition n/a
subroutine 7 9 77.7
pod 2 2 100.0
total 30 45 66.6


line stmt bran cond sub pod time code
1             package Auth::YubiKey::Client::Web;
2             {
3             $Auth::YubiKey::Client::Web::DIST = 'Auth-YubiKey-Client-Web';
4             }
5             $Auth::YubiKey::Client::Web::VERSION = '0.0.2';
6 1     1   1491 use Moo;
  1         2  
  1         8  
7 1     1   277 use Carp;
  1         1  
  1         89  
8 1     1   7 use Digest::HMAC_SHA1 qw(hmac_sha1_hex hmac_sha1);
  1         2  
  1         58  
9 1     1   2736852 use HTTP::Tiny;
  1         61296  
  1         36  
10 1     1   9 use MIME::Base64;
  1         2  
  1         66  
11 1     1   870 use URI::Escape;
  1         1454  
  1         61  
12              
13 1     1   6 use Auth::YubiKey::Client::Web::Response;
  1         2  
  1         416  
14              
15              
16             has id => (
17             is => 'ro',
18             isa => sub { Carp::confess( 'id must be defined' ) unless defined $_[0] },
19             required => 1,
20             );
21              
22             has api_key => (
23             is => 'ro',
24             isa => sub { Carp::confess( 'api_key must be defined' ) unless defined $_[0] },
25             required => 1,
26             );
27              
28             # https://code.google.com/p/yubikey-val-server-php/wiki/GettingStartedWritingClients
29             has verify_url => (
30             is => 'ro',
31             default => 'https://api2.yubico.com/wsapi/2.0/verify?',
32             );
33              
34             has ua => (
35             is => 'ro',
36             default => sub {
37             HTTP::Tiny->new(
38             agent => __PACKAGE__,
39             );
40             }
41             );
42              
43              
44             sub nonce {
45 0     0 1   my $data = rand() . $$ . {} . time;
46 0           my $key = "@INC";
47 0           my $digest = hmac_sha1_hex($data, $key);
48             };
49              
50             sub verify_otp {
51 0     0 1   my $self = shift;
52 0           my $otp = shift;
53            
54 0           my $nonce = nonce();
55 0           chomp($otp);
56              
57             # Start generating the parameters
58 0           my $params;
59 0           $params = sprintf(
60             'id=%d&nonce=%s&otp=%s×tamp=1',
61             $self->id,
62             $nonce,
63             uri_escape($otp)
64             );
65 0           $params .= sprintf (
66             '&h=%s',
67             uri_escape(
68             encode_base64(hmac_sha1($params,
69             decode_base64($self->api_key)), ''))
70             );
71            
72 0           my $url = $self->verify_url . $params; #join('&', @param_blobs);
73              
74 0           my $response = $self->ua->get( $url );
75              
76             my $yubi_response = Auth::YubiKey::Client::Web::Response->new(
77             request_apikey => $self->api_key,
78             request_otp => $otp,
79             request_nonce => $nonce,
80             request_response => $response->{content},
81 0           );
82             }
83              
84              
85             1;
86             # ABSTRACT: Authenticate using the Yubico Web API
87              
88             =pod
89              
90             =encoding UTF-8
91              
92             =head1 NAME
93              
94             Auth::YubiKey::Client::Web - Authenticate using the Yubico Web API
95              
96             =head1 VERSION
97              
98             version 0.0.2
99              
100             =head1 SYNOPSIS
101              
102             use Auth::YubiKey::Client::Web;
103              
104             my $yubiauth = Auth::YubiKey::Client::Web->new(
105             id => $id,
106             api_key => $apikey,
107             );
108              
109             my $result = $yubiauth->verify_otp($input);
110              
111             if ($result->is_success) {
112             say 'Good to go';
113             say 'user-id: ' . $result->public_id;
114             }
115             else {
116             say 'Oh dear: ' . $result->status;
117             }
118              
119             =head1 CLASS ATTRIBUTES
120              
121             =head2 id
122              
123             =head2 api_key
124              
125             =head2 verify_url
126              
127             =head2 ua
128              
129             =head1 METHODS
130              
131             =head2 nonce()
132              
133             This function returns a
134             L for use in the
135             validation step,
136              
137             my $nonce = nonce();
138              
139             =head2 verify_otp($self, $otp)
140              
141             Given an OTP make a call to the remote service and validate the value
142             provided.
143              
144             This method returns an L object which
145             can be queried for the validity of the request.
146              
147             my $response = $self->verify_otp( $otp );
148             if ($response->is_success) {
149             # yay!
150             }
151             else {
152             # boo!
153             }
154              
155             =head1 API KEY
156              
157             To use this module you will require an API key from Yubico. You can
158             get a key by visiting the following page and entering the required
159             information:
160              
161             =over 4
162              
163             =item L
164              
165             =back
166              
167             =head1 FURTHER READING
168              
169             Here are some related, useful or interesting links:
170              
171             =over 4
172              
173             =item L
174              
175             =item L
176              
177             =back
178              
179             =head1 AUTHOR
180              
181             Chisel
182              
183             =head1 COPYRIGHT AND LICENSE
184              
185             This software is copyright (c) 2013 by Chisel Wright.
186              
187             This is free software; you can redistribute it and/or modify it under
188             the same terms as the Perl 5 programming language system itself.
189              
190             =cut
191              
192             __END__