diff -r 5d275133868b -r 687f53554299 index.cgi --- a/index.cgi Fri Jul 01 16:25:21 2011 +0200 +++ b/index.cgi Sun Jul 03 23:15:37 2011 +0200 @@ -17,7 +17,7 @@ use Mail::RFC822::Address qw(valid); sub insert(\%); -sub confirm($); +sub confirm($$); sub slurp($); @@ -26,7 +26,7 @@ my $DSN = "DBI:SQLite:db.sqlite3"; my $SECRET = slurp "./secret"; chomp($SECRET); -my $EXPIRATION = 3600; # the link is valid for 1 hour only +my $EXPIRATION = 60; # the link is valid for XX minutes only my $SUBJECT = "Retter packen"; # ASCII only! *used for mail subject* my %FIELDS = ( MAN => [qw[givenname surname mail]], @@ -79,7 +79,7 @@ Sender => "hs\@schlittermann.de", Subject => "[$SUBJECT] Link zur Online-Anmeldung", Message => "Bitte benutze den folgenden Link, um zum Anmeldeformular zu gelangen:\n" - . url(-query => 0) . "/$xxx\n" + . url(-query => 0) . "/$xxx.tmp\n" . "\n-- \nHeiko Schlittermann\n"); $sent = param("mail"); @@ -88,19 +88,24 @@ $tt->process("access.tpl", { sent => $sent, warn => %warn ? \%warn : undef, + expires => $EXPIRATION, value => { mail => scalar param("mail") }, }); exit 0; } + # /.tmp + # /.user + # No access without correct path_info - if (my $_ = basename(path_info())) { + if (path_info() =~ /^\/?(.*)\.tmp$/) { + my $_ = $1; s/_/\//g; s/-/+/g; eval { my $time = decrypt($_) or die "DECRYPTION ERROR"; $time =~ /^\d+$/ or die "FORMAT ERROR"; - time() - $time < $EXPIRATION or die "EXPIRED"; + time() - $time < (60 * $EXPIRATION) or die "EXPIRED"; }; if ($@) { $tt->process("denied.tpl", { @@ -110,6 +115,18 @@ } } + if (path_info() =~ /^\/?(.*)\.user$/) { + my $uuid = $1; + my $confirmed = param("confirm") eq "yes"; + my %data = confirm($uuid => $confirmed); + + $tt->process("confirm.tpl", { + confirmed => $confirmed, + error => delete $data{error}, + value => \%data}) or die $tt->error(); + exit 0; + } + ### all went fine, we start processing ### the form @@ -156,10 +173,21 @@ sendmail(To => $value{mail}, From => "hs\@schlittermann.de", "Content-Type" => "text/plain; charset=\"UTF-8\"", - Subject => "Bitte die Anmeldung bestaetigen.", - Message => "Bitte bestätige Deine Anmeldung, in dem Du folgende Webseite aufrufst:\n" - . url(-path_info => 1, -query => 0) . "?confirm=$r{uuid}\n"); + Subject => "[$SUBJECT] Bitte die Anmeldung bestaetigen.", + Message => <<_EOF); + +Bitte bestätige Deine Anmeldung. Dazu mußt Du folgenden Link in Deinem +Browser öffnen: + +@{[url(-path_info => 0, -query => 0)]}/$r{uuid}.user?confirm=yes +Wenn alles nur ein Irrtum war, dann kannst Du Deine Daten wieder +AUSTRAGEN und wir vergessen Deine Anmeldung. Hier ist der Link zum +AUSTRAGEN: + +@{[url(-path_info => 0, -query => 0)]}/$r{uuid}.user?confirm=no + +_EOF $tt->process("ack.tpl", { value => \%value, timestamp => $r{timestamp}, @@ -169,15 +197,9 @@ } } - if (param("confirm") =~ /^\s*(.+)\s*/) { - my %data = confirm($1); - $tt->process("confirm.tpl", { - value => \%data}) or die $tt->error(); - exit 0; - } ## Formular - $tt->process("entry.tpl", { + $tt->process("form.tpl", { warn => %warn ? \%warn : undef, value => { givenname => scalar param("givenname"), @@ -190,7 +212,8 @@ sub insert(\%) { my %value = %{$_[0]}; - my $uuid = sha1_hex($SECRET . values %value); + my $uuid = sha1_hex($SECRET . + join "\0" => @value{@FIELDS{MAN}}); $DBH->begin_work; my $sth; @@ -203,10 +226,10 @@ return (uuid => $uuid, timestamp => $r->{timestamp}); } - $sth = $DBH->prepare("INSERT INTO db - (givenname, surname, mail, uuid, timestamp) - VALUES(?, ?, ?, ?, ?)"); - $sth->execute(@value{qw/givenname surname mail/}, $uuid, time); + local $" = ", "; + $sth = $DBH->prepare("INSERT INTO db (@{$FIELDS{MAN}}, @{$FIELDS{OPT}}, uuid, timestamp) + VALUES(?, ?, ?, ?, ?, ?)"); + $sth->execute(@value{@{$FIELDS{MAN}}, @{$FIELDS{OPT}}}, $uuid, time); $DBH->commit; return (uuid => $uuid, @@ -214,26 +237,53 @@ } -sub confirm($) { - my $uuid = shift; +sub confirm($$) { + my ($uuid, $confirmed) = @_; my %data; $DBH->begin_work; - my $sth = $DBH->prepare("SELECT givenname, surname, mail FROM db WHERE uuid = ?"); + + local $" = ", "; + my $sth = $DBH->prepare("SELECT @{$FIELDS{MAN}}, @{$FIELDS{OPT}} FROM db WHERE uuid = ?"); $sth->execute($uuid); my $r = $sth->fetchrow_hashref; if (!$r) { $DBH->rollback; return (error => "NOT FOUND"); } - %data = ( - givenname => $r->{givenname}, - surname => $r->{surname}, - mail => $r->{mail} - ); + @data{@{$FIELDS{MAN}}} = @{$r}{@{$FIELDS{MAN}}}; + @data{@{$FIELDS{OPT}}} = @{$r}{@{$FIELDS{OPT}}}; + + + if ($confirmed) { + $sth = $DBH->prepare("UPDATE db SET ack = 1 WHERE uuid = ?"); + } + else { + $sth = $DBH->prepare("DELETE FROM db WHERE uuid = ?"); + } + $sth->execute($uuid); + + $DBH->commit; - $sth = $DBH->prepare("UPDATE db SET ack = ? WHERE uuid = ?"); - $sth->execute(1, $uuid); - $DBH->commit; + if ($confirmed) { + sendmail( + To => $data{mail}, + From => "hs+retter\@schlittermann.de", + Subject => "[$SUBJECT] Bestaetigung der Anmeldung", + Message => <<_EOF); +Du bist erfolgreich angemeldet. Für weitere Fragen kontaktiere bitte +hs+retter\@schlittermann.de. +_EOF + } + else { + sendmail( + To => $data{mail}, + From => "hs+retter\@schlittermann.de", + Subject => "[$SUBJECT] Bestaetigung der NICHT-Anmeldung", + Message => <<_EOF); +Wir vergessen Deine Anmeldung. Fuer weitere Fragen kontaktiere bitte +hs+retter\@schlittermann.de. +_EOF + } return %data; }