--- 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;
}
+ # /<uuid>.tmp
+ # /<uuid>.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;
}