update
authorjoey <joey@0fa5a96a-9a0e-0410-b3b2-a0fd24251071>
Fri, 10 Mar 2006 23:43:44 +0000 (23:43 +0000)
committerjoey <joey@0fa5a96a-9a0e-0410-b3b2-a0fd24251071>
Fri, 10 Mar 2006 23:43:44 +0000 (23:43 +0000)
doc/bugs.mdwn
doc/security.mdwn
doc/todo.mdwn
ikiwiki

index e052763f13e679279eb658e7363ad89b6132ffc0..53c82a00c7d624f07d84cbb7e95a4b04d3233b98 100644 (file)
@@ -6,3 +6,5 @@
   back to Foo/Baz.
 * Foo/Bar/Baz shows up as Bar/Baz in the linkbacks on page Foo/Bar. Should
   show as just Baz there.
+* If I try to do a web commit, to a svn+ssh repo, it fails with
+  "Host key verification failed."
index 7b056fd6c1fecbb4101cb8f9c5ba9dbf3efb867e..1521a5f46a77b9a41ea9d38c77892d6c4969bf82 100644 (file)
@@ -1,4 +1,4 @@
-Let's do an ikiwiki security analysis..
+Let's do an ikiwiki security analysis.. ok
 
 If you are using ikiwiki to render pages that only you can edit, do not
 generate any wrappers, and do not use the cgi, then there are no more
index b7b23ef564a3a3e83d587cbbeb3d946304c499ba..ef3600d43c2b07770bfe293442f461d13faf13a1 100644 (file)
@@ -1,17 +1,10 @@
 ## online page editing
 
-To support editing pages in a web browser,  a CGI script is needed that
-pulls the page out of [[Subversion]], presents it to the user for editing,
-and then commits the changed page back to [[Subversion]].
-
-Due to [[WikiSpam]], this will probably also need to incorporate a user
-registration system. So there will need to be a script that handles logins
-and registrations, sets a cookie, and the page editor can refuse to edit
-pages for users who arn't logged in, and include a not of who made the
-change in the svn log.
-
-If possible I'd prefer to use someone else's generic web user registration
-and login system, if one exists.
+* Missing support for preview, cancel.
+* Missing conflict detection.
+* Missing commit message box.
+* No support for web user tracking/login yet.
+* Doesn't svn commit yet.
 
 ## [[RecentChanges]]
 
diff --git a/ikiwiki b/ikiwiki
index 8ba3249616a556e652f57a4ef86607926f4609af..5efca6c7ffa24a1993a2b83824df7fd4ed7dc038 100755 (executable)
--- a/ikiwiki
+++ b/ikiwiki
@@ -23,6 +23,7 @@ my $wikiname="wiki";
 my $default_pagetype=".mdwn";
 my $cgi=0;
 my $url="";
+my $svn=1;
 
 sub usage {
        die "usage: ikiwiki [options] source dest\n";
@@ -322,7 +323,7 @@ sub saveindex () {
        close OUT;
 }
 
-sub update () {
+sub rcs_update () {
        if (-d "$srcdir/.svn") {
                if (system("svn", "update", "--quiet", $srcdir) != 0) {
                        warn("svn update failed\n");
@@ -330,6 +331,27 @@ sub update () {
        }
 }
 
+sub rcs_commit ($) {
+       my $message=shift;
+
+       if (-d "$srcdir/.svn") {
+               if (system("svn", "commit", "--quiet", "-m",
+                          possibly_foolish_untaint($message), $srcdir) != 0) {
+                       warn("svn commit failed\n");
+               }
+       }
+}
+
+sub rcs_ad ($) {
+       my $file=shift;
+
+       if (-d "$srcdir/.svn") {
+               if (system("svn", "add", "--quiet", $file) != 0) {
+                       warn("svn add failed\n");
+               }
+       }
+}
+
 sub prune ($) {
        my $file=shift;
 
@@ -466,7 +488,7 @@ FILE:               foreach my $file (@files) {
 # Generates a C wrapper program for running ikiwiki in a specific way.
 # The wrapper may be safely made suid.
 sub gen_wrapper ($$) {
-       my ($offline, $rebuild)=@_;
+       my ($svn, $rebuild)=@_;
 
        eval {use Cwd 'abs_path'};
        $srcdir=abs_path($srcdir);
@@ -479,13 +501,13 @@ sub gen_wrapper ($$) {
        my $call=qq{"$this", "$this", "$srcdir", "$destdir", "--wikiname=$wikiname"};
        $call.=', "--verbose"' if $verbose;
        $call.=', "--rebuild"' if $rebuild;
-       $call.=', "--offline"' if $offline;
+       $call.=', "--nosvn"' if !$svn;
        $call.=', "--cgi"' if $cgi;
        $call.=', "--url='.$url.'"' if $url;
        
-       # For CGI we need all these environment variables.
-       my @envsave=qw{REMOTE_ADDR QUERY_STRING REQUEST_METHOD REQUEST_URI
-                      CONTENT_TYPE CONTENT_LENGTH GATEWAY_INTERFACE};
+       my @envsave;
+       push @envsave, qw{REMOTE_ADDR QUERY_STRING REQUEST_METHOD REQUEST_URI
+                      CONTENT_TYPE CONTENT_LENGTH GATEWAY_INTERFACE} if $cgi;
        my $envsave="";
        foreach my $var (@envsave) {
                $envsave.=<<"EOF"
@@ -507,17 +529,13 @@ extern char **environ;
 
 int main (void) {
        /* Sanitize environment. */
-       if ($cgi) {
-               char *s;
-               char *newenviron[$#envsave+2];
-               int i=0;
-               $envsave;
-               newenviron[i]=NULL;
-               environ=newenviron;
-       }
-       else {
-               clearenv();
-       }
+       char *s;
+       char *newenviron[$#envsave+3];
+       int i=0;
+       $envsave;
+       newenviron[i++]="HOME=$ENV{HOME}";
+       newenviron[i]=NULL;
+       environ=newenviron;
 
        execl($call, NULL);
        perror("failed to run $this");
@@ -568,19 +586,21 @@ sub cgi () {
                               -default => $content,
                               -rows => 20,
                               -columns => 80),
-                     $q->p,
+                     $q->br,
+                     "$ENV{HOME} Optional comment about this change",
+                     $q->br,
+                     $q->textfield(-name => "comments", -size => 80),
+                     $q->br,
                      $q->submit("Save Changes"),
-                     # TODO: Cancel button returns to page.
-                     # TODO: Preview button.
-                     # TODO: Commit message field.
-                     # TODO: Conflict prevention.
                      $q->end_form,
                      $q->end_html;
        }
        elsif ($do eq 'save') {
                my $file=$page.$default_pagetype;
+               my $newfile=1;
                if (exists $pagesources{lc($page)}) {
                        $file=$pagesources{lc($page)};
+                       $newfile=0;
                }
                
                my $content=$q->param('content');
@@ -588,6 +608,23 @@ sub cgi () {
                $content=~s/\r/\n/g;
                writefile("$srcdir/$file", $content);
                
+               my $message="web commit from $ENV{REMOTE_ADDR}";
+               if (defined $q->param('comments')) {
+                       $message.="\n".$q->param('comments');
+               }
+               
+               if ($svn) {
+                       if ($newfile) {
+                               rcs_add($file);
+                       }
+                       # presumably the commit will trigger an update
+                       # of the wiki
+                       rcs_commit($message);
+               }
+               else {
+                       refresh();
+               }
+               
                print $q->redirect("$url/".htmlpage($page));
        }
        else {
@@ -596,7 +633,6 @@ sub cgi () {
 }
 
 my $rebuild=0;
-my $offline=0;
 my $wrapper=0;
 if (grep /^-/, @ARGV) {
        eval {use Getopt::Long};
@@ -605,7 +641,7 @@ if (grep /^-/, @ARGV) {
                "verbose|v" => \$verbose,
                "rebuild" => \$rebuild,
                "wrapper" => \$wrapper,
-               "offline" => \$offline,
+               "svn!" => \$svn,
                "cgi" => \$cgi,
                "url=s" => \$url,
        ) || usage();
@@ -618,7 +654,7 @@ if ($cgi && ! length $url) {
        error("Must specify url to wiki with --url when using --cgi");
 }
 
-gen_wrapper($offline, $rebuild) if $wrapper;
+gen_wrapper($svn, $rebuild) if $wrapper;
 memoize('pagename');
 memoize('bestlink');
 loadindex() unless $rebuild;
@@ -626,7 +662,7 @@ if ($cgi) {
        cgi();
 }
 else {
-       update() unless $offline;
+       rcs_update() if $svn;
        refresh();
        saveindex();
 }