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