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   115184 use strict;
  47         98  
  47         1317  
3 47     47   232 use warnings;
  47         87  
  47         1143  
4              
5 47     47   222 use Carp 'carp';
  47         94  
  47         2898  
6             our @CARP_NOT = qw( LINE::Bot::API::Event LINE::Bot::API);
7              
8 47     47   24970 use Digest::SHA 'hmac_sha256';
  47         142070  
  47         4435  
9 47     47   1137 use JSON::XS 'decode_json';
  47         7786  
  47         2461  
10 47     47   22932 use MIME::Base64 'decode_base64';
  47         28368  
  47         2712  
11              
12 47     47   21834 use LINE::Bot::API::Event::Message;
  47         119  
  47         1331  
13 47     47   20337 use LINE::Bot::API::Event::Follow;
  47         128  
  47         1278  
14 47     47   20067 use LINE::Bot::API::Event::Unfollow;
  47         128  
  47         1276  
15 47     47   20205 use LINE::Bot::API::Event::Join;
  47         124  
  47         1382  
16 47     47   20087 use LINE::Bot::API::Event::Leave;
  47         133  
  47         1384  
17 47     47   19777 use LINE::Bot::API::Event::MemberJoin;
  47         161  
  47         1318  
18 47     47   19745 use LINE::Bot::API::Event::MemberLeave;
  47         134  
  47         1263  
19 47     47   19391 use LINE::Bot::API::Event::Postback;
  47         120  
  47         1271  
20 47     47   19755 use LINE::Bot::API::Event::BeaconDetection;
  47         132  
  47         1370  
21 47     47   20016 use LINE::Bot::API::Event::Things;
  47         123  
  47         1298  
22 47     47   19888 use LINE::Bot::API::Event::AccountLink;
  47         133  
  47         16863  
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 4289 my($self, $json) = @_;
40 2         4 my $events = [];
41              
42 2         170 my $data = decode_json $json;
43 2         5 for my $event_data (@{ $data->{events} }) {
  2         6  
44 40         50 my $type = $event_data->{type};
45 40         54 my $event_class = $TYPE2CLASS{$type};
46 40 50       62 unless ($event_class) {
47 0         0 carp 'Unsupported event type: ' . $type;
48             }
49              
50 40         40 my $event = $event_class->new(%{ $event_data });
  40         235  
51 40         83 push @{ $events }, $event;
  40         81  
52             }
53              
54 2         22 $events;
55             }
56              
57             sub validate_signature {
58 4     4 0 5287 my($class, $json, $channel_secret, $signature) = @_;
59 4 50 66     29 return unless $signature && $json && $channel_secret;
      66        
60 2         105 my $json_signature = hmac_sha256($json, $channel_secret);
61 2         14 _secure_compare(decode_base64($signature), $json_signature);
62             }
63              
64             # Constant time string comparison for timing attacks.
65             sub _secure_compare {
66 2     2   5 my($x, $y) = @_;
67 2 50       7 return unless length $x == length $y;
68 2         13 my @a = unpack 'C*', $x;
69 2         8 my @b = unpack 'C*', $y;
70 2         4 my $compare = 0;
71 2         8 for my $i (0..(scalar(@a) - 1)) {
72 64         74 $compare |= $a[$i] ^ $b[$i];
73             }
74 2         12 return !$compare;
75             }
76              
77             1;
78             __END__