File Coverage

blib/lib/Dancer/Plugin/EncodeID.pm
Criterion Covered Total %
statement 55 59 93.2
branch 22 34 64.7
condition 1 2 50.0
subroutine 8 9 88.8
pod n/a
total 86 104 82.6


line stmt bran cond sub pod time code
1             package Dancer::Plugin::EncodeID;
2              
3 6     6   1727960 use strict;
  6         17  
  6         223  
4 6     6   35 use warnings;
  6         12  
  6         265  
5             our $VERSION = '0.02';
6              
7 6     6   1197 use Dancer ':syntax';
  6         325096  
  6         42  
8 6     6   7956 use Dancer::Plugin;
  6         8734  
  6         449  
9 6     6   5117 use Crypt::Blowfish;
  6         6385  
  6         4384  
10              
11             my $cipher = undef ;
12             my $padding_character = '!';
13              
14             sub _create_cipher {
15             ## Crate a new cipher, based on the 'secret' in the configuration
16 6 50   6   31 my $settings = plugin_setting or
17             die "Configuration Error: can't find plugin settings for Dancer::Plugin::EncodeID. Please see documentation regarding proper configuration.";
18              
19 6 100       155 my $secret = $settings->{secret} or
20             die "Configuration Error: can't find 'secret' key settings for Dancer::Plugin::EncodeID. Please see documentation regarding proper configuration.";
21              
22 5   50     39 $padding_character = $settings->{padding_character} || '!';
23 5 50       23 die "Configuration error: padding_character must be 1 character long for Dancer::Plugin::EncodeID. Please see documentation regarding proper configuration." unless length($padding_character)==1;
24              
25 5         50 $cipher = new Crypt::Blowfish ( $secret ) ;
26             }
27              
28             register encode_id => sub {
29 139     139   47306 my $cleartext_id = shift;
30 139 50       323 die "Missing Clear text ID parameter" unless defined $cleartext_id;
31              
32             ## Prefix is optional, can be undef
33 139         190 my $prefix = shift ;
34 139 100       280 $cleartext_id = $prefix . $cleartext_id if defined $prefix;
35              
36 139 100       313 _create_cipher() unless $cipher;
37              
38 138         559 my $hash_id = "" ;
39              
40             #Special case - user asked to encode an empty string
41 138 100       589 $cleartext_id = $padding_character x '8' if length($cleartext_id)==0;
42              
43 138         463 while ( length($cleartext_id)>0 ) {
44 253         621 my $sub_text = substr($cleartext_id,0,8,'');
45 253         298 my $padded_str_id = $sub_text;
46 253 100       514 if (length($sub_text)<8) {
47 37         83 $padded_str_id = ( $padding_character x (8- length($sub_text) % 8 ) ). $sub_text ;
48             };
49             #print STDERR "Encoding '$padded_str_id'\n";
50 253         666 my $ciphertext = $cipher->encrypt($padded_str_id);
51 253         2568 $hash_id .= unpack('H*', $ciphertext ) ;
52             }
53 138         377 return $hash_id;
54             };
55              
56             register valid_encoded_id => sub {
57 0 0   0   0 my $encoded_id = shift or die "Missing Encoded ID parameter";
58              
59 0 0       0 return 0 unless $encoded_id =~ /^[0-9A-F]+$/i;
60 0 0       0 return 0 unless length($encoded_id)%16==0;
61 0         0 return 1;
62             };
63              
64             register decode_id => sub {
65 136 50   136   1025 my $encoded_id = shift or die "Missing Encoded ID parameter";
66 136         159 my $orig_encoded_id = $encoded_id;
67              
68             ## Prefix is optional, can be undef
69 136         162 my $prefix = shift ;
70              
71 136 100       265 _create_cipher() unless $cipher;
72              
73 136 50       638 die "Invalid Hash-ID value ($encoded_id)" unless $encoded_id =~ /^[0-9A-F]+$/i;
74 136 50       325 die "Invalid Hash-ID value ($encoded_id) - must be a multiple of 8 bytes (16 hex digits)"
75             unless length($encoded_id)%16==0;
76              
77 136         171 my $cleartext = "";
78              
79 136         273 while ( length($encoded_id)>0 ) {
80 251         493 my $sub_text = substr($encoded_id,0,16,'');
81 251         2154 my @list = $sub_text =~ /([0-9A-F]{2})/gi;
82             #print STDERR "Decoding: '$sub_text'\n";
83 251         987 my $ciphertext = pack('H2' x scalar(@list), @list) ;
84              
85 251         681 my $text = $cipher->decrypt($ciphertext);
86 251         2408 $text =~ s/^$padding_character+//;
87             #print STDERR "Decoded: '$text'\n";
88 251         1038 $cleartext .= $text;
89             };
90              
91 136 100       261 if (defined $prefix) {
92             ## Ensure the decoded ID contains the prefix
93 2         24 my $i = index $cleartext,$prefix;
94 2 100       7 if ($i != 0) {
95 1         11 die "Invalid Hash-ID value ($orig_encoded_id) - bad prefix" ;
96             }
97             #skip the prefix;
98 1         3 $cleartext = substr $cleartext, length($prefix);
99             }
100              
101 135         779 return $cleartext;
102             };
103              
104             register_plugin;
105              
106             # ABSTRACT: A Dancer plugin for Encoding/Obfuscating IDs in URLs
107              
108             1;
109             __END__