master
joey 2006-03-10 23:43:44 +00:00
parent 942d5896cd
commit deb4e4b0c2
4 changed files with 70 additions and 39 deletions

View 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."

View 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

View 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]]

88
ikiwiki
View File

@ -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();
}