]> sipb.mit.edu Git - ikiwiki.git/blobdiff - ikiwiki
web commit by joey
[ikiwiki.git] / ikiwiki
diff --git a/ikiwiki b/ikiwiki
index 4b3bd488eac4715ead8a3e415da2fb1b81694df5..aec52ca8601951f5dbe547d43d66ed249fdfcb75 100755 (executable)
--- 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 {