Skip to content

Commit

Permalink
Item14506: Enhancements to Reset Password
Browse files Browse the repository at this point in the history
 - Avoid sending the die message to the UI if send email fails.
 - Add ability to reset password by email address
 - Other cleanup on sendEmail ... It doesn't need to handle registration
   messages
  • Loading branch information
gac410 committed Oct 13, 2017
1 parent 5f4cdb2 commit f659d6a
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 18 deletions.
2 changes: 1 addition & 1 deletion PasswordManagementPlugin/data/System/ResetPassword.txt
Expand Up @@ -21,7 +21,7 @@
</div>
<div class="foswikiFormStep">
%TABLE{databg="transparent" tableborder="0" tablerules="none"}%
| %MAKETEXT{"Your [[[_1]][username]]:" args="%SYSTEMWEB%.UserName"}% | <input type="text" name="LoginName" value="%URLPARAM{username}%" size="40" class="foswikiInputField" /> |
| %IF{ "{TemplateLogin}{AllowLoginUsingEmailAddress}" then="%MAKETEXT{"Username or email address"}%" else="%MAKETEXT{"Username"}%" }% | <input type="text" name="LoginName" value="%URLPARAM{username}%" size="40" class="foswikiInputField" /> |
</div><!-- /foswikiFormStep-->
<div class="foswikiFormStep foswikiLast">
<input type="hidden" name="action" value="resetPassword">
Expand Down
Expand Up @@ -60,6 +60,38 @@ sub _RESTresetPassword {
throw Foswiki::OopsException( 'password', def => 'no_users_to_reset' );
}

if ( $Foswiki::cfg{TemplateLogin}{AllowLoginUsingEmailAddress}
&& ( $userName =~ $Foswiki::regex{emailAddrRegex} ) )
{

# try email addresses if it is one
my $cuidList = $users->findUserByEmail($userName);

if ( scalar @$cuidList > 1 ) {
throw Foswiki::OopsException(
'password',
topic => $Foswiki::cfg{HomeTopicName},
def => 'reset_bad',
params =>
['The entered email address is not unique. Use a WikiName']
);
}
else {
$userName = @$cuidList[0];
}
}
else {
throw Foswiki::OopsException(
'password',
status => 200,
topic => $Foswiki::cfg{HomeTopicName},
def => 'reset_bad',
params => [
'This Foswiki is not configured to permit access by email address. Please enter a WikiName or Login name.'
],
);
}

my $user = Foswiki::Func::getCanonicalUserID($userName);
unless ( $user && $session->{users}->userExists($user) ) {
throw Foswiki::OopsException(
Expand Down Expand Up @@ -143,7 +175,7 @@ sub _RESTresetPassword {
status => 200,
topic => $Foswiki::cfg{HomeTopicName},
def => 'reset_ok',
params => [ $Foswiki::cfg{Login}{TokenLifetime}, $errors ]
params => [ $Foswiki::cfg{Login}{TokenLifetime} || 900, $errors ]
);
}
else {
Expand All @@ -158,7 +190,7 @@ sub _RESTresetPassword {

=begin TML
---++ StaticMethod RESTchangePassword
---++ StaticMethod RESTchangePassword
Change the user's password. Details of the user and password
are passed in CGI parameters.
Expand Down Expand Up @@ -228,8 +260,9 @@ sub _RESTchangePassword {
if ($resetActive) {
$oldpassword = 1; # Allow password change without oldpassword.
}
elsif ( $users->isAdmin($requestUser)
&& ! length($oldpassword) ) {
elsif ( $users->isAdmin($requestUser)
&& !length($oldpassword) )
{
$oldpassword = 1; # Allow an admin to omit the oldpassword
}
else {
Expand All @@ -244,8 +277,7 @@ sub _RESTchangePassword {
);
}

unless ( $users->checkPassword( $login, $oldpassword ) )
{
unless ( $users->checkPassword( $login, $oldpassword ) ) {
throw Foswiki::OopsException(
'password',
web => $webName,
Expand Down Expand Up @@ -302,27 +334,26 @@ sub _sendEmail {
my ( $session, $template, $data ) = @_;

my $text = $session->templates->readTemplate($template);
$data->{Introduction} ||= '';
$data->{Name} ||= $data->{WikiName};
my @unexpanded;
foreach my $field ( keys %$data ) {
my $f = uc($field);
unless ( $text =~ s/\%$f\%/$data->{$field}/g ) {
unless ( $field =~ m/^Password|Confirm|form|webName/
|| !defined( $data->{$field} )
|| $data->{$field} !~ /\W/ )
{
push( @unexpanded, "$field: $data->{$field}" );
}
}
$text =~ s/\%$f\%/$data->{$field}/g;
}
$text =~ s/%REGISTRATION_DATA%/join("\n", map {"\t* $_" } @unexpanded)/ge;

my $topicObject = Foswiki::Meta->new( $session, $Foswiki::cfg{UsersWebName},
$data->{WikiName} );
$text = $topicObject->expandMacros($text);

return $session->net->sendEmail($text);
# SMELL: For some reason Net::sendEmail issues a "die" if the email address
# is bad. But only in a REST handler. Send to the exact same email from
# UI::Password, and it returns an error without the "die".
# The eval{} avoids the issue.

my $results;
eval { $results = $session->net->sendEmail($text); };

return $results;
}

1;
Expand Down

0 comments on commit f659d6a

Please sign in to comment.