web commit by http://harningt.eharning.us/: more git attribution corner-case ideas
[ikiwiki] / 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                         $form->field(name => "confirm_password",
35                                 validate => sub {
36                                         shift eq $form->field("password");
37                                 },
38                         );
39                         $form->field(name => "password",
40                                 validate => sub {
41                                         shift eq $form->field("confirm_password");
42                                 },
43                         );
44                 }
45
46                 if ($form->submitted) {
47                         my $submittype=$form->submitted;
48                         # Set required fields based on how form was submitted.
49                         my %required=(
50                                 "Login" => [qw(name password)],
51                                 "Register" => [],
52                                 "Create Account" => [qw(name password confirm_password email)],
53                                 "Mail Password" => [qw(name)],
54                         );
55                         foreach my $opt (@{$required{$submittype}}) {
56                                 $form->field(name => $opt, required => 1);
57                         }
58         
59                         if ($submittype eq "Create Account") {
60                                 $form->field(
61                                         name => "account_creation_password",
62                                         validate => sub {
63                                                 shift eq $config{account_creation_password};
64                                         },
65                                         required => 1,
66                                 ) if (length $config{account_creation_password});
67                                 $form->field(
68                                         name => "email",
69                                         validate => "EMAIL",
70                                 );
71                         }
72
73                         # Validate password against name for Login.
74                         if ($submittype eq "Login") {
75                                 $form->field(
76                                         name => "password",
77                                         validate => sub {
78                                                 length $form->field("name") &&
79                                                 shift eq IkiWiki::userinfo_get($form->field("name"), 'password');
80                                         },
81                                 );
82                         }
83                         elsif ($submittype eq "Register" ||
84                                $submittype eq "Create Account" ||
85                                $submittype eq "Mail Password") {
86                                 $form->field(name => "password", validate => 'VALUE');
87                         }
88                         
89                         # And make sure the entered name exists when logging
90                         # in or sending email, and does not when registering.
91                         if ($submittype eq 'Create Account' ||
92                             $submittype eq 'Register') {
93                                 $form->field(
94                                         name => "name",
95                                         validate => sub {
96                                                 my $name=shift;
97                                                 length $name &&
98                                                 $name=~/$config{wiki_file_regexp}/ &&
99                                                 ! IkiWiki::userinfo_get($name, "regdate");
100                                         },
101                                 );
102                         }
103                         elsif ($submittype eq "Login" ||
104                                $submittype eq "Mail Password") {
105                                 $form->field( 
106                                         name => "name",
107                                         validate => sub {
108                                                 my $name=shift;
109                                                 length $name &&
110                                                 IkiWiki::userinfo_get($name, "regdate");
111                                         },
112                                 );
113                         }
114                 }
115                 else {
116                         # First time settings.
117                         $form->field(name => "name");
118                         if ($session->param("name")) {
119                                 $form->field(name => "name", value => $session->param("name"));
120                         }
121                 }
122         }
123         elsif ($form->title eq "preferences") {
124                 $form->field(name => "name", disabled => 1, 
125                         value => $session->param("name"), force => 1,
126                         fieldset => "login");
127                 $form->field(name => "password", type => "password",
128                         fieldset => "login",
129                         validate => sub {
130                                 shift eq $form->field("confirm_password");
131                         }),
132                 $form->field(name => "confirm_password", type => "password",
133                         fieldset => "login",
134                         validate => sub {
135                                 shift eq $form->field("password");
136                         }),
137         }
138 }
139
140 sub formbuilder (@) { #{{{
141         my %params=@_;
142
143         my $form=$params{form};
144         my $session=$params{session};
145         my $cgi=$params{cgi};
146         my $buttons=$params{buttons};
147
148         if ($form->title eq "signin" || $form->title eq "register") {
149                 if ($form->submitted && $form->validate) {
150                         if ($form->submitted eq 'Login') {
151                                 $session->param("name", $form->field("name"));
152                                 IkiWiki::cgi_postsignin($cgi, $session);
153                         }
154                         elsif ($form->submitted eq 'Create Account') {
155                                 my $user_name=$form->field('name');
156                                 if (IkiWiki::userinfo_setall($user_name, {
157                                         'email' => $form->field('email'),
158                                         'password' => $form->field('password'),
159                                         'regdate' => time})) {
160                                         $form->field(name => "confirm_password", type => "hidden");
161                                         $form->field(name => "email", type => "hidden");
162                                         $form->text(gettext("Account creation successful. Now you can Login."));
163                                 }
164                                 else {
165                                         error(gettext("Error creating account."));
166                                 }
167                         }
168                         elsif ($form->submitted eq 'Mail Password') {
169                                 my $user_name=$form->field("name");
170                                 my $template=template("passwordmail.tmpl");
171                                 $template->param(
172                                         user_name => $user_name,
173                                         user_password => IkiWiki::userinfo_get($user_name, "password"),
174                                         wikiurl => $config{url},
175                                         wikiname => $config{wikiname},
176                                         REMOTE_ADDR => $ENV{REMOTE_ADDR},
177                                 );
178                         
179                                 eval q{use Mail::Sendmail};
180                                 error($@) if $@;
181                                 sendmail(
182                                         To => IkiWiki::userinfo_get($user_name, "email"),
183                                         From => "$config{wikiname} admin <$config{adminemail}>",
184                                         Subject => "$config{wikiname} information",
185                                         Message => $template->output,
186                                 ) or error(gettext("Failed to send mail"));
187                         
188                                 $form->text(gettext("Your password has been emailed to you."));
189                                 $form->field(name => "name", required => 0);
190                                 push @$buttons, "Mail Password";
191                         }
192                         elsif ($form->submitted eq "Register") {
193                                 @$buttons="Create Account";
194                         }
195                 }
196                 elsif ($form->submitted eq "Create Account") {
197                         @$buttons="Create Account";
198                 }
199                 else {
200                         push @$buttons, "Register", "Mail Password";
201                 }
202         }
203         elsif ($form->title eq "preferences") {
204                 if ($form->submitted eq "Save Preferences" && $form->validate) {
205                         my $user_name=$form->field('name');
206                         foreach my $field (qw(password)) {
207                                 if (defined $form->field($field) && length $form->field($field)) {
208                                         IkiWiki::userinfo_set($user_name, $field, $form->field($field)) ||
209                                                 error("failed to set $field");
210                                 }
211                         }
212                 }
213         }
214 } #}}}
215
216 1