File Coverage

blib/lib/CGI/Untaint/Facebook.pm
Criterion Covered Total %
statement 61 76 80.2
branch 17 28 60.7
condition 2 6 33.3
subroutine 10 10 100.0
pod 1 1 100.0
total 91 121 75.2


line stmt bran cond sub pod time code
1             package CGI::Untaint::Facebook;
2              
3 2     2   182529 use warnings;
  2         5  
  2         59  
4 2     2   11 use strict;
  2         4  
  2         31  
5 2     2   9 use Carp;
  2         9  
  2         91  
6              
7             # use base 'CGI::Untaint::object';
8 2     2   11 use base 'CGI::Untaint::url';
  2         3  
  2         792  
9 2     2   17030 use LWP::UserAgent;
  2         58946  
  2         65  
10 2     2   851 use URI::Heuristic;
  2         2576  
  2         87  
11 2     2   689 use Mozilla::CA;
  2         640  
  2         46  
12 2     2   764 use LWP::Protocol::https;
  2         145017  
  2         76  
13 2     2   17 use URI::Escape;
  2         4  
  2         1062  
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.14
22              
23             =cut
24              
25             our $VERSION = '0.14';
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 21107 my $self = shift;
55              
56 13         53 my $value = $self->value;
57              
58 13 50       185 if(!defined($value)) {
59 0         0 return 0;
60             }
61              
62             # Ignore leading and trailing spaces
63 13         62 $value =~ s/\s+$//;
64 13         39 $value =~ s/^\s+//;
65              
66 13 100       57 if(length($value) == 0) {
67 1         3 return 0;
68             }
69              
70 12 100       60 if($value =~ /\s/) {
71 1         4 return 0;
72             }
73              
74             # Allow URLs such as https://m.facebook.com/#!/groups/6000106799?ref=bookmark&__user=764645045)
75 11 50       60 if($value =~ /([a-zA-Z0-9\-\/\.:\?&_=#!]+)/) {
76 11         36 $value = $1;
77             } else {
78 0         0 return 0;
79             }
80              
81 11         25 my $url;
82 11 100       95 if($value =~ /^http:\/\/www.facebook.com\/(.+)/) {
    50          
    100          
83 2         8 $url = "https://www.facebook.com/$1";
84 2         7 $self->value($url);
85             } elsif($value =~ /^www\.facebook\.com/) {
86 0         0 $url = "https://$value";
87 0         0 $self->value($url);
88             } elsif($value !~ /^https:\/\/(www|m).facebook.com\//) {
89 6         49 $url = URI::Heuristic::uf_uristr("https://www.facebook.com/$value");
90 6         272 $self->value($url);
91             } else {
92 3 50       19 if(!$self->SUPER::is_valid()) {
93 0         0 return 0;
94             }
95 3         23652 $url = $value;
96             }
97              
98 11         146 my $request = new HTTP::Request('HEAD' => $url);
99 11         2095 $request->header('Accept' => 'text/html');
100 11 50       902 if($ENV{'HTTP_ACCEPT_LANGUAGE'}) {
101 0         0 $request->header('Accept-Language' => $ENV{'HTTP_ACCEPT_LANGUAGE'});
102             }
103 11         103 my $browser = LWP::UserAgent->new();
104 11         5612 $browser->ssl_opts(verify_hostname => 1, SSL_ca_file => Mozilla::CA::SSL_ca_file());
105 11         1455 $browser->agent(ref($self)); # Should be CGI::Untaint::Facebook
106 11         874 $browser->timeout(10);
107 11         278 $browser->max_size(128);
108 11         163 $browser->env_proxy(1);
109              
110 11         12440 my $webdoc = $browser->simple_request($request);
111 11         11353786 my $error_code = $webdoc->code;
112 11 100       176 unless($webdoc->is_success()) {
113 4 50 33     102 if((($error_code == 301) || ($error_code == 302)) &&
    50 33        
114             ($webdoc->as_string =~ /^location: (.+)$/im)) {
115 0         0 my $location = $1;
116 0 0       0 if($location =~ /^https?:\/\/(www|m).facebook.com\/pages\/.+/) {
117 0         0 $self->value($location);
118 0         0 return 1;
119             } else {
120 0         0 my $e = uri_escape($url);
121 0 0       0 if($location =~ /^https?:\/\/(www|m).facebook.com\/login.php\?next=\Q$e\E/) {
122 0         0 return 1;
123             }
124             }
125 0         0 carp "redirect from $url to $location";
126             } elsif($error_code != 404) {
127             # Probably the certs file is wrong, or there
128             # was a timeout
129 0         0 carp "$url: " . $webdoc->status_line;
130             }
131 4         553 return 0;
132             }
133 7         365 return 1;
134             }
135              
136             =head1 AUTHOR
137              
138             Nigel Horne, C<< >>
139              
140             =head1 BUGS
141              
142             Please report any bugs or feature requests to C, or through
143             the web interface at L. I will be notified, and then you'll
144             automatically be notified of progress on your bug as I make changes.
145              
146              
147             =head1 SEE ALSO
148              
149             CGI::Untaint::url
150              
151              
152             =head1 SUPPORT
153              
154             You can find documentation for this module with the perldoc command.
155              
156             perldoc CGI::Untaint::Facebook
157              
158              
159             You can also look for information at:
160              
161             =over 4
162              
163             =item * RT: CPAN's request tracker
164              
165             L
166              
167             =item * AnnoCPAN: Annotated CPAN documentation
168              
169             L
170              
171             =item * CPAN Ratings
172              
173             L
174              
175             =item * Search CPAN
176              
177             L
178              
179             =back
180              
181             =head1 ACKNOWLEDGEMENTS
182              
183              
184             =head1 LICENSE AND COPYRIGHT
185              
186             Copyright 2012-2017 Nigel Horne.
187              
188             This program is released under the following licence: GPL
189              
190              
191             =cut
192              
193             1; # End of CGI::Untaint::Facebook