index.cgi
changeset 18 c250bcee5857
parent 17 bf0ff90e2cf5
child 21 12e7ee4c5302
--- a/index.cgi	Wed Jul 06 10:03:18 2011 +0200
+++ b/index.cgi	Thu Jul 07 09:42:53 2011 +0200
@@ -24,6 +24,20 @@
 sub page;
 sub mail;
 
+sub _encrypt {
+    my $_ = encrypt(shift);
+    s/\+/-/g;
+    s/\//_/g;
+    return $_;
+}
+
+sub _decrypt {
+    my $_ = shift;
+    s/_/\//g;
+    s/-/+/g;
+    return decrypt($_);
+}
+
 
 delete @ENV{grep /PATH$/ => keys %ENV};
 $ENV{PATH} = "/usr/bin:/usr/sbin:/bin:/sbin";
@@ -40,6 +54,7 @@
     OPT => [qw[tel]]
 );
 
+
 my %ttconfig = (
     INCLUDE_PATH => "templates",
     VARIABLES => {
@@ -58,14 +73,32 @@
 	print redirect(basename($ENV{SCRIPT_NAME}));
     }
 
+    # ACCESS
+    if (!path_info()) {
+        do_invite();
+	exit 0;
+    }
 
-    # ACCESS
-    # Here we generate a link URL (sent via Mail) containing the
-    # encrypted current timestamp. Accessing the form is only possible
-    # using this link. Note: These links may not be unique!
-    if (!path_info()) {
-	do_invite();
-	exit 0;
+    # /done.<uuid>/ filled forms etc
+    # /done/
+    if (path_info() =~ /^\/?done(?:\.(?<uuid>.*?))?\/(?<step>.*)$/) {
+	my %x = %+;
+	if ($x{step} ~~ [qw(invitation form confirmation)]) {	
+	    eval {
+		page("html.$x{step}.done.tpl", {
+		    done => {
+			map({ ($_, _decrypt(param($_))) } param()),
+		    },
+		    uuid => UUID->new($x{uuid}, map { @$_ } values %FIELDS),
+		});
+		exit 0;
+	    };
+	    die $@ if $@;
+	    if ($@) {
+		page("html.denied.tpl");
+		exit 0;
+	    }
+	}
     }
 
     # /show/(…)
@@ -79,10 +112,12 @@
     }
 
     # /user.<uuid>
-    if (path_info() =~ /^\/?user\.(.*)$/) {
+    if (path_info() =~ /^\/?user\.(.*)(?:\/(.*))?$/) {
 	my $uuid = $1;
 
-	my $confirmed = param("confirm") eq "yes";   
+	if (param("confirm")) {
+
+	my $confirmed = param("confirm") eq "yes" ? 1 : 0;   
 	my %data = confirm($uuid => $confirmed);
 
 	if ($data{error}) {
@@ -95,21 +130,20 @@
 	    confirmed => $confirmed,
 	});
 
-	page("html.confirmed.tpl", {
-	    confirmed => $confirmed,
-	    error => delete $data{error},
-	    value => \%data});
+	print redirect("$SELF/done.$uuid/confirmation?"
+	    . "confirmed=" . _encrypt($confirmed));
+
 	exit 0;
+	}
+
     }
 
     # /tmp.<uuid>
     if (path_info() =~ /^\/?tmp\.(.*)$/) {
 	my $_ = $1;
-	s/_/\//g;
-	s/-/+/g;
 
 	eval {
-	    my $time = decrypt($_) or die "DECRYPTION ERROR";
+	    my $time = _decrypt($_) or die "DECRYPTION ERROR";
 	    $time =~ /^\d+$/ or die "FORMAT ERROR";
 	    time() - $time < (60 * $EXPIRATION) or die "EXPIRED";
 	}; if ($@) {
@@ -154,34 +188,33 @@
 		$warn{$_} = join " ", @{$warn{$_}};
 	    }
 
-	    if (!%warn) {
-		my %r = insert(%value);
-
-		mail("mail.form-ack.tpl", {
-		    to => $value{email},
-		    url => {
-			yes => "$SELF/user.$r{uuid}?confirm=yes",
-			no  => "$SELF/user.$r{uuid}?confirm=no",
+	    if (%warn) {
+		page("html.form.tpl", {
+		    warn => %warn ? \%warn : undef,
+		    value => {
+			givenname => scalar param("givenname"),
+			surname => scalar param("surname"),
+			email => scalar param("email"),
 		    }
 		});
-
-		page("html.form-ack.tpl", {
-		    value => \%value,
-		    created => $r{created},
-		    uuid => $r{uuid},
-		});
 		exit 0;
 	    }
+
+	    my %r = insert(%value);
+
+	    mail("mail.form.done.tpl", {
+		to => $value{email},
+		url => {
+		    yes => "$SELF/user.$r{uuid}?confirm=yes",
+		    no  => "$SELF/user.$r{uuid}?confirm=no",
+		}
+	    });
+
+	    print redirect("$SELF/done.$r{uuid}/form");
+	    exit 0;
 	}
 
-	page("html.form.tpl", {
-	    warn => %warn ? \%warn : undef,
-	    value => {
-		givenname => scalar param("givenname"),
-		surname => scalar param("surname"),
-		email => scalar param("email"),
-	    },
-	} );
+	page("html.form.tpl");
 	exit 0;
     }
 
@@ -205,16 +238,16 @@
 	    my $created = $r->{created};
 	    $DBH->rollback;
 	    return (uuid => $uuid,
-	            created => $r->{created});
+	            exists => $created);
 	}
+
 	local $" = ", ";
 	$sth = $DBH->prepare("INSERT INTO db (@{$FIELDS{MAN}}, @{$FIELDS{OPT}}, uuid, created)
 		VALUES(?, ?, ?, ?, ?, datetime('now'))");
 	$sth->execute(@value{@{$FIELDS{MAN}}, @{$FIELDS{OPT}}}, $uuid);
     $DBH->commit;
 
-    return (uuid => $uuid,
-	    timestamp => undef);
+    return (uuid => $uuid);
 }
 
 sub confirm($$) {
@@ -266,9 +299,7 @@
 		$warn{email} = "INVALID";
 	    }
 	    else {
-		my $xxx = encrypt(time);
-		$xxx =~ s/\+/-/g;
-		$xxx =~ s/\//_/g;
+		my $xxx = _encrypt(time);
 
 		mail("mail.invitation.tpl", {
 		    to   => scalar(param("email")),
@@ -276,7 +307,10 @@
 
 		$sent = param("email");
 	    }
+	    print redirect("$SELF/done/invitation?email=" . _encrypt($sent));
+	    exit 0;
 	}
+	
 	page("html.invitation.tpl", {
 	    sent => $sent,
 	    warn => %warn ? \%warn : undef,
@@ -302,3 +336,28 @@
 	or die "SENDMAIL: $!\n";
 }
 
+{ package UUID;
+  use strict;
+  use warnings;
+
+  sub new {
+    my $self = bless {} => shift;
+    $self->{uuid} = shift;
+    $self->{fields} = [@_];
+    my $sth = $DBH->prepare("SELECT "
+	. join(", " => @{$self->{fields}})
+	. " FROM db WHERE uuid = ?");
+    $sth->execute($self->{uuid});
+    $self->{r} = $sth->fetchrow_hashref;
+    $sth->finish;
+    return undef if not $self->{r};
+    return $self;
+  }
+
+  sub AUTOLOAD {
+    my $self = shift;
+    my ($f) = ($UUID::AUTOLOAD =~ /.*::(.*)/);
+    return $self->{r}{$f};
+  }
+}
+