Merge branch 'emailauth'
10
IkiWiki.pm
|
@ -165,7 +165,7 @@ sub getsetup () {
|
||||||
default_plugins => {
|
default_plugins => {
|
||||||
type => "internal",
|
type => "internal",
|
||||||
default => [qw{mdwn link inline meta htmlscrubber passwordauth
|
default => [qw{mdwn link inline meta htmlscrubber passwordauth
|
||||||
openid signinedit lockedit conditional
|
openid emailauth signinedit lockedit conditional
|
||||||
recentchanges parentlinks editpage
|
recentchanges parentlinks editpage
|
||||||
templatebody}],
|
templatebody}],
|
||||||
description => "plugins to enable by default",
|
description => "plugins to enable by default",
|
||||||
|
@ -1464,6 +1464,14 @@ sub openiduser ($) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub emailuser ($) {
|
||||||
|
my $user=shift;
|
||||||
|
if (defined $user && $user =~ m/(.+)@/) {
|
||||||
|
return $1;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
sub htmlize ($$$$) {
|
sub htmlize ($$$$) {
|
||||||
my $page=shift;
|
my $page=shift;
|
||||||
my $destpage=shift;
|
my $destpage=shift;
|
||||||
|
|
|
@ -198,7 +198,6 @@ sub preprocess {
|
||||||
$commentuser = $params{username};
|
$commentuser = $params{username};
|
||||||
|
|
||||||
my $oiduser = eval { IkiWiki::openiduser($commentuser) };
|
my $oiduser = eval { IkiWiki::openiduser($commentuser) };
|
||||||
|
|
||||||
if (defined $oiduser) {
|
if (defined $oiduser) {
|
||||||
# looks like an OpenID
|
# looks like an OpenID
|
||||||
$commentauthorurl = $commentuser;
|
$commentauthorurl = $commentuser;
|
||||||
|
@ -206,6 +205,11 @@ sub preprocess {
|
||||||
$commentopenid = $commentuser;
|
$commentopenid = $commentuser;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
my $emailuser = IkiWiki::emailuser($commentuser);
|
||||||
|
if (defined $emailuser) {
|
||||||
|
$commentuser=$emailuser;
|
||||||
|
}
|
||||||
|
|
||||||
if (length $config{cgiurl}) {
|
if (length $config{cgiurl}) {
|
||||||
$commentauthorurl = IkiWiki::cgiurl(
|
$commentauthorurl = IkiWiki::cgiurl(
|
||||||
do => 'goto',
|
do => 'goto',
|
||||||
|
|
|
@ -0,0 +1,193 @@
|
||||||
|
#!/usr/bin/perl
|
||||||
|
# Ikiwiki email address as login
|
||||||
|
package IkiWiki::Plugin::emailauth;
|
||||||
|
|
||||||
|
use warnings;
|
||||||
|
use strict;
|
||||||
|
use IkiWiki 3.00;
|
||||||
|
|
||||||
|
sub import {
|
||||||
|
hook(type => "getsetup", id => "emailauth", "call" => \&getsetup);
|
||||||
|
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",
|
||||||
|
\&email_setup,
|
||||||
|
\&email_check_input,
|
||||||
|
\&email_auth,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
sub getsetup () {
|
||||||
|
return
|
||||||
|
plugin => {
|
||||||
|
safe => 1,
|
||||||
|
rebuild => 0,
|
||||||
|
section => "auth",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
sub email_setup ($$) {
|
||||||
|
my $q=shift;
|
||||||
|
my $template=shift;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub email_check_input ($) {
|
||||||
|
my $cgi=shift;
|
||||||
|
defined $cgi->param('do')
|
||||||
|
&& $cgi->param("do") eq "signin"
|
||||||
|
&& defined $cgi->param('Email_entry')
|
||||||
|
&& length $cgi->param('Email_entry');
|
||||||
|
}
|
||||||
|
|
||||||
|
# Send login link to email.
|
||||||
|
sub email_auth ($$$$) {
|
||||||
|
my $cgi=shift;
|
||||||
|
my $session=shift;
|
||||||
|
my $errordisplayer=shift;
|
||||||
|
my $infodisplayer=shift;
|
||||||
|
|
||||||
|
my $email=$cgi->param('Email_entry');
|
||||||
|
unless ($email =~ /.\@./) {
|
||||||
|
$errordisplayer->(gettext("Invalid email address."));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Implicit account creation.
|
||||||
|
my $userinfo=IkiWiki::userinfo_retrieve();
|
||||||
|
if (! exists $userinfo->{$email} || ! ref $userinfo->{$email}) {
|
||||||
|
IkiWiki::userinfo_setall($email, {
|
||||||
|
'email' => $email,
|
||||||
|
'regdate' => time,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
my $token=gentoken($email, $session);
|
||||||
|
my $template=template("emailauth.tmpl");
|
||||||
|
$template->param(
|
||||||
|
wikiname => $config{wikiname},
|
||||||
|
# Intentionally using short field names to keep link short.
|
||||||
|
authurl => IkiWiki::cgiurl_abs(
|
||||||
|
'e' => $email,
|
||||||
|
'v' => $token,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
eval q{use Mail::Sendmail};
|
||||||
|
error($@) if $@;
|
||||||
|
sendmail(
|
||||||
|
To => $email,
|
||||||
|
From => "$config{wikiname} admin <".
|
||||||
|
(defined $config{adminemail} ? $config{adminemail} : "")
|
||||||
|
.">",
|
||||||
|
Subject => "$config{wikiname} login",
|
||||||
|
Message => $template->output,
|
||||||
|
) or error(gettext("Failed to send mail"));
|
||||||
|
|
||||||
|
$infodisplayer->(gettext("You have been sent an email, with a link you can open to complete the login process."));
|
||||||
|
}
|
||||||
|
|
||||||
|
# Finish login process.
|
||||||
|
sub cgi ($$) {
|
||||||
|
my $cgi=shift;
|
||||||
|
|
||||||
|
my $email=$cgi->param('e');
|
||||||
|
my $v=$cgi->param('v');
|
||||||
|
if (defined $email && defined $v && length $email && length $v) {
|
||||||
|
my $token=gettoken($email);
|
||||||
|
if ($token eq $v) {
|
||||||
|
cleartoken($email);
|
||||||
|
my $session=getsession($email);
|
||||||
|
IkiWiki::cgi_postsignin($cgi, $session);
|
||||||
|
}
|
||||||
|
elsif (length $token ne length $cgi->param('v')) {
|
||||||
|
error(gettext("Wrong login token length. Please check that you pasted in the complete login link from the email!"));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
loginfailure();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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.
|
||||||
|
#
|
||||||
|
# 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;
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Gets the token, checking for expiry.
|
||||||
|
sub gettoken ($) {
|
||||||
|
my $email=shift;
|
||||||
|
my $val=IkiWiki::userinfo_get($email, "emailauth");
|
||||||
|
my $expire=IkiWiki::userinfo_get($email, "emailauthexpire");
|
||||||
|
if (! length $val || time > $expire) {
|
||||||
|
loginfailure();
|
||||||
|
}
|
||||||
|
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);
|
||||||
|
IkiWiki::userinfo_set($email, "emailauth", "");
|
||||||
|
}
|
||||||
|
|
||||||
|
sub loginfailure () {
|
||||||
|
error "Bad email authentication token. Please retry login.";
|
||||||
|
}
|
||||||
|
|
||||||
|
1
|
|
@ -0,0 +1,132 @@
|
||||||
|
#!/usr/bin/perl
|
||||||
|
package IkiWiki::Plugin::loginselector;
|
||||||
|
|
||||||
|
use warnings;
|
||||||
|
use strict;
|
||||||
|
use IkiWiki 3.00;
|
||||||
|
|
||||||
|
# Plugins that provide login methods can register themselves here.
|
||||||
|
# Note that the template and js file also have be be modifed to add a new
|
||||||
|
# login method.
|
||||||
|
our %login_plugins;
|
||||||
|
|
||||||
|
sub register_login_plugin ($$$$) {
|
||||||
|
# Same as the name of the plugin that is registering itself as a
|
||||||
|
# login plugin. eg, "openid"
|
||||||
|
my $plugin_name=shift;
|
||||||
|
# This sub is passed a cgi object and a template object which it
|
||||||
|
# can manipulate. It should return true if the plugin can be used
|
||||||
|
# (it might load necessary modules for auth checking, for example).
|
||||||
|
my $plugin_setup=shift;
|
||||||
|
# This sub is passed a cgi object, and should return true
|
||||||
|
# if it looks like the user is logging in using the plugin.
|
||||||
|
my $plugin_check_input=shift;
|
||||||
|
# This sub is passed a cgi object, a session object, an error
|
||||||
|
# display callback, and an info display callback, and should
|
||||||
|
# handle the actual authentication. It can either exit w/o
|
||||||
|
# returning, if it is able to handle auth, or it can pass an
|
||||||
|
# error message to the error display callback to make the
|
||||||
|
# openid selector form be re-disiplayed with an error message
|
||||||
|
# on it.
|
||||||
|
my $plugin_auth=shift;
|
||||||
|
$login_plugins{$plugin_name}={
|
||||||
|
setup => $plugin_setup,
|
||||||
|
check_input => $plugin_check_input,
|
||||||
|
auth => $plugin_auth,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
sub login_selector {
|
||||||
|
my $real_cgi_signin=shift;
|
||||||
|
my $otherform_label=shift;
|
||||||
|
my $q=shift;
|
||||||
|
my $session=shift;
|
||||||
|
|
||||||
|
my $template=IkiWiki::template("login-selector.tmpl");
|
||||||
|
|
||||||
|
foreach my $plugin (keys %login_plugins) {
|
||||||
|
if (! $login_plugins{$plugin}->{setup}->($template)) {
|
||||||
|
delete $login_plugins{$plugin};
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$template->param("login_selector_$plugin", 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach my $plugin (keys %login_plugins) {
|
||||||
|
if ($login_plugins{$plugin}->{check_input}->($q)) {
|
||||||
|
$login_plugins{$plugin}->{auth}->($q, $session, sub {
|
||||||
|
$template->param(login_error => shift());
|
||||||
|
}, sub {
|
||||||
|
$template->param(login_info => shift());
|
||||||
|
});
|
||||||
|
last;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$template->param(
|
||||||
|
cgiurl => IkiWiki::cgiurl(),
|
||||||
|
($real_cgi_signin ? (otherform => $real_cgi_signin->($q, $session, 1)) : ()),
|
||||||
|
otherform_label => $otherform_label,
|
||||||
|
);
|
||||||
|
|
||||||
|
IkiWiki::printheader($session);
|
||||||
|
print IkiWiki::cgitemplate($q, "signin", $template->output);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub import {
|
||||||
|
add_underlay("login-selector");
|
||||||
|
add_underlay("jquery");
|
||||||
|
hook(type => "getsetup", id => "loginselector", call => \&getsetup);
|
||||||
|
hook(type => "checkconfig", id => "loginselector", call => \&checkconfig);
|
||||||
|
hook(type => "auth", id => "loginselector", call => \&authstub);
|
||||||
|
}
|
||||||
|
|
||||||
|
sub checkconfig () {
|
||||||
|
if ($config{cgi}) {
|
||||||
|
# Intercept normal signin form, so the login selector
|
||||||
|
# can be displayed.
|
||||||
|
#
|
||||||
|
# When other auth hooks are registered, give the selector
|
||||||
|
# a reference to the normal signin form.
|
||||||
|
require IkiWiki::CGI;
|
||||||
|
my $real_cgi_signin;
|
||||||
|
my $otherform_label=gettext("Other");
|
||||||
|
if (keys %{$IkiWiki::hooks{auth}} > 1) {
|
||||||
|
$real_cgi_signin=\&IkiWiki::cgi_signin;
|
||||||
|
# Special case to avoid labeling password auth as
|
||||||
|
# "Other" when it's the only auth plugin not
|
||||||
|
# integrated with the loginselector.
|
||||||
|
my %h=%{$IkiWiki::hooks{auth}};
|
||||||
|
foreach my $p (keys %login_plugins) {
|
||||||
|
delete $h{$p};
|
||||||
|
}
|
||||||
|
delete $h{loginselector};
|
||||||
|
if (keys %h == 1 && exists $h{passwordauth}) {
|
||||||
|
$otherform_label=gettext("Password");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
inject(name => "IkiWiki::cgi_signin", call => sub ($$) {
|
||||||
|
login_selector($real_cgi_signin, $otherform_label, @_);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sub getsetup () {
|
||||||
|
return
|
||||||
|
plugin => {
|
||||||
|
# this plugin is safe but only makes sense as a
|
||||||
|
# dependency
|
||||||
|
safe => 0,
|
||||||
|
rebuild => 0,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
sub authstub ($$) {
|
||||||
|
# While this hook is not currently used, it needs to exist
|
||||||
|
# so ikiwiki knows that the wiki supports logins, and will
|
||||||
|
# enable the Preferences page.
|
||||||
|
}
|
||||||
|
|
||||||
|
1
|
|
@ -7,35 +7,17 @@ use strict;
|
||||||
use IkiWiki 3.00;
|
use IkiWiki 3.00;
|
||||||
|
|
||||||
sub import {
|
sub import {
|
||||||
add_underlay("openid-selector");
|
|
||||||
add_underlay("jquery");
|
|
||||||
hook(type => "checkconfig", id => "openid", call => \&checkconfig);
|
|
||||||
hook(type => "getsetup", id => "openid", call => \&getsetup);
|
hook(type => "getsetup", id => "openid", call => \&getsetup);
|
||||||
hook(type => "auth", id => "openid", call => \&auth);
|
hook(type => "auth", id => "openid", call => \&auth);
|
||||||
hook(type => "formbuilder_setup", id => "openid",
|
hook(type => "formbuilder_setup", id => "openid",
|
||||||
call => \&formbuilder_setup, last => 1);
|
call => \&formbuilder_setup, last => 1);
|
||||||
}
|
IkiWiki::loadplugin("loginselector");
|
||||||
|
IkiWiki::Plugin::loginselector::register_login_plugin(
|
||||||
sub checkconfig () {
|
"openid",
|
||||||
if ($config{cgi}) {
|
\&openid_setup,
|
||||||
# Intercept normal signin form, so the openid selector
|
\&openid_check_input,
|
||||||
# can be displayed.
|
\&openid_auth,
|
||||||
#
|
);
|
||||||
# When other auth hooks are registered, give the selector
|
|
||||||
# a reference to the normal signin form.
|
|
||||||
require IkiWiki::CGI;
|
|
||||||
my $real_cgi_signin;
|
|
||||||
my $nonopenidform_label=gettext("Other");
|
|
||||||
if (keys %{$IkiWiki::hooks{auth}} > 1) {
|
|
||||||
$real_cgi_signin=\&IkiWiki::cgi_signin;
|
|
||||||
if (keys %{$IkiWiki::hooks{auth}} == 2 && exists $IkiWiki::hooks{auth}->{passwordauth}) {
|
|
||||||
$nonopenidform_label=gettext("Password");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
inject(name => "IkiWiki::cgi_signin", call => sub ($$) {
|
|
||||||
openid_selector($real_cgi_signin, $nonopenidform_label, @_);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sub getsetup () {
|
sub getsetup () {
|
||||||
|
@ -59,40 +41,34 @@ sub getsetup () {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
sub openid_selector {
|
sub openid_setup ($$) {
|
||||||
my $real_cgi_signin=shift;
|
my $q=shift;
|
||||||
my $nonopenidform_label=shift;
|
my $template=shift;
|
||||||
my $q=shift;
|
|
||||||
my $session=shift;
|
|
||||||
|
|
||||||
my $openid_url=$q->param('openid_identifier');
|
if (load_openid_module()) {
|
||||||
my $openid_error;
|
my $openid_url=$q->param('openid_identifier');
|
||||||
|
if (defined $openid_url) {
|
||||||
if (! load_openid_module()) {
|
$template->param(openid_url => $openid_url);
|
||||||
if ($real_cgi_signin) {
|
|
||||||
$real_cgi_signin->($q, $session);
|
|
||||||
exit;
|
|
||||||
}
|
}
|
||||||
error(sprintf(gettext("failed to load openid module: "), @_));
|
return 1;
|
||||||
}
|
}
|
||||||
elsif (defined $q->param("action") && $q->param("action") eq "verify") {
|
else {
|
||||||
validate($q, $session, $openid_url, sub {
|
return 0;
|
||||||
$openid_error=shift;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
my $template=IkiWiki::template("openid-selector.tmpl");
|
sub openid_check_input ($) {
|
||||||
$template->param(
|
my $q=shift;
|
||||||
cgiurl => IkiWiki::cgiurl(),
|
my $openid_url=$q->param('openid_identifier');
|
||||||
(defined $openid_error ? (openid_error => $openid_error) : ()),
|
defined $q->param("action") && $q->param("action") eq "verify" && defined $openid_url && length $openid_url;
|
||||||
(defined $openid_url ? (openid_url => $openid_url) : ()),
|
}
|
||||||
($real_cgi_signin ? (nonopenidform => $real_cgi_signin->($q, $session, 1)) : ()),
|
|
||||||
nonopenidform_label => $nonopenidform_label,
|
|
||||||
);
|
|
||||||
|
|
||||||
IkiWiki::printheader($session);
|
sub openid_auth ($$$$) {
|
||||||
print IkiWiki::cgitemplate($q, "signin", $template->output);
|
my $q=shift;
|
||||||
exit;
|
my $session=shift;
|
||||||
|
my $errordisplayer=shift;
|
||||||
|
my $openid_url=$q->param('openid_identifier');
|
||||||
|
validate($q, $session, $openid_url, $errordisplayer);
|
||||||
}
|
}
|
||||||
|
|
||||||
sub formbuilder_setup (@) {
|
sub formbuilder_setup (@) {
|
||||||
|
|
|
@ -277,7 +277,7 @@ sub formbuilder_setup (@) {
|
||||||
}
|
}
|
||||||
elsif ($form->title eq "preferences") {
|
elsif ($form->title eq "preferences") {
|
||||||
my $user=$session->param("name");
|
my $user=$session->param("name");
|
||||||
if (! IkiWiki::openiduser($user)) {
|
if (! IkiWiki::openiduser($user) && ! IkiWiki::emailuser($user)) {
|
||||||
$form->field(name => "name", disabled => 1,
|
$form->field(name => "name", disabled => 1,
|
||||||
value => $user, force => 1,
|
value => $user, force => 1,
|
||||||
fieldset => "login");
|
fieldset => "login");
|
||||||
|
|
|
@ -154,31 +154,33 @@ sub import (@) {
|
||||||
foreach my $admin (@{$config{adminuser}}) {
|
foreach my $admin (@{$config{adminuser}}) {
|
||||||
next if defined IkiWiki::openiduser($admin);
|
next if defined IkiWiki::openiduser($admin);
|
||||||
|
|
||||||
# Prompt for password w/o echo.
|
if (! defined IkiWiki::emailuser($admin)) {
|
||||||
my ($password, $password2);
|
# Prompt for password w/o echo.
|
||||||
system('stty -echo 2>/dev/null');
|
my ($password, $password2);
|
||||||
local $|=1;
|
system('stty -echo 2>/dev/null');
|
||||||
print "\n\nCreating wiki admin $admin ...\n";
|
local $|=1;
|
||||||
for (;;) {
|
print "\n\nCreating wiki admin $admin ...\n";
|
||||||
print "Choose a password: ";
|
for (;;) {
|
||||||
chomp($password=<STDIN>);
|
print "Choose a password: ";
|
||||||
print "\n";
|
chomp($password=<STDIN>);
|
||||||
print "Confirm password: ";
|
print "\n";
|
||||||
chomp($password2=<STDIN>);
|
print "Confirm password: ";
|
||||||
|
chomp($password2=<STDIN>);
|
||||||
|
|
||||||
|
last if $password2 eq $password;
|
||||||
|
|
||||||
|
print "Password mismatch.\n\n";
|
||||||
|
}
|
||||||
|
print "\n\n\n";
|
||||||
|
system('stty sane 2>/dev/null');
|
||||||
|
|
||||||
last if $password2 eq $password;
|
if (IkiWiki::userinfo_setall($admin, { regdate => time }) &&
|
||||||
|
IkiWiki::Plugin::passwordauth::setpassword($admin, $password)) {
|
||||||
print "Password mismatch.\n\n";
|
IkiWiki::userinfo_set($admin, "email", $config{adminemail}) if defined $config{adminemail};
|
||||||
}
|
}
|
||||||
print "\n\n\n";
|
else {
|
||||||
system('stty sane 2>/dev/null');
|
error("problem setting up $admin user");
|
||||||
|
}
|
||||||
if (IkiWiki::userinfo_setall($admin, { regdate => time }) &&
|
|
||||||
IkiWiki::Plugin::passwordauth::setpassword($admin, $password)) {
|
|
||||||
IkiWiki::userinfo_set($admin, "email", $config{adminemail}) if defined $config{adminemail};
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
error("problem setting up $admin user");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,7 @@ our $wikiname_short=IkiWiki::Setup::Automator::sanitize_wikiname($wikiname);
|
||||||
our $rcs=IkiWiki::Setup::Automator::ask(
|
our $rcs=IkiWiki::Setup::Automator::ask(
|
||||||
gettext("What revision control system to use?"), "git");
|
gettext("What revision control system to use?"), "git");
|
||||||
our $admin=IkiWiki::Setup::Automator::ask(
|
our $admin=IkiWiki::Setup::Automator::ask(
|
||||||
gettext("Which user (wiki account or openid) will be admin?"), $ENV{USER});
|
gettext("Which user (wiki account, openid, or email) will be admin?"), $ENV{USER});
|
||||||
use Net::Domain q{hostfqdn};
|
use Net::Domain q{hostfqdn};
|
||||||
our $domain=hostfqdn() || IkiWiki::Setup::Automator::ask(
|
our $domain=hostfqdn() || IkiWiki::Setup::Automator::ask(
|
||||||
gettext("What is the domain name of the web server?"), "");
|
gettext("What is the domain name of the web server?"), "");
|
||||||
|
|
|
@ -1,10 +1,14 @@
|
||||||
ikiwiki (3.20150330) UNRELEASED; urgency=medium
|
ikiwiki (3.20150330) UNRELEASED; urgency=medium
|
||||||
|
|
||||||
|
* New emailauth plugin lets users log in, without any registration,
|
||||||
|
by simply clicking on a link in an email.
|
||||||
* Re-remove google from openid selector; their openid provider is
|
* Re-remove google from openid selector; their openid provider is
|
||||||
gone for good.
|
gone for good.
|
||||||
* When openid and passwordauth are the only enabled auth plugins,
|
* Make the openid selector display "Password" instead of "Other"
|
||||||
make the openid selector display "Password" instead of "Other",
|
when appropriate, so users are more likely to click on it when
|
||||||
so users are more likely to click on it when they don't have an openid.
|
they don't have an openid.
|
||||||
|
* Converted openid-selector into a more generic loginselector helper
|
||||||
|
plugin.
|
||||||
|
|
||||||
-- Joey Hess <id@joeyh.name> Tue, 28 Apr 2015 12:24:08 -0400
|
-- Joey Hess <id@joeyh.name> Tue, 28 Apr 2015 12:24:08 -0400
|
||||||
|
|
||||||
|
|
|
@ -201,20 +201,20 @@ Comment:
|
||||||
Republished with permission.
|
Republished with permission.
|
||||||
License: GPL-2+
|
License: GPL-2+
|
||||||
|
|
||||||
Files: underlays/openid-selector/ikiwiki/openid/*
|
Files: underlays/openid-selector/ikiwiki/login-selector/*
|
||||||
Copyright: © 2008-2010 andyjm, david.j.boden
|
Copyright: © 2008-2010 andyjm, david.j.boden
|
||||||
Comment:
|
Comment:
|
||||||
From http://code.google.com/p/openid-selector/
|
From http://code.google.com/p/openid-selector/
|
||||||
License: BSD-2-clause
|
License: BSD-2-clause
|
||||||
|
|
||||||
Files: underlays/openid-selector/ikiwiki/openid/goa-*
|
Files: underlays/openid-selector/ikiwiki/login-selector/goa-*
|
||||||
Copyright:
|
Copyright:
|
||||||
© 2011 Red Hat, Inc.
|
© 2011 Red Hat, Inc.
|
||||||
License: LGPL-2.1+
|
License: LGPL-2.1+
|
||||||
Comment:
|
Comment:
|
||||||
taken from data/icons/16x16/ in gnome-online-accounts git
|
taken from data/icons/16x16/ in gnome-online-accounts git
|
||||||
|
|
||||||
Files: underlays/openid-selector/ikiwiki/openid/wordpress.png
|
Files: underlays/openid-selector/ikiwiki/login-selector/wordpress.png
|
||||||
Copyright:
|
Copyright:
|
||||||
© 2003-2013 "the contributors"
|
© 2003-2013 "the contributors"
|
||||||
License: GPL-2+
|
License: GPL-2+
|
||||||
|
@ -226,9 +226,8 @@ Files:
|
||||||
icons/aol.svg
|
icons/aol.svg
|
||||||
icons/livejournal.svg
|
icons/livejournal.svg
|
||||||
icons/verisign.svg
|
icons/verisign.svg
|
||||||
underlays/openid-selector/ikiwiki/openid/aol.png
|
underlays/openid-selector/ikiwiki/login-selector/aol.png
|
||||||
underlays/openid-selector/ikiwiki/openid/livejournal.png
|
underlays/openid-selector/ikiwiki/login-selector/verisign.png
|
||||||
underlays/openid-selector/ikiwiki/openid/verisign.png
|
|
||||||
Copyright:
|
Copyright:
|
||||||
© 2014 Simon McVittie
|
© 2014 Simon McVittie
|
||||||
License: other
|
License: other
|
||||||
|
|
|
@ -10,7 +10,7 @@ It currently includes these pages:
|
||||||
* [[templates]]
|
* [[templates]]
|
||||||
* [[ikiwiki/formatting]]
|
* [[ikiwiki/formatting]]
|
||||||
* [[ikiwiki/markdown]]
|
* [[ikiwiki/markdown]]
|
||||||
* [[ikiwiki/openid]]
|
* [[ikiwiki/login-selector]]
|
||||||
* [[ikiwiki/pagespec]]
|
* [[ikiwiki/pagespec]]
|
||||||
* [[ikiwiki/directive]]
|
* [[ikiwiki/directive]]
|
||||||
* [[ikiwiki/subpage]]
|
* [[ikiwiki/subpage]]
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
[[!template id=plugin name=emailauth core=1 author="[[Joey]]"]]
|
||||||
|
[[!tag type/auth]]
|
||||||
|
|
||||||
|
This plugin lets users log into ikiwiki using any email address. To complete
|
||||||
|
the login, a one-time-use link is emailed to the user, and they can simply
|
||||||
|
open that link in their browser.
|
||||||
|
|
||||||
|
It is enabled by default, but can be turned off if you want to only use
|
||||||
|
some other form of authentication, such as [[passwordauth]] or [[openid]].
|
||||||
|
|
||||||
|
Users who have logged in using emailauth will have their email address used as
|
||||||
|
their username. In places where the username is displayed, like the
|
||||||
|
RecentChanges page, the domain will be omitted, to avoid exposing the
|
||||||
|
user's email address.
|
||||||
|
|
||||||
|
This plugin needs the [[!cpan Mail::SendMail]] perl module installed,
|
||||||
|
and able to send outgoing email.
|
|
@ -458,6 +458,9 @@ object's "name" parameter to the authenticated user's name. Note that
|
||||||
if the name is set to the name of a user who is not registered,
|
if the name is set to the name of a user who is not registered,
|
||||||
a basic registration of the user will be automatically performed.
|
a basic registration of the user will be automatically performed.
|
||||||
|
|
||||||
|
Auth plugins can use the loginselector helper plugin to let the user
|
||||||
|
select which authentication method to use.
|
||||||
|
|
||||||
### <a name="sessioncgi">sessioncgi</a>
|
### <a name="sessioncgi">sessioncgi</a>
|
||||||
|
|
||||||
hook(type => "sessioncgi", id => "foo", call => \&sessioncgi);
|
hook(type => "sessioncgi", id => "foo", call => \&sessioncgi);
|
||||||
|
|
|
@ -465,40 +465,40 @@ li.L8 { list-style: upper-alpha; }
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* openid selector */
|
/* login selector */
|
||||||
#openid_choice {
|
#login_choice {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
#openid_input_area {
|
#login_input_area {
|
||||||
clear: both;
|
clear: both;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
}
|
}
|
||||||
#openid_btns, #openid_btns br {
|
#login_btns, #login_btns br {
|
||||||
clear: both;
|
clear: both;
|
||||||
}
|
}
|
||||||
#openid_highlight {
|
#login_highlight {
|
||||||
background-color: black;
|
background-color: black;
|
||||||
float: left;
|
float: left;
|
||||||
}
|
}
|
||||||
.openid_large_btn {
|
.login_large_btn {
|
||||||
padding: 1em 1.5em;
|
padding: 1em 1.5em;
|
||||||
border: 1px solid #DDD;
|
border: 1px solid #DDD;
|
||||||
margin: 3px;
|
margin: 3px;
|
||||||
float: left;
|
float: left;
|
||||||
}
|
}
|
||||||
.openid_small_btn {
|
.login_small_btn {
|
||||||
padding: 4px 4px;
|
padding: 4px 4px;
|
||||||
border: 1px solid #DDD;
|
border: 1px solid #DDD;
|
||||||
margin: 3px;
|
margin: 3px;
|
||||||
float: left;
|
float: left;
|
||||||
}
|
}
|
||||||
a.openid_large_btn:focus {
|
a.login_large_btn:focus {
|
||||||
outline: none;
|
outline: none;
|
||||||
}
|
}
|
||||||
a.openid_large_btn:focus {
|
a.login_large_btn:focus {
|
||||||
outline-style: none;
|
outline-style: none;
|
||||||
}
|
}
|
||||||
.openid_selected {
|
.login_selected {
|
||||||
border: 4px solid #DDD;
|
border: 4px solid #DDD;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -92,8 +92,9 @@ Here is a full list of the template files used:
|
||||||
* `editpage.tmpl`, `editconflict.tmpl`, `editcreationconflict.tmpl`,
|
* `editpage.tmpl`, `editconflict.tmpl`, `editcreationconflict.tmpl`,
|
||||||
`editfailedsave.tmpl`, `editpagegone.tmpl`, `pocreatepage.tmpl`,
|
`editfailedsave.tmpl`, `editpagegone.tmpl`, `pocreatepage.tmpl`,
|
||||||
`editcomment.tmpl` `commentmoderation.tmpl`, `renamesummary.tmpl`,
|
`editcomment.tmpl` `commentmoderation.tmpl`, `renamesummary.tmpl`,
|
||||||
`passwordmail.tmpl`, `openid-selector.tmpl`, `revert.tmpl` - Parts of ikiwiki's user
|
`passwordmail.tmpl`, `emailauth.tmpl, `login-selector.tmpl`,
|
||||||
interface; do not normally need to be customised.
|
`revert.tmpl` - Parts of ikiwiki's user interface; do not normally need
|
||||||
|
to be customised.
|
||||||
|
|
||||||
|
|
||||||
[[!meta robots="noindex, follow"]]
|
[[!meta robots="noindex, follow"]]
|
||||||
|
|
After Width: | Height: | Size: 685 B |
|
@ -0,0 +1,10 @@
|
||||||
|
To log into <TMPL_VAR WIKINAME>, just open the following link:
|
||||||
|
|
||||||
|
<TMPL_VAR AUTHURL>
|
||||||
|
|
||||||
|
This link can only be used once to log in, and will expire in one day.
|
||||||
|
|
||||||
|
(Please disregard this email if you were not trying to log in.)
|
||||||
|
|
||||||
|
--
|
||||||
|
ikiwiki
|
|
@ -0,0 +1,65 @@
|
||||||
|
<script type="text/javascript" src="ikiwiki/jquery.min.js"></script>
|
||||||
|
<script type="text/javascript" src="ikiwiki/login-selector/login-selector.js"></script>
|
||||||
|
<script type="text/javascript">
|
||||||
|
$(document).ready(function() {
|
||||||
|
selector.init(
|
||||||
|
'openid_identifier',
|
||||||
|
{
|
||||||
|
<TMPL_IF LOGIN_SELECTOR_OPENID>'openid': 1,</TMPL_IF>
|
||||||
|
<TMPL_IF LOGIN_SELECTOR_EMAILAUTH>'email': 1,</TMPL_IF>
|
||||||
|
},
|
||||||
|
'<TMPL_IF OTHERFORM>otherform</TMPL_IF>',
|
||||||
|
'<TMPL_VAR OTHERFORM_LABEL>'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<form action="<TMPL_VAR CGIURL>" method="get" id="login_selector_form">
|
||||||
|
<div>
|
||||||
|
<script>
|
||||||
|
$('fieldset').append("<legend>Select login method</legend>");
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<input type="hidden" name="do" value="signin" />
|
||||||
|
<input type="hidden" name="action" value="verify" />
|
||||||
|
<div id="login_choice">
|
||||||
|
<div id="login_btns"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="login_input_area">
|
||||||
|
<TMPL_IF LOGIN_SELECTOR_OPENID>
|
||||||
|
<div>
|
||||||
|
<h3>OpenId login:</h3>
|
||||||
|
<label for="openid_identifier" class="block">Enter your OpenID:</label>
|
||||||
|
<input id="openid_identifier" name="openid_identifier" type="text" value="<TMPL_VAR ESCAPE=HTML OPENID_URL>"/>
|
||||||
|
<input id="openid_submit" type="submit" value="Login"/>
|
||||||
|
</div>
|
||||||
|
</TMPL_IF>
|
||||||
|
<TMPL_IF LOGIN_SELECTOR_EMAILAUTH>
|
||||||
|
<div>
|
||||||
|
<h3>Email login:</h3>
|
||||||
|
<label for="email_address" class="block">Enter your email address:</label>
|
||||||
|
<input id="email_address" name="Email_entry" type="text" value="<TMPL_VAR ESCAPE=HTML EMAIL_ADDRESS>"/>
|
||||||
|
<input id="email_submit" type="submit" value="Login"/>
|
||||||
|
</div>
|
||||||
|
</TMPL_IF>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<TMPL_IF LOGIN_ERROR>
|
||||||
|
<div class="error"><TMPL_VAR LOGIN_ERROR></div>
|
||||||
|
</TMPL_IF>
|
||||||
|
<TMPL_IF LOGIN_INFO>
|
||||||
|
<TMPL_VAR LOGIN_INFO>
|
||||||
|
</TMPL_IF>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<div id="otherform">
|
||||||
|
<TMPL_IF OTHERFORM>
|
||||||
|
<br />
|
||||||
|
<noscript>
|
||||||
|
<h3><TMPL_VAR OTHERFORM_LABEL> login:</h3>
|
||||||
|
</noscript>
|
||||||
|
</TMPL_IF>
|
||||||
|
<TMPL_VAR OTHERFORM>
|
||||||
|
</div>
|
|
@ -1,43 +0,0 @@
|
||||||
<script type="text/javascript" src="ikiwiki/jquery.min.js"></script>
|
|
||||||
<script type="text/javascript" src="ikiwiki/openid/openid-jquery.js"></script>
|
|
||||||
<script type="text/javascript">
|
|
||||||
$(document).ready(function() {
|
|
||||||
openid.init('openid_identifier','<TMPL_IF NONOPENIDFORM>nonopenidform</TMPL_IF>', '<TMPL_VAR NONOPENIDFORM_LABEL>');
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<noscript>
|
|
||||||
<h2>OpenID:</h2>
|
|
||||||
</noscript>
|
|
||||||
|
|
||||||
<form action="<TMPL_VAR CGIURL>" method="get" id="openid_form">
|
|
||||||
<fieldset>
|
|
||||||
<script>
|
|
||||||
$('fieldset').append("<legend>Select login method</legend>");
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<input type="hidden" name="do" value="signin" />
|
|
||||||
<input type="hidden" name="action" value="verify" />
|
|
||||||
<div id="openid_choice">
|
|
||||||
<div id="openid_btns"></div>
|
|
||||||
</div>
|
|
||||||
<div id="openid_input_area">
|
|
||||||
<label for="openid_identifier" class="block">Enter your OpenID:</label>
|
|
||||||
<input id="openid_identifier" name="openid_identifier" type="text" value="<TMPL_VAR ESCAPE=HTML OPENID_URL>"/>
|
|
||||||
<input id="openid_submit" type="submit" value="Login"/>
|
|
||||||
</div>
|
|
||||||
<TMPL_IF OPENID_ERROR>
|
|
||||||
<div class="error"><TMPL_VAR OPENID_ERROR></div>
|
|
||||||
</TMPL_IF>
|
|
||||||
</fieldset>
|
|
||||||
</form>
|
|
||||||
|
|
||||||
<div id="nonopenidform">
|
|
||||||
<TMPL_IF NONOPENIDFORM>
|
|
||||||
<br />
|
|
||||||
<noscript>
|
|
||||||
<h2><TMPL_VAR NONOPENIDFORM_LABEL>:</h2>
|
|
||||||
</noscript>
|
|
||||||
</TMPL_IF>
|
|
||||||
<TMPL_VAR NONOPENIDFORM>
|
|
||||||
</div>
|
|
After Width: | Height: | Size: 460 B |
After Width: | Height: | Size: 592 B |
Before Width: | Height: | Size: 741 B After Width: | Height: | Size: 741 B |
|
@ -0,0 +1,264 @@
|
||||||
|
/*
|
||||||
|
Based on the Simple OpenID Plugin
|
||||||
|
http://code.google.com/p/openid-selector/
|
||||||
|
|
||||||
|
This code is licenced under the New BSD License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
var selections_email_large = {
|
||||||
|
email: {
|
||||||
|
name: 'Email',
|
||||||
|
icon: 'wikiicons/email.png',
|
||||||
|
label: 'Enter your email address:',
|
||||||
|
url: null
|
||||||
|
}
|
||||||
|
};
|
||||||
|
var selections_openid_large = {
|
||||||
|
openid: {
|
||||||
|
name: 'OpenID',
|
||||||
|
icon: 'wikiicons/openidlogin-bg.gif',
|
||||||
|
label: 'Enter your OpenID:',
|
||||||
|
url: null
|
||||||
|
}
|
||||||
|
};
|
||||||
|
var selections_openid_small = {
|
||||||
|
verisign: {
|
||||||
|
name: 'Verisign',
|
||||||
|
icon: 'ikiwiki/login-selector/verisign.png',
|
||||||
|
label: 'Enter your Verisign username:',
|
||||||
|
url: 'http://{username}.pip.verisignlabs.com/'
|
||||||
|
},
|
||||||
|
yahoo: {
|
||||||
|
name: 'Yahoo',
|
||||||
|
icon: 'ikiwiki/login-selector/goa-account-yahoo.png',
|
||||||
|
url: 'http://me.yahoo.com/'
|
||||||
|
},
|
||||||
|
flickr: {
|
||||||
|
name: 'Flickr',
|
||||||
|
icon: 'ikiwiki/login-selector/goa-account-flickr.png',
|
||||||
|
label: 'Enter your Flickr username:',
|
||||||
|
url: 'http://flickr.com/photos/{username}/'
|
||||||
|
},
|
||||||
|
wordpress: {
|
||||||
|
name: 'Wordpress',
|
||||||
|
icon: 'ikiwiki/login-selector/wordpress.png',
|
||||||
|
label: 'Enter your Wordpress.com username:',
|
||||||
|
url: 'http://{username}.wordpress.com/'
|
||||||
|
},
|
||||||
|
aol: {
|
||||||
|
name: 'AOL',
|
||||||
|
icon: 'ikiwiki/login-selector/aol.png',
|
||||||
|
label: 'Enter your AOL username:',
|
||||||
|
url: 'http://openid.aol.com/{username}'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
var selections = $.extend({}, selections_email_large, selections_openid_large, selections_openid_small);
|
||||||
|
|
||||||
|
var selector = {
|
||||||
|
|
||||||
|
ajaxHandler: null,
|
||||||
|
cookie_expires: 6*30, // 6 months.
|
||||||
|
cookie_name: 'openid_selection', // historical name
|
||||||
|
cookie_path: '/',
|
||||||
|
|
||||||
|
img_path: 'images/',
|
||||||
|
|
||||||
|
input_id: null,
|
||||||
|
selection_url: null,
|
||||||
|
selection_id: null,
|
||||||
|
othersignin_id: null,
|
||||||
|
|
||||||
|
init: function(input_id, login_methods, othersignin_id, othersignin_label) {
|
||||||
|
|
||||||
|
var selector_btns = $('#login_btns');
|
||||||
|
|
||||||
|
this.input_id = input_id;
|
||||||
|
|
||||||
|
$('#login_choice').show();
|
||||||
|
$('#login_input_area').empty();
|
||||||
|
|
||||||
|
// add box for each selection
|
||||||
|
if (login_methods['openid']) {
|
||||||
|
for (id in selections_openid_large) {
|
||||||
|
selector_btns.append(this.getBoxHTML(selections_openid_large[id], 'large'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (login_methods['email']) {
|
||||||
|
for (id in selections_email_large) {
|
||||||
|
selector_btns.prepend(this.getBoxHTML(selections_email_large[id], 'large'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (othersignin_label != "") {
|
||||||
|
this.othersignin_label=othersignin_label;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.othersignin_label="other";
|
||||||
|
}
|
||||||
|
if (othersignin_id != "") {
|
||||||
|
this.othersignin_id=othersignin_id;
|
||||||
|
selector_btns.prepend(
|
||||||
|
'<a href="javascript: selector.signin(\'othersignin\');"' +
|
||||||
|
' style="background: #FFF" ' +
|
||||||
|
'class="othersignin login_large_btn">' +
|
||||||
|
'<img alt="" width="16" height="16" src="favicon.ico" />' +
|
||||||
|
' ' + this.othersignin_label +
|
||||||
|
'</a>'
|
||||||
|
);
|
||||||
|
$('#'+this.othersignin_id).hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (login_methods['openid'] && selections_openid_small) {
|
||||||
|
selector_btns.append('<br/>');
|
||||||
|
|
||||||
|
for (id in selections_openid_small) {
|
||||||
|
selector_btns.append(this.getBoxHTML(selections_openid_small[id], 'small'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$('#login_selector_form').submit(this.submit);
|
||||||
|
|
||||||
|
var box_id = this.readCookie();
|
||||||
|
if (box_id) {
|
||||||
|
this.signin(box_id, true);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
getBoxHTML: function(selection, box_size) {
|
||||||
|
var label="";
|
||||||
|
var title=""
|
||||||
|
if (box_size == 'large') {
|
||||||
|
label=' ' + selection["name"];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
title=' title="'+selection["name"]+'"';
|
||||||
|
}
|
||||||
|
var box_id = selection["name"].toLowerCase();
|
||||||
|
return '<a' + title +' href="javascript: selector.signin(\''+ box_id +'\');"' +
|
||||||
|
' style="background: #FFF" ' +
|
||||||
|
'class="' + box_id + ' login_' + box_size + '_btn">' +
|
||||||
|
'<img alt="" width="16" height="16" src="' + selection["icon"] + '" />' +
|
||||||
|
label +
|
||||||
|
'</a>';
|
||||||
|
|
||||||
|
},
|
||||||
|
/* selection image click */
|
||||||
|
signin: function(box_id, onload) {
|
||||||
|
|
||||||
|
if (box_id == 'othersignin') {
|
||||||
|
this.highlight(box_id);
|
||||||
|
$('#login_input_area').empty();
|
||||||
|
$('#'+this.othersignin_id).show();
|
||||||
|
this.setCookie(box_id);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (this.othersignin_id) {
|
||||||
|
$('#'+this.othersignin_id).hide();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var selection = selections[box_id];
|
||||||
|
if (! selection) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.highlight(box_id);
|
||||||
|
|
||||||
|
this.selection_id = box_id;
|
||||||
|
this.selection_url = selection['url'];
|
||||||
|
|
||||||
|
// prompt user for input?
|
||||||
|
if (selection['label']) {
|
||||||
|
this.setCookie(box_id);
|
||||||
|
this.useInputBox(selection);
|
||||||
|
} else {
|
||||||
|
this.setCookie('');
|
||||||
|
$('#login_input_area').empty();
|
||||||
|
if (! onload) {
|
||||||
|
$('#login_selector_form').submit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
/* Sign-in button click */
|
||||||
|
submit: function() {
|
||||||
|
var url = selector.selection_url;
|
||||||
|
if (url) {
|
||||||
|
url = url.replace('{username}', $('#entry').val());
|
||||||
|
selector.setOpenIdUrl(url);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
selector.setOpenIdUrl("");
|
||||||
|
}
|
||||||
|
if (selector.ajaxHandler) {
|
||||||
|
selector.ajaxHandler(selector.selection_id, document.getElementById(selector.input_id).value);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
setOpenIdUrl: function (url) {
|
||||||
|
|
||||||
|
var hidden = $('#'+this.input_id);
|
||||||
|
if (hidden.length > 0) {
|
||||||
|
hidden.value = url;
|
||||||
|
} else {
|
||||||
|
$('#login_selector_form').append('<input style="display:none" id="' + this.input_id + '" name="' + this.input_id + '" value="'+url+'"/>');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
highlight: function (box_id) {
|
||||||
|
|
||||||
|
// remove previous highlight.
|
||||||
|
var highlight = $('#login_highlight');
|
||||||
|
if (highlight) {
|
||||||
|
highlight.replaceWith($('#login_highlight a')[0]);
|
||||||
|
}
|
||||||
|
// add new highlight.
|
||||||
|
$('.'+box_id).wrap('<div id="login_highlight"></div>');
|
||||||
|
},
|
||||||
|
setCookie: function (value) {
|
||||||
|
|
||||||
|
var date = new Date();
|
||||||
|
date.setTime(date.getTime()+(this.cookie_expires*24*60*60*1000));
|
||||||
|
var expires = "; expires="+date.toGMTString();
|
||||||
|
|
||||||
|
document.cookie = this.cookie_name+"="+value+expires+"; path=" + this.cookie_path;
|
||||||
|
},
|
||||||
|
readCookie: function () {
|
||||||
|
var nameEQ = this.cookie_name + "=";
|
||||||
|
var ca = document.cookie.split(';');
|
||||||
|
for(var i=0;i < ca.length;i++) {
|
||||||
|
var c = ca[i];
|
||||||
|
while (c.charAt(0)==' ') c = c.substring(1,c.length);
|
||||||
|
if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
useInputBox: function (selection) {
|
||||||
|
|
||||||
|
var input_area = $('#login_input_area');
|
||||||
|
|
||||||
|
var html = '';
|
||||||
|
var id = selection['name']+'_entry';
|
||||||
|
var value = '';
|
||||||
|
var label = selection['label'];
|
||||||
|
var style = '';
|
||||||
|
|
||||||
|
if (selection['name'] == 'OpenID') {
|
||||||
|
id = this.input_id;
|
||||||
|
value = '';
|
||||||
|
style = 'background:#FFF url(wikiicons/openidlogin-bg.gif) no-repeat scroll 0 50%; padding-left:18px;';
|
||||||
|
}
|
||||||
|
if (label) {
|
||||||
|
html = '<label for="'+ id +'" class="block">' + label + '</label>';
|
||||||
|
}
|
||||||
|
html += '<input id="'+id+'" type="text" style="'+style+'" name="'+id+'" value="'+value+'" />' +
|
||||||
|
'<input id="selector_submit" type="submit" value="Login"/>';
|
||||||
|
|
||||||
|
input_area.empty();
|
||||||
|
input_area.append(html);
|
||||||
|
|
||||||
|
$('#'+id).focus();
|
||||||
|
},
|
||||||
|
setAjaxHandler: function (ajaxFunction) {
|
||||||
|
this.ajaxHandler = ajaxFunction;
|
||||||
|
}
|
||||||
|
};
|
Before Width: | Height: | Size: 714 B After Width: | Height: | Size: 714 B |
After Width: | Height: | Size: 886 B |
|
@ -1,237 +0,0 @@
|
||||||
/*
|
|
||||||
Simple OpenID Plugin
|
|
||||||
http://code.google.com/p/openid-selector/
|
|
||||||
|
|
||||||
This code is licenced under the New BSD License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
var providers_large = {
|
|
||||||
verisign: {
|
|
||||||
name: 'Verisign',
|
|
||||||
icon: 'ikiwiki/openid/verisign.png',
|
|
||||||
label: 'Enter your Verisign username:',
|
|
||||||
url: 'http://{username}.pip.verisignlabs.com/'
|
|
||||||
},
|
|
||||||
yahoo: {
|
|
||||||
name: 'Yahoo',
|
|
||||||
icon: 'ikiwiki/openid/goa-account-yahoo.png',
|
|
||||||
url: 'http://me.yahoo.com/'
|
|
||||||
},
|
|
||||||
openid: {
|
|
||||||
name: 'OpenID',
|
|
||||||
icon: 'wikiicons/openidlogin-bg.gif',
|
|
||||||
label: 'Enter your OpenID:',
|
|
||||||
url: null
|
|
||||||
}
|
|
||||||
};
|
|
||||||
var providers_small = {
|
|
||||||
};
|
|
||||||
var providers = $.extend({}, providers_large, providers_small);
|
|
||||||
|
|
||||||
var openid = {
|
|
||||||
|
|
||||||
demo: false,
|
|
||||||
ajaxHandler: null,
|
|
||||||
cookie_expires: 6*30, // 6 months.
|
|
||||||
cookie_name: 'openid_provider',
|
|
||||||
cookie_path: '/',
|
|
||||||
|
|
||||||
img_path: 'images/',
|
|
||||||
|
|
||||||
input_id: null,
|
|
||||||
provider_url: null,
|
|
||||||
provider_id: null,
|
|
||||||
localsignin_id: null,
|
|
||||||
|
|
||||||
init: function(input_id, localsignin_id, localsignin_label) {
|
|
||||||
|
|
||||||
var openid_btns = $('#openid_btns');
|
|
||||||
|
|
||||||
this.input_id = input_id;
|
|
||||||
|
|
||||||
$('#openid_choice').show();
|
|
||||||
$('#openid_input_area').empty();
|
|
||||||
|
|
||||||
// add box for each provider
|
|
||||||
for (id in providers_large) {
|
|
||||||
openid_btns.append(this.getBoxHTML(providers_large[id], 'large'));
|
|
||||||
}
|
|
||||||
if (localsignin_label != "") {
|
|
||||||
this.localsignin_label=localsignin_label;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
this.localsignin_label="other";
|
|
||||||
}
|
|
||||||
if (localsignin_id != "") {
|
|
||||||
this.localsignin_id=localsignin_id;
|
|
||||||
openid_btns.append(
|
|
||||||
'<a href="javascript: openid.signin(\'localsignin\');"' +
|
|
||||||
' style="background: #FFF" ' +
|
|
||||||
'class="localsignin openid_large_btn">' +
|
|
||||||
'<img alt="" width="16" height="16" src="favicon.ico" />' +
|
|
||||||
' ' + this.localsignin_label +
|
|
||||||
'</a>'
|
|
||||||
);
|
|
||||||
$('#'+this.localsignin_id).hide();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (providers_small) {
|
|
||||||
openid_btns.append('<br/>');
|
|
||||||
|
|
||||||
for (id in providers_small) {
|
|
||||||
|
|
||||||
openid_btns.append(this.getBoxHTML(providers_small[id], 'small'));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$('#openid_form').submit(this.submit);
|
|
||||||
|
|
||||||
var box_id = this.readCookie();
|
|
||||||
if (box_id) {
|
|
||||||
this.signin(box_id, true);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
getBoxHTML: function(provider, box_size) {
|
|
||||||
var label="";
|
|
||||||
var title=""
|
|
||||||
if (box_size == 'large') {
|
|
||||||
label=' ' + provider["name"];
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
title=' title="'+provider["name"]+'"';
|
|
||||||
}
|
|
||||||
var box_id = provider["name"].toLowerCase();
|
|
||||||
return '<a' + title +' href="javascript: openid.signin(\''+ box_id +'\');"' +
|
|
||||||
' style="background: #FFF" ' +
|
|
||||||
'class="' + box_id + ' openid_' + box_size + '_btn">' +
|
|
||||||
'<img alt="" width="16" height="16" src="' + provider["icon"] + '" />' +
|
|
||||||
label +
|
|
||||||
'</a>';
|
|
||||||
|
|
||||||
},
|
|
||||||
/* Provider image click */
|
|
||||||
signin: function(box_id, onload) {
|
|
||||||
|
|
||||||
if (box_id == 'localsignin') {
|
|
||||||
this.highlight(box_id);
|
|
||||||
$('#openid_input_area').empty();
|
|
||||||
$('#'+this.localsignin_id).show();
|
|
||||||
this.setCookie(box_id);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (this.localsignin_id) {
|
|
||||||
$('#'+this.localsignin_id).hide();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var provider = providers[box_id];
|
|
||||||
if (! provider) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.highlight(box_id);
|
|
||||||
|
|
||||||
this.provider_id = box_id;
|
|
||||||
this.provider_url = provider['url'];
|
|
||||||
|
|
||||||
// prompt user for input?
|
|
||||||
if (provider['label']) {
|
|
||||||
this.setCookie(box_id);
|
|
||||||
this.useInputBox(provider);
|
|
||||||
} else {
|
|
||||||
this.setCookie('');
|
|
||||||
$('#openid_input_area').empty();
|
|
||||||
if (! onload) {
|
|
||||||
$('#openid_form').submit();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
/* Sign-in button click */
|
|
||||||
submit: function() {
|
|
||||||
|
|
||||||
var url = openid.provider_url;
|
|
||||||
if (url) {
|
|
||||||
url = url.replace('{username}', $('#openid_username').val());
|
|
||||||
openid.setOpenIdUrl(url);
|
|
||||||
}
|
|
||||||
if(openid.ajaxHandler) {
|
|
||||||
openid.ajaxHandler(openid.provider_id, document.getElementById(openid.input_id).value);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if(openid.demo) {
|
|
||||||
alert("In client demo mode. Normally would have submitted OpenID:\r\n" + document.getElementById(openid.input_id).value);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
},
|
|
||||||
setOpenIdUrl: function (url) {
|
|
||||||
|
|
||||||
var hidden = $('#'+this.input_id);
|
|
||||||
if (hidden.length > 0) {
|
|
||||||
hidden.value = url;
|
|
||||||
} else {
|
|
||||||
$('#openid_form').append('<input style="display:none" id="' + this.input_id + '" name="' + this.input_id + '" value="'+url+'"/>');
|
|
||||||
}
|
|
||||||
},
|
|
||||||
highlight: function (box_id) {
|
|
||||||
|
|
||||||
// remove previous highlight.
|
|
||||||
var highlight = $('#openid_highlight');
|
|
||||||
if (highlight) {
|
|
||||||
highlight.replaceWith($('#openid_highlight a')[0]);
|
|
||||||
}
|
|
||||||
// add new highlight.
|
|
||||||
$('.'+box_id).wrap('<div id="openid_highlight"></div>');
|
|
||||||
},
|
|
||||||
setCookie: function (value) {
|
|
||||||
|
|
||||||
var date = new Date();
|
|
||||||
date.setTime(date.getTime()+(this.cookie_expires*24*60*60*1000));
|
|
||||||
var expires = "; expires="+date.toGMTString();
|
|
||||||
|
|
||||||
document.cookie = this.cookie_name+"="+value+expires+"; path=" + this.cookie_path;
|
|
||||||
},
|
|
||||||
readCookie: function () {
|
|
||||||
var nameEQ = this.cookie_name + "=";
|
|
||||||
var ca = document.cookie.split(';');
|
|
||||||
for(var i=0;i < ca.length;i++) {
|
|
||||||
var c = ca[i];
|
|
||||||
while (c.charAt(0)==' ') c = c.substring(1,c.length);
|
|
||||||
if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
},
|
|
||||||
useInputBox: function (provider) {
|
|
||||||
|
|
||||||
var input_area = $('#openid_input_area');
|
|
||||||
|
|
||||||
var html = '';
|
|
||||||
var id = 'openid_username';
|
|
||||||
var value = '';
|
|
||||||
var label = provider['label'];
|
|
||||||
var style = '';
|
|
||||||
|
|
||||||
if (provider['name'] == 'OpenID') {
|
|
||||||
id = this.input_id;
|
|
||||||
value = '';
|
|
||||||
style = 'background:#FFF url(wikiicons/openidlogin-bg.gif) no-repeat scroll 0 50%; padding-left:18px;';
|
|
||||||
}
|
|
||||||
if (label) {
|
|
||||||
html = '<label for="'+ id +'" class="block">' + label + '</label>';
|
|
||||||
}
|
|
||||||
html += '<input id="'+id+'" type="text" style="'+style+'" name="'+id+'" value="'+value+'" />' +
|
|
||||||
'<input id="openid_submit" type="submit" value="Login"/>';
|
|
||||||
|
|
||||||
input_area.empty();
|
|
||||||
input_area.append(html);
|
|
||||||
|
|
||||||
$('#'+id).focus();
|
|
||||||
},
|
|
||||||
setDemoMode: function (demoMode) {
|
|
||||||
this.demo = demoMode;
|
|
||||||
},
|
|
||||||
setAjaxHandler: function (ajaxFunction) {
|
|
||||||
this.ajaxHandler = ajaxFunction;
|
|
||||||
}
|
|
||||||
};
|
|