File Coverage

blib/lib/LINE/Bot/API/Event.pm
Criterion Covered Total %
statement 76 77 98.7
branch 3 6 50.0
condition 4 6 66.6
subroutine 20 20 100.0
pod 0 2 0.0
total 103 111 92.7


line stmt bran cond sub pod time code
1             package LINE::Bot::API::Event;
2 47     47   138544 use strict;
  47         108  
  47         1340  
3 47     47   225 use warnings;
  47         85  
  47         1265  
4              
5 47     47   247 use Carp 'carp';
  47         147  
  47         2972  
6             our @CARP_NOT = qw( LINE::Bot::API::Event LINE::Bot::API);
7              
8 47     47   23938 use Digest::SHA 'hmac_sha256';
  47         142853  
  47         4004  
9 47     47   1126 use JSON::XS 'decode_json';
  47         7405  
  47         2641  
10 47     47   21489 use MIME::Base64 'decode_base64';
  47         28715  
  47         2756  
11              
12 47     47   20262 use LINE::Bot::API::Event::Message;
  47         128  
  47         1357  
13 47     47   19875 use LINE::Bot::API::Event::Follow;
  47         127  
  47         1328  
14 47     47   19267 use LINE::Bot::API::Event::Unfollow;
  47         132  
  47         1312  
15 47     47   19059 use LINE::Bot::API::Event::Join;
  47         137  
  47         1329  
16 47     47   19184 use LINE::Bot::API::Event::Leave;
  47         146  
  47         1530  
17 47     47   18873 use LINE::Bot::API::Event::MemberJoin;
  47         158  
  47         1655  
18 47     47   18874 use LINE::Bot::API::Event::MemberLeave;
  47         137  
  47         1318  
19 47     47   18515 use LINE::Bot::API::Event::Postback;
  47         204  
  47         1393  
20 47     47   19564 use LINE::Bot::API::Event::BeaconDetection;
  47         133  
  47         1334  
21 47     47   19255 use LINE::Bot::API::Event::Things;
  47         133  
  47         1338  
22 47     47   19672 use LINE::Bot::API::Event::AccountLink;
  47         132  
  47         17379  
23              
24             my %TYPE2CLASS = (
25             message => 'LINE::Bot::API::Event::Message',
26             follow => 'LINE::Bot::API::Event::Follow',
27             unfollow => 'LINE::Bot::API::Event::Unfollow',
28             join => 'LINE::Bot::API::Event::Join',
29             leave => 'LINE::Bot::API::Event::Leave',
30             memberJoined => 'LINE::Bot::API::Event::MemberJoin',
31             memberLeft => 'LINE::Bot::API::Event::MemberLeave',
32             postback => 'LINE::Bot::API::Event::Postback',
33             beacon => 'LINE::Bot::API::Event::BeaconDetection',
34             things => 'LINE::Bot::API::Event::Things',
35             accountLink => 'LINE::Bot::API::Event::AccountLink',
36             );
37              
38             sub parse_events_json {
39 2     2 0 5977 my($self, $json) = @_;
40 2         6 my $events = [];
41              
42 2         235 my $data = decode_json $json;
43 2         10 for my $event_data (@{ $data->{events} }) {
  2         9  
44 40         66 my $type = $event_data->{type};
45 40         64 my $event_class = $TYPE2CLASS{$type};
46 40 50       73 unless ($event_class) {
47 0         0 carp 'Unsupported event type: ' . $type;
48             }
49              
50 40         46 my $event = $event_class->new(%{ $event_data });
  40         254  
51 40         69 push @{ $events }, $event;
  40         92  
52             }
53              
54 2         24 $events;
55             }
56              
57             sub validate_signature {
58 4     4 0 6885 my($class, $json, $channel_secret, $signature) = @_;
59 4 50 66     37 return unless $signature && $json && $channel_secret;
      66        
60 2         128 my $json_signature = hmac_sha256($json, $channel_secret);
61 2         15 _secure_compare(decode_base64($signature), $json_signature);
62             }
63              
64             # Constant time string comparison for timing attacks.
65             sub _secure_compare {
66 2     2   6 my($x, $y) = @_;
67 2 50       9 return unless length $x == length $y;
68 2         28 my @a = unpack 'C*', $x;
69 2         9 my @b = unpack 'C*', $y;
70 2         14 my $compare = 0;
71 2         12 for my $i (0..(scalar(@a) - 1)) {
72 64         142 $compare |= $a[$i] ^ $b[$i];
73             }
74 2         17 return !$compare;
75             }
76              
77             1;
78             __END__