aboutsummaryrefslogtreecommitdiff
path: root/IkiWiki
diff options
context:
space:
mode:
authorJoey Hess <joeyh@joeyh.name>2015-05-13 18:37:24 -0400
committerJoey Hess <joeyh@joeyh.name>2015-05-13 18:50:29 -0400
commit5b459737a50d83ff94490d86d1b9a4438d4b50a1 (patch)
treebbef22e5ca5f1288f226c2044cbfb46565e4bcb6 /IkiWiki
parentf8add0adb327a6514bbfc1773e1fc9577c98fa32 (diff)
downloadikiwiki-5b459737a50d83ff94490d86d1b9a4438d4b50a1.tar
ikiwiki-5b459737a50d83ff94490d86d1b9a4438d4b50a1.tar.gz
Converted openid-selector into a more generic loginselector helper plugin.
Diffstat (limited to 'IkiWiki')
-rw-r--r--IkiWiki/Plugin/loginselector.pm121
-rw-r--r--IkiWiki/Plugin/openid.pm85
2 files changed, 150 insertions, 56 deletions
diff --git a/IkiWiki/Plugin/loginselector.pm b/IkiWiki/Plugin/loginselector.pm
new file mode 100644
index 000000000..b5e2056a4
--- /dev/null
+++ b/IkiWiki/Plugin/loginselector.pm
@@ -0,0 +1,121 @@
+#!/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, and an error
+ # 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());
+ });
+ 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);
+}
+
+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;
+ my %h=%{$IkiWiki::hooks{auth}};
+ foreach my $p (keys %login_plugins) {
+ delete $h{$p};
+ }
+ # Special case to avoid labeling password auth as
+ # "Other" when it's the only auth plugin not
+ # integrated with the 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,
+ },
+}
+
+1
diff --git a/IkiWiki/Plugin/openid.pm b/IkiWiki/Plugin/openid.pm
index a12c83b8c..67b8cd387 100644
--- a/IkiWiki/Plugin/openid.pm
+++ b/IkiWiki/Plugin/openid.pm
@@ -7,38 +7,17 @@ use strict;
use IkiWiki 3.00;
sub import {
- add_underlay("login-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 $otherform_label=gettext("Other");
- if (keys %{$IkiWiki::hooks{auth}} > 1) {
- $real_cgi_signin=\&IkiWiki::cgi_signin;
- my %h=%{$IkiWiki::hooks{auth}};
- delete $h{openid};
- delete $h{emailauth};
- if (keys %h == 1 && exists $h{passwordauth}) {
- $otherform_label=gettext("Password");
- }
- }
- inject(name => "IkiWiki::cgi_signin", call => sub ($$) {
- openid_selector($real_cgi_signin, $otherform_label, @_);
- });
- }
+ IkiWiki::loadplugin("loginselector");
+ IkiWiki::Plugin::loginselector::register_login_plugin(
+ "openid",
+ \&openid_setup,
+ \&openid_check_input,
+ \&openid_auth,
+ );
}
sub getsetup () {
@@ -62,40 +41,34 @@ sub getsetup () {
},
}
-sub openid_selector {
- my $real_cgi_signin=shift;
- my $otherform_label=shift;
- my $q=shift;
- my $session=shift;
-
- my $template=IkiWiki::template("login-selector.tmpl");
- my $openid_url=$q->param('openid_identifier');
+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" && defined $openid_url && length $openid_url) {
- validate($q, $session, $openid_url, sub {
- $template->param(login_error => shift())
- });
+ else {
+ return 0;
}
+}
- $template->param(
- cgiurl => IkiWiki::cgiurl(),
- (defined $openid_url ? (openid_url => $openid_url) : ()),
- ($real_cgi_signin ? (otherform => $real_cgi_signin->($q, $session, 1)) : ()),
- otherform_label => $otherform_label,
- login_selector_openid => 1,
- login_selector_email => 1,
- );
+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 (@) {