summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Friesel <derf@finalrewind.org>2019-04-30 18:05:07 +0200
committerDaniel Friesel <derf@finalrewind.org>2019-04-30 18:05:07 +0200
commit048767149e571469d888ec81d324caa7b3b64671 (patch)
treed713208b260e83b9b134b48d61cf2817718efde0
parenta57a24c2d68daa4d4561ed9035c863e574cdc70a (diff)
use a separate table for registration tokens
-rwxr-xr-xlib/Travelynx.pm37
-rw-r--r--lib/Travelynx/Command/database.pm32
-rw-r--r--lib/Travelynx/Command/maintenance.pm3
-rw-r--r--lib/Travelynx/Controller/Account.pm10
-rw-r--r--t/02-registration.t8
-rw-r--r--templates/_invalid_input.html.ep2
6 files changed, 70 insertions, 22 deletions
diff --git a/lib/Travelynx.pm b/lib/Travelynx.pm
index 99d0fb2..b04526a 100755
--- a/lib/Travelynx.pm
+++ b/lib/Travelynx.pm
@@ -728,17 +728,26 @@ sub startup {
);
$self->helper(
- 'get_user_token' => sub {
- my ( $self, $uid ) = @_;
+ 'verify_registration_token' => sub {
+ my ( $self, $uid, $token ) = @_;
- my $res = $self->pg->db->select(
- 'users',
- [ 'name', 'status', 'token' ],
- { id => $uid }
+ my $db = $self->pg->db;
+ my $tx = $db->begin;
+
+ my $res = $db->select(
+ 'pending_registrations',
+ 'count(*) as count',
+ {
+ user_id => $uid,
+ token => $token
+ }
);
- if ( my $ret = $res->array ) {
- return @{$ret};
+ if ( $res->hash->{count} ) {
+ $db->update( 'users', { status => 1 }, { id => $uid } );
+ $db->delete( 'pending_registrations', { user_id => $uid } );
+ $tx->commit;
+ return 1;
}
return;
}
@@ -976,15 +985,23 @@ sub startup {
status => 0,
public_level => 0,
email => $email,
- token => $token,
password => $password,
registered_at => $now,
last_seen => $now,
},
{ returning => 'id' }
);
+ my $uid = $res->hash->{id};
+
+ $db->insert(
+ 'pending_registrations',
+ {
+ user_id => $uid,
+ token => $token
+ }
+ );
- return $res->hash->{id};
+ return $uid;
}
);
diff --git a/lib/Travelynx/Command/database.pm b/lib/Travelynx/Command/database.pm
index 05b43d6..79ff086 100644
--- a/lib/Travelynx/Command/database.pm
+++ b/lib/Travelynx/Command/database.pm
@@ -424,6 +424,38 @@ my @migrations = (
}
);
},
+
+ # v9 -> v10
+ # Add pending_registrations table. The users.token column is no longer
+ # needed.
+ sub {
+ my ($db) = @_;
+ $db->query(
+ qq{
+ create table pending_registrations (
+ user_id integer not null references users (id) primary key,
+ token varchar(80) not null
+ );
+ comment on table pending_registrations is 'Verification tokens for newly registered accounts';
+ update schema_version set version = 10;
+ }
+ );
+ my $res = $db->select( 'users', [ 'id', 'token' ], { status => 0 } );
+ for my $user ( $res->hashes->each ) {
+ $db->insert(
+ 'pending_registrations',
+ {
+ user_id => $user->{id},
+ token => $user->{token}
+ }
+ );
+ }
+ $db->query(
+ qq{
+ alter table users drop column token;
+ }
+ );
+ },
);
sub setup_db {
diff --git a/lib/Travelynx/Command/maintenance.pm b/lib/Travelynx/Command/maintenance.pm
index 8c07728..fc64884 100644
--- a/lib/Travelynx/Command/maintenance.pm
+++ b/lib/Travelynx/Command/maintenance.pm
@@ -59,7 +59,8 @@ sub run {
}
);
}
- $db->delete( 'users', { id => $user->{id} } );
+ $db->delete( 'pending_registrations', { user_id => $user->{id} } );
+ $db->delete( 'users', { id => $user->{id} } );
printf( "Pruned unverified user %d\n", $user->{id} );
}
diff --git a/lib/Travelynx/Controller/Account.pm b/lib/Travelynx/Controller/Account.pm
index dc3adb4..e4b385c 100644
--- a/lib/Travelynx/Controller/Account.pm
+++ b/lib/Travelynx/Controller/Account.pm
@@ -159,20 +159,16 @@ sub verify {
my $id = $self->stash('id');
my $token = $self->stash('token');
- my @db_user = $self->get_user_token($id);
-
- if ( not @db_user ) {
+ if ( not $id =~ m{ ^ \d+ $ }x ) {
$self->render( 'register', invalid => 'token' );
return;
}
- my ( $db_name, $db_status, $db_token ) = @db_user;
-
- if ( not $db_name or $token ne $db_token or $db_status != 0 ) {
+ if ( not $self->verify_registration_token( $id, $token ) ) {
$self->render( 'register', invalid => 'token' );
return;
}
- $self->app->pg->db->update( 'users', { status => 1 }, { id => $id } );
+
$self->render( 'login', from => 'verification' );
}
diff --git a/t/02-registration.t b/t/02-registration.t
index 89bf475..b595337 100644
--- a/t/02-registration.t
+++ b/t/02-registration.t
@@ -71,9 +71,11 @@ $t->post_ok(
);
$t->status_is(200)->content_like(qr{nicht freigeschaltet});
-my $res = $t->app->pg->db->select( 'users', [ 'id', 'token' ],
- { name => 'someone' } );
-my ( $uid, $token ) = @{ $res->hash }{qw{id token}};
+my $res = $t->app->pg->db->select( 'users', ['id'], { name => 'someone' } );
+my $uid = $res->hash->{id};
+$res = $t->app->pg->db->select( 'pending_registrations', ['token'],
+ { user_id => $uid } );
+my $token = $res->hash->{token};
# Successful verification
$t->get_ok("/reg/${uid}/${token}");
diff --git a/templates/_invalid_input.html.ep b/templates/_invalid_input.html.ep
index b6353d7..ad01c15 100644
--- a/templates/_invalid_input.html.ep
+++ b/templates/_invalid_input.html.ep
@@ -47,7 +47,7 @@
% }
% elsif ($invalid eq 'token') {
<span class="card-title">Ungültiger Token</span>
- <p>Die Verifikation deiner Mail-Adresse ist fehlgeschlagen oder du hast den Token schon einmal verwendet.</p>
+ <p>Möglicherweise ist die Verifikation deiner Mail-Adresse fehlgeschlagen oder du hast den Token schon einmal verwendet.</p>
% }
% elsif ($invalid eq 'confirmation') {
<span class="card-title">Account nicht freigeschaltet</span>