3

We need to enforce password complexity in a wordpress site, we used this article:

http://www.webtipblog.com/force-password-complexity-requirements-wordpress/

We created the following in functions.php:

add_action('user_profile_update_errors', 'validateProfileUpdate', 10, 3 );
add_filter('registration_errors', 'validateRegistration', 10, 3 );
add_action('validate_password_reset', 'validatePasswordReset', 10, 2 );

function validateProfileUpdate( WP_Error &$errors, $update, &$user ) {
    return validateComplexPassword( $errors );
}

function validateRegistration( WP_Error &$errors, $sanitized_user_login, $user_email ) {
    return validateComplexPassword( $errors );
}

function validatePasswordReset( WP_Error &$errors, $userData ) {
    return validateComplexPassword( $errors );
}

function validateComplexPassword( $errors ) {

    $password = ( isset( $_POST[ 'pass1' ] ) && trim( $_POST[ 'pass1' ] ) ) ? $_POST[ 'pass1' ] : null;

    if ( empty( $password ) || ( $errors->get_error_data( 'pass' ) ) )
        return $errors;

    $passwordValidation = validatePassword($password);

    if ( $passwordValidation !== true ) {
        $errors->add( "pass", "<strong>ERROR</strong>: " . $passwordValidation . "." );
    }

    return $errors;
}

function validatePassword($Password) {
    //#### Check it's greater than 6 Characters
    if (strlen($Password) < 6) {
        return "Password is too short (" . strlen($Password) . "), please use 6 characters or more.";
    }

    //#### Test password has uppercase and lowercase letters
    if (preg_match("/^(?=.*[a-z])(?=.*[A-Z]).+$/", $Password) !== 1) {
        return "Password does not contain a mix of uppercase & lowercase characters.";
    }

    //#### Test password has mix of letters and numbers
    if (preg_match("/^((?=.*[a-z])|(?=.*[A-Z]))(?=.*\d).+$/", $Password) !== 1) {
        return "Password does not contain a mix of letters and numbers.";
    }

    //#### Password looks good
    return true;
}

As you can see, we've made use of the validate_password_reset hook & used it to call our bespoke validatePassword() function that tests the password with a couple of simple regular expressions.

However, this code just doesn't seem to be called at all when a user resets their password via wp-login.php - we know this because its still allowing us to enter the password "woof" (which is clearly invalid) and to double check we put some code in the validateComplexPassword() function to send us an email, again, no email was fired.

Is there something wrong with our code? is the validate_password_reset action no longer called? Help :)

Edit: we have noticed the following in the php error log - could this be the problem?

[12-Jun-2014 14:38:12 UTC] PHP Warning:  Parameter 1 to mycohens_validatePasswordReset() expected to be a reference, value given in C:\inetpub\wwwroot\www.cohenschemist.co.uk\wp-includes\plugin.php on line 470

Edit 2: Attempting to change our password via wp-admin/profile.php is working perfectly, the errors from our custom code are being returned by wordpress, its just the forgotten password reset that does not seem to be working.

2

Well, ended up fixing this after hours of banging my head against ones keyboard. Fixed by making the first parameter of my hooked function a value instead of a reference - curious when nearly all hooks in wordpress pass the error object by reference!

function validatePasswordReset( &$errors, $userData ) {
    return validateComplexPassword( $errors );
}

changed to

function validatePasswordReset( $errors, $userData ) {
    return validateComplexPassword( $errors );
}

Curious as to why most actions have a reference on the codex, for example:

http://codex.wordpress.org/Plugin_API/Action_Reference/user_profile_update_errors

but there is no entry for validate_password_reset?

  • Hooks in WordPress, if considering ones with variable part in names, are several hundreds, only a little portion have docs... and only a very little portion have proper docs – gmazzap Jun 12 '14 at 16:27
  • The $errors parameter is an instance of a WP_Error object. In PHP, object variables are really aliases (or pointers, if you like) to the actual instance of the object. Thus, passing them "by reference" is more or less the default. The variable is passed by value, but the value is a pointer to the instance of the object. Thus, using the & for pass by reference on variables which hold object instances is unnecessary and really makes no sense. – Otto Jun 12 '14 at 16:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.