ikiwiki (3.20130711) unstable; urgency=low
[ikiwiki.git] / IkiWiki / Plugin / httpauth.pm
1 #!/usr/bin/perl
2 # HTTP basic auth plugin.
3 package IkiWiki::Plugin::httpauth;
4
5 use warnings;
6 use strict;
7 use IkiWiki 3.00;
8
9 sub import {
10         hook(type => "checkconfig", id => "httpauth", call => \&checkconfig);
11         hook(type => "getsetup", id => "httpauth", call => \&getsetup);
12         hook(type => "auth", id => "httpauth", call => \&auth);
13         hook(type => "formbuilder_setup", id => "httpauth",
14                 call => \&formbuilder_setup);
15         hook(type => "canedit", id => "httpauth", call => \&canedit,
16                 first => 1);
17 }
18
19 sub getsetup () {
20         return
21                 plugin => {
22                         safe => 1,
23                         rebuild => 0,
24                         section => "auth",
25                 },
26                 cgiauthurl => {
27                         type => "string",
28                         example => "http://example.com/wiki/auth/ikiwiki.cgi",
29                         description => "url to redirect to when authentication is needed",
30                         safe => 1,
31                         rebuild => 0,
32                 },
33                 httpauth_pagespec => {
34                         type => "pagespec",
35                         example => "!*/Discussion",
36                         description => "PageSpec of pages where only httpauth will be used for authentication",
37                         safe => 0,
38                         rebuild => 0,
39                 },
40 }
41
42 sub checkconfig () {
43         if ($config{cgi} && defined $config{cgiauthurl} &&
44             keys %{$IkiWiki::hooks{auth}} < 2) {
45                 # There are no other auth hooks registered, so avoid
46                 # the normal signin form, and jump right to httpauth.
47                 require IkiWiki::CGI;
48                 inject(name => "IkiWiki::cgi_signin", call => sub ($$) {
49                         my $cgi=shift;
50                         redir_cgiauthurl($cgi, $cgi->query_string());
51                 });
52         }
53 }
54                         
55 sub redir_cgiauthurl ($;@) {
56         my $cgi=shift;
57
58         IkiWiki::redirect($cgi, 
59                 @_ > 1 ? IkiWiki::cgiurl(cgiurl => $config{cgiauthurl}, @_)
60                        : $config{cgiauthurl}."?@_"
61         );
62         exit;
63 }
64
65 sub auth ($$) {
66         my $cgi=shift;
67         my $session=shift;
68
69         if (defined $cgi->remote_user()) {
70                 $session->param("name", $cgi->remote_user());
71         }
72 }
73
74 sub formbuilder_setup (@) {
75         my %params=@_;
76
77         my $form=$params{form};
78         my $session=$params{session};
79         my $cgi=$params{cgi};
80         my $buttons=$params{buttons};
81
82         if ($form->title eq "signin" &&
83             ! defined $cgi->remote_user() && defined $config{cgiauthurl}) {
84                 my $button_text="Login with HTTP auth";
85                 push @$buttons, $button_text;
86
87                 if ($form->submitted && $form->submitted eq $button_text) {
88                         # bounce thru cgiauthurl and then back to
89                         # the stored postsignin action
90                         redir_cgiauthurl($cgi, do => "postsignin");
91                 }
92         }
93 }
94
95 sub canedit ($$$) {
96         my $page=shift;
97         my $cgi=shift;
98         my $session=shift;
99
100         if (! defined $cgi->remote_user() &&
101             (! defined $session->param("name") ||
102              ! IkiWiki::userinfo_get($session->param("name"), "regdate")) &&
103             defined $config{httpauth_pagespec} &&
104             length $config{httpauth_pagespec} &&
105             defined $config{cgiauthurl} &&
106             pagespec_match($page, $config{httpauth_pagespec})) {
107                 return sub {
108                         # bounce thru cgiauthurl and back to edit action
109                         redir_cgiauthurl($cgi, $cgi->query_string());
110                 };
111         }
112         else {
113                 return undef;
114         }
115 }
116
117 1