diff options
author | Joey Hess <joeyh@joeyh.name> | 2015-05-13 18:37:24 -0400 |
---|---|---|
committer | Joey Hess <joeyh@joeyh.name> | 2015-05-13 18:50:29 -0400 |
commit | 5b459737a50d83ff94490d86d1b9a4438d4b50a1 (patch) | |
tree | bbef22e5ca5f1288f226c2044cbfb46565e4bcb6 /IkiWiki | |
parent | f8add0adb327a6514bbfc1773e1fc9577c98fa32 (diff) | |
download | ikiwiki-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.pm | 121 | ||||
-rw-r--r-- | IkiWiki/Plugin/openid.pm | 85 |
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 (@) { |