]> sipb.mit.edu Git - ikiwiki.git/blobdiff - IkiWiki/Plugin/attachment.pm
map: The fix for #449285 was buggy and broke display of parents in certian circumstances.
[ikiwiki.git] / IkiWiki / Plugin / attachment.pm
index 720078be15cfcd51399f375815b4d22e1a2e8d7b..c78a1c177ee6cbccb1085c7f456f7d62afbe7db5 100644 (file)
@@ -6,11 +6,35 @@ use strict;
 use IkiWiki 2.00;
 
 sub import { #{{{
+       hook(type => "getsetup", id => "attachment", call => \&getsetup);
        hook(type => "checkconfig", id => "attachment", call => \&checkconfig);
        hook(type => "formbuilder_setup", id => "attachment", call => \&formbuilder_setup);
        hook(type => "formbuilder", id => "attachment", call => \&formbuilder);
 } # }}}
 
+sub getsetup () { #{{{
+       return
+               plugin => {
+                       safe => 1,
+                       rebuild => 0,
+               },
+               allowed_attachments => {
+                       type => "pagespec",
+                       example => "virusfree() and mimetype(image/*) and maxsize(50kb)",
+                       description => "enhanced PageSpec specifying what attachments are allowed",
+                       link => "ikiwiki/PageSpec/attachment",
+                       safe => 1,
+                       rebuild => 0,
+               },
+               virus_checker => {
+                       type => "string",
+                       example => "clamdscan -",
+                       description => "virus checker program (reads STDIN, returns nonzero if virus found)",
+                       safe => 0, # executed
+                       rebuild => 0,
+               },
+} #}}}
+
 sub check_canattach ($$;$) { #{{{
        my $session=shift;
        my $dest=shift; # where it's going to be put, under the srcdir
@@ -18,25 +42,40 @@ sub check_canattach ($$;$) { #{{{
 
        # Don't allow an attachment to be uploaded with the same name as an
        # existing page.
-       if (exists $pagesources{$dest} && $pagesources{$dest} ne $dest) {
+       if (exists $IkiWiki::pagesources{$dest} &&
+           $IkiWiki::pagesources{$dest} ne $dest) {
                error(sprintf(gettext("there is already a page named %s"), $dest));
        }
 
        # Use a special pagespec to test that the attachment is valid.
        my $allowed=1;
-       foreach my $admin (@{$config{adminuser}}) {
-               my $allowed_attachments=IkiWiki::userinfo_get($admin, "allowed_attachments");
-               if (defined $allowed_attachments &&
-                   length $allowed_attachments) {
-                       $allowed=pagespec_match($dest,
-                               $allowed_attachments,
-                               file => $file,
-                               user => $session->param("name"),
-                               ip => $ENV{REMOTE_ADDR},
-                       );
-                       last if $allowed;
+       if (defined $config{allowed_attachments} &&
+           length $config{allowed_attachments}) {
+               $allowed=pagespec_match($dest,
+                       $config{allowed_attachments},
+                       file => $file,
+                       user => $session->param("name"),
+                       ip => $ENV{REMOTE_ADDR},
+               );
+       }
+
+       # XXX deprecated, should be removed eventually
+       if ($allowed) {
+               foreach my $admin (@{$config{adminuser}}) {
+                       my $allowed_attachments=IkiWiki::userinfo_get($admin, "allowed_attachments");
+                       if (defined $allowed_attachments &&
+                           length $allowed_attachments) {
+                               $allowed=pagespec_match($dest,
+                                       $allowed_attachments,
+                                       file => $file,
+                                       user => $session->param("name"),
+                                       ip => $ENV{REMOTE_ADDR},
+                               );
+                               last if $allowed;
+                       }
                }
        }
+
        if (! $allowed) {
                error(gettext("prohibited by allowed_attachments")." ($allowed)");
        }
@@ -79,30 +118,35 @@ sub formbuilder_setup (@) { #{{{
                }
        }
        elsif ($form->title eq "preferences") {
+               # XXX deprecated, should remove eventually
                my $session=$params{session};
                my $user_name=$session->param("name");
 
                $form->field(name => "allowed_attachments", size => 50,
                        fieldset => "admin",
-                       comment => "(".
-                               htmllink("", "", 
-                                       "ikiwiki/PageSpec/attachment", 
-                                       noimageinline => 1,
-                                       linktext => "Enhanced PageSpec",
-                               ).")"
+                       comment => "deprecated; please move to allowed_attachments in setup file",
                );
                if (! IkiWiki::is_admin($user_name)) {
                        $form->field(name => "allowed_attachments", type => "hidden");
                }
                 if (! $form->submitted) {
-                       $form->field(name => "allowed_attachments", force => 1,
-                               value => IkiWiki::userinfo_get($user_name, "allowed_attachments"));
+                       my $value=IkiWiki::userinfo_get($user_name, "allowed_attachments");
+                       if (length $value) {
+                               $form->field(name => "allowed_attachments", force => 1,
+                                       value => IkiWiki::userinfo_get($user_name, "allowed_attachments"));
+                       }
+                       else {
+                               $form->field(name => "allowed_attachments", type => "hidden");
+                       }
                 }
                if ($form->submitted && $form->submitted eq 'Save Preferences') {
                        if (defined $form->field("allowed_attachments")) {
                                IkiWiki::userinfo_set($user_name, "allowed_attachments",
                                $form->field("allowed_attachments")) ||
                                        error("failed to set allowed_attachments");
+                               if (! length $form->field("allowed_attachments")) {
+                                       $form->field(name => "allowed_attachments", type => "hidden");
+                               }
                        }
                }
        }
@@ -306,19 +350,20 @@ sub humansize ($) { #{{{
 package IkiWiki::PageSpec;
 
 sub match_maxsize ($$;@) { #{{{
-       shift;
+       my $page=shift;
        my $maxsize=eval{IkiWiki::Plugin::attachment::parsesize(shift)};
        if ($@) {
                return IkiWiki::FailReason->new("unable to parse maxsize (or number too large)");
        }
 
        my %params=@_;
-       if (! exists $params{file}) {
+       my $file=exists $params{file} ? $params{file} : $IkiWiki::pagesources{$page};
+       if (! defined $file) {
                return IkiWiki::FailReason->new("no file specified");
        }
 
-       if (-s $params{file} > $maxsize) {
-               return IkiWiki::FailReason->new("file too large (".(-s $params{file})." >  $maxsize)");
+       if (-s $file > $maxsize) {
+               return IkiWiki::FailReason->new("file too large (".(-s $file)." >  $maxsize)");
        }
        else {
                return IkiWiki::SuccessReason->new("file not too large");
@@ -326,18 +371,19 @@ sub match_maxsize ($$;@) { #{{{
 } #}}}
 
 sub match_minsize ($$;@) { #{{{
-       shift;
+       my $page=shift;
        my $minsize=eval{IkiWiki::Plugin::attachment::parsesize(shift)};
        if ($@) {
                return IkiWiki::FailReason->new("unable to parse minsize (or number too large)");
        }
 
        my %params=@_;
-       if (! exists $params{file}) {
+       my $file=exists $params{file} ? $params{file} : $IkiWiki::pagesources{$page};
+       if (! defined $file) {
                return IkiWiki::FailReason->new("no file specified");
        }
 
-       if (-s $params{file} < $minsize) {
+       if (-s $file < $minsize) {
                return IkiWiki::FailReason->new("file too small");
        }
        else {
@@ -346,11 +392,12 @@ sub match_minsize ($$;@) { #{{{
 } #}}}
 
 sub match_mimetype ($$;@) { #{{{
-       shift;
+       my $page=shift;
        my $wanted=shift;
 
        my %params=@_;
-       if (! exists $params{file}) {
+       my $file=exists $params{file} ? $params{file} : $IkiWiki::pagesources{$page};
+       if (! defined $file) {
                return IkiWiki::FailReason->new("no file specified");
        }
 
@@ -360,7 +407,7 @@ sub match_mimetype ($$;@) { #{{{
        if ($@) {
                return IkiWiki::FailReason->new("failed to load File::MimeInfo::Magic ($@); cannot check MIME type");
        }
-       my $mimetype=File::MimeInfo::Magic::magic($params{file});
+       my $mimetype=File::MimeInfo::Magic::magic($file);
        if (! defined $mimetype) {
                $mimetype="unknown";
        }
@@ -375,11 +422,12 @@ sub match_mimetype ($$;@) { #{{{
 } #}}}
 
 sub match_virusfree ($$;@) { #{{{
-       shift;
+       my $page=shift;
        my $wanted=shift;
 
        my %params=@_;
-       if (! exists $params{file}) {
+       my $file=exists $params{file} ? $params{file} : $IkiWiki::pagesources{$page};
+       if (! defined $file) {
                return IkiWiki::FailReason->new("no file specified");
        }
 
@@ -393,7 +441,7 @@ sub match_virusfree ($$;@) { #{{{
        # used, clamd would fail to read it.
        eval q{use IPC::Open2};
        error($@) if $@;
-       open (IN, "<", $params{file}) || return IkiWiki::FailReason->new("failed to read file");
+       open (IN, "<", $file) || return IkiWiki::FailReason->new("failed to read file");
        binmode(IN);
        my $sigpipe=0;
        $SIG{PIPE} = sub { $sigpipe=1 };