X-Git-Url: http://git.vanrenterghem.biz/git.ikiwiki.info.git/blobdiff_plain/95e1e51caafbb3e4b179936b6d191ca87f47d4ae..bd6a4567fda279697962cc13efa0c293edae2e71:/IkiWiki/Plugin/emailauth.pm?ds=sidebyside diff --git a/IkiWiki/Plugin/emailauth.pm b/IkiWiki/Plugin/emailauth.pm index 3266e21ab..6674fe3d6 100644 --- a/IkiWiki/Plugin/emailauth.pm +++ b/IkiWiki/Plugin/emailauth.pm @@ -8,7 +8,8 @@ use IkiWiki 3.00; sub import { hook(type => "getsetup", id => "emailauth", "call" => \&getsetup); - hook(type => "cgi", id => "cgi", "call" => \&cgi); + hook(type => "cgi", id => "emailauth", "call" => \&cgi); + hook(type => "formbuilder_setup", id => "emailauth", "call" => \&formbuilder_setup); IkiWiki::loadplugin("loginselector"); IkiWiki::Plugin::loginselector::register_login_plugin( "emailauth", @@ -25,6 +26,12 @@ sub getsetup () { rebuild => 0, section => "auth", }, + emailauth_sender => { + type => "string", + description => "email address to send emailauth mails as (default: adminemail)", + safe => 1, + rebuild => 0, + }, } sub email_setup ($$) { @@ -64,7 +71,7 @@ sub email_auth ($$$$) { }); } - my $token=gentoken($email); + my $token=gentoken($email, $session); my $template=template("emailauth.tmpl"); $template->param( wikiname => $config{wikiname}, @@ -77,12 +84,16 @@ sub email_auth ($$$$) { eval q{use Mail::Sendmail}; error($@) if $@; + my $shorturl=$config{url}; + $shorturl=~s/^https?:\/\///i; + my $emailauth_sender=$config{emailauth_sender}; + $emailauth_sender=$config{adminemail} unless defined $emailauth_sender; sendmail( To => $email, From => "$config{wikiname} admin <". - (defined $config{adminemail} ? $config{adminemail} : "") + (defined $emailauth_sender ? $emailauth_sender : "") .">", - Subject => "$config{wikiname} login", + Subject => "$config{wikiname} login | $shorturl", Message => $template->output, ) or error(gettext("Failed to send mail")); @@ -96,19 +107,10 @@ sub cgi ($$) { my $email=$cgi->param('e'); my $v=$cgi->param('v'); if (defined $email && defined $v && length $email && length $v) { - # Need to lock the wiki before getting a session. - IkiWiki::lockwiki(); - IkiWiki::loadindex(); - my $session=IkiWiki::cgi_getsession(); - my $token=gettoken($email); if ($token eq $v) { - print STDERR "SUCCESS $email!!\n"; cleartoken($email); - $session->param(name => $email); - my $nickname=$email; - $nickname=~s/@.*//; - $session->param(nickname => Encode::decode_utf8($nickname)); + my $session=getsession($email); IkiWiki::cgi_postsignin($cgi, $session); } elsif (length $token ne length $cgi->param('v')) { @@ -120,19 +122,36 @@ sub cgi ($$) { } } +sub formbuilder_setup (@) { + my %params=@_; + my $form=$params{form}; + my $session=$params{session}; + + if ($form->title eq "preferences" && + IkiWiki::emailuser($session->param("name"))) { + $form->field(name => "email", disabled => 1); + } +} + # Generates the token that will be used in the authurl to log the user in. # This needs to be hard to guess, and relatively short. Generating a cgi # session id will make it as hard to guess as any cgi session. -sub gentoken ($) { +# +# Store token in userinfo; this allows the user to log in +# using a different browser session, if it takes a while for the +# email to get to them. +# +# The postsignin value from the session is also stored in the userinfo +# to allow resuming in a different browser session. +sub gentoken ($$) { my $email=shift; + my $session=shift; eval q{use CGI::Session}; error($@) if $@; my $token = CGI::Session->new->id; - # Store token in userinfo; this allows the user to log in - # using a different browser session, if it takes a while for the - # email to get to them. IkiWiki::userinfo_set($email, "emailauthexpire", time+(60*60*24)); IkiWiki::userinfo_set($email, "emailauth", $token); + IkiWiki::userinfo_set($email, "emailauthpostsignin", defined $session->param("postsignin") ? $session->param("postsignin") : ""); return $token; } @@ -147,6 +166,30 @@ sub gettoken ($) { return $val; } +# Generate a session to use after successful login. +sub getsession ($) { + my $email=shift; + + IkiWiki::lockwiki(); + IkiWiki::loadindex(); + my $session=IkiWiki::cgi_getsession(); + + my $postsignin=IkiWiki::userinfo_get($email, "emailauthpostsignin"); + IkiWiki::userinfo_set($email, "emailauthpostsignin", ""); + if (defined $postsignin && length $postsignin) { + $session->param(postsignin => $postsignin); + } + + $session->param(name => $email); + my $nickname=$email; + $nickname=~s/@.*//; + $session->param(nickname => Encode::decode_utf8($nickname)); + + IkiWiki::cgi_savesession($session); + + return $session; +} + sub cleartoken ($) { my $email=shift; IkiWiki::userinfo_set($email, "emailauthexpire", 0);