aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoey Hess <joeyh@joeyh.name>2015-05-13 23:38:56 -0400
committerJoey Hess <joeyh@joeyh.name>2015-05-13 23:38:56 -0400
commitcfb2c22906f41d4a4dd1c3404e8e430a35c1cd41 (patch)
treeb2f0271a5fa334530b3ac3051ad42bc02172a708
parentee2905ae0a2786fd5f195fdc1779a34b5f62c1d9 (diff)
parentbf8b7fe2d1602827f7419521d140bac4be6200a8 (diff)
downloadikiwiki-cfb2c22906f41d4a4dd1c3404e8e430a35c1cd41.tar
ikiwiki-cfb2c22906f41d4a4dd1c3404e8e430a35c1cd41.tar.gz
Merge branch 'emailauth'
-rw-r--r--IkiWiki.pm10
-rw-r--r--IkiWiki/Plugin/comments.pm6
-rw-r--r--IkiWiki/Plugin/emailauth.pm193
-rw-r--r--IkiWiki/Plugin/loginselector.pm132
-rw-r--r--IkiWiki/Plugin/openid.pm82
-rw-r--r--IkiWiki/Plugin/passwordauth.pm2
-rw-r--r--IkiWiki/Setup/Automator.pm50
-rw-r--r--auto.setup2
-rw-r--r--debian/changelog10
-rw-r--r--debian/copyright11
-rw-r--r--doc/basewiki.mdwn2
-rw-r--r--doc/plugins/emailauth.pm17
-rw-r--r--doc/plugins/write.mdwn3
-rw-r--r--doc/style.css20
-rw-r--r--doc/templates.mdwn5
-rw-r--r--doc/wikiicons/emaillogin.pngbin0 -> 685 bytes
-rw-r--r--templates/emailauth.tmpl10
-rw-r--r--templates/login-selector.tmpl65
-rw-r--r--templates/openid-selector.tmpl43
-rw-r--r--underlays/login-selector/ikiwiki/login-selector/aol.pngbin0 -> 460 bytes
-rw-r--r--underlays/login-selector/ikiwiki/login-selector/goa-account-flickr.pngbin0 -> 592 bytes
-rw-r--r--underlays/login-selector/ikiwiki/login-selector/goa-account-yahoo.png (renamed from underlays/openid-selector/ikiwiki/openid/goa-account-yahoo.png)bin741 -> 741 bytes
-rw-r--r--underlays/login-selector/ikiwiki/login-selector/login-selector.js264
-rw-r--r--underlays/login-selector/ikiwiki/login-selector/verisign.png (renamed from underlays/openid-selector/ikiwiki/openid/verisign.png)bin714 -> 714 bytes
-rw-r--r--underlays/login-selector/ikiwiki/login-selector/wordpress.pngbin0 -> 886 bytes
-rw-r--r--underlays/openid-selector/ikiwiki/openid/openid-jquery.js237
26 files changed, 781 insertions, 383 deletions
diff --git a/IkiWiki.pm b/IkiWiki.pm
index f414996db..53eb8235b 100644
--- a/IkiWiki.pm
+++ b/IkiWiki.pm
@@ -165,7 +165,7 @@ sub getsetup () {
default_plugins => {
type => "internal",
default => [qw{mdwn link inline meta htmlscrubber passwordauth
- openid signinedit lockedit conditional
+ openid emailauth signinedit lockedit conditional
recentchanges parentlinks editpage
templatebody}],
description => "plugins to enable by default",
@@ -1464,6 +1464,14 @@ sub openiduser ($) {
return;
}
+sub emailuser ($) {
+ my $user=shift;
+ if (defined $user && $user =~ m/(.+)@/) {
+ return $1;
+ }
+ return;
+}
+
sub htmlize ($$$$) {
my $page=shift;
my $destpage=shift;
diff --git a/IkiWiki/Plugin/comments.pm b/IkiWiki/Plugin/comments.pm
index fb423e713..eaa924e51 100644
--- a/IkiWiki/Plugin/comments.pm
+++ b/IkiWiki/Plugin/comments.pm
@@ -198,7 +198,6 @@ sub preprocess {
$commentuser = $params{username};
my $oiduser = eval { IkiWiki::openiduser($commentuser) };
-
if (defined $oiduser) {
# looks like an OpenID
$commentauthorurl = $commentuser;
@@ -206,6 +205,11 @@ sub preprocess {
$commentopenid = $commentuser;
}
else {
+ my $emailuser = IkiWiki::emailuser($commentuser);
+ if (defined $emailuser) {
+ $commentuser=$emailuser;
+ }
+
if (length $config{cgiurl}) {
$commentauthorurl = IkiWiki::cgiurl(
do => 'goto',
diff --git a/IkiWiki/Plugin/emailauth.pm b/IkiWiki/Plugin/emailauth.pm
new file mode 100644
index 000000000..aa067238f
--- /dev/null
+++ b/IkiWiki/Plugin/emailauth.pm
@@ -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
diff --git a/IkiWiki/Plugin/loginselector.pm b/IkiWiki/Plugin/loginselector.pm
new file mode 100644
index 000000000..26c80b4ce
--- /dev/null
+++ b/IkiWiki/Plugin/loginselector.pm
@@ -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
diff --git a/IkiWiki/Plugin/openid.pm b/IkiWiki/Plugin/openid.pm
index 00652ebb7..cc4b4ba3d 100644
--- a/IkiWiki/Plugin/openid.pm
+++ b/IkiWiki/Plugin/openid.pm
@@ -7,35 +7,17 @@ use strict;
use IkiWiki 3.00;
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 => "auth", id => "openid", call => \&auth);
hook(type => "formbuilder_setup", id => "openid",
call => \&formbuilder_setup, last => 1);
-}
-
-sub checkconfig () {
- if ($config{cgi}) {
- # Intercept normal signin form, so the openid 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 $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, @_);
- });
- }
+ IkiWiki::loadplugin("loginselector");
+ IkiWiki::Plugin::loginselector::register_login_plugin(
+ "openid",
+ \&openid_setup,
+ \&openid_check_input,
+ \&openid_auth,
+ );
}
sub getsetup () {
@@ -59,40 +41,34 @@ sub getsetup () {
},
}
-sub openid_selector {
- my $real_cgi_signin=shift;
- my $nonopenidform_label=shift;
- my $q=shift;
- my $session=shift;
-
- my $openid_url=$q->param('openid_identifier');
- my $openid_error;
+sub openid_setup ($$) {
+ my $q=shift;
+ my $template=shift;
- if (! load_openid_module()) {
- if ($real_cgi_signin) {
- $real_cgi_signin->($q, $session);
- exit;
+ if (load_openid_module()) {
+ my $openid_url=$q->param('openid_identifier');
+ if (defined $openid_url) {
+ $template->param(openid_url => $openid_url);
}
- error(sprintf(gettext("failed to load openid module: "), @_));
+ return 1;
}
- elsif (defined $q->param("action") && $q->param("action") eq "verify") {
- validate($q, $session, $openid_url, sub {
- $openid_error=shift;
- });
+ else {
+ return 0;
}
+}
- my $template=IkiWiki::template("openid-selector.tmpl");
- $template->param(
- cgiurl => IkiWiki::cgiurl(),
- (defined $openid_error ? (openid_error => $openid_error) : ()),
- (defined $openid_url ? (openid_url => $openid_url) : ()),
- ($real_cgi_signin ? (nonopenidform => $real_cgi_signin->($q, $session, 1)) : ()),
- nonopenidform_label => $nonopenidform_label,
- );
+sub openid_check_input ($) {
+ my $q=shift;
+ my $openid_url=$q->param('openid_identifier');
+ defined $q->param("action") && $q->param("action") eq "verify" && defined $openid_url && length $openid_url;
+}
- IkiWiki::printheader($session);
- print IkiWiki::cgitemplate($q, "signin", $template->output);
- exit;
+sub openid_auth ($$$$) {
+ my $q=shift;
+ my $session=shift;
+ my $errordisplayer=shift;
+ my $openid_url=$q->param('openid_identifier');
+ validate($q, $session, $openid_url, $errordisplayer);
}
sub formbuilder_setup (@) {
diff --git a/IkiWiki/Plugin/passwordauth.pm b/IkiWiki/Plugin/passwordauth.pm
index 0cf2a26ea..7c01bb3ff 100644
--- a/IkiWiki/Plugin/passwordauth.pm
+++ b/IkiWiki/Plugin/passwordauth.pm
@@ -277,7 +277,7 @@ sub formbuilder_setup (@) {
}
elsif ($form->title eq "preferences") {
my $user=$session->param("name");
- if (! IkiWiki::openiduser($user)) {
+ if (! IkiWiki::openiduser($user) && ! IkiWiki::emailuser($user)) {
$form->field(name => "name", disabled => 1,
value => $user, force => 1,
fieldset => "login");
diff --git a/IkiWiki/Setup/Automator.pm b/IkiWiki/Setup/Automator.pm
index a8b04d966..9239974ad 100644
--- a/IkiWiki/Setup/Automator.pm
+++ b/IkiWiki/Setup/Automator.pm
@@ -154,31 +154,33 @@ sub import (@) {
foreach my $admin (@{$config{adminuser}}) {
next if defined IkiWiki::openiduser($admin);
- # Prompt for password w/o echo.
- my ($password, $password2);
- system('stty -echo 2>/dev/null');
- local $|=1;
- print "\n\nCreating wiki admin $admin ...\n";
- for (;;) {
- print "Choose a password: ";
- chomp($password=<STDIN>);
- print "\n";
- 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');
+ if (! defined IkiWiki::emailuser($admin)) {
+ # Prompt for password w/o echo.
+ my ($password, $password2);
+ system('stty -echo 2>/dev/null');
+ local $|=1;
+ print "\n\nCreating wiki admin $admin ...\n";
+ for (;;) {
+ print "Choose a password: ";
+ chomp($password=<STDIN>);
+ print "\n";
+ 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');
- 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");
+ 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");
+ }
}
}
diff --git a/auto.setup b/auto.setup
index 843b4193a..1bcac36cb 100644
--- a/auto.setup
+++ b/auto.setup
@@ -18,7 +18,7 @@ our $wikiname_short=IkiWiki::Setup::Automator::sanitize_wikiname($wikiname);
our $rcs=IkiWiki::Setup::Automator::ask(
gettext("What revision control system to use?"), "git");
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};
our $domain=hostfqdn() || IkiWiki::Setup::Automator::ask(
gettext("What is the domain name of the web server?"), "");
diff --git a/debian/changelog b/debian/changelog
index 4d8b589cf..45801567f 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,10 +1,14 @@
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
gone for good.
- * When openid and passwordauth are the only enabled auth plugins,
- make the openid selector display "Password" instead of "Other",
- so users are more likely to click on it when they don't have an openid.
+ * Make the openid selector display "Password" instead of "Other"
+ when appropriate, so users are more likely to click on it when
+ 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
diff --git a/debian/copyright b/debian/copyright
index a73d1ccff..35fadf56b 100644
--- a/debian/copyright
+++ b/debian/copyright
@@ -201,20 +201,20 @@ Comment:
Republished with permission.
License: GPL-2+
-Files: underlays/openid-selector/ikiwiki/openid/*
+Files: underlays/openid-selector/ikiwiki/login-selector/*
Copyright: © 2008-2010 andyjm, david.j.boden
Comment:
From http://code.google.com/p/openid-selector/
License: BSD-2-clause
-Files: underlays/openid-selector/ikiwiki/openid/goa-*
+Files: underlays/openid-selector/ikiwiki/login-selector/goa-*
Copyright:
© 2011 Red Hat, Inc.
License: LGPL-2.1+
Comment:
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:
© 2003-2013 "the contributors"
License: GPL-2+
@@ -226,9 +226,8 @@ Files:
icons/aol.svg
icons/livejournal.svg
icons/verisign.svg
- underlays/openid-selector/ikiwiki/openid/aol.png
- underlays/openid-selector/ikiwiki/openid/livejournal.png
- underlays/openid-selector/ikiwiki/openid/verisign.png
+ underlays/openid-selector/ikiwiki/login-selector/aol.png
+ underlays/openid-selector/ikiwiki/login-selector/verisign.png
Copyright:
© 2014 Simon McVittie
License: other
diff --git a/doc/basewiki.mdwn b/doc/basewiki.mdwn
index 8392884eb..b4aa60c78 100644
--- a/doc/basewiki.mdwn
+++ b/doc/basewiki.mdwn
@@ -10,7 +10,7 @@ It currently includes these pages:
* [[templates]]
* [[ikiwiki/formatting]]
* [[ikiwiki/markdown]]
-* [[ikiwiki/openid]]
+* [[ikiwiki/login-selector]]
* [[ikiwiki/pagespec]]
* [[ikiwiki/directive]]
* [[ikiwiki/subpage]]
diff --git a/doc/plugins/emailauth.pm b/doc/plugins/emailauth.pm
new file mode 100644
index 000000000..8cb060e93
--- /dev/null
+++ b/doc/plugins/emailauth.pm
@@ -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.
diff --git a/doc/plugins/write.mdwn b/doc/plugins/write.mdwn
index c3f531b66..95f4a39df 100644
--- a/doc/plugins/write.mdwn
+++ b/doc/plugins/write.mdwn
@@ -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,
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>
hook(type => "sessioncgi", id => "foo", call => \&sessioncgi);
diff --git a/doc/style.css b/doc/style.css
index fe1eb903d..f0846c0d6 100644
--- a/doc/style.css
+++ b/doc/style.css
@@ -465,40 +465,40 @@ li.L8 { list-style: upper-alpha; }
display: none;
}
-/* openid selector */
-#openid_choice {
+/* login selector */
+#login_choice {
display: none;
}
-#openid_input_area {
+#login_input_area {
clear: both;
padding: 10px;
}
-#openid_btns, #openid_btns br {
+#login_btns, #login_btns br {
clear: both;
}
-#openid_highlight {
+#login_highlight {
background-color: black;
float: left;
}
-.openid_large_btn {
+.login_large_btn {
padding: 1em 1.5em;
border: 1px solid #DDD;
margin: 3px;
float: left;
}
-.openid_small_btn {
+.login_small_btn {
padding: 4px 4px;
border: 1px solid #DDD;
margin: 3px;
float: left;
}
-a.openid_large_btn:focus {
+a.login_large_btn:focus {
outline: none;
}
-a.openid_large_btn:focus {
+a.login_large_btn:focus {
outline-style: none;
}
-.openid_selected {
+.login_selected {
border: 4px solid #DDD;
}
diff --git a/doc/templates.mdwn b/doc/templates.mdwn
index 80372fcb7..c45316e44 100644
--- a/doc/templates.mdwn
+++ b/doc/templates.mdwn
@@ -92,8 +92,9 @@ Here is a full list of the template files used:
* `editpage.tmpl`, `editconflict.tmpl`, `editcreationconflict.tmpl`,
`editfailedsave.tmpl`, `editpagegone.tmpl`, `pocreatepage.tmpl`,
`editcomment.tmpl` `commentmoderation.tmpl`, `renamesummary.tmpl`,
- `passwordmail.tmpl`, `openid-selector.tmpl`, `revert.tmpl` - Parts of ikiwiki's user
- interface; do not normally need to be customised.
+ `passwordmail.tmpl`, `emailauth.tmpl, `login-selector.tmpl`,
+ `revert.tmpl` - Parts of ikiwiki's user interface; do not normally need
+ to be customised.
[[!meta robots="noindex, follow"]]
diff --git a/doc/wikiicons/emaillogin.png b/doc/wikiicons/emaillogin.png
new file mode 100644
index 000000000..1b16befd6
--- /dev/null
+++ b/doc/wikiicons/emaillogin.png
Binary files differ
diff --git a/templates/emailauth.tmpl b/templates/emailauth.tmpl
new file mode 100644
index 000000000..55614068d
--- /dev/null
+++ b/templates/emailauth.tmpl
@@ -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
diff --git a/templates/login-selector.tmpl b/templates/login-selector.tmpl
new file mode 100644
index 000000000..3e7045c63
--- /dev/null
+++ b/templates/login-selector.tmpl
@@ -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>
diff --git a/templates/openid-selector.tmpl b/templates/openid-selector.tmpl
deleted file mode 100644
index 95ba086fe..000000000
--- a/templates/openid-selector.tmpl
+++ /dev/null
@@ -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>
diff --git a/underlays/login-selector/ikiwiki/login-selector/aol.png b/underlays/login-selector/ikiwiki/login-selector/aol.png
new file mode 100644
index 000000000..d47f5fa54
--- /dev/null
+++ b/underlays/login-selector/ikiwiki/login-selector/aol.png
Binary files differ
diff --git a/underlays/login-selector/ikiwiki/login-selector/goa-account-flickr.png b/underlays/login-selector/ikiwiki/login-selector/goa-account-flickr.png
new file mode 100644
index 000000000..5321642f6
--- /dev/null
+++ b/underlays/login-selector/ikiwiki/login-selector/goa-account-flickr.png
Binary files differ
diff --git a/underlays/openid-selector/ikiwiki/openid/goa-account-yahoo.png b/underlays/login-selector/ikiwiki/login-selector/goa-account-yahoo.png
index 51e1c119b..51e1c119b 100644
--- a/underlays/openid-selector/ikiwiki/openid/goa-account-yahoo.png
+++ b/underlays/login-selector/ikiwiki/login-selector/goa-account-yahoo.png
Binary files differ
diff --git a/underlays/login-selector/ikiwiki/login-selector/login-selector.js b/underlays/login-selector/ikiwiki/login-selector/login-selector.js
new file mode 100644
index 000000000..71ae0466e
--- /dev/null
+++ b/underlays/login-selector/ikiwiki/login-selector/login-selector.js
@@ -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;
+ }
+};
diff --git a/underlays/openid-selector/ikiwiki/openid/verisign.png b/underlays/login-selector/ikiwiki/login-selector/verisign.png
index 5120812ed..5120812ed 100644
--- a/underlays/openid-selector/ikiwiki/openid/verisign.png
+++ b/underlays/login-selector/ikiwiki/login-selector/verisign.png
Binary files differ
diff --git a/underlays/login-selector/ikiwiki/login-selector/wordpress.png b/underlays/login-selector/ikiwiki/login-selector/wordpress.png
new file mode 100644
index 000000000..96e08bd99
--- /dev/null
+++ b/underlays/login-selector/ikiwiki/login-selector/wordpress.png
Binary files differ
diff --git a/underlays/openid-selector/ikiwiki/openid/openid-jquery.js b/underlays/openid-selector/ikiwiki/openid/openid-jquery.js
deleted file mode 100644
index 2c72f19fb..000000000
--- a/underlays/openid-selector/ikiwiki/openid/openid-jquery.js
+++ /dev/null
@@ -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;
- }
-};