File Coverage

blib/lib/Firebase/Auth.pm
Criterion Covered Total %
statement 48 50 96.0
branch 11 16 68.7
condition 3 3 100.0
subroutine 13 13 100.0
pod 5 5 100.0
total 80 87 91.9


line stmt bran cond sub pod time code
1             package Firebase::Auth;
2             $Firebase::Auth::VERSION = '1.0002';
3 2     2   39976 use strict;
  2         4  
  2         165  
4 2     2   11 use warnings;
  2         4  
  2         69  
5 2     2   2883 use Digest::SHA qw(hmac_sha256);
  2         13137  
  2         504  
6 2     2   1172 use JSON::XS;
  2         10854  
  2         150  
7 2     2   3588 use POSIX;
  2         20367  
  2         14  
8 2     2   8272 use MIME::Base64;
  2         1458  
  2         162  
9 2     2   1108 use Moo;
  2         27821  
  2         18  
10 2     2   19199 use Ouch;
  2         12047  
  2         2595  
11              
12              
13             has token_version => (
14             is => 'rw',
15             default => sub { 0 },
16             );
17              
18             has secret => (
19             is => 'rw',
20             required=> 1,
21             );
22              
23             has data => (
24             is => 'rw',
25             predicate => 'has_data',
26             );
27              
28             has token_seperator => (
29             is => 'rw',
30             default => sub { '.' },
31             );
32              
33             has expires => (
34             is => 'rw',
35             predicate => 'has_expires',
36             );
37              
38             has not_before => (
39             is => 'rw',
40             predicate => 'has_not_before',
41             );
42              
43             has admin => (
44             is => 'rw',
45             predicate => 'has_admin',
46             );
47              
48             has debug => (
49             is => 'rw',
50             predicate => 'has_debug',
51             );
52              
53             sub create_token {
54 13     13 1 896 my ($self, $data) = @_;
55 13   100     158 return $self->encode_token($self->create_claims($data || $self->data));
56             }
57              
58             sub create_claims {
59 13     13 1 29 my ($self, $data) = @_;
60 13 100       355 if (! exists $data->{uid}) {
    50          
    50          
61 1 50       5 ouch('missing param', 'Data payload must contain a "uid" key that must be a string.', 'uid') unless $self->admin;
62             }
63             elsif ($data->{uid} eq '') {
64 0         0 ouch('param out of range', 'Data payload must contain a "uid" key that must not be empty or null.', 'uid');
65             }
66             elsif (length $data->{uid} > 256) {
67 0         0 ouch('param out of range', 'Data payload must contain a "uid" key that must not be longer than 256 characters.', 'uid');
68             }
69 13         1559 my %claims = (
70             v => $self->token_version,
71             iat => mktime(localtime(time)),
72             d => $data,
73             );
74 13 100       95 $claims{admin} = $self->admin if $self->has_admin;
75 13 50       64 $claims{exp} = $self->expires if $self->has_expires;
76 13 50       53 $claims{nbf} = $self->not_before if $self->has_not_before;
77 13 100       84 $claims{debug} = $self->debug if $self->has_debug;
78 13         70 return \%claims;
79             }
80              
81             sub encode_token {
82 13     13 1 30 my ($self, $claims) = @_;
83 13         307 my $ejsn = JSON::XS->new->utf8->space_after->encode ({'typ'=> 'JWT', 'alg'=> 'HS256'}) ;
84 13         106 my $encoded_header = $self->urlbase64_encode( $ejsn);
85 13         238 my $eclm = JSON::XS->new->utf8->space_after->encode ($claims);
86 13         52 my $encoded_claims = $self->urlbase64_encode( $eclm );
87 13         62 my $secure_bits = $encoded_header . $self->token_seperator . $encoded_claims;
88 13         71 return $secure_bits . $self->token_seperator . $self->urlbase64_encode($self->sign($secure_bits));
89             }
90              
91             sub urlbase64_encode {
92 39     39 1 66 my ($self, $data) = @_;
93 39         156 $data = encode_base64($data, '');
94 39         83 $data =~ tr|+/=|\-_|d;
95 39         135 return $data;
96             }
97              
98             sub sign {
99 13     13 1 25 my ($self, $bits) = @_;
100 13         327 return hmac_sha256($bits, $self->secret);
101             }
102              
103              
104              
105             =head1 NAME
106              
107             Firebase::Auth - Auth token generation for firebase.com.
108              
109             =head1 VERSION
110              
111             version 1.0002
112              
113             =head1 SYNOPSIS
114              
115             use Firebase::Auth;
116            
117             my $token = Firebase::Auth->new(token => 'xxxxxxxxx', admin => 'true', data => { uid => '1' } )->create_token();
118              
119              
120             =head1 DESCRIPTION
121              
122             This module provides a Perl class to generate auth tokens for L. See L for details on the spec.
123            
124            
125             =head1 METHODS
126              
127              
128             =head2 new
129              
130             Constructor.
131              
132             =over
133              
134             =item data
135              
136             Optional. If you don't specify this, then you need to specify it when you call create_token(). This should be a hash reference of all the data you want to pass for user data. This data will be available as the C object in Firebase's security rules. If you do specify it, then it must have a C key that contain's the users unique user id, which must be a non-null string that is no longer than 256 characters.
137              
138             =item secret
139              
140             Required. The api secret token provided by firebase.com.
141              
142             =item admin
143              
144             Defaults to C<\0>. If set to C<\1> (a reference to zero or one) then full access will be granted for this token.
145              
146             =item debug
147              
148             Defaults to C<\0>. If set to C<\1> (a reference to zero or one) then verbose error messages will be returned from service calls.
149              
150             B To access debug info, call C on the L object after making a request.
151              
152             =item expires
153              
154             An epoch date. Defaults to expiring 24 hours from the issued date.
155              
156             =item not_before
157              
158             An epoch date. The opposite of C. Defaults to now. The token will not be valid until after this date.
159              
160             =item token_version
161              
162             Defaults to C<0>.
163              
164             =item token_separator
165              
166             Defaults to C<.>
167              
168             =back
169              
170              
171             =head2 urlbase64_encode
172              
173             URL base-64 encodes a string, and then does some minor translation on it to make it compatible with Firebase.
174              
175             =over
176              
177             =item string
178              
179             The string to encode.
180              
181             =back
182              
183              
184              
185              
186             =head2 create_token
187              
188             Generates a signed token. This is probably the only method you'll ever need to call besides the constructor.
189              
190             =over
191              
192             =item data
193              
194             Required if not specified in constructor. Defaults to the C element in the constructor. A hash reference of parameters you wish to pass to the service. If specified it must have a C key that contain's the users unique user id, which must be a non-null string that is no longer than 256 characters.
195              
196             =back
197              
198              
199              
200             =head2 create_claims
201              
202             Generates a list of claims based upon the options provided to the constructor.
203              
204             =over
205              
206             =item data
207              
208             Required. A hash reference of user data you wish to pass to the service. It must have a C key that contain's the users unique user id, which must be a non-null string that is no longer than 256 characters.
209              
210             =back
211              
212              
213              
214             =head2 encode_token
215              
216             Encodes, signs, and formats the data into a token.
217              
218             =over
219              
220             =item claims
221              
222             Required. A list of claims as created by C
223              
224             =back
225              
226              
227             =head2 sign
228              
229             Generates a signature based upon a string of data.
230              
231             =over
232              
233             =item string
234              
235             A string to sign.
236              
237             =back
238              
239              
240              
241             =head1 EXCEPTIONS
242              
243             This module may L exceptions.
244              
245             =head2 missing param
246              
247             This will be thrown if a required parameter was not set. For example the C key in the C payload.
248              
249             =head2 param out of range
250              
251             This will be thrown if a parameter is outside it's acceptable range. For example the C key in the C payload.
252              
253              
254              
255             =head1 AUTHOR
256              
257             =over
258              
259             =item *
260              
261             Kiran Kumar, C<< >>
262              
263             =item *
264              
265             JT Smith, C<< >>
266              
267             =back
268              
269              
270              
271             =head1 SUPPORT
272              
273             =over
274              
275             =item Source Code Repository
276              
277             L
278              
279             =item Issue Tracker
280              
281             L
282              
283             =back
284              
285              
286              
287              
288             =head1 LICENSE AND COPYRIGHT
289              
290             Copyright 2013 Kiran Kumar.
291              
292             This program is free software; you can redistribute it and/or modify it
293             under the terms of the the Artistic License (2.0). You may obtain a
294             copy of the full license at:
295              
296             L
297              
298             Any use, modification, and distribution of the Standard or Modified
299             Versions is governed by this Artistic License. By using, modifying or
300             distributing the Package, you accept this license. Do not use, modify,
301             or distribute the Package, if you do not accept this license.
302              
303             If your Modified Version has been derived from a Modified Version made
304             by someone other than you, you are nevertheless required to ensure that
305             your Modified Version complies with the requirements of this license.
306              
307             This license does not grant you the right to use any trademark, service
308             mark, tradename, or logo of the Copyright Holder.
309              
310             This license includes the non-exclusive, worldwide, free-of-charge
311             patent license to make, have made, use, offer to sell, sell, import and
312             otherwise transfer the Package with respect to any patent claims
313             licensable by the Copyright Holder that are necessarily infringed by the
314             Package. If you institute patent litigation (including a cross-claim or
315             counterclaim) against any party alleging that the Package constitutes
316             direct or contributory patent infringement, then this Artistic License
317             to you shall terminate on the date that such litigation is filed.
318              
319             Disclaimer of Warranty: THE PACKAGE IS PROVIDED BY THE COPYRIGHT HOLDER
320             AND CONTRIBUTORS "AS IS' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES.
321             THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
322             PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED TO THE EXTENT PERMITTED BY
323             YOUR LOCAL LAW. UNLESS REQUIRED BY LAW, NO COPYRIGHT HOLDER OR
324             CONTRIBUTOR WILL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OR
325             CONSEQUENTIAL DAMAGES ARISING IN ANY WAY OUT OF THE USE OF THE PACKAGE,
326             EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
327              
328              
329             =cut
330              
331             1; # End of WWW::Firebase