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);
80 hook(type => "auth", id => "loginselector", call => \&authstub);
85 # Intercept normal signin form, so the login selector
88 # When other auth hooks are registered, give the selector
89 # a reference to the normal signin form.
92 my $otherform_label=gettext("Other");
93 if (keys %{$IkiWiki::hooks{auth}} > 1) {
94 $real_cgi_signin=\&IkiWiki::cgi_signin;
95 # Special case to avoid labeling password auth as
96 # "Other" when it's the only auth plugin not
97 # integrated with the loginselector.
98 my %h=%{$IkiWiki::hooks{auth}};
99 foreach my $p (keys %login_plugins) {
102 delete $h{loginselector};
103 if (keys %h == 1 && exists $h{passwordauth}) {
104 $otherform_label=gettext("Password");
107 inject(name => "IkiWiki::cgi_signin", call => sub ($$) {
108 login_selector($real_cgi_signin, $otherform_label, @_);
116 # this plugin is safe but only makes sense as a
124 # While this hook is not currently used, it needs to exist
125 # so ikiwiki knows that the wiki supports logins, and will
126 # enable the Preferences page.