Merge branch 'master' 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 => "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 redir_cgiauthurl ($;@) {
43         my $cgi=shift;
44
45         IkiWiki::redirect($cgi, 
46                 @_ > 1 ? IkiWiki::cgiurl(cgiurl => $config{cgiauthurl}, @_)
47                        : $config{cgiauthurl}."?@_"
48         );
49         exit;
50 }
51
52 sub auth ($$) {
53         my $cgi=shift;
54         my $session=shift;
55
56         if (defined $cgi->remote_user()) {
57                 my $user = $cgi->remote_user();
58                 $session->param("name", $user);
59                 eval IkiWiki::possibly_foolish_untaint($ENV{SSL_CLIENT_S_DN_CN});
60                 my $realname = IkiWiki::userinfo_get($user, "realname");
61                 if ((!defined $realname || $realname eq "") &&
62                     defined $ENV{SSL_CLIENT_S_DN_CN}) {
63                 IkiWiki::userinfo_set($user, "realname", $ENV{SSL_CLIENT_S_DN_CN});
64                 }
65         }
66 }
67
68 sub formbuilder_setup (@) {
69         my %params=@_;
70
71         my $form=$params{form};
72         my $session=$params{session};
73         my $cgi=$params{cgi};
74         my $buttons=$params{buttons};
75
76         if ($form->title eq "signin" &&
77             ! defined $cgi->remote_user() && defined $config{cgiauthurl}) {
78                 my $button_text="Login with HTTP auth";
79                 push @$buttons, $button_text;
80
81                 if ($form->submitted && $form->submitted eq $button_text) {
82                         # bounce thru cgiauthurl and then back to
83                         # the stored postsignin action
84                         redir_cgiauthurl($cgi, do => "postsignin");
85                 }
86         }
87 }
88
89 sub test_httpauth_pagespec ($) {
90         my $page=shift;
91
92         return (
93        );
94 }
95
96 sub canedit ($$$) {
97         my $page=shift;
98         my $cgi=shift;
99         my $session=shift;
100
101         if (! defined $cgi->remote_user() &&
102             defined $config{httpauth_pagespec} &&
103             length $config{httpauth_pagespec} &&
104             defined $config{cgiauthurl} &&
105             pagespec_match($page, $config{httpauth_pagespec})) {
106                 return sub {
107                         # bounce thru cgiauthurl and back to edit action
108                         redir_cgiauthurl($cgi, $cgi->query_string());
109                 };
110         }
111         else {
112                 return undef;
113         }
114 }
115
116 1