]> git.vanrenterghem.biz Git - git.ikiwiki.info.git/blobdiff - IkiWiki.pm
(no commit message)
[git.ikiwiki.info.git] / IkiWiki.pm
index cfa4f5f039781205d404819388c6700e1d2a90a3..2190f008c483bc4d0b715706b322de9a6b9317f6 100644 (file)
@@ -717,7 +717,7 @@ sub pagename ($) {
 
        my $type=pagetype($file);
        my $page=$file;
-       $page=~s/\Q.$type\E*$//
+       $page=~s/\Q.$type\E*$//
                if defined $type && !$hooks{htmlize}{$type}{keepextension}
                        && !$hooks{htmlize}{$type}{noextension};
        if ($config{indexpages} && $page=~/(.*)\/index$/) {
@@ -1124,7 +1124,7 @@ sub isselflink ($$) {
        my $page=shift;
        my $link=shift;
 
-        return $page eq $link;
+       return $page eq $link;
 }
 
 sub htmllink ($$$;@) {
@@ -1519,6 +1519,69 @@ sub check_content (@) {
        return defined $ok ? $ok : 1;
 }
 
+sub check_canchange (@) {
+       my %params = @_;
+       my $cgi = $params{cgi};
+       my $session = $params{session};
+       my @changes = @{$params{changes}};
+
+       my %newfiles;
+       foreach my $change (@changes) {
+               # This untaint is safe because we check file_pruned and
+               # wiki_file_regexp.
+               my ($file)=$change->{file}=~/$config{wiki_file_regexp}/;
+               $file=possibly_foolish_untaint($file);
+               if (! defined $file || ! length $file ||
+                   file_pruned($file)) {
+                       error(gettext("bad file name %s"), $file);
+               }
+
+               my $type=pagetype($file);
+               my $page=pagename($file) if defined $type;
+
+               if ($change->{action} eq 'add') {
+                       $newfiles{$file}=1;
+               }
+
+               if ($change->{action} eq 'change' ||
+                   $change->{action} eq 'add') {
+                       if (defined $page) {
+                               check_canedit($page, $cgi, $session);
+                               next;
+                       }
+                       else {
+                               if (IkiWiki::Plugin::attachment->can("check_canattach")) {
+                                       IkiWiki::Plugin::attachment::check_canattach($session, $file, $change->{path});
+                                       check_canedit($file, $cgi, $session);
+                                       next;
+                               }
+                       }
+               }
+               elsif ($change->{action} eq 'remove') {
+                       # check_canremove tests to see if the file is present
+                       # on disk. This will fail when a single commit adds a
+                       # file and then removes it again. Avoid the problem
+                       # by not testing the removal in such pairs of changes.
+                       # (The add is still tested, just to make sure that
+                       # no data is added to the repo that a web edit
+                       # could not add.)
+                       next if $newfiles{$file};
+
+                       if (IkiWiki::Plugin::remove->can("check_canremove")) {
+                               IkiWiki::Plugin::remove::check_canremove(defined $page ? $page : $file, $cgi, $session);
+                               check_canedit(defined $page ? $page : $file, $cgi, $session);
+                               next;
+                       }
+               }
+               else {
+                       error "unknown action ".$change->{action};
+               }
+
+               error sprintf(gettext("you are not allowed to change %s"), $file);
+       }
+}
+
+
 my $wikilock;
 
 sub lockwiki () {
@@ -1596,6 +1659,12 @@ sub loadindex () {
        if (exists $index->{version} && ! ref $index->{version}) {
                $pages=$index->{page};
                %wikistate=%{$index->{state}};
+               # Handle plugins that got disabled by loading a new setup.
+               if (exists $config{setupfile}) {
+                       require IkiWiki::Setup;
+                       IkiWiki::Setup::disabled_plugins(
+                               grep { ! $loaded_plugins{$_} } keys %wikistate);
+               }
        }
        else {
                $pages=$index;
@@ -1663,11 +1732,7 @@ sub loadindex () {
 sub saveindex () {
        run_hooks(savestate => sub { shift->() });
 
-       my %hookids;
-       foreach my $type (keys %hooks) {
-               $hookids{$_}=1 foreach keys %{$hooks{$type}};
-       }
-       my @hookids=keys %hookids;
+       my @plugins=keys %loaded_plugins;
 
        if (! -d $config{wikistatedir}) {
                mkdir($config{wikistatedir});
@@ -1701,7 +1766,7 @@ sub saveindex () {
                }
 
                if (exists $pagestate{$page}) {
-                       foreach my $id (@hookids) {
+                       foreach my $id (@plugins) {
                                foreach my $key (keys %{$pagestate{$page}{$id}}) {
                                        $index{page}{$src}{state}{$id}{$key}=$pagestate{$page}{$id}{$key};
                                }
@@ -1710,7 +1775,8 @@ sub saveindex () {
        }
 
        $index{state}={};
-       foreach my $id (@hookids) {
+       foreach my $id (@plugins) {
+               $index{state}{$id}={}; # used to detect disabled plugins
                foreach my $key (keys %{$wikistate{$id}}) {
                        $index{state}{$id}{$key}=$wikistate{$id}{$key};
                }
@@ -1766,12 +1832,14 @@ sub template_depends ($$;@) {
        my $page=shift;
        
        my ($filename, $tpage, $untrusted)=template_file($name);
+       if (! defined $filename) {
+               error(sprintf(gettext("template %s not found"), $name))
+       }
+
        if (defined $page && defined $tpage) {
                add_depends($page, $tpage);
        }
-
-       return unless defined $filename;
-
+       
        my @opts=(
                filter => sub {
                        my $text_ref = shift;
@@ -2399,10 +2467,16 @@ sub derel ($$) {
        my $path=shift;
        my $from=shift;
 
-       if ($path =~ m!^\./!) {
-               $from=~s#/?[^/]+$## if defined $from;
-               $path=~s#^\./##;
-               $path="$from/$path" if defined $from && length $from;
+       if ($path =~ m!^\.(/|$)!) {
+               if ($1) {
+                       $from=~s#/?[^/]+$## if defined $from;
+                       $path=~s#^\./##;
+                       $path="$from/$path" if defined $from && length $from;
+               }
+               else {
+                       $path = $from;
+                       $path = "" unless defined $path;
+               }
        }
 
        return $path;
@@ -2436,13 +2510,16 @@ sub match_internal ($$;@) {
 sub match_page ($$;@) {
        my $page=shift;
        my $match=match_glob($page, shift, @_);
-       if ($match && ! (exists $IkiWiki::pagesources{$page}
-           && defined IkiWiki::pagetype($IkiWiki::pagesources{$page}))) {
-               return IkiWiki::FailReason->new("$page is not a page");
-       }
-       else {
-               return $match;
+       if ($match) {
+               my $source=exists $IkiWiki::pagesources{$page} ?
+                       $IkiWiki::pagesources{$page} :
+                       $IkiWiki::delpagesources{$page};
+               my $type=defined $source ? IkiWiki::pagetype($source) : undef;
+               if (! defined $type) {  
+                       return IkiWiki::FailReason->new("$page is not a page");
+               }
        }
+       return $match;
 }
 
 sub match_link ($$;@) {