allow users to subscribe to comments w/o registering
Technically, when the user does this, a passwordless account is created for them. The notify mails include a login url, and once logged in that way, the user can enter a password to get a regular account (although one with an annoying username). This all requires the passwordauth plugin is enabled. A future enhancement could be to split the passwordless user concept out into a separate plugin.master
parent
c16b1e638e
commit
c885ec66e0
|
@ -302,7 +302,7 @@ sub editcomment ($$) {
|
|||
my @buttons = (POST_COMMENT, PREVIEW, CANCEL);
|
||||
my $form = CGI::FormBuilder->new(
|
||||
fields => [qw{do sid page subject editcontent type author
|
||||
url subscribe}],
|
||||
email url subscribe anonsubscribe}],
|
||||
charset => 'utf-8',
|
||||
method => 'POST',
|
||||
required => [qw{editcontent}],
|
||||
|
@ -349,24 +349,33 @@ sub editcomment ($$) {
|
|||
|
||||
my $username=$session->param('name');
|
||||
$form->tmpl_param(username => $username);
|
||||
if (defined $username && IkiWiki::Plugin::notifyemail->can("subscribe")) {
|
||||
$form->field(name => "subscribe",
|
||||
options => [gettext("email replies to me")]);
|
||||
}
|
||||
else {
|
||||
$form->field(name => "subscribe", type => 'hidden');
|
||||
|
||||
$form->field(name => "subscribe", type => 'hidden');
|
||||
$form->field(name => "anonsubscribe", type => 'hidden');
|
||||
if (IkiWiki::Plugin::notifyemail->can("subscribe")) {
|
||||
if (defined $username) {
|
||||
$form->field(name => "subscribe", type => "checkbox",
|
||||
options => [gettext("email replies to me")]);
|
||||
}
|
||||
elsif (IkiWiki::Plugin::passwordauth->can("anonuser")) {
|
||||
$form->field(name => "anonsubscribe", type => "checkbox",
|
||||
options => [gettext("email replies to me")]);
|
||||
}
|
||||
}
|
||||
|
||||
if ($config{comments_allowauthor} and
|
||||
! defined $session->param('name')) {
|
||||
$form->tmpl_param(allowauthor => 1);
|
||||
$form->field(name => 'author', type => 'text', size => '40');
|
||||
$form->field(name => 'email', type => 'text', size => '40');
|
||||
$form->field(name => 'url', type => 'text', size => '40');
|
||||
}
|
||||
else {
|
||||
$form->tmpl_param(allowauthor => 0);
|
||||
$form->field(name => 'author', type => 'hidden', value => '',
|
||||
force => 1);
|
||||
$form->field(name => 'email', type => 'hidden', value => '',
|
||||
force => 1);
|
||||
$form->field(name => 'url', type => 'hidden', value => '',
|
||||
force => 1);
|
||||
}
|
||||
|
@ -500,10 +509,18 @@ sub editcomment ($$) {
|
|||
if ($form->submitted eq POST_COMMENT && $form->validate) {
|
||||
IkiWiki::checksessionexpiry($cgi, $session);
|
||||
|
||||
if (defined $username && length $form->field("subscribe") &&
|
||||
IkiWiki::Plugin::notifyemail->can("subscribe")) {
|
||||
IkiWiki::Plugin::notifyemail::subscribe($username,
|
||||
"comment($page)");
|
||||
if (IkiWiki::Plugin::notifyemail->can("subscribe")) {
|
||||
my $subspec="comment($page)";
|
||||
if (defined $username &&
|
||||
length $form->field("subscribe")) {
|
||||
IkiWiki::Plugin::notifyemail::subscribe(
|
||||
$username, $subspec);
|
||||
}
|
||||
elsif (length $form->field("email") &&
|
||||
length $form->field("anonsubscribe")) {
|
||||
IkiWiki::Plugin::notifyemail::anonsubscribe(
|
||||
$form->field("email"), $subspec);
|
||||
}
|
||||
}
|
||||
|
||||
$postcomment=1;
|
||||
|
@ -590,7 +607,8 @@ sub editcomment ($$) {
|
|||
|
||||
sub getavatar ($) {
|
||||
my $user=shift;
|
||||
|
||||
return undef unless defined $user;
|
||||
|
||||
my $avatar;
|
||||
eval q{use Libravatar::URL};
|
||||
if (! $@) {
|
||||
|
|
|
@ -62,6 +62,19 @@ sub subscribe ($$) {
|
|||
length $pagespec ? $pagespec." or ".$addpagespec : $addpagespec);
|
||||
}
|
||||
|
||||
# Called by other plugins to subscribe an email to a pagespec.
|
||||
sub anonsubscribe ($$) {
|
||||
my $email=shift;
|
||||
my $addpagespec=shift;
|
||||
if (IkiWiki::Plugin::passwordauth->can("anonuser")) {
|
||||
my $user=IkiWiki::Plugin::passwordauth::anonuser($email);
|
||||
if (! defined $user) {
|
||||
error(gettext("Cannot subscribe your email address without logging in."));
|
||||
}
|
||||
subscribe($user, $addpagespec);
|
||||
}
|
||||
}
|
||||
|
||||
sub notify (@) {
|
||||
my @files=@_;
|
||||
return unless @files;
|
||||
|
@ -123,11 +136,20 @@ sub notify (@) {
|
|||
if (pagetype($file) eq '_comment') {
|
||||
$subject=gettext("comment notification:")." ".$pagedesc;
|
||||
}
|
||||
my $prefsurl=IkiWiki::cgiurl_abs(do => 'prefs');
|
||||
if (IkiWiki::Plugin::passwordauth->can("anonusertoken")) {
|
||||
my $token=IkiWiki::Plugin::passwordauth::anonusertoken($userinfo->{$user});
|
||||
$prefsurl=IkiWiki::cgiurl_abs(
|
||||
do => 'tokenauth',
|
||||
name => $user,
|
||||
token => $token,
|
||||
) if defined $token;
|
||||
}
|
||||
my $template=template("notifyemail.tmpl");
|
||||
$template->param(
|
||||
wikiname => $config{wikiname},
|
||||
url => $url,
|
||||
prefsurl => IkiWiki::cgiurl_abs(do => 'prefs'),
|
||||
prefsurl => $prefsurl,
|
||||
showcontent => $showcontent,
|
||||
content => $content,
|
||||
);
|
||||
|
|
|
@ -99,11 +99,71 @@ sub setpassword ($$;$) {
|
|||
|
||||
# Setting the password clears any passwordless login token.
|
||||
if ($field ne 'passwordless') {
|
||||
IkiWiki::userinfo_set($user, "cryptpasswordless", "");
|
||||
IkiWiki::userinfo_set($user, "passwordless", "");
|
||||
}
|
||||
}
|
||||
|
||||
# Generates a token that can be used to log the user in.
|
||||
# This needs to be hard to guess. Generating a cgi session id will
|
||||
# make it as hard to guess as any cgi session.
|
||||
sub gentoken ($$;$) {
|
||||
my $user=shift;
|
||||
my $tokenfield=shift;
|
||||
my $reversable=shift;
|
||||
|
||||
eval q{use CGI::Session};
|
||||
error($@) if $@;
|
||||
my $token = CGI::Session->new->id;
|
||||
if (! $reversable) {
|
||||
setpassword($user, $token, $tokenfield);
|
||||
}
|
||||
else {
|
||||
IkiWiki::userinfo_set($user, $tokenfield, $token);
|
||||
}
|
||||
return $token;
|
||||
}
|
||||
|
||||
# An anonymous user has no normal password, only a passwordless login
|
||||
# token. Given an email address, this sets up such a user for that email,
|
||||
# unless one already exists, and returns the username.
|
||||
sub anonuser ($) {
|
||||
my $email=shift;
|
||||
|
||||
# Want a username for this email that won't overlap with any other.
|
||||
my $user=$email;
|
||||
$user=~s/@/_/g;
|
||||
|
||||
my $userinfo=IkiWiki::userinfo_retrieve();
|
||||
if (! exists $userinfo->{$user} || ! ref $userinfo->{$user}) {
|
||||
if (IkiWiki::userinfo_setall($user, {
|
||||
'email' => $email,
|
||||
'regdate' => time})) {
|
||||
gentoken($user, "passwordless", 1);
|
||||
return $user;
|
||||
}
|
||||
else {
|
||||
error(gettext("Error creating account."));
|
||||
}
|
||||
}
|
||||
elsif (defined anonusertoken($userinfo->{$user})) {
|
||||
return $user;
|
||||
}
|
||||
else {
|
||||
return undef;
|
||||
}
|
||||
}
|
||||
|
||||
sub anonusertoken ($) {
|
||||
my $userhash=shift;
|
||||
if (exists $userhash->{passwordless} &&
|
||||
length $userhash->{passwordless}) {
|
||||
return $userhash->{passwordless};
|
||||
}
|
||||
else {
|
||||
return undef;
|
||||
}
|
||||
}
|
||||
|
||||
sub formbuilder_setup (@) {
|
||||
my %params=@_;
|
||||
|
||||
|
@ -283,15 +343,8 @@ sub formbuilder (@) {
|
|||
if (! length $email) {
|
||||
error(gettext("No email address, so cannot email password reset instructions."));
|
||||
}
|
||||
|
||||
# Store a token that can be used once
|
||||
# to log the user in. This needs to be hard
|
||||
# to guess. Generating a cgi session id will
|
||||
# make it as hard to guess as any cgi session.
|
||||
eval q{use CGI::Session};
|
||||
error($@) if $@;
|
||||
my $token = CGI::Session->new->id;
|
||||
setpassword($user_name, $token, "resettoken");
|
||||
|
||||
my $token=gentoken($user_name, "resettoken");
|
||||
|
||||
my $template=template("passwordmail.tmpl");
|
||||
$template->param(
|
||||
|
|
|
@ -13,6 +13,9 @@
|
|||
<label for="url" class="block">Website:</label>
|
||||
<TMPL_VAR NAME=FIELD-URL> (optional)
|
||||
<br />
|
||||
<label for="url" class="block">Email:</label>
|
||||
<TMPL_VAR NAME=FIELD-EMAIL> <TMPL_VAR FIELD-ANONSUBSCRIBE>
|
||||
<br />
|
||||
<TMPL_ELSE>
|
||||
(You might want to <a href="<TMPL_VAR SIGNINURL>">Signin</a> first?)
|
||||
<br />
|
||||
|
|
Loading…
Reference in New Issue