X-Git-Url: http://git.vanrenterghem.biz/git.ikiwiki.info.git/blobdiff_plain/33b7f3444c20da53a18203ed33bb470b1c513f07..325d5c791fc50dc3868b2f1938d052d39b676248:/ikiwiki diff --git a/ikiwiki b/ikiwiki index 4b3bd488e..aec52ca86 100755 --- a/ikiwiki +++ b/ikiwiki @@ -1,4 +1,7 @@ #!/usr/bin/perl -T + +eval 'exec /usr/bin/perl -T -S $0 ${1+"$@"}' + if 0; # not running under some shell $ENV{PATH}="/usr/local/bin:/usr/bin:/bin"; use warnings; @@ -32,6 +35,7 @@ our %config=( #{{{ destdir => undef, templatedir => undef, setup => undef, + adminuser => undef, ); #}}} GetOptions( #{{{ @@ -51,6 +55,7 @@ GetOptions( #{{{ "exclude=s@" => sub { $config{wiki_file_prune_regexp}=qr/$config{wiki_file_prune_regexp}|$_[1]/; }, + "adminuser=s@" => sub { push @{$config{adminuser}}, $_[1] }, ) || usage(); if (! $config{setup}) { @@ -778,6 +783,7 @@ sub gen_wrapper (@) { #{{{ push @params, "--historyurl=$config{historyurl}" if length $config{historyurl}; push @params, "--diffurl=$config{diffurl}" if length $config{diffurl}; push @params, "--anonok" if $config{anonok}; + push @params, "--adminuser=$_" foreach @{$config{adminuser}}; my $params=join(" ", @params); my $call=''; foreach my $p ($this, $this, @params) { @@ -878,7 +884,8 @@ sub userinfo_get ($$) { #{{{ eval q{use Storable}; my $userdata=eval{ Storable::lock_retrieve("$config{srcdir}/.ikiwiki/userdb") }; if (! defined $userdata || ! ref $userdata || - ! exists $userdata->{$user} || ! ref $userdata->{$user}) { + ! exists $userdata->{$user} || ! ref $userdata->{$user} || + ! exists $userdata->{$user}->{$field}) { return ""; } return $userdata->{$user}->{$field}; @@ -1079,6 +1086,59 @@ sub cgi_signin ($$) { #{{{ } } #}}} +sub is_admin ($) { #{{{ + my $user_name=shift; + + return grep { $_ eq $user_name } @{$config{adminuser}}; +} #}}} + +sub glob_match ($$) { #{{{ + my $page=shift; + my $glob=shift; + + # turn glob into safe regexp + $glob=quotemeta($glob); + $glob=~s/\\\*/.*/g; + $glob=~s/\\\?/./g; + $glob=~s!\\/!/!g; + + $page=~/^$glob$/i; +} #}}} + +sub globlist_match ($$) { #{{{ + my $page=shift; + my @globlist=split(" ", shift); + + # check any negated globs first + foreach my $glob (@globlist) { + return 0 if $glob=~/^!(.*)/ && glob_match($page, $1); + } + + foreach my $glob (@globlist) { + return 1 if glob_match($page, $glob); + } + + return 0; +} #}}} + +sub page_locked ($$;$) { #{{{ + my $page=shift; + my $session=shift; + my $nonfatal=shift; + + my $user=$session->param("name"); + return if length $user && is_admin($user); + + foreach my $admin (@{$config{adminuser}}) { + my $locked_pages=userinfo_get($admin, "locked_pages"); + if (globlist_match($page, userinfo_get($admin, "locked_pages"))) { + return 1 if $nonfatal; + error(htmllink("", $page, 1)." is locked by ". + htmllink("", $admin, 1)." and cannot be edited."); + } + } +} #}}} + sub cgi_prefs ($$) { #{{{ my $q=shift; my $session=shift; @@ -1086,7 +1146,7 @@ sub cgi_prefs ($$) { #{{{ eval q{use CGI::FormBuilder}; my $form = CGI::FormBuilder->new( title => "preferences", - fields => [qw(do name password confirm_password email)], + fields => [qw(do name password confirm_password email locked_pages)], header => 0, method => 'POST', validate => { @@ -1110,9 +1170,18 @@ sub cgi_prefs ($$) { #{{{ value => $user_name, force => 1); $form->field(name => "password", type => "password"); $form->field(name => "confirm_password", type => "password"); + $form->field(name => "locked_pages", size => 50, + comment => "(".htmllink("", "GlobList", 1).")"); + + if (! is_admin($user_name)) { + $form->field(name => "locked_pages", type => "hidden"); + } if (! $form->submitted) { - $form->field(name => "email", value => userinfo_get($user_name, "email")); + $form->field(name => "email", force => 1, + value => userinfo_get($user_name, "email")); + $form->field(name => "locked_pages", force => 1, + value => userinfo_get($user_name, "locked_pages")); } if ($form->submitted eq 'Logout') { @@ -1125,7 +1194,7 @@ sub cgi_prefs ($$) { #{{{ return; } elsif ($form->submitted eq "Save Preferences" && $form->validate) { - foreach my $field (qw(password email)) { + foreach my $field (qw(password email locked_pages)) { if (length $form->field($field)) { userinfo_set($user_name, $field, $form->field($field)) || error("failed to set $field"); } @@ -1238,8 +1307,10 @@ sub cgi_editpage ($$) { #{{{ push @page_locs, $dir.$page; } - @page_locs = grep { ! exists - $pagesources{lc($_)} } @page_locs; + @page_locs = grep { + ! exists $pagesources{lc($_)} && + ! page_locked($_, $session, 1) + } @page_locs; } $form->tmpl_param("page_select", 1); @@ -1248,6 +1319,7 @@ sub cgi_editpage ($$) { #{{{ $form->title("creating $page"); } elsif ($form->field("do") eq "edit") { + page_locked($page, $session); if (! defined $form->field('content') || ! length $form->field('content')) { my $content=""; @@ -1267,13 +1339,15 @@ sub cgi_editpage ($$) { #{{{ } else { # save page + page_locked($page, $session); + my $content=$form->field('content'); $content=~s/\r\n/\n/g; $content=~s/\r/\n/g; writefile("$config{srcdir}/$file", $content); my $message="web commit "; - if ($session->param("name")) { + if (length $session->param("name")) { $message.="by ".$session->param("name"); } else {