From: joey Date: Sun, 12 Mar 2006 20:10:42 +0000 (+0000) Subject: - finish user registration and password request email X-Git-Tag: 1.0~408 X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=60631f58b8f6532eccbead29d239aaf25de93610;p=ikiwiki.git - finish user registration and password request email - make sure a user is in the userdb before assuming they're logged on based on session info (allows deleting uerdb item and invalidating all sessions) --- diff --git a/doc/features.mdwn b/doc/features.mdwn index dc3401bba..8a05a1679 100644 --- a/doc/features.mdwn +++ b/doc/features.mdwn @@ -44,11 +44,19 @@ Currently implemented: * [[PageHistory]] - Well, sorta. Rather than implementing YA history browser, it can link to [[ViewCVS]] or the link to browse the history of a wiki page. + Well, sorta. Rather than implementing YA history browser, it can link to + [[ViewCVS]] or the link to browse the history of a wiki page. * [[RecentChanges]], editing pages in a web browser - Nearly the definition of a wiki, although perhaps ikiwiki challenges how much of that web gunk a wiki really needs. These features are optional and can be enabled by enabling [[CGI]]. + Nearly the definition of a wiki, although perhaps ikiwiki challenges how + much of that web gunk a wiki really needs. These features are optional + and can be enabled by enabling [[CGI]]. + +* User registration + + Can optionally be configured to allow only registered users to post + pages; online user registration form, etc. ---- diff --git a/doc/templates.mdwn b/doc/templates.mdwn index 6d4d8793d..f22e50dec 100644 --- a/doc/templates.mdwn +++ b/doc/templates.mdwn @@ -8,7 +8,9 @@ It ships with some basic templates which can be customised: * `templates/misc.tmpl` - Generic template used for any page that doesn't have a custom template. * `templates/recentchanges.tmpl` - Used for the RecentChanges page. -* `templates/editpage.tmpl' - Create/edit page. +* `templates/editpage.tmpl` - Create/edit page. +* `templates/passwordmail.tmpl` - Not a html template, this is used to + generate the mail with the user's password in it. If you like, you can add these to further customise it: diff --git a/doc/todo.mdwn b/doc/todo.mdwn index 355c36a28..5442653be 100644 --- a/doc/todo.mdwn +++ b/doc/todo.mdwn @@ -1,9 +1,8 @@ ## online page editing * Missing support for preview, cancel. -* Missing conflict detection. -* Missing commit message box. -* No support for web user tracking/login yet. +* Missing conflict detection, just overwrites changes and does not svn up + first. * Eventually, might want page deletion. * Eventually, might want file upload. diff --git a/ikiwiki b/ikiwiki index 44e2197e6..67004e413 100755 --- a/ikiwiki +++ b/ikiwiki @@ -709,6 +709,35 @@ sub cgi_recentchanges ($) { #{{{ print $q->header, $template->output; } #}}} +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; @@ -720,7 +749,6 @@ sub cgi_signin ($$) { #{{{ header => 1, method => 'POST', validate => { - name => '/^\w+$/', confirm_password => { perl => q{eq $form->field("password")}, }, @@ -740,9 +768,6 @@ sub cgi_signin ($$) { #{{{ $form->field(name => "password", type => "password", required => 0); $form->field(name => "confirm_password", type => "password", required => 0); $form->field(name => "email", required => 0); - if ($session->param("name")) { - $form->field(name => "name", value => $session->param("name")); - } if ($q->param("do") ne "signin") { $form->text("You need to log in before you can edit pages."); } @@ -758,26 +783,52 @@ sub cgi_signin ($$) { #{{{ $form->field(name => $opt, required => 1); } - # Validate password differently depending on how form was - # submitted. + # Validate password differently depending on how + # form was submitted. if ($form->submitted eq 'Login') { $form->field( name => "password", validate => sub { - # TODO get real user password - shift eq "foo"; + 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 { - # Comments only shown first time. + # 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) { @@ -794,16 +845,47 @@ sub cgi_signin ($$) { #{{{ } } elsif ($form->submitted eq 'Register') { - # TODO: save registration info - $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"])); + 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') { - # TODO 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"])); } @@ -916,7 +998,8 @@ sub cgi_editpage ($$) { #{{{ else { $message.="from $ENV{REMOTE_ADDR}"; } - if (length $form->field('comments')) { + if (defined $form->field('comments') && + length $form->field('comments')) { $message.=": ".$form->field('comments'); } @@ -961,7 +1044,8 @@ sub cgi () { #{{{ umask($oldmask); # Everything below this point needs the user to be signed in. - if ((! $anonok && ! defined $session->param("name")) || $do eq 'signin') { + if ((! $anonok && ! defined $session->param("name") || + ! userinfo_get($session->param("name"), "regdate")) || $do eq 'signin') { cgi_signin($q, $session); # Force session flush with safe umask. diff --git a/templates/passwordmail.tmpl b/templates/passwordmail.tmpl new file mode 100644 index 000000000..8484d39b2 --- /dev/null +++ b/templates/passwordmail.tmpl @@ -0,0 +1,10 @@ +Someone[1], possibly you, requested that you be emailed the password for user + on [2]. + +The password is: + +-- +ikiwiki + +[1] The user requesting the password was at IP address +[2] Located at