diff -r bf0ff90e2cf5 -r c250bcee5857 index.cgi --- 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./ filled forms etc + # /done/ + if (path_info() =~ /^\/?done(?:\.(?.*?))?\/(?.*)$/) { + 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. - 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. 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}; + } +} +