+sub userinfo_get ($$) { #{{
+ my $user=shift;
+ my $field=shift;
+
+ eval q{use Storable};
+ my $userdata=eval{ Storable::lock_retrieve("$srcdir/.ikiwiki/userdb") };
+ if (! defined $userdata || ! ref $userdata ||
+ ! exists $userdata->{$user} || ! ref $userdata->{$user}) {
+ return "";
+ }
+ return $userdata->{$user}->{$field};
+} #}}
+
+sub userinfo_set ($$) { #{{
+ my $user=shift;
+ my $info=shift;
+
+ eval q{use Storable};
+ my $userdata=eval{ Storable::lock_retrieve("$srcdir/.ikiwiki/userdb") };
+ if (! defined $userdata || ! ref $userdata) {
+ $userdata={};
+ }
+ $userdata->{$user}=$info;
+ my $oldmask=umask(077);
+ my $ret=Storable::lock_store($userdata, "$srcdir/.ikiwiki/userdb");
+ umask($oldmask);
+ return $ret;
+} #}}
+
+sub cgi_signin ($$) { #{{{
+ my $q=shift;
+ my $session=shift;
+
+ eval q{use CGI::FormBuilder};
+ my $form = CGI::FormBuilder->new(
+ title => "$wikiname signin",
+ fields => [qw(do page name password confirm_password email)],
+ header => 1,
+ method => 'POST',
+ validate => {
+ confirm_password => {
+ perl => q{eq $form->field("password")},
+ },
+ email => 'EMAIL',
+ },
+ required => 'NONE',
+ javascript => 0,
+ params => $q,
+ action => $q->request_uri,
+ header => 0,
+ template => (-e "$templatedir/signin.tmpl" ? "$templatedir/signin.tmpl" : "")
+ );
+
+ $form->field(name => "name", required => 0);
+ $form->field(name => "do", type => "hidden");
+ $form->field(name => "page", type => "hidden");
+ $form->field(name => "password", type => "password", required => 0);
+ $form->field(name => "confirm_password", type => "password", required => 0);
+ $form->field(name => "email", required => 0);
+ if ($q->param("do") ne "signin") {
+ $form->text("You need to log in before you can edit pages.");
+ }
+
+ if ($form->submitted) {
+ # Set required fields based on how form was submitted.
+ my %required=(
+ "Login" => [qw(name password)],
+ "Register" => [qw(name password confirm_password email)],
+ "Mail Password" => [qw(name)],
+ );
+ foreach my $opt (@{$required{$form->submitted}}) {
+ $form->field(name => $opt, required => 1);
+ }
+
+ # Validate password differently depending on how
+ # form was submitted.
+ if ($form->submitted eq 'Login') {
+ $form->field(
+ name => "password",
+ validate => sub {
+ length $form->field("name") &&
+ shift eq userinfo_get($form->field("name"), 'password');
+ },
+ );
+ $form->field(name => "name", validate => '/^\w+$/');
+ }
+ else {
+ $form->field(name => "password", validate => 'VALUE');
+ }
+ # And make sure the entered name exists when logging
+ # in or sending email, and does not when registering.
+ if ($form->submitted eq 'Register') {
+ $form->field(
+ name => "name",
+ validate => sub {
+ my $name=shift;
+ length $name &&
+ ! userinfo_get($name, "regdate");
+ },
+ );
+ }
+ else {
+ $form->field(
+ name => "name",
+ validate => sub {
+ my $name=shift;
+ length $name &&
+ userinfo_get($name, "regdate");
+ },
+ );
+ }
+ }
+ else {
+ # First time settings.
+ $form->field(name => "name", comment => "use FirstnameLastName");
+ $form->field(name => "confirm_password", comment => "(only needed");
+ $form->field(name => "email", comment => "for registration)");
+ if ($session->param("name")) {
+ $form->field(name => "name", value => $session->param("name"));
+ }
+ }
+
+ if ($form->submitted && $form->validate) {
+ if ($form->submitted eq 'Login') {
+ $session->param("name", $form->field("name"));
+ if (defined $form->field("do") &&
+ $form->field("do") ne 'signin') {
+ print $q->redirect(
+ "$cgiurl?do=".$form->field("do").
+ "&page=".$form->field("page"));
+ }
+ else {
+ print $q->redirect($url);
+ }
+ }
+ elsif ($form->submitted eq 'Register') {
+ my $user_name=$form->field('name');
+ if (userinfo_set($user_name, {
+ 'email' => $form->field('email'),
+ 'password' => $form->field('password'),
+ 'regdate' => time
+ })) {
+ $form->field(name => "confirm_password", type => "hidden");
+ $form->field(name => "email", type => "hidden");
+ $form->text("Registration successful. Now you can Login.");
+ print $session->header();
+ print misctemplate($form->title, $form->render(submit => ["Login"]));
+ }
+ else {
+ error("Error saving registration.");
+ }
+ }
+ elsif ($form->submitted eq 'Mail Password') {
+ my $user_name=$form->field("name");
+ my $template=HTML::Template->new(
+ filename => "$templatedir/passwordmail.tmpl"
+ );
+ $template->param(
+ user_name => $user_name,
+ user_password => userinfo_get($user_name, "password"),
+ wikiurl => $url,
+ wikiname => $wikiname,
+ REMOTE_ADDR => $ENV{REMOTE_ADDR},
+ );
+
+ eval q{use Mail::Sendmail};
+ my ($fromhost) = $cgiurl =~ m!/([^/]+)!;
+ print STDERR "$< $> >>> $cgiurl ".(getpwuid($>))[0]."@".$fromhost."\n";
+ sendmail(
+ To => userinfo_get($user_name, "email"),
+ From => "$wikiname admin <".(getpwuid($>))[0]."@".$fromhost.">",
+ Subject => "$wikiname information",
+ Message => $template->output,
+ ) or error("Failed to send mail");
+
+ $form->text("Your password has been emailed to you.");
+ $form->field(name => "name", required => 0);
+ print $session->header();
+ print misctemplate($form->title, $form->render(submit => ["Login", "Register", "Mail Password"]));
+ }
+ }
+ else {
+ print $session->header();
+ print misctemplate($form->title, $form->render(submit => ["Login", "Register", "Mail Password"]));