X-Git-Url: https://sipb.mit.edu/gitweb.cgi/ikiwiki.git/blobdiff_plain/0f25ec8eb640a850a8f1efe7081c03d05d04eda4..e7ee388ea1eb9b0c9625df828a3f565636acbc9c:/IkiWiki/CGI.pm diff --git a/IkiWiki/CGI.pm b/IkiWiki/CGI.pm index f07a4e5a2..c399ad8a6 100644 --- a/IkiWiki/CGI.pm +++ b/IkiWiki/CGI.pm @@ -74,21 +74,37 @@ sub cgi_recentchanges ($) { #{{{ # during page builds as the return values may change, but they # won't here.) eval q{use Memoize}; + error($@) if $@; memoize("htmllink"); eval q{use Time::Duration}; + error($@) if $@; eval q{use CGI 'escapeHTML'}; + error($@) if $@; my $changelog=[rcs_recentchanges(100)]; foreach my $change (@$changelog) { $change->{when} = concise(ago($change->{when})); - $change->{user} = htmllink("", "", escapeHTML($change->{user}), 1); + + if ($change->{user} =~ m!^https?://! && + eval q{use Net::OpenID::VerifiedIdentity; 1} && !$@) { + # Munge user-urls, as used by eg, OpenID. + my $oid=Net::OpenID::VerifiedIdentity->new(identity => $change->{user}); + $change->{user} = "{user}."\">".escapeHTML($oid->display).""; + } + else { + $change->{user} = htmllink("", "", escapeHTML($change->{user}), 1); + } + + my $is_excess = exists $change->{pages}[10]; # limit pages to first 10 + delete @{$change->{pages}}[10 .. @{$change->{pages}}] if $is_excess; $change->{pages} = [ map { $_->{link} = htmllink("", "", $_->{page}, 1); $_; } @{$change->{pages}} ]; + push @{$change->{pages}}, { link => '...' } if $is_excess; } my $template=template("recentchanges.tmpl"); @@ -110,9 +126,10 @@ sub cgi_signin ($$) { #{{{ my $session=shift; eval q{use CGI::FormBuilder}; + error($@) if $@; my $form = CGI::FormBuilder->new( title => "signin", - fields => [qw(do title page subpage from name password confirm_password email)], + fields => [qw(do title page subpage from name password openid_url)], header => 1, charset => "utf-8", method => 'POST', @@ -141,26 +158,57 @@ sub cgi_signin ($$) { #{{{ $form->field(name => "from", type => "hidden"); $form->field(name => "subpage", type => "hidden"); $form->field(name => "password", type => "password", required => 0); - $form->field(name => "confirm_password", type => "password", required => 0); - $form->field(name => "email", required => 0); + if ($config{openid}) { + $form->field(name => "openid_url", label => "OpenID", + comment => '('.htmllink("", "", "OpenID", 1, 0, "What's this?").')'); + } + else { + $form->field(name => "openid_url", type => "hidden"); + } + if ($form->submitted eq "Register" || $form->submitted eq "Create Account") { + $form->title("register"); + $form->text(""); + $form->fields(qw(do title page subpage from name password confirm_password email)); + $form->field(name => "confirm_password", type => "password"); + $form->field(name => "email", type => "text"); + $form->field(name => "openid_url", type => "hidden"); + } if ($q->param("do") ne "signin" && !$form->submitted) { $form->text("You need to log in first."); } if ($form->submitted) { + my $submittype=$form->submitted; + # OpenID login uses the Login button, but validates + # differently. + if ($submittype eq "Login" && $config{openid} && + length $form->field("openid_url")) { + $submittype="OpenID"; + + $form->field( + name => "openid_url", + validate => sub { + # FIXME: ugh + IkiWiki::Plugin::openid::validate($q, $session, $form, shift); + }, + ); + } + # Set required fields based on how form was submitted. my %required=( "Login" => [qw(name password)], - "Register" => [qw(name password confirm_password email)], + "Register" => [], + "Create Account" => [qw(name password confirm_password email)], "Mail Password" => [qw(name)], + "OpenID" => [qw(openid_url)], ); - foreach my $opt (@{$required{$form->submitted}}) { + foreach my $opt (@{$required{$submittype}}) { $form->field(name => $opt, required => 1); } # Validate password differently depending on how # form was submitted. - if ($form->submitted eq 'Login') { + if ($submittype eq 'Login') { $form->field( name => "password", validate => sub { @@ -170,12 +218,13 @@ sub cgi_signin ($$) { #{{{ ); $form->field(name => "name", validate => '/^\w+$/'); } - else { + elsif ($submittype ne 'OpenID') { $form->field(name => "password", validate => 'VALUE'); } # And make sure the entered name exists when logging # in or sending email, and does not when registering. - if ($form->submitted eq 'Register') { + if ($submittype eq 'Create Account' || + $submittype eq 'Register') { $form->field( name => "name", validate => sub { @@ -186,7 +235,7 @@ sub cgi_signin ($$) { #{{{ }, ); } - else { + elsif ($submittype ne 'OpenID') { $form->field( name => "name", validate => sub { @@ -200,8 +249,6 @@ sub cgi_signin ($$) { #{{{ else { # First time settings. $form->field(name => "name", comment => "use FirstnameLastName"); - $form->field(name => "confirm_password", comment => "(only needed"); - $form->field(name => "email", comment => "for registration)"); if ($session->param("name")) { $form->field(name => "name", value => $session->param("name")); } @@ -216,15 +263,15 @@ sub cgi_signin ($$) { #{{{ do => $form->field("do"), page => $form->field("page"), title => $form->field("title"), - subpage => $form->field("subpage"), from => $form->field("from"), + subpage => $form->field("subpage"), )); } else { redirect($q, $config{url}); } } - elsif ($form->submitted eq 'Register') { + elsif ($form->submitted eq 'Create Account') { my $user_name=$form->field('name'); if (userinfo_setall($user_name, { 'email' => $form->field('email'), @@ -233,12 +280,12 @@ sub cgi_signin ($$) { #{{{ })) { $form->field(name => "confirm_password", type => "hidden"); $form->field(name => "email", type => "hidden"); - $form->text("Registration successful. Now you can Login."); + $form->text("Account creation successful. Now you can Login."); printheader($session); print misctemplate($form->title, $form->render(submit => ["Login"])); } else { - error("Error saving registration."); + error("Error creating account."); } } elsif ($form->submitted eq 'Mail Password') { @@ -253,6 +300,7 @@ sub cgi_signin ($$) { #{{{ ); eval q{use Mail::Sendmail}; + error($@) if $@; sendmail( To => userinfo_get($user_name, "email"), From => "$config{wikiname} admin <$config{adminemail}>", @@ -263,9 +311,17 @@ sub cgi_signin ($$) { #{{{ $form->text("Your password has been emailed to you."); $form->field(name => "name", required => 0); printheader($session); - print misctemplate($form->title, $form->render(submit => ["Login", "Register", "Mail Password"])); + print misctemplate($form->title, $form->render(submit => ["Login", "Mail Password"])); + } + elsif ($form->submitted eq "Register") { + printheader($session); + print misctemplate($form->title, $form->render(submit => ["Create Account"])); } } + elsif ($form->submitted eq "Create Account") { + printheader($session); + print misctemplate($form->title, $form->render(submit => ["Create Account"])); + } else { printheader($session); print misctemplate($form->title, $form->render(submit => ["Login", "Register", "Mail Password"])); @@ -277,6 +333,7 @@ sub cgi_prefs ($$) { #{{{ my $session=shift; eval q{use CGI::FormBuilder}; + error($@) if $@; my $form = CGI::FormBuilder->new( title => "preferences", fields => [qw(do name password confirm_password email @@ -310,9 +367,16 @@ sub cgi_prefs ($$) { #{{{ comment => "(".htmllink("", "", "PageSpec", 1).")"); $form->field(name => "locked_pages", size => 50, comment => "(".htmllink("", "", "PageSpec", 1).")"); + $form->field(name => "banned_users", size => 50); if (! is_admin($user_name)) { $form->field(name => "locked_pages", type => "hidden"); + $form->field(name => "banned_users", type => "hidden"); + } + + if ($config{httpauth}) { + $form->field(name => "password", type => "hidden"); + $form->field(name => "confirm_password", type => "hidden"); } if (! $form->submitted) { @@ -322,6 +386,10 @@ sub cgi_prefs ($$) { #{{{ value => userinfo_get($user_name, "subscriptions")); $form->field(name => "locked_pages", force => 1, value => userinfo_get($user_name, "locked_pages")); + if (is_admin($user_name)) { + $form->field(name => "banned_users", force => 1, + value => join(" ", get_banned_users())); + } } decode_form_utf8($form); @@ -341,6 +409,10 @@ sub cgi_prefs ($$) { #{{{ userinfo_set($user_name, $field, $form->field($field)) || error("failed to set $field"); } } + if (is_admin($user_name)) { + set_banned_users(grep { ! is_admin($_) } + split(' ', $form->field("banned_users"))); + } $form->text("Preferences saved."); } @@ -356,6 +428,7 @@ sub cgi_editpage ($$) { #{{{ my @buttons=("Save Page", "Preview", "Cancel"); eval q{use CGI::FormBuilder; use CGI::FormBuilder::Template::HTML}; + error($@) if $@; my $renderer=CGI::FormBuilder::Template::HTML->new( fields => \@fields, template_params("editpage.tmpl"), @@ -439,7 +512,15 @@ sub cgi_editpage ($$) { #{{{ } if ($form->submitted eq "Cancel") { - redirect($q, "$config{url}/".htmlpage($page)); + if ($newfile && defined $from) { + redirect($q, "$config{url}/".htmlpage($from)); + } + elsif ($newfile) { + redirect($q, $config{url}); + } + else { + redirect($q, "$config{url}/".htmlpage($page)); + } return; } elsif ($form->submitted eq "Preview") { @@ -449,7 +530,7 @@ sub cgi_editpage ($$) { #{{{ value => $content, force => 1); $form->field(name => "comments", value => $comments, force => 1); - $config{rss}=0; # avoid preview writing an rss feed! + $config{rss}=$config{atom}=0; # avoid preview writing a feed! $form->tmpl_param("page_preview", htmlize($page, $type, linkify($page, "", @@ -599,8 +680,8 @@ sub cgi_editpage ($$) { #{{{ } #}}} sub cgi () { #{{{ - eval q{use CGI}; - eval q{use CGI::Session}; + eval q{use CGI; use CGI::Session}; + error($@) if $@; my $q=CGI->new; @@ -633,10 +714,30 @@ sub cgi () { #{{{ { FileName => "$config{wikistatedir}/sessions.db" }); umask($oldmask); + # Auth hooks can sign a user in. + if ($do ne 'signin' && ! defined $session->param("name")) { + run_hooks(auth => sub { + shift->($q, $session) + }); + if (defined $session->param("name")) { + # Make sure whatever user was authed is in the + # userinfo db. + if (! userinfo_get($session->param("name"), "regdate")) { + userinfo_setall($session->param("name"), { + email => "", + password => "", + regdate => time, + }); + } + } + } + # Everything below this point needs the user to be signed in. if (((! $config{anonok} || $do eq 'prefs') && + (! $config{httpauth}) && (! defined $session->param("name") || - ! userinfo_get($session->param("name"), "regdate"))) || $do eq 'signin') { + ! userinfo_get($session->param("name"), "regdate"))) + || $do eq 'signin') { cgi_signin($q, $session); # Force session flush with safe umask. @@ -646,6 +747,13 @@ sub cgi () { #{{{ return; } + + if (defined $session->param("name") && userinfo_get($session->param("name"), "banned")) { + print $q->header(-status => "403 Forbidden"); + $session->delete(); + print "You are banned."; + exit; + } if ($do eq 'create' || $do eq 'edit') { cgi_editpage($q, $session);