File Coverage

blib/lib/CGI/Untaint/Facebook.pm
Criterion Covered Total %
statement 64 74 86.4
branch 18 26 69.2
condition 4 6 66.6
subroutine 10 10 100.0
pod 1 1 100.0
total 97 117 82.9


line stmt bran cond sub pod time code
1             package CGI::Untaint::Facebook;
2              
3 2     2   169183 use warnings;
  2         5  
  2         77  
4 2     2   10 use strict;
  2         4  
  2         45  
5 2     2   9 use Carp;
  2         7  
  2         136  
6              
7             # use base 'CGI::Untaint::object';
8 2     2   11 use base 'CGI::Untaint::url';
  2         3  
  2         1724  
9 2     2   26368 use LWP::UserAgent;
  2         85281  
  2         73  
10 2     2   1513 use URI::Heuristic;
  2         5152  
  2         119  
11 2     2   1605 use Mozilla::CA;
  2         453  
  2         57  
12 2     2   1528 use LWP::Protocol::https;
  2         263321  
  2         117  
13 2     2   18 use URI::Escape;
  2         4  
  2         1758  
14              
15             =head1 NAME
16              
17             CGI::Untaint::Facebook - Validate a string is a valid Facebook URL or ID
18              
19             =head1 VERSION
20              
21             Version 0.13
22              
23             =cut
24              
25             our $VERSION = '0.13';
26              
27             =head1 SYNOPSIS
28              
29             CGI::Untaint::Facebook validate if a given ID in a form is a valid Facebook ID.
30             The ID can be either a full Facebook URL, or a page on facebook, so
31             'http://www.facebook.com/nigelhorne' and 'nigelhorne' will both return true.
32              
33             use CGI::Info;
34             use CGI::Untaint;
35             use CGI::Untaint::Facebook;
36             # ...
37             my $info = CGI::Info->new();
38             my $params = $info->params();
39             # ...
40             my $u = CGI::Untaint->new($params);
41             my $tid = $u->extract(-as_Facebook => 'web_address');
42             # $tid will be lower case
43              
44             =head1 SUBROUTINES/METHODS
45              
46             =head2 is_valid
47              
48             Validates the data.
49             Returns a boolean if $self->value is a valid Facebook URL.
50              
51             =cut
52              
53             sub is_valid {
54 13     13 1 23045 my $self = shift;
55              
56 13         59 my $value = $self->value;
57              
58 13 50       142 if(!defined($value)) {
59 0         0 return 0;
60             }
61              
62             # Ignore leading and trailing spaces
63 13         107 $value =~ s/\s+$//;
64 13         57 $value =~ s/^\s+//;
65              
66 13 100       61 if(length($value) == 0) {
67 1         5 return 0;
68             }
69              
70             # Allow URLs such as https://m.facebook.com/#!/groups/6000106799?ref=bookmark&__user=764645045)
71 12 50       79 if($value =~ /([a-zA-Z0-9\-\/\.:\?&_=#!]+)/) {
72 12         49 $value = $1;
73             } else {
74 0         0 return 0;
75             }
76              
77 12         23 my $url;
78 12 100       123 if($value =~ /^http:\/\/www.facebook.com\/(.+)/) {
    50          
    100          
79 2         8 $url = "https://www.facebook.com/$1";
80 2         7 $self->value($url);
81             } elsif($value =~ /^www\.facebook\.com/) {
82 0         0 $url = "https://$value";
83 0         0 $self->value($url);
84             } elsif($value !~ /^https:\/\/(www|m).facebook.com\//) {
85 6         200 $url = URI::Heuristic::uf_uristr("https://www.facebook.com/$value");
86 6         343 $self->value($url);
87             } else {
88 4 50       34 if(!$self->SUPER::is_valid()) {
89 0         0 return 0;
90             }
91 4         47464 $url = $value;
92             }
93              
94 12         186 my $request = new HTTP::Request('HEAD' => $url);
95 12         2127 $request->header('Accept' => 'text/html');
96 12 50       901 if($ENV{'HTTP_ACCEPT_LANGUAGE'}) {
97 0         0 $request->header('Accept-Language' => $ENV{'HTTP_ACCEPT_LANGUAGE'});
98             }
99 12         127 my $browser = LWP::UserAgent->new();
100 12         7455 $browser->ssl_opts(verify_hostname => 1, SSL_ca_file => Mozilla::CA::SSL_ca_file());
101 12         1859 $browser->agent(ref($self)); # Should be CGI::Untaint::Facebook
102 12         1133 $browser->timeout(10);
103 12         223 $browser->max_size(128);
104 12         175 $browser->env_proxy(1);
105              
106 12         19529 my $webdoc = $browser->simple_request($request);
107 12         8992833 my $error_code = $webdoc->code;
108 12 100       211 unless($webdoc->is_success()) {
109 5 100 66     170 if((($error_code == 301) || ($error_code == 302)) &&
    50 66        
110             ($webdoc->as_string =~ /^location: (.+)$/im)) {
111 1         1105 my $location = $1;
112 1 50       6 if($location =~ /^https?:\/\/(www|m).facebook.com\/pages\/.+/) {
113 0         0 $self->value($location);
114 0         0 return 1;
115             } else {
116 1         7 my $e = uri_escape($url);
117 1 50       117 if($location =~ /^https?:\/\/(www|m).facebook.com\/login.php\?next=\Q$e\E/) {
118 1         46 return 1;
119             }
120             }
121 0         0 carp "redirect to from $url to $location";
122             } elsif($error_code != 404) {
123             # Probably the certs file is wrong, or there
124             # was a timeout
125 0         0 carp "$url: " . $webdoc->status_line;
126             }
127 4         242 return 0;
128             }
129 7         527 return 1;
130             }
131              
132             =head1 AUTHOR
133              
134             Nigel Horne, C<< >>
135              
136             =head1 BUGS
137              
138             Please report any bugs or feature requests to C, or through
139             the web interface at L. I will be notified, and then you'll
140             automatically be notified of progress on your bug as I make changes.
141              
142              
143             =head1 SEE ALSO
144              
145             CGI::Untaint::url
146              
147              
148             =head1 SUPPORT
149              
150             You can find documentation for this module with the perldoc command.
151              
152             perldoc CGI::Untaint::Facebook
153              
154              
155             You can also look for information at:
156              
157             =over 4
158              
159             =item * RT: CPAN's request tracker
160              
161             L
162              
163             =item * AnnoCPAN: Annotated CPAN documentation
164              
165             L
166              
167             =item * CPAN Ratings
168              
169             L
170              
171             =item * Search CPAN
172              
173             L
174              
175             =back
176              
177              
178             =head1 ACKNOWLEDGEMENTS
179              
180              
181             =head1 LICENSE AND COPYRIGHT
182              
183             Copyright 2012-2015 Nigel Horne.
184              
185             This program is released under the following licence: GPL
186              
187              
188             =cut
189              
190             1; # End of CGI::Untaint::Facebook