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, an error
25 # display callback, and an info display callback, and should
26 # handle the actual authentication. It can either exit w/o
27 # returning, if it is able to handle auth, or it can pass an
28 # error message to the error display callback to make the
29 # openid selector form be re-disiplayed with an error message
31 my $plugin_auth=shift;
32 $login_plugins{$plugin_name}={
33 setup => $plugin_setup,
34 check_input => $plugin_check_input,
40 my $real_cgi_signin=shift;
41 my $otherform_label=shift;
45 my $template=IkiWiki::template("login-selector.tmpl");
47 foreach my $plugin (keys %login_plugins) {
48 if (! $login_plugins{$plugin}->{setup}->($template)) {
49 delete $login_plugins{$plugin};
52 $template->param("login_selector_$plugin", 1);
56 foreach my $plugin (keys %login_plugins) {
57 if ($login_plugins{$plugin}->{check_input}->($q)) {
58 $login_plugins{$plugin}->{auth}->($q, $session, sub {
59 $template->param(login_error => shift());
61 $template->param(login_info => shift());
68 cgiurl => IkiWiki::cgiurl(),
69 ($real_cgi_signin ? (otherform => $real_cgi_signin->($q, $session, 1)) : ()),
70 otherform_label => $otherform_label,
73 IkiWiki::printheader($session);
74 print IkiWiki::cgitemplate($q, "signin", $template->output);
79 add_underlay("login-selector");
80 add_underlay("jquery");
81 hook(type => "getsetup", id => "loginselector", call => \&getsetup);
82 hook(type => "checkconfig", id => "loginselector", call => \&checkconfig);
83 hook(type => "auth", id => "loginselector", call => \&authstub);
88 # Intercept normal signin form, so the login selector
91 # When other auth hooks are registered, give the selector
92 # a reference to the normal signin form.
95 my $otherform_label=gettext("Other");
96 if (keys %{$IkiWiki::hooks{auth}} > 1) {
97 # Special case to avoid labeling password auth as
98 # "Other" when it's the only auth plugin not
99 # integrated with the loginselector.
100 my %h=%{$IkiWiki::hooks{auth}};
101 foreach my $p (keys %login_plugins) {
104 delete $h{loginselector};
105 if (keys %h == 1 && exists $h{passwordauth}) {
106 $otherform_label=gettext("Password");
109 $real_cgi_signin=\&IkiWiki::cgi_signin;
112 inject(name => "IkiWiki::cgi_signin", call => sub ($$) {
113 login_selector($real_cgi_signin, $otherform_label, @_);
121 # this plugin is safe but only makes sense as a
129 # While this hook is not currently used, it needs to exist
130 # so ikiwiki knows that the wiki supports logins, and will
131 # enable the Preferences page.