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   247163 use warnings;
  2         12  
  2         77  
4 2     2   12 use strict;
  2         4  
  2         41  
5 2     2   8 use Carp;
  2         4  
  2         127  
6              
7             # use base 'CGI::Untaint::object';
8 2     2   13 use base 'CGI::Untaint::url';
  2         3  
  2         1038  
9 2     2   24278 use LWP::UserAgent;
  2         85461  
  2         76  
10 2     2   1016 use URI::Heuristic;
  2         3622  
  2         97  
11 2     2   845 use Mozilla::CA;
  2         472  
  2         58  
12 2     2   950 use LWP::Protocol::https;
  2         210309  
  2         107  
13 2     2   18 use URI::Escape;
  2         5  
  2         1405  
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.15
22              
23             =cut
24              
25             our $VERSION = '0.15';
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 16874 my $self = shift;
55              
56 13         41 my $value = $self->value;
57              
58 13 50       119 if(!defined($value)) {
59 0         0 return 0;
60             }
61              
62             # Ignore leading and trailing spaces
63 13         56 $value =~ s/\s+$//;
64 13         51 $value =~ s/^\s+//;
65              
66 13 100       52 if(length($value) == 0) {
67 1         3 return 0;
68             }
69              
70 12 100       48 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       62 if($value =~ /([a-zA-Z0-9\-\/\.:\?&_=#!]+)/) {
76 11         40 $value = $1;
77             } else {
78 0         0 return 0;
79             }
80              
81 11         37 my $url;
82 11 100       81 if($value =~ /^http:\/\/www.facebook.com\/(.+)/) {
    50          
    100          
83 2         8 $url = "https://www.facebook.com/$1";
84 2         9 $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         39 $url = URI::Heuristic::uf_uristr("https://www.facebook.com/$value");
90 6         238 $self->value($url);
91             } else {
92 3 50       18 if(!$self->SUPER::is_valid()) {
93 0         0 return 0;
94             }
95 3         30225 $url = $value;
96             }
97              
98 11         124 my $request = new HTTP::Request('HEAD' => $url);
99 11         1889 $request->header('Accept' => 'text/html');
100 11 50       748 if($ENV{'HTTP_ACCEPT_LANGUAGE'}) {
101 0         0 $request->header('Accept-Language' => $ENV{'HTTP_ACCEPT_LANGUAGE'});
102             }
103 11         128 my $browser = LWP::UserAgent->new();
104 11         5637 $browser->ssl_opts(verify_hostname => 1, SSL_ca_file => Mozilla::CA::SSL_ca_file());
105 11         1408 $browser->agent(ref($self)); # Should be CGI::Untaint::Facebook
106 11         734 $browser->timeout(10);
107 11         202 $browser->max_size(128);
108 11         149 $browser->env_proxy(1);
109              
110 11         16147 my $webdoc = $browser->simple_request($request);
111 11         4804187 my $error_code = $webdoc->code;
112 11 100       156 unless($webdoc->is_success()) {
113 4 50 33     99 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         131 return 0;
132             }
133 7         1625 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 * CPAN Ratings
168              
169             L
170              
171             =item * Search CPAN
172              
173             L
174              
175             =back
176              
177             =head1 ACKNOWLEDGEMENTS
178              
179              
180             =head1 LICENSE AND COPYRIGHT
181              
182             Copyright 2012-2019 Nigel Horne.
183              
184             This program is released under the following licence: GPL2
185              
186              
187             =cut
188              
189             1; # End of CGI::Untaint::Facebook