ikiwiki (3.20130711) unstable; urgency=low
[ikiwiki.git] / doc / todo / cas_authentication.mdwn
1 [[!tag patch wishlist]]
2
3 ikiwiki should support [Central Authentication
4 Service](http://www.ja-sig.org/products/cas/) authentication in order to use
5 this <acronym title='Single Sign On'>SSO</acronym> mechanism very popular in
6 universities web services.
7
8 I have already written a first draft plugin supporting that authentication
9 mechanism. It works for me with my university CAS service. I did not try it
10 with other CAS server but it do not see any reason why it should not work.
11
12 What is the best way to submit it to you (just in case it can help my patch
13 follows) ?
14
15 --[[/users/bbb]]
16
17 > Inline here is ok; git-am by mail is ok; a git repo I can pull from also
18 > ok.
19
20 > This looks pretty acceptable as-is, but you need to put a copyright and
21 > license statement at the top. I have a few questions that I'll insert
22 > inline with the patch below. --[[Joey]]
23
24 >> I have made some corrections to this patch (my cas plugin) in order to use
25 >> IkiWiki 3.00 interface and take your comments into account. It should work
26 >> fine now.
27 >>
28 >> You can pull it from my git repo at
29 >> http://git.boulgour.com/bbb/ikiwiki.git/ and maybe add it to your main
30 >> repo.
31 >> 
32 >> I will add GNU GPL copyright license statement as soon as I get some free
33 >> time.
34 >>
35 >> --[[/users/bbb]]
36
37 ------------------------------------------------------------------------------
38     diff --git a/IkiWiki/Plugin/cas.pm b/IkiWiki/Plugin/cas.pm
39     new file mode 100644
40     index 0000000..ea189df
41     --- /dev/null
42     +++ b/IkiWiki/Plugin/cas.pm
43     @@ -0,0 +1,94 @@
44     +#!/usr/bin/perl
45     +# JaSIG CAS support by Bruno Beaufils <bruno@boulgour.com>
46     +package IkiWiki::Plugin::cas;
47     +
48     +use warnings;
49     +use strict;
50     +use IkiWiki 2.00;
51     +use AuthCAS;                  # http://search.cpan.org/~osalaun/AuthCAS-1.3.1/
52
53 > In ikiwiki we generally deman-load perl modules only when they're used.
54 > This avoids loading expensive modules when the CGI isn't doing
55 > authentication. Can you do that with AuthCAS? Something like this before
56 > the use of it: `eval q{use AuthCAS}; error $@ if $@`
57
58     +
59     +sub import {
60     +    hook(type => "getopt", id => "cas", call => \&getopt);
61     +    hook(type => "auth", id => "cas", call => \&auth);
62     +    hook(type => "formbuilder_setup", id => "cas", call => \&formbuilder_setup);
63     +}
64
65 > Could you please use tabs for indentation of program flow?
66
67     +# FIXME: We should check_config to ensure that :
68     +# * cas_url and ca_file are present
69
70 > Please fix that..
71
72     +# * no other auth plugin are present (at least passwordauth and openid)
73
74 > Why would you want to make other auth plugins not work? Could a site not
75 > legitimatly chose to use this and another auth method?
76
77     +sub getopt () {
78     +    eval q{use Getopt::Long};
79     +    error($@) if $@;
80     +    Getopt::Long::Configure('pass_through');
81     +    GetOptions("cas_url=s" => \$config{cas_url});
82     +    GetOptions("ca_file=s" => \$config{ca_file});
83     +}
84     +
85     +sub auth ($$) {
86     +    my $q=shift;
87     +    my $session=shift;
88     +
89     +    my $cas = new AuthCAS(casUrl => $config{'cas'}{'cas_url'},
90     +                          CAFile => $config{'cas'}{'ca_file'});
91     +
92     +    my $service = $config{'cgiurl'};
93     +    my $ticket = $q->param('ticket');
94     +
95     +    unless (defined($ticket)) {
96     +        $service .= "?$ENV{QUERY_STRING}";
97     +        my $login_url = $cas->getServerLoginURL($service);
98     +        debug("CAS: asking a Service Ticket for service $service");
99     +        IkiWiki::redirect($q, $login_url);
100     +        exit 0;
101     +    } else {
102     +        $service = $service . "?$ENV{QUERY_STRING}";
103     +        $service =~ s/\&ticket=$ticket//;
104     +        my $user = $cas->validateST($service, $ticket);
105     +        if (defined $user) {
106     +            debug("CAS: validating a Service Ticket ($ticket) for service $service");
107     +            $session->param(name=>$user);
108     +            $session->param(CASservice=>$service);
109     +            IkiWiki::cgi_savesession($session);
110     +        } else {
111     +            error("CAS failure: ".&AuthCAS::get_errors());
112     +        }
113     +    }
114     +}
115     +
116     +# I use formbuilder_setup and not formbuilder type in order to bypass the
117     +# Logout processing done in IkiWiki::CGI::cgi_prefs()
118     +sub formbuilder_setup (@) {
119     +    my %params=@_;
120     +    
121     +    my $form=$params{form};
122     +    my $session=$params{session};
123     +    my $cgi=$params{cgi};
124     +    my $buttons=$params{buttons};
125     +
126     +    my $cas = new AuthCAS(casUrl => $config{'cas'}{'cas_url'},
127     +                          CAFile => $config{'cas'}{'ca_file'});
128     +
129     +    if ($form->title eq "preferences") {
130     +        # Show the login
131     +        if (! defined $form->field(name => "name")) {
132     +            $form->field(name => "CAS ID",
133     +                         disabled => 1,
134     +                         value => $session->param("name"), 
135     +                         size => 50,
136     +                         force => 1,
137     +                         fieldset => "login");
138     +        }
139     +        
140     +        # Force a logout if asked
141     +        if ($form->submitted && $form->submitted eq 'Logout')
142     +        {
143     +            debug("CAS: asking to remove the Ticket Grant Cookie");
144     +            IkiWiki::redirect($cgi, $cas->getServerLogoutURL($config{'url'}));
145     +            $session->delete();
146     +            exit 0;
147     +        }
148     +    }
149     +}
150     +
151     +1
152     diff --git a/doc/plugins/cas.mdwn b/doc/plugins/cas.mdwn
153     new file mode 100644
154     index 0000000..2f2f53e
155     --- /dev/null
156     +++ b/doc/plugins/cas.mdwn
157     @@ -0,0 +1,18 @@
158     +[[ template id=plugin name=cas core=0 author="[[bbb]]"]]
159     +[[ tag type/auth]]
160     +
161     +This plugin allows users to use authentication offered by a
162     +[JaSIG](http://www.ja-sig.org) [<acronym title='Central Authentication
163     +Service'>CAS</acronym>](http://www.ja-sig.org/products/cas/) server to log
164     +into the wiki.
165     +
166     +The plugin needs the [[!cpan AuthCAS-1.3.1]] perl module.
167
168 > Does it really need that specific version? I think you should lose the
169 > version part.
170
171     +
172     +This plugin has two mandatory configuration option. You **must** set `--cas_url`
173     +to the url of a server offering CAS 2.0 authentication. You must also set the
174     +`--ca_file` to an absolute path to the file containing CA certificates used by
175     +the server (generally, aka under Debian, fixing that value to
176     +`/etc/ssl/certs/ca-certificates.crt` is sufficient).
177
178 > It would be good to add commented-out examples of these to
179 > ikiwiki.setup as well.
180
181     +This plugin is not enabled by default. It can not be used with other
182     +authentication plugin, such as [[passwordauth]] or [[openid]].
183
184 ------------------------------------------------------------------------------