2 package IkiWiki::Plugin::loginselector;
8 # Plugins that provide login methods can register themselves here.
9 # Note that the template and js file also have be be modifed to add a new
13 sub register_login_plugin ($$$$) {
14 # Same as the name of the plugin that is registering itself as a
15 # login plugin. eg, "openid"
16 my $plugin_name=shift;
17 # This sub is passed a cgi object and a template object which it
18 # can manipulate. It should return true if the plugin can be used
19 # (it might load necessary modules for auth checking, for example).
20 my $plugin_setup=shift;
21 # This sub is passed a cgi object, and should return true
22 # if it looks like the user is logging in using the plugin.
23 my $plugin_check_input=shift;
24 # This sub is passed a cgi object, a session object, and an error
25 # display callback, and should handle the actual authentication.
26 # It can either exit w/o returning, if it is able to handle
27 # auth, or it can pass an error message to the error display
28 # callback to make the openid selector form be re-disiplayed with
29 # an error message on it.
30 my $plugin_auth=shift;
31 $login_plugins{$plugin_name}={
32 setup => $plugin_setup,
33 check_input => $plugin_check_input,
39 my $real_cgi_signin=shift;
40 my $otherform_label=shift;
44 my $template=IkiWiki::template("login-selector.tmpl");
46 foreach my $plugin (keys %login_plugins) {
47 if (! $login_plugins{$plugin}->{setup}->($template)) {
48 delete $login_plugins{$plugin};
51 $template->param("login_selector_$plugin", 1);
55 foreach my $plugin (keys %login_plugins) {
56 if ($login_plugins{$plugin}->{check_input}->($q)) {
57 $login_plugins{$plugin}->{auth}->($q, $session, sub {
58 $template->param(login_error => shift());
65 cgiurl => IkiWiki::cgiurl(),
66 ($real_cgi_signin ? (otherform => $real_cgi_signin->($q, $session, 1)) : ()),
67 otherform_label => $otherform_label,
70 IkiWiki::printheader($session);
71 print IkiWiki::cgitemplate($q, "signin", $template->output);
76 add_underlay("login-selector");
77 add_underlay("jquery");
78 hook(type => "getsetup", id => "loginselector", call => \&getsetup);
79 hook(type => "checkconfig", id => "loginselector", call => \&checkconfig);
84 # Intercept normal signin form, so the login selector
87 # When other auth hooks are registered, give the selector
88 # a reference to the normal signin form.
91 my $otherform_label=gettext("Other");
92 if (keys %{$IkiWiki::hooks{auth}} > 1) {
93 $real_cgi_signin=\&IkiWiki::cgi_signin;
94 my %h=%{$IkiWiki::hooks{auth}};
95 foreach my $p (keys %login_plugins) {
98 # Special case to avoid labeling password auth as
99 # "Other" when it's the only auth plugin not
100 # integrated with the loginselector.
101 if (keys %h == 1 && exists $h{passwordauth}) {
102 $otherform_label=gettext("Password");
105 inject(name => "IkiWiki::cgi_signin", call => sub ($$) {
106 login_selector($real_cgi_signin, $otherform_label, @_);
114 # this plugin is safe but only makes sense as a