133 lines
3.7 KiB
Perl
133 lines
3.7 KiB
Perl
#!/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
|