1

For the last 2 hours I've trying to create a mu plugin that requires the user to answer a question first, so he can login in the website.

It is "What is the name of the white horse of Napoleon?", so the user replies "white" and it should work, by theory. The problem is that it seems it is not getting validated during the login. This is my code:

 <?php

add_action( 'login_form', 'add_login_field' );
function add_login_field() { ?>
    <p>
        <label><?php _e('What is the name of the white horse of Napoleon?') ?><br />
        <input type="text" name="user_proof" id="user_proof" class="input" size="25" tabindex="20" /></label>
    </p>
<?php }

add_action( 'login_post', 'add_login_field_validate', 10, 3 );

function add_login_field_validate( $sanitized_user_login, $user_email, $errors) {
    if (!isset($_POST[ 'user_proof' ]) || empty($_POST[ 'user_proof' ])) {
        return $errors->add( 'proofempty', '<strong>ERROR</strong>: You did not answer the proof-of-humanship question.'  );
    } elseif ( strtolower( $_POST[ 'user_proof' ] ) != 'white' ) {
        return $errors->add( 'prooffail', '<strong>ERROR</strong>: You did not answer the proof-of-humanship question correctly.'  );
    }
}

?>

I believe the problem is with the part:

add_action( 'login_post', 'add_login_field_validate', 10, 3 );

Can anyone give me a hand here?

1 Answer 1

1

There is no login_post action that I know of - use the authenticate filter instead, inside wp_authenticate(), called by wp_signon():

function wpse_185339_check_user_answer( $user ) {
    if ( $_SERVER['REQUEST_METHOD'] === 'POST' ) {
        if ( empty( $_POST[ 'user_proof' ] ) ) {
            $user = new WP_Error( 'proofempty', '<strong>ERROR</strong>: You did not answer the proof-of-humanship question.' );
        } elseif ( strtolower( $_POST[ 'user_proof' ] ) !== 'white' ) {
            $user = new WP_Error( 'prooffail', '<strong>ERROR</strong>: You did not answer the proof-of-humanship question correctly.' );
        }
    }

    return $user;
}

add_filter( 'authenticate', 'wpse_185339_check_user_answer', 100 );
7
  • Thank you, it's working, but don't you think it should validate against something else? Because when I open the login page, the error message is already there.
    – 023023
    Commented Apr 25, 2015 at 18:01
  • This is the only hook I could find for passing errors back to WordPress and prevent successful sign in. I would suggest adding a request type check, see edit. Commented Apr 25, 2015 at 18:09
  • Is this method safe? Also, if I input the the answer corretly, but don't fill the user and password field, and submit the form, it will return to the page with no errors, when it actually should say "Incorrect user name or password", but if I input the answer and username, and submit, it will return with the wrong password error. The username error is not appearing because of the return $user;?
    – 023023
    Commented Apr 25, 2015 at 20:08
  • Safe in what way? If you want a more rigid solution, check out wp-login.php (from line 768 as of 4.1.2) and see how WordPress handles the logic flow. Commented Apr 25, 2015 at 20:20
  • That code is being loaded before the wp-login.php, it's a mu-plugin. By safe I mean if I can implement it without worrying. Also, why I can't see the error message when the user field is empty? Sorry for being taking your time.
    – 023023
    Commented Apr 25, 2015 at 20:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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