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