Merge branch 'master' into sipb
authorQuentin Smith <quentin@mit.edu>
Sat, 13 Mar 2010 22:53:12 +0000 (17:53 -0500)
committerQuentin Smith <quentin@mit.edu>
Sat, 13 Mar 2010 22:53:12 +0000 (17:53 -0500)
Conflicts:
po/bg.po
po/cs.po
po/da.po
po/de.po
po/es.po
po/fr.po
po/gu.po
po/ikiwiki.pot
po/pl.po
po/sv.po
po/vi.po
templates/misc.tmpl
templates/page.tmpl

1  2 
IkiWiki/CGI.pm
IkiWiki/Plugin/git.pm
IkiWiki/Plugin/httpauth.pm
IkiWiki/Plugin/mdwn.pm
IkiWiki/Plugin/parentlinks.pm
IkiWiki/Wrapper.pm

diff --combined IkiWiki/CGI.pm
index 64a481ce01f49ce2a5427695f4448da24340a232,07369ac1076e748f8cd95e1aab5c2354a33877c8..d7c85ecb88c93b286cabe23ddb218c4f3fb48b68
@@@ -15,7 -15,8 +15,8 @@@ sub printheader ($) 
        if ($config{sslcookie}) {
                print $session->header(-charset => 'utf-8',
                        -cookie => $session->cookie(-httponly => 1, -secure => 1));
-       } else {
+       }
+       else {
                print $session->header(-charset => 'utf-8',
                        -cookie => $session->cookie(-httponly => 1));
        }
@@@ -40,7 -41,8 +41,8 @@@ sub showform ($$$$;@) 
  
  sub redirect ($$) {
        my $q=shift;
-       my $url=shift;
+       eval q{use URI};
+       my $url=URI->new(shift);
        if (! $config{w3mmode}) {
                print $q->redirect($url);
        }
@@@ -51,7 -53,7 +53,7 @@@
  }
  
  sub decode_cgi_utf8 ($) {
-       # decode_form_utf8 method is needed for 5.10
+       # decode_form_utf8 method is needed for 5.01
        if ($] < 5.01) {
                my $cgi = shift;
                foreach my $f ($cgi->param) {
@@@ -64,8 -66,9 +66,9 @@@ sub decode_form_utf8 ($) 
        if ($] >= 5.01) {
                my $form = shift;
                foreach my $f ($form->field) {
+                       my @value=map { decode_utf8($_) } $form->field($f);
                        $form->field(name  => $f,
-                                    value => decode_utf8($form->field($f)),
+                                    value => \@value,
                                     force => 1,
                        );
                }
@@@ -107,14 -110,10 +110,14 @@@ sub cgi_signin ($$) 
                template => {type => 'div'},
                stylesheet => baseurl()."style.css",
        );
 -      my $buttons=["Login"];
 -      
 +      # MITLOGIN: These should be restored when logins are allowed again.
 +      #my $buttons=["Login"];
 +      my $buttons=[];
 +
        if ($q->param("do") ne "signin" && !$form->submitted) {
 -              $form->text(gettext("You need to log in first."));
 +          #$form->text(gettext("You need to log in first."));
 +              $form->text(
 +                "You must have an MIT personal certificate to edit");
        }
        $form->field(name => "do", type => "hidden", value => "signin",
                force => 1);
@@@ -208,16 -207,13 +211,16 @@@ sub cgi_prefs ($$) 
                force => 1);
        $form->field(name => "sid", type => "hidden", value => $session->id,
                force => 1);
 -      $form->field(name => "email", size => 50, fieldset => "preferences");
 +            #$form->field(name => "email", size => 50, fieldset => "preferences");
 +      $form->field(name => "realname", size => 50, fieldset => "preferences");
        
        my $user_name=$session->param("name");
  
        if (! $form->submitted) {
 -              $form->field(name => "email", force => 1,
 -                      value => userinfo_get($user_name, "email"));
 +            #$form->field(name => "email", force => 1,
 +            #value => userinfo_get($user_name, "email"));
 +              $form->field(name => "realname", force => 1,
 +                      value => userinfo_get($user_name, "realname"));
        }
        
        if ($form->submitted eq 'Logout') {
                        userinfo_set($user_name, 'email', $form->field('email')) ||
                                error("failed to set email");
                }
 -
 +              if (defined $form->field('realname')) {
 +                      userinfo_set($user_name, 'realname', $form->field('realname')) ||
 +                              error("failed to set realname");
 +                }
                $form->text(gettext("Preferences saved."));
        }
        
        showform($form, $buttons, $session, $q);
  }
  
- sub cgi_custom_failure ($$) {
-       my $header=shift;
+ sub cgi_custom_failure ($$$) {
+       my $q=shift;
+       my $httpstatus=shift;
        my $message=shift;
  
-       print $header;
+       print $q->header(
+               -status => $httpstatus,
+               -charset => 'utf-8',
+       );
        print $message;
  
        # Internet Explod^Hrer won't show custom 404 responses
@@@ -283,7 -280,7 +290,7 @@@ sub check_banned ($$) 
                $session->delete();
                cgi_savesession($session);
                cgi_custom_failure(
-                       $q->header(-status => "403 Forbidden"),
+                       $q, "403 Forbidden",
                        gettext("You are banned."));
        }
  }
diff --combined IkiWiki/Plugin/git.pm
index 1d94b927922de5f6263fb9a433423ec3a0a29a6d,b02f4a5ed5750145fe711095c3f7afa085c38732..e3e1448d357ac11ea611f4c14d9b81472258861d
@@@ -4,7 -4,6 +4,7 @@@ package IkiWiki::Plugin::git
  use warnings;
  use strict;
  use IkiWiki;
 +use IkiWiki::UserInfo;
  use Encode;
  use open qw{:utf8 :std};
  
@@@ -52,6 -51,9 +52,9 @@@ sub checkconfig () 
                        wrappermode => (defined $config{git_wrappermode} ? $config{git_wrappermode} : "06755"),
                };
        }
+       # Avoid notes, parser does not handle and they only slow things down.
+       $ENV{GIT_NOTES_REF}="";
        
        # Run receive test only if being called by the wrapper, and not
        # when generating same.
@@@ -66,6 -68,7 +69,7 @@@ sub getsetup () 
                plugin => {
                        safe => 0, # rcs plugin
                        rebuild => undef,
+                       section => "rcs",
                },
                git_wrapper => {
                        type => "string",
@@@ -420,7 -423,10 +424,10 @@@ sub git_sha1 (;$) 
                '--', $file);
        if ($sha1) {
                ($sha1) = $sha1 =~ m/($sha1_pattern)/; # sha1 is untainted now
-       } else { debug("Empty sha1sum for '$file'.") }
+       }
+       else {
+               debug("Empty sha1sum for '$file'.");
+       }
        return defined $sha1 ? $sha1 : q{};
  }
  
@@@ -470,9 -476,8 +477,9 @@@ sub rcs_commit_staged ($$$) 
        my %env=%ENV;
        if (defined $user || defined $ipaddr) {
                my $u=encode_utf8(defined $user ? $user : $ipaddr);
 -              $ENV{GIT_AUTHOR_NAME}=$u;
 -              $ENV{GIT_AUTHOR_EMAIL}="$u\@web";
 +              # MITLOGIN This algorithm could be improved
 +              $ENV{GIT_AUTHOR_NAME}=IkiWiki::userinfo_get($u, "realname");
 +              $ENV{GIT_AUTHOR_EMAIL}="$u\@mit.edu";
        }
  
        $message = IkiWiki::possibly_foolish_untaint($message);
@@@ -615,9 -620,15 +622,15 @@@ sub rcs_getctime ($) 
        # Remove srcdir prefix
        $file =~ s/^\Q$config{srcdir}\E\/?//;
  
-       my @sha1s = run_or_non('git', 'rev-list', 'HEAD', '--', $file);
-       my $ci    = git_commit_info($sha1s[$#sha1s], 1);
-       my $ctime = $ci->{'author_epoch'};
+       my @raw_lines = run_or_die('git', 'log', 
+               '--follow', '--no-merges',
+               '--pretty=raw', '--raw', '--abbrev=40', '--always', '-c',
+               '-r', '--', $file);
+       my @ci;
+       while (my $parsed = parse_diff_tree("", \@raw_lines)) {
+               push @ci, $parsed;
+       }
+       my $ctime = $ci[$#ci]->{'author_epoch'};
        debug("ctime for '$file': ". localtime($ctime));
  
        return $ctime;
index c2e55b015bba003701522130b0ca6dfd376154cf,478f6744656f5bdbd4baa00f79cadb9a74ebd255..0bdc4a75423a4156f1312d2d20c3872c738d7514
@@@ -5,11 -5,14 +5,15 @@@ package IkiWiki::Plugin::httpauth
  use warnings;
  use strict;
  use IkiWiki 3.00;
 +use Data::Dumper;
  
  sub import {
        hook(type => "getsetup", id => "httpauth", call => \&getsetup);
        hook(type => "auth", id => "httpauth", call => \&auth);
+       hook(type => "formbuilder_setup", id => "httpauth",
+               call => \&formbuilder_setup);
+       hook(type => "canedit", id => "httpauth", call => \&canedit,
+               first => 1);
  }
  
  sub getsetup () {
                plugin => {
                        safe => 1,
                        rebuild => 0,
+                       section => "auth",
+               },
+               cgiauthurl => {
+                       type => "string",
+                       example => "http://example.com/wiki/auth/ikiwiki.cgi",
+                       description => "url to redirect to when authentication is needed",
+                       safe => 1,
+                       rebuild => 0,
+               },
+               httpauth_pagespec => {
+                       type => "pagespec",
+                       example => "!*/Discussion",
+                       description => "PageSpec of pages where only httpauth will be used for authentication",
+                       safe => 0,
+                       rebuild => 0,
                },
  }
+                       
+ sub redir_cgiauthurl ($;@) {
+       my $cgi=shift;
+       IkiWiki::redirect($cgi, 
+               @_ > 1 ? IkiWiki::cgiurl(cgiurl => $config{cgiauthurl}, @_)
+                      : $config{cgiauthurl}."?@_"
+       );
+       exit;
+ }
  
  sub auth ($$) {
        my $cgi=shift;
        my $session=shift;
  
        if (defined $cgi->remote_user()) {
 -              $session->param("name", $cgi->remote_user());
 +              my $user = $cgi->remote_user();
 +              $session->param("name", $user);
 +              eval IkiWiki::possibly_foolish_untaint($ENV{SSL_CLIENT_S_DN_CN});
 +              my $realname = IkiWiki::userinfo_get($user, "realname");
 +              if ((!defined $realname || $realname eq "") &&
 +                  defined $ENV{SSL_CLIENT_S_DN_CN}) {
 +              IkiWiki::userinfo_set($user, "realname", $ENV{SSL_CLIENT_S_DN_CN});
 +              }
        }
  }
  
+ sub formbuilder_setup (@) {
+       my %params=@_;
+       my $form=$params{form};
+       my $session=$params{session};
+       my $cgi=$params{cgi};
+       my $buttons=$params{buttons};
+       if ($form->title eq "signin" &&
+           ! defined $cgi->remote_user() && defined $config{cgiauthurl}) {
+               my $button_text="Login with HTTP auth";
+               push @$buttons, $button_text;
+               if ($form->submitted && $form->submitted eq $button_text) {
+                       # bounce thru cgiauthurl and then back to
+                       # the stored postsignin action
+                       redir_cgiauthurl($cgi, do => "postsignin");
+               }
+       }
+ }
+ sub test_httpauth_pagespec ($) {
+       my $page=shift;
+       return (
+        );
+ }
+ sub canedit ($$$) {
+       my $page=shift;
+       my $cgi=shift;
+       my $session=shift;
+       if (! defined $cgi->remote_user() &&
+           defined $config{httpauth_pagespec} &&
+           length $config{httpauth_pagespec} &&
+           defined $config{cgiauthurl} &&
+           pagespec_match($page, $config{httpauth_pagespec})) {
+               return sub {
+                       # bounce thru cgiauthurl and back to edit action
+                       redir_cgiauthurl($cgi, $cgi->query_string());
+               };
+       }
+       else {
+               return undef;
+       }
+ }
  1
diff --combined IkiWiki/Plugin/mdwn.pm
index 52cfd8eebac3f32470b8a99170586195c6b03647,b892eabee29be50387fa493baafd5dbd6d1024a8..68765c6b8c0c71fb4a1d75992a51290522134d90
@@@ -16,6 -16,7 +16,7 @@@ sub getsetup () 
                plugin => {
                        safe => 1,
                        rebuild => 1, # format plugin
+                       section => "format",
                },
                multimarkdown => {
                        type => "boolean",
@@@ -43,13 -44,15 +44,15 @@@ sub htmlize (@) 
                        if ($@) {
                                debug(gettext("multimarkdown is enabled, but Text::MultiMarkdown is not installed"));
                        }
-                       $markdown_sub=sub {
-                               Text::MultiMarkdown::markdown(shift, {use_metadata => 0});
+                       else {
+                               $markdown_sub=sub {
+                                       Text::MultiMarkdown::markdown(shift, {use_metadata => 0});
+                               }
                        }
                }
                if (! defined $markdown_sub) {
                        eval q{use Text::Markdown};
 -                      if (! $@) {
 +                      if (1) {#! $@) {  # Text::Markdown throws this but works.  Shrug.
                                if (Text::Markdown->can('markdown')) {
                                        $markdown_sub=\&Text::Markdown::markdown;
                                }
index b24eff612ee1146635aede561479df836762d5cd,728bbc399fe8b50e247318158a57bd5c2facad96..bdf678069877b3c09bd29894d3f5d6b0353d2619
@@@ -16,6 -16,7 +16,7 @@@ sub getsetup () 
                plugin => {
                        safe => 1,
                        rebuild => 1,
+                       section => "core",
                },
  }
  
@@@ -31,17 -32,10 +32,17 @@@ sub parentlinks ($) 
  
        my @pagepath=(split("/", $page));
        my $pagedepth=@pagepath;
 +
 +      # The last element in @pagepath is the page itself, so punt that
 +      # (These are /parent/ links, after all.)
 +      pop @pagepath;
 +
        foreach my $dir (@pagepath) {
                next if $dir eq 'index';
                $depth=$i;
                $height=($pagedepth - $depth);
 +              $path.="/".$dir;
 +              $title=pagetitle($dir);
                push @ret, {
                        url => urlto(bestlink($page, $path), $page),
                        page => $title,
@@@ -50,6 -44,8 +51,6 @@@
                        "depth_$depth" => 1,
                        "height_$height" => 1,
                };
 -              $path.="/".$dir;
 -              $title=pagetitle($dir);
                $i++;
        }
        return @ret;
@@@ -60,8 -56,11 +61,11 @@@ sub pagetemplate (@) 
          my $page=$params{page};
          my $template=$params{template};
  
-       if ($template->query(name => "parentlinks")) {
-               $template->param(parentlinks => [parentlinks($page)]);
+       if ($template->query(name => "parentlinks") ||
+          $template->query(name => "has_parentlinks")) {
+               my @links=parentlinks($page);
+               $template->param(parentlinks => \@links);
+               $template->param(has_parentlinks => (@links > 0));
        }
  }
  
diff --combined IkiWiki/Wrapper.pm
index d2488bc7497bc7289755052c633ea1954f7e8dc7,5427a5c80b1f0762775231eadb9663b6f8841d2f..31b4f30414cd90a6304050d39508283dd6712ba9
@@@ -28,7 -28,7 +28,7 @@@ sub gen_wrapper () 
        my @envsave;
        push @envsave, qw{REMOTE_ADDR QUERY_STRING REQUEST_METHOD REQUEST_URI
                       CONTENT_TYPE CONTENT_LENGTH GATEWAY_INTERFACE
 -                     HTTP_COOKIE REMOTE_USER HTTPS REDIRECT_STATUS
 +                     HTTP_COOKIE REMOTE_USER HTTPS SSL_CLIENT_S_DN_CN REDIRECT_STATUS
                       REDIRECT_URL} if $config{cgi};
        my $envsave="";
        foreach my $var (@envsave) {
@@@ -142,11 -142,13 +142,12 @@@ $pre_exe
  }
  EOF
  
-       my $cc=exists $ENV{CC} ? possibly_foolish_untaint($ENV{CC}) : 'cc';
-       if (system($cc, "$wrapper.c", "-o", "$wrapper.new") != 0) {
+       my @cc=exists $ENV{CC} ? possibly_foolish_untaint($ENV{CC}) : 'cc';
+       push @cc, possibly_foolish_untaint($ENV{CFLAGS}) if exists $ENV{CFLAGS};
+       if (system(@cc, "$wrapper.c", "-o", "$wrapper.new") != 0) {
                #translators: The parameter is a C filename.
                error(sprintf(gettext("failed to compile %s"), "$wrapper.c"));
        }
 -      unlink("$wrapper.c");
        if (defined $config{wrappergroup}) {
                my $gid=(getgrnam($config{wrappergroup}))[2];
                if (! defined $gid) {