password_requests.pm: improve password check

* css for form
* return reason for failed password check
* show check reults as error or info
This commit is contained in:
Milan
2021-12-10 16:57:58 +01:00
parent 473144c2eb
commit 124ccdb9a8
3 changed files with 47 additions and 49 deletions

View File

@@ -146,10 +146,10 @@ sub sendToken ($$) {
my $baseUrl = $config->{locations}->{source_base_url} . $config->{locations}->{editor_base_url}; my $baseUrl = $config->{locations}->{source_base_url} . $config->{locations}->{editor_base_url};
my $url = $baseUrl . "/request-password.cgi?token=" . $entry->{token}; my $url = $baseUrl . "/request-password.cgi?token=" . $entry->{token};
my $content = "Hi,$user->{full_name}\n\n"; my $content = "Hi,$user->{full_name}\n\n";
$content .= "Someone just tried to reset your password for $baseUrl.\n\n"; $content .= "Someone has just tried to reset your password for $baseUrl.\n\n";
$content .= "If you like to set a new password, please follow the link below\n"; $content .= "If you want to set a new password, please follow this link\n";
$content .= $url . "\n\n"; $content .= $url . "\n\n";
$content .= "If you do not like to set a new password, please ignore this mail.\n"; $content .= "If you do not want to set a new password, please ignore this mail.\n";
mail::send( mail::send(
{ {
@@ -171,21 +171,21 @@ sub changePassword ($$$) {
my $permissions = $request->{permissions}; my $permissions = $request->{permissions};
unless ( ( defined $userName ) || ( $userName eq '' ) ) { unless ( ( defined $userName ) || ( $userName eq '' ) ) {
return { error => 'user not found' }; return { error => 'The User could not be found.' };
} }
my $user = uac::get_user( $config, $userName ); my $user = uac::get_user( $config, $userName );
unless ( ( defined $user ) && ( defined $user->{id} ) && ( $user->{id} ne '' ) ) { unless ( ( defined $user ) && ( defined $user->{id} ) && ( $user->{id} ne '' ) ) {
return { error => 'user id not found' }; return { error => 'Te User ID could not be found.' };
} }
unless ( password_requests::checkPassword( $params->{user_password} ) ) { if ( my $msg = password_requests::isPasswordInvalid( $params->{user_password} ) ) {
return { error => 'password does not meet requirements' }; return { error => $msg } if $msg;
} }
if ( $params->{user_password} ne $params->{user_password2} ) { if ( $params->{user_password} ne $params->{user_password2} ) {
return { error => 'entered passwords do not match' }; return { error => 'The passwords entered do not match.' };
} }
my $crypt = auth::crypt_password( $params->{user_password} ); my $crypt = auth::crypt_password( $params->{user_password} );
@@ -196,41 +196,30 @@ sub changePassword ($$$) {
$config->{access}->{write} = 1; $config->{access}->{write} = 1;
my $result = uac::update_user( $config, $user ); my $result = uac::update_user( $config, $user );
$config->{access}->{write} = 0; $config->{access}->{write} = 0;
return { success => "password changed for $userName" }; return { success => "The password was changed for $userName." };
} }
sub checkPassword($) { sub isPasswordInvalid($) {
my $password = shift; my $password = shift;
unless ( defined $password || $password eq '' ) { unless ( defined $password || $password eq '' ) {
error("password is empty"); return "The password must not be empty.";
return;
} }
if ( length($password) < 8 ) { if ( length($password) < 8 ) {
error("password to short"); return "The password must have at least 8 characters.";
return 0;
} }
unless ( $password =~ /[a-z]/ ) { unless ( $password =~ /[a-z]/ ) {
error("password should contains at least one small character"); return "The password must contain at least one small character.";
return 0;
} }
unless ( $password =~ /[A-Z]/ ) { unless ( $password =~ /[A-Z]/ ) {
error("password should contains at least one big character"); return "The password must contain at least one big character";
return 0;
} }
unless ( $password =~ /[0-9]/ ) { unless ( $password =~ /[0-9]/ ) {
error("password should contains at least one number"); return "The password must contain at least one number.";
return 0;
} }
unless ( $password =~ /[^a-zA-Z0-9]/ ) { unless ( $password =~ /[^a-zA-Z0-9]/ ) {
error("password should contains at least one special character"); return "The password must contain at least one special character.";
return 0;
} }
return 1; return 0;
}
sub error($) {
my $msg = shift;
print "ERROR: $msg<br/>\n";
} }
#do not delete last line! #do not delete last line!

View File

@@ -27,11 +27,25 @@ print "Content-type:text/html\n\n";
print qq{<!DOCTYPE html> print qq{<!DOCTYPE html>
<html> <html>
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
</head> </head>
<style>
* {text-align:center; font-family: sans-serif;}
div,input {padding:6px;margin:6px;}
.error {background:red; color:white;}
.info {background:blue; color:white;}
</style>
<body> <body>
<h1>Change your password</h1>
}; };
sub info{
print qq{<div class="info">$_[0]</div>\n};
}
sub error{
print qq{<div class="error">$_[0]</div>\n};
}
if ( defined $params->{user} ) { if ( defined $params->{user} ) {
sendToken( $config, $params ); sendToken( $config, $params );
return; return;
@@ -45,9 +59,9 @@ sub sendToken {
my $params = shift; my $params = shift;
my $entry = password_requests::sendToken( $config, { user => $params->{user} } ); my $entry = password_requests::sendToken( $config, { user => $params->{user} } );
if ( defined $entry ) { if ( defined $entry ) {
print "Please check you mails\n"; info "Please check you mails.";
} else { } else {
print "Sorry\n"; error "Sorry.";
} }
} }
@@ -59,20 +73,17 @@ sub checkToken {
my $entry = password_requests::get( $config, { token => $token } ); my $entry = password_requests::get( $config, { token => $token } );
unless ( defined $entry ) { unless ( defined $entry ) {
print "invalid token\n"; return error "The token is invalid.";
return undef;
} }
print STDERR Dumper($entry);
my $created_at = $entry->{created_at}; my $created_at = $entry->{created_at};
unless ( defined $created_at ) { unless ( defined $created_at ) {
print "invalid token age\n"; return error "The token age is invalid.";
return undef;
} }
my $age = time() - time::datetime_to_time($created_at); my $age = time() - time::datetime_to_time($created_at);
if ( $age > 600 ) { if ( $age > 600 ) {
print "token is too old\n"; error "The token is too old.";
password_requests::delete( $config, { token => $token } ); password_requests::delete( $config, { token => $token } );
return undef; return undef;
} }
@@ -83,7 +94,7 @@ sub checkToken {
$config->{access}->{write} = 0; $config->{access}->{write} = 0;
if ( $entry->{max_attempts} > 10 ) { if ( $entry->{max_attempts} > 10 ) {
print "too many failed attempts, please request a new token by mail\n"; error "Too many failed attempts. Please request a new token by mail.";
password_requests::delete( $config, { token => $token } ); password_requests::delete( $config, { token => $token } );
return undef; return undef;
} }
@@ -100,24 +111,20 @@ sub checkToken {
params => { checked => $params } params => { checked => $params }
}; };
my $result = password_requests::changePassword( $config, $request, $user ); my $result = password_requests::changePassword( $config, $request, $user );
if ( defined $result->{error} ) { if ( defined $result->{error} ) {
error $result->{error};
#print "sorry\n";
print $result->{error} . "\n";
printForm($token); printForm($token);
} }
if ( defined $result->{success} ) { if ( defined $result->{success} ) {
info $result->{success};
#print "success\n";
print $result->{success} . "\n";
password_requests::delete( $config, { user => $user } ); password_requests::delete( $config, { user => $user } );
my $url = $config->{locations}->{editor_base_url}; my $url = $config->{locations}->{editor_base_url};
print qq{ print qq{
<script type="text/javascript"> <script type="text/javascript">
window.location = "$url"; setTimeout( () => window.location = "$url", 3000);
</script> </script>
You will be forwarded to $url …
}; };
} }
} }
@@ -129,8 +136,8 @@ sub printForm {
print qq{ print qq{
<form method="post"> <form method="post">
<input type="hidden" name="token" value="$token"> <input type="hidden" name="token" value="$token">
<input type="password" name="user_password" placeholder="enter new password"> <input type="password" name="user_password" placeholder="Please enter a password">
<input type="password" name="user_password2" placeholder="repeat password"> <input type="password" name="user_password2" placeholder="Please repeat the password">
<input type="submit" name="action" value="change"> <input type="submit" name="action" value="change">
</form> </form>
}; };

View File

@@ -200,7 +200,9 @@ sub update_user {
return; return;
} }
return unless password_requests::checkPassword( $params->{user_password} ); my $error = password_requests::isPasswordInvalid( $params->{user_password} );
error($error) if $error;
return if $error;
if ( $params->{user_password} ne $params->{user_password2} ) { if ( $params->{user_password} ne $params->{user_password2} ) {
error('password mismatch'); error('password mismatch');