summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYorhel <git@yorhel.nl>2011-08-23 14:55:14 +0200
committerYorhel <git@yorhel.nl>2011-08-23 14:55:14 +0200
commit18c681f059389646d0b48b305ccf5e7622cb47e4 (patch)
tree61b631703f3c3c68913502decf56c752683c8a2d
parent341928b722fa6c276ae8c091aebd3f33cc2cbd60 (diff)
Re-structured password recovery feature
Rather than setting an automatically password, reset the password and send an email with a secure token instead. The password can then be set again using this token. This doesn't really have an advantage at this point, just makes the interface and code more consistent when I update the registration code to do something similar.
-rw-r--r--data/lang.txt117
-rw-r--r--lib/VNDB/Handler/Users.pm46
-rw-r--r--lib/VNDB/Util/Auth.pm30
3 files changed, 117 insertions, 76 deletions
diff --git a/data/lang.txt b/data/lang.txt
index 9c981418..dee67f24 100644
--- a/data/lang.txt
+++ b/data/lang.txt
@@ -6420,64 +6420,32 @@ nl : Wachtwoord vergeten?
:_newpass_mail_body
en : Hello [_1]
- Your password has been reset, you can now login at http://vndb.org/ with the
- following information:
+ Your VNDB.org login has been disabled, you can now set a new password by following the link below:
- Username: [_1]
- Password: [_2]
+ [_2]
Now don't forget your password again! :-)
vndb.org
-ru : Привет, [_1]
-
- Ваш пароль был сброшен, теперь вы можете пройти авторизацию на http://vndb.org/
- со следующими данными:
-
- Имя пользователя: [_1]
- Ваш новый пароль: [_2]
-
- Постарайтесь больше не забывать свой пароль! :-)
-
- vndb.org
-cs : Zdravíme, [_1]
-
- Vaše heslo bylo změněno, nyní se můžete přihlásit na http://vndb.org
- s následujícími informacemi:
-
- Uživatelské jmno: [_1]
- Heslo: [_2]
-
- A snažte se už heslo znovu nezapomenout! :-)
-hu : Üdv [_1]
-
- A jelszavad vissza lett állítva, most már bejelentkezhetsz a http://vndb.org/ címen az
- új adataiddal:
-
- Felhasználónév: [_1]
- Jelszó: [_2]
-
- Legközelebb próbáld meg nem elfelejteni a jelszavad! :-)
-
- vndb.org
+ru*:
+cs*:
+hu*:
nl : Hallo [_1],
- Je wachtwoord is gereset, je kan nu inloggen op http://vndb.org/ met de
- volgende gegevens:
+ Je VNDB.org account is tijdelijk uitgeschakeld, je kan nu een nieuw wachtwoord instellen door de volgende link te volgen:
- Gebruikersnaam: [_1]
- Wachtwoord: [_2]
+ [_2]
Vergeet je wachtwoord in de toekomst niet weer! :-)
vndb.org
:_newpass_mail_subject
-en : New password for [_1]
-ru : Новый пароль для [_1]
-cs : Nové heslo pro uživatele [_1]
-hu : Új jelszó [_1]-nak
-nl : Nieuw wachtwoord voor [_1]
+en : Password reset for [_1]
+ru*: Новый пароль для [_1]
+cs*: Nové heslo pro uživatele [_1]
+hu*: Új jelszó [_1]-nak
+nl : Wachtwoord gereset voor [_1]
:_newpass_title
en : Forgot password
@@ -6489,20 +6457,20 @@ nl : Wachtwoord vergeten
:_newpass_msg
en : Forgot your password and can't login to VNDB anymore?
Don't worry! Just give us the email address you used to register on VNDB,
- and we'll send you a new password within a few minutes!
-ru : Забыли пароль и больше не можете авторизоваться на VNDB?
+ and we'll send you instructions to set a new password within a few minutes!
+ru*: Забыли пароль и больше не можете авторизоваться на VNDB?
Без паники! Всё что вам нужно - указать адрес электронной почты, который
вы использовали для регистрации в VNDB, и мы вышлем вам новый пароль за
считанные минуты!
-cs : Zapomněli jste své heslo a nemůžete se přihlásit na VNDB?
+cs*: Zapomněli jste své heslo a nemůžete se přihlásit na VNDB?
Nebojte! Stačí zadat e-mailovou adresu, se kterou jste se na VNDB registrovali,
a my vám do několika minut pošleme heslo nové!
-hu : Elfelejtetted a jelszavad és nem tudsz bejelentkezni a VNBD-be?
+hu*: Elfelejtetted a jelszavad és nem tudsz bejelentkezni a VNBD-be?
Ne aggódj! Csak add meg nekünk az email címet amivel regisztráltál,
s egy pár percen belül kapsz tőlünk egy új jelszót!
nl : Je wachtwoord vergeten?
Geen nood! Geef aan wat je emailadres was die je hebt gebruikt om je te registreren op VNDB,
- en je krijgt binnen een paar minuten je nieuwe wachtwoord op je mail!
+ en je krijgt binnen een paar minuten instructies op je mail om een nieuw wachtwoord in te stellen!
:_newpass_reset_title
en : Reset password
@@ -6533,26 +6501,37 @@ hu : Jelszó visszaállitás
nl : Wachtwoord gereset
:_newpass_sent_msg
-en : Your password has been reset and your new password should reach your mailbox in a few minutes.[br]
- You can always change your password again after logging in.[br]
- [br]
- [url,/u/login,Login] - [url,/,Home]
-ru : Ваш пароль был сброшен. Через несколько минут на ваш ящик прибудет письмо с новым паролем.[br]
- Вы всегда можете изменить пароль после того, как прошли авторизацию.[br]
- [br]
- [url,/u/login,Вход] - [url,/,Главная]
-cs : Vaše heslo bylo změněno a vaše nové heslo by mělo být za několik minut doručeno do vaší schránky.[br]
- Vždy můžete změnit vaše heslo po přihlášení.[br]
- [br]
- [url,/u/login,Přihlásit] - [url,/,Home]
-hu : A jelszavad vissza lett állítva s pár percen belül kapsz egy ujjat a postafiókodba.[br]
- Miután bejelentkezel, nyugodtan megváltoztathatod a jelszavad amire akarod.[br]
- [br]
- [url,/u/login,Bejelentkezés] - [url,/,Kezdőlap]
-nl : Je wachtwoord is gereset, en je nieuwe wachtwoord zal binnen een paar minuten in je mailbox verschijnen.[br]
- Je kan je wachtwoord na het inloggen altijd nog veranderen.[br]
- [br]
- [url,/u/login,Login] - [url,/,Home]
+en : Your password has been reset and instructions to set a new one should reach your mailbox in a few minutes.
+ru*:
+cs*:
+hu*:
+nl : Je wachtwoord is gereset, en instructies om een nieuwe te zetten zullen binnen een paar minuten in je mailbox verschijnen.
+
+
+# Set password page (/u+/setpass)
+# The labels before the input boxes are the same as _register_password and _register_confirm.
+
+:_setpass_title
+en : Set password for [_1]
+ru*:
+cs*:
+hu*:
+nl : Stel wachtwoord in voor [_1]
+
+:_setpass_title
+en : Set password for [_1]
+ru*:
+cs*:
+hu*:
+nl : Stel wachtwoord in voor [_1]
+
+:_setpass_msg
+en : Now you can set a password for your account. You will be logged in automatically after your password has been saved.
+ru*:
+cs*:
+hu*:
+nl : Nu kan je een wachtwoord instellen voor je account. Je wordt automatisch ingelogd nadat je wachtwoord is opgeslagen.
+
# Register new account (/u/register)
diff --git a/lib/VNDB/Handler/Users.pm b/lib/VNDB/Handler/Users.pm
index dc748f75..641190aa 100644
--- a/lib/VNDB/Handler/Users.pm
+++ b/lib/VNDB/Handler/Users.pm
@@ -14,6 +14,7 @@ TUWF::register(
qr{u([1-9]\d*)/logout} => \&logout,
qr{u/newpass} => \&newpass,
qr{u/newpass/sent} => \&newpass_sent,
+ qr{u([1-9]\d*)/setpass} => \&setpass,
qr{u/register} => \&register,
qr{u([1-9]\d*)/edit} => \&edit,
qr{u([1-9]\d*)/posts} => \&posts,
@@ -187,12 +188,11 @@ sub newpass {
$frm->{_err} = [ 'nomail' ] if !$u || !$u->{id};
}
if(!$frm->{_err}) {
- my @chars = ( 'A'..'Z', 'a'..'z', 0..9 );
- my $pass = join '', map $chars[int rand $#chars+1], 0..8;
my %o;
- ($o{passwd}, $o{salt}) = $self->authPreparePass($pass);
+ my $token;
+ ($token, $o{passwd}, $o{salt}) = $self->authPrepareReset();
$self->dbUserEdit($u->{id}, %o);
- $self->mail(mt('_newpass_mail_body', $u->{username}, $pass),
+ $self->mail(mt('_newpass_mail_body', $u->{username}, "$self->{url}/u$u->{id}/setpass?t=$token"),
To => $frm->{mail},
From => 'VNDB <noreply@vndb.org>',
Subject => mt('_newpass_mail_subject', $u->{username}),
@@ -230,6 +230,44 @@ sub newpass_sent {
}
+sub setpass {
+ my($self, $uid) = @_;
+ return $self->resRedirect('/') if $self->authInfo->{id};
+
+ my $t = $self->formValidate({get => 't', regex => qr/^[a-f0-9]{40}$/i });
+ return $self->resNotFound if $t->{_err};
+ $t = $t->{t};
+
+ my $u = $self->dbUserGet(uid => $uid, what => 'extended')->[0];
+ return $self->resNotFound if !$u || !$self->authValidateReset($u, $t);
+
+ my $frm;
+ if($self->reqMethod eq 'POST') {
+ return if !$self->authCheckCode("/u$u->{id}/setpass?t=$t");
+ $frm = $self->formValidate(
+ { post => 'usrpass', minlength => 4, maxlength => 64, template => 'asciiprint' },
+ { post => 'usrpass2', minlength => 4, maxlength => 64, template => 'asciiprint' },
+ );
+ push @{$frm->{_err}}, 'passmatch' if $frm->{usrpass} ne $frm->{usrpass2};
+
+ if(!$frm->{_err}) {
+ my %o;
+ ($o{passwd}, $o{salt}) = $self->authPreparePass($frm->{usrpass});
+ $self->dbUserEdit($uid, %o);
+ return $self->authLogin($u->{username}, $frm->{usrpass}, "/u$uid");
+ }
+ }
+
+ $self->htmlHeader(title => mt('_setpass_title', $u->{username}), noindex => 1);
+ $self->htmlForm({ frm => $frm, action => "/u$u->{id}/setpass?t=$t" }, setpass => [ mt('_setpass_title', $u->{username}),
+ [ static => nolabel => 1, content => mt '_setpass_msg' ],
+ [ passwd => short => 'usrpass', name => mt('_register_password') ],
+ [ passwd => short => 'usrpass2', name => mt('_register_confirm') ],
+ ]);
+ $self->htmlFooter;
+}
+
+
sub register {
my $self = shift;
return $self->resRedirect('/') if $self->authInfo->{id};
diff --git a/lib/VNDB/Util/Auth.pm b/lib/VNDB/Util/Auth.pm
index 06ed1984..c7e8b973 100644
--- a/lib/VNDB/Util/Auth.pm
+++ b/lib/VNDB/Util/Auth.pm
@@ -13,7 +13,10 @@ use TUWF ':html';
use VNDB::Func;
-our @EXPORT = qw| authInit authLogin authLogout authInfo authCan authPreparePass authGetCode authCheckCode authPref |;
+our @EXPORT = qw|
+ authInit authLogin authLogout authInfo authCan authPreparePass
+ authPrepareReset authValidateReset authGetCode authCheckCode authPref
+|;
# initializes authentication information and checks the vndb_auth cookie
@@ -114,7 +117,7 @@ sub _authCheck {
# Encryption algorithm for user passwords
# Arguments: self, pass, salt
# Returns: encrypted password (in hex)
-sub _authEncryptPass{
+sub _authEncryptPass {
my($self, $pass, $salt, $bin) = @_;
return sha256_hex($self->{global_salt} . encode_utf8($pass) . encode_utf8($salt));
}
@@ -123,7 +126,7 @@ sub _authEncryptPass{
# Prepares a plaintext password for database storage
# Arguments: pass
# Returns: list (pass, salt)
-sub authPreparePass{
+sub authPreparePass {
my($self, $pass) = @_;
my $salt = join '', map chr(rand(93)+33), 1..9;
my $hash = _authEncryptPass($self, $pass, $salt);
@@ -131,6 +134,27 @@ sub authPreparePass{
}
+# Generates a random token that can be used to reset the password.
+# Returns: token, token-encrypted, salt
+sub authPrepareReset {
+ my $self = shift;
+ my $token = sha1_hex(join('', Time::HiRes::gettimeofday()) . join('', map chr(rand(93)+33), 1..9));
+ my $salt = join '', map chr(rand(93)+33), 1..9;
+ my $token_e = sha1_hex(lc($token).$salt);
+ return ($token, $token_e, $salt);
+}
+
+
+# Checks whether the password reset token is valid.
+# Arguments: $u obj, token
+sub authValidateReset {
+ my($self, $u, $t) = @_;
+ return 0 if !$u->{salt} || !$u->{passwd} || length $u->{passwd} != 40
+ || lc sha1_hex(lc($t).$u->{salt}) ne lc $u->{passwd};
+ return 1;
+}
+
+
# Generate a code to be used later on to validate that the form was indeed
# submitted from our site and by the same user/visitor. Not limited to
# logged-in users.