Yes, you can add an authenticate filter to handle the email and no password case with a higher priority than the default wp_authenticate_email_password handler. e.g. (untested)
function wpse_380353_authenticate_email_no_password( $user, $email, $password ) {
if ( is_wp_error( $user ) || ( $user instanceof WP_User ) ) {
// Already handled by a higher-priority filter
return $user;
}
if ( ! empty( $email ) && is_email( $email ) && empty( $password ) ) {
// This is an email login with empty password
$user = get_user_by( 'email', $email );
if ( $user && ! is_wp_error( $user ) ) {
// TODO: Verify that the user is someone you'd want to login without
// a password. For now, let's reject anyone who can edit posts.
if ( $user->has_cap( 'edit_posts' ) ) {
$error = new WP_Error();
// TODO: localize the error message
$error->add( 'empty_password',
'<strong>Error</strong>: This user requires a password.' );
return $error;
}
// We'll allow this user to login without a password.
// Return the user object and the calling code will handle the login.
return $user;
}
// else could not fetch the user by email address.
// You'll probably now get a 'password field is empty' error
// from a later filter.
// TODO: If you want a different error then generate it here.
}
return $user;
}
// Add an authenticate filter with a higher priority (= lower number) than
// wp_authenticate_email_password which has priority 20.
add_filter( 'authenticate', 'wpse_380353_authenticate_email_no_password', 10, 3 );