index.cgi
changeset 2 687f53554299
parent 1 5d275133868b
child 3 17ddf9a1e376
--- 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;
 }