X-Git-Url: http://git.vanrenterghem.biz/git.ikiwiki.info.git/blobdiff_plain/238e8b95a5b084e7131d3314b78419b9404cba4c..3993757cf8f5747dd19cf35e95e1078de1513acf:/IkiWiki.pm?ds=inline

diff --git a/IkiWiki.pm b/IkiWiki.pm
index faf4af5c7..1fa89586e 100644
--- a/IkiWiki.pm
+++ b/IkiWiki.pm
@@ -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 () {
@@ -1941,14 +2004,6 @@ sub rcs_receive () {
 	$hooks{rcs}{rcs_receive}{call}->();
 }
 
-sub rcs_preprevert ($) {
-	$hooks{rcs}{rcs_preprevert}{call}->(@_);
-}
-
-sub rcs_revert ($) {
-	$hooks{rcs}{rcs_revert}{call}->(@_);
-}
-
 sub add_depends ($$;$) {
 	my $page=shift;
 	my $pagespec=shift;
@@ -2553,6 +2608,10 @@ sub match_created_after ($$;@) {
 }
 
 sub match_creation_day ($$;@) {
+	my $d=shift;
+	if ($d !~ /^\d+$/) {
+		return IkiWiki::ErrorReason->new("invalid day $d");
+	}
 	if ((localtime($IkiWiki::pagectime{shift()}))[3] == shift) {
 		return IkiWiki::SuccessReason->new('creation_day matched');
 	}
@@ -2562,6 +2621,10 @@ sub match_creation_day ($$;@) {
 }
 
 sub match_creation_month ($$;@) {
+	my $m=shift;
+	if ($m !~ /^\d+$/) {
+		return IkiWiki::ErrorReason->new("invalid month $m");
+	}
 	if ((localtime($IkiWiki::pagectime{shift()}))[4] + 1 == shift) {
 		return IkiWiki::SuccessReason->new('creation_month matched');
 	}
@@ -2571,7 +2634,11 @@ sub match_creation_month ($$;@) {
 }
 
 sub match_creation_year ($$;@) {
-	if ((localtime($IkiWiki::pagectime{shift()}))[5] + 1900 == shift) {
+	my $y=shift;
+	if ($y !~ /^\d+$/) {
+		return IkiWiki::ErrorReason->new("invalid year $y");
+	}
+	if ((localtime($IkiWiki::pagectime{shift()}))[5] + 1900 == $y) {
 		return IkiWiki::SuccessReason->new('creation_year matched');
 	}
 	else {