use a separate table for registration tokens
This commit is contained in:
parent
a57a24c2d6
commit
048767149e
6 changed files with 70 additions and 22 deletions
|
@ -728,17 +728,26 @@ sub startup {
|
||||||
);
|
);
|
||||||
|
|
||||||
$self->helper(
|
$self->helper(
|
||||||
'get_user_token' => sub {
|
'verify_registration_token' => sub {
|
||||||
my ( $self, $uid ) = @_;
|
my ( $self, $uid, $token ) = @_;
|
||||||
|
|
||||||
my $res = $self->pg->db->select(
|
my $db = $self->pg->db;
|
||||||
'users',
|
my $tx = $db->begin;
|
||||||
[ 'name', 'status', 'token' ],
|
|
||||||
{ id => $uid }
|
my $res = $db->select(
|
||||||
|
'pending_registrations',
|
||||||
|
'count(*) as count',
|
||||||
|
{
|
||||||
|
user_id => $uid,
|
||||||
|
token => $token
|
||||||
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
if ( my $ret = $res->array ) {
|
if ( $res->hash->{count} ) {
|
||||||
return @{$ret};
|
$db->update( 'users', { status => 1 }, { id => $uid } );
|
||||||
|
$db->delete( 'pending_registrations', { user_id => $uid } );
|
||||||
|
$tx->commit;
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -976,15 +985,23 @@ sub startup {
|
||||||
status => 0,
|
status => 0,
|
||||||
public_level => 0,
|
public_level => 0,
|
||||||
email => $email,
|
email => $email,
|
||||||
token => $token,
|
|
||||||
password => $password,
|
password => $password,
|
||||||
registered_at => $now,
|
registered_at => $now,
|
||||||
last_seen => $now,
|
last_seen => $now,
|
||||||
},
|
},
|
||||||
{ returning => 'id' }
|
{ returning => 'id' }
|
||||||
);
|
);
|
||||||
|
my $uid = $res->hash->{id};
|
||||||
|
|
||||||
return $res->hash->{id};
|
$db->insert(
|
||||||
|
'pending_registrations',
|
||||||
|
{
|
||||||
|
user_id => $uid,
|
||||||
|
token => $token
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
return $uid;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -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 {
|
sub setup_db {
|
||||||
|
|
|
@ -59,6 +59,7 @@ sub run {
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
$db->delete( 'pending_registrations', { user_id => $user->{id} } );
|
||||||
$db->delete( 'users', { id => $user->{id} } );
|
$db->delete( 'users', { id => $user->{id} } );
|
||||||
printf( "Pruned unverified user %d\n", $user->{id} );
|
printf( "Pruned unverified user %d\n", $user->{id} );
|
||||||
}
|
}
|
||||||
|
|
|
@ -159,20 +159,16 @@ sub verify {
|
||||||
my $id = $self->stash('id');
|
my $id = $self->stash('id');
|
||||||
my $token = $self->stash('token');
|
my $token = $self->stash('token');
|
||||||
|
|
||||||
my @db_user = $self->get_user_token($id);
|
if ( not $id =~ m{ ^ \d+ $ }x ) {
|
||||||
|
|
||||||
if ( not @db_user ) {
|
|
||||||
$self->render( 'register', invalid => 'token' );
|
$self->render( 'register', invalid => 'token' );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
my ( $db_name, $db_status, $db_token ) = @db_user;
|
if ( not $self->verify_registration_token( $id, $token ) ) {
|
||||||
|
|
||||||
if ( not $db_name or $token ne $db_token or $db_status != 0 ) {
|
|
||||||
$self->render( 'register', invalid => 'token' );
|
$self->render( 'register', invalid => 'token' );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
$self->app->pg->db->update( 'users', { status => 1 }, { id => $id } );
|
|
||||||
$self->render( 'login', from => 'verification' );
|
$self->render( 'login', from => 'verification' );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -71,9 +71,11 @@ $t->post_ok(
|
||||||
);
|
);
|
||||||
$t->status_is(200)->content_like(qr{nicht freigeschaltet});
|
$t->status_is(200)->content_like(qr{nicht freigeschaltet});
|
||||||
|
|
||||||
my $res = $t->app->pg->db->select( 'users', [ 'id', 'token' ],
|
my $res = $t->app->pg->db->select( 'users', ['id'], { name => 'someone' } );
|
||||||
{ name => 'someone' } );
|
my $uid = $res->hash->{id};
|
||||||
my ( $uid, $token ) = @{ $res->hash }{qw{id token}};
|
$res = $t->app->pg->db->select( 'pending_registrations', ['token'],
|
||||||
|
{ user_id => $uid } );
|
||||||
|
my $token = $res->hash->{token};
|
||||||
|
|
||||||
# Successful verification
|
# Successful verification
|
||||||
$t->get_ok("/reg/${uid}/${token}");
|
$t->get_ok("/reg/${uid}/${token}");
|
||||||
|
|
|
@ -47,7 +47,7 @@
|
||||||
% }
|
% }
|
||||||
% elsif ($invalid eq 'token') {
|
% elsif ($invalid eq 'token') {
|
||||||
<span class="card-title">Ungültiger Token</span>
|
<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') {
|
% elsif ($invalid eq 'confirmation') {
|
||||||
<span class="card-title">Account nicht freigeschaltet</span>
|
<span class="card-title">Account nicht freigeschaltet</span>
|
||||||
|
|
Loading…
Reference in a new issue