]> sipb.mit.edu Git - ikiwiki.git/blob - IkiWiki/Plugin/passwordauth.pm
* Add an account-creation password as a simple anti-spam mechanism. If
[ikiwiki.git] / IkiWiki / Plugin / passwordauth.pm
1 #!/usr/bin/perl
2 # Ikiwiki password authentication.
3 package IkiWiki::Plugin::passwordauth;
4
5 use warnings;
6 use strict;
7 use IkiWiki 2.00;
8
9 sub import { #{{{
10         hook(type => "formbuilder_setup", id => "passwordauth",
11                 call => \&formbuilder_setup);
12         hook(type => "formbuilder", id => "passwordauth",
13                 call => \&formbuilder);
14 } # }}}
15
16 sub formbuilder_setup (@) { #{{{
17         my %params=@_;
18
19         my $form=$params{form};
20         my $session=$params{session};
21         my $cgi=$params{cgi};
22
23         if ($form->title eq "signin" || $form->title eq "register") {
24                 $form->field(name => "name", required => 0);
25                 $form->field(name => "password", type => "password", required => 0);
26                 
27                 if ($form->submitted eq "Register" || $form->submitted eq "Create Account") {
28                         $form->field(name => "confirm_password", type => "password");
29                         $form->field(name => "account_creation_password", type => "password") if (length $config{account_creation_password});
30                         $form->field(name => "email", size => 50);
31                         $form->title("register");
32                         $form->text("");
33                 }
34
35                 if ($form->submitted) {
36                         my $submittype=$form->submitted;
37                         # Set required fields based on how form was submitted.
38                         my %required=(
39                                 "Login" => [qw(name password)],
40                                 "Register" => [],
41                                 "Create Account" => [qw(name password confirm_password email)],
42                                 "Mail Password" => [qw(name)],
43                         );
44                         foreach my $opt (@{$required{$submittype}}) {
45                                 $form->field(name => $opt, required => 1);
46                         }
47         
48                         if ($submittype eq "Create Account") {
49                                 $form->field(
50                                         name => "confirm_password",
51                                         validate => sub {
52                                                 shift eq $form->field("password");
53                                         },
54                                 );
55                                 $form->field(
56                                         name => "account_creation_password",
57                                         validate => sub {
58                                                 shift eq $config{account_creation_password};
59                                         },
60                                         required => 1,
61                                 ) if (length $config{account_creation_password});
62                                 $form->field(
63                                         name => "email",
64                                         validate => "EMAIL",
65                                 );
66                         }
67
68                         # Validate password against name for Login.
69                         if ($submittype eq "Login") {
70                                 $form->field(
71                                         name => "password",
72                                         validate => sub {
73                                                 length $form->field("name") &&
74                                                 shift eq IkiWiki::userinfo_get($form->field("name"), 'password');
75                                         },
76                                 );
77                         }
78                         elsif ($submittype eq "Register" ||
79                                $submittype eq "Create Account" ||
80                                $submittype eq "Mail Password") {
81                                 $form->field(name => "password", validate => 'VALUE');
82                         }
83                         
84                         # And make sure the entered name exists when logging
85                         # in or sending email, and does not when registering.
86                         if ($submittype eq 'Create Account' ||
87                             $submittype eq 'Register') {
88                                 $form->field(
89                                         name => "name",
90                                         validate => sub {
91                                                 my $name=shift;
92                                                 length $name &&
93                                                 $name=~/$config{wiki_file_regexp}/ &&
94                                                 ! IkiWiki::userinfo_get($name, "regdate");
95                                         },
96                                 );
97                         }
98                         elsif ($submittype eq "Login" ||
99                                $submittype eq "Mail Password") {
100                                 $form->field( 
101                                         name => "name",
102                                         validate => sub {
103                                                 my $name=shift;
104                                                 length $name &&
105                                                 IkiWiki::userinfo_get($name, "regdate");
106                                         },
107                                 );
108                         }
109                 }
110                 else {
111                         # First time settings.
112                         $form->field(name => "name");
113                         if ($session->param("name")) {
114                                 $form->field(name => "name", value => $session->param("name"));
115                         }
116                 }
117         }
118         elsif ($form->title eq "preferences") {
119                 $form->field(name => "name", disabled => 1, 
120                         value => $session->param("name"), force => 1,
121                         fieldset => "login");
122                 $form->field(name => "password", type => "password",
123                         fieldset => "login");
124                 $form->field(name => "confirm_password", type => "password",
125                         fieldset => "login",
126                         validate => sub {
127                                 shift eq $form->field("password");
128                         });
129                 
130         }
131 }
132
133 sub formbuilder (@) { #{{{
134         my %params=@_;
135
136         my $form=$params{form};
137         my $session=$params{session};
138         my $cgi=$params{cgi};
139         my $buttons=$params{buttons};
140
141         if ($form->title eq "signin" || $form->title eq "register") {
142                 if ($form->submitted && $form->validate) {
143                         if ($form->submitted eq 'Login') {
144                                 $session->param("name", $form->field("name"));
145                                 IkiWiki::cgi_postsignin($cgi, $session);
146                         }
147                         elsif ($form->submitted eq 'Create Account') {
148                                 my $user_name=$form->field('name');
149                                 if (IkiWiki::userinfo_setall($user_name, {
150                                         'email' => $form->field('email'),
151                                         'password' => $form->field('password'),
152                                         'regdate' => time})) {
153                                         $form->field(name => "confirm_password", type => "hidden");
154                                         $form->field(name => "email", type => "hidden");
155                                         $form->text(gettext("Account creation successful. Now you can Login."));
156                                 }
157                                 else {
158                                         error(gettext("Error creating account."));
159                                 }
160                         }
161                         elsif ($form->submitted eq 'Mail Password') {
162                                 my $user_name=$form->field("name");
163                                 my $template=template("passwordmail.tmpl");
164                                 $template->param(
165                                         user_name => $user_name,
166                                         user_password => IkiWiki::userinfo_get($user_name, "password"),
167                                         wikiurl => $config{url},
168                                         wikiname => $config{wikiname},
169                                         REMOTE_ADDR => $ENV{REMOTE_ADDR},
170                                 );
171                         
172                                 eval q{use Mail::Sendmail};
173                                 error($@) if $@;
174                                 sendmail(
175                                         To => IkiWiki::userinfo_get($user_name, "email"),
176                                         From => "$config{wikiname} admin <$config{adminemail}>",
177                                         Subject => "$config{wikiname} information",
178                                         Message => $template->output,
179                                 ) or error(gettext("Failed to send mail"));
180                         
181                                 $form->text(gettext("Your password has been emailed to you."));
182                                 $form->field(name => "name", required => 0);
183                                 push @$buttons, "Mail Password";
184                         }
185                         elsif ($form->submitted eq "Register") {
186                                 @$buttons="Create Account";
187                         }
188                 }
189                 elsif ($form->submitted eq "Create Account") {
190                         @$buttons="Create Account";
191                 }
192                 else {
193                         push @$buttons, "Register", "Mail Password";
194                 }
195         }
196         elsif ($form->title eq "preferences") {
197                 if ($form->submitted eq "Save Preferences" && $form->validate) {
198                         my $user_name=$form->field('name');
199                         foreach my $field (qw(password)) {
200                                 if (defined $form->field($field)) {
201                                         IkiWiki::userinfo_set($user_name, $field, $form->field($field)) ||
202                                                 error("failed to set $field");
203                                 }
204                         }
205                 }
206         }
207         
208         IkiWiki::printheader($session);
209         print IkiWiki::misctemplate($form->title, $form->render(submit => $buttons));
210 } #}}}
211
212 1