File Coverage

lib/Kwiki/URLBlock.pm
Criterion Covered Total %
statement 1 3 33.3
branch n/a
condition n/a
subroutine 1 1 100.0
pod n/a
total 2 4 50.0


line stmt bran cond sub pod time code
1             package Kwiki::URLBlock;
2 1     1   27973 use Kwiki::Plugin -Base;
  0            
  0            
3             use Kwiki::Installer -base;
4              
5             our $VERSION = '0.05';
6              
7             const class_id => 'urlblock';
8             const class_title => 'URL Block';
9             const config_file => 'urlblock.yaml';
10              
11             sub register {
12             require URI::Find;
13             my $registry = shift;
14             $registry->add(hook => 'edit:save', pre => 'urlblock_hook');
15             $registry->add(action => 'blocked_url');
16             }
17              
18             sub urlblock_hook {
19             my $hook = pop;
20             my $urlblock = $self->hub->urlblock;
21             my $old_page = $self->hub->pages->new_page($self->pages->current->id);
22             my @old_urls = $urlblock->get_urls($old_page->content);
23             my @urls = $urlblock->get_urls($self->cgi->page_content);
24             my @new_urls = $urlblock->get_new_urls(\@old_urls, \@urls);
25             if (@new_urls && $urlblock->is_blocked(\@new_urls)) {
26             $hook->cancel();
27             return $self->redirect("action=blocked_url");
28             }
29             }
30              
31             sub get_urls {
32             require URI::Find;
33             my ($content) = @_;
34             my @list;
35             my $finder = URI::Find->new( sub {
36             my($uri, $orig_uri) = @_;
37             push @list, $uri;
38             return $orig_uri;
39             });
40             $finder->find(\$content);
41             return @list;
42             }
43              
44             sub get_new_urls {
45             my ($old_urls, $urls) = @_;
46             my @new_urls;
47             my %old = map { $_ => 1 } @$old_urls;
48             foreach my $url (@$urls) {
49             push @new_urls, $url unless $old{$url};
50             }
51             return @new_urls;
52             }
53              
54             sub is_blocked {
55             my ($new_urls) = @_;
56             my $max_allowed = $self->config->urlblock_max_allowed;
57             if ($max_allowed && @$new_urls > $max_allowed) {
58             return 1;
59             }
60             my $blacklist = $self->blacklist($self->config->urlblock_blacklist);
61             return unless $blacklist;
62             foreach (@$new_urls) {
63             return 1 if /$blacklist/;
64             }
65             return;
66             }
67              
68             sub blacklist {
69             my ($path) = @_;
70             my $file = io($path);
71             return unless $file->exists;
72             my $list = $file->slurp;
73             $list =~ s/\#.*//g;
74             $list =~ s/\s+/|/g;
75             $list =~ s/^\|//g;
76             $list =~ s/\|$//g;
77             return qr/$list/;
78             }
79              
80             sub blocked_url {
81             return $self->render_screen(
82             content_pane => 'blocked_url.html',
83             );
84             }
85              
86             __DATA__