Skip to content

Instantly share code, notes, and snippets.

@neo22s
Last active December 27, 2021 15:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save neo22s/26036c64b81fa853bae8910532efd80e to your computer and use it in GitHub Desktop.
Save neo22s/26036c64b81fa853bae8910532efd80e to your computer and use it in GitHub Desktop.
Get unique cookie for password protected posts in wordpress. We use the url of the post as MD5 for unique cookie storage. This way you can be loged in in different posts without putting the password in each of them. Also if you are an admin no need ot insert the password
<?php
/**
* Plugin Name: Advanced Post Password
* Plugin URI: https://garridodiaz.com
* Description: Password protected posts/pages adding some extra security features.
* Version: 1.0
* Author: Chema
* Author URI: https://garridodiaz.com
* License: GPL2
*/
/**
* check if trying a post_password authentication so we can add extra cookie per page
*/
if ($_POST AND array_key_exists( 'post_password', $_POST ) )
{
//getting a referer if there's none we do nothing...
$referer = wp_get_raw_referer();
if ( $referer && wp_unslash( $_SERVER['REQUEST_URI'] ) !== $referer && home_url() . wp_unslash( $_SERVER['REQUEST_URI'] ) !== $referer )
{
//setting unique cookie name used later in cookie_post_password_required
$cookie_name = 'wp-postpass_'.md5($referer).'_'. COOKIEHASH;
//copied from wp-login.php case 'postpass':
require_once ABSPATH . WPINC . '/class-phpass.php';
$hasher = new PasswordHash( 8, true );
$expire = apply_filters( 'post_password_expires', time() + 365 * DAY_IN_SECONDS );
if ( $referer ) {
$secure = ( 'https' === parse_url( $referer, PHP_URL_SCHEME ) );
} else {
$secure = false;
}
setcookie( $cookie_name, $hasher->HashPassword( wp_unslash( $_POST['post_password'] ) ), $expire, COOKIEPATH, COOKIE_DOMAIN, $secure );
//special page has access to all restricted pages, cookie setup if they visited this special page
if (defined('SPECIAL_PAGE_URL') AND defined('SPECIAL_PAGE_PWD') AND !empty(SPECIAL_PAGE_URL) AND SPECIAL_PAGE_URL == $referer)
{
setcookie( 'wp-postpass_all_' . COOKIEHASH, $hasher->HashPassword( wp_unslash( SPECIAL_PAGE_PWD )), $expire, COOKIEPATH, COOKIE_DOMAIN, $secure );
}
}
}
/**
* Whether post requires password and correct password has been provided. same as original but reading from different cookie
* @param boolean $required
* @param id|post $post
* @return boolean
*/
function cookie_post_password_required($required, $post)
{
$post = get_post( $post );
if ( empty( $post->post_password ) )
return false;
//admin no need of password
if (current_user_can( 'administrator' ))
return false;
// if user had access to the special URL no need to request other pages passwords.
if (defined('SPECIAL_PAGE_URL') AND defined('SPECIAL_PAGE_PWD') AND !empty(SPECIAL_PAGE_URL) )
{
//he did access previously with a correct password to the special page
if (!check_cookie_pwd('wp-postpass_all_' . COOKIEHASH,SPECIAL_PAGE_PWD))
return false;
}
//read correct cookie for this url/post
$url = md5(get_permalink($post));
$cookie_name = 'wp-postpass_'.$url.'_'. COOKIEHASH ;
return check_cookie_pwd($cookie_name, $post->post_password);
}
add_filter( 'post_password_required', 'cookie_post_password_required', 10, 2 );
/**
* checks a password stored in a cookie
* @param string $cookie_name comes with the cookiehash already
* @param string $password
* @return boolean false means correct password... I know it's confusing..... but its used in cookie_post_password_required
*/
function check_cookie_pwd($cookie_name, $password)
{
if ( ! isset( $_COOKIE[ $cookie_name] ) ) {
return true;
}
require_once ABSPATH . WPINC . '/class-phpass.php';
$hasher = new PasswordHash( 8, true );
$hash = wp_unslash( $_COOKIE[ $cookie_name] );
if ( 0 !== strpos( $hash, '$P$B' ) ) {
$required = true;
} else {
$required = ! $hasher->CheckPassword( $password, $hash );
}
return $required;
}
/**
* Removes "Private" or "Protected" prefix that wordpress adds to password-protected & private pages thanks to https://wordpress.org/plugins/remove-protected-in-title/
* @param string $title
* @return string
*/
function remove_protected_in_title($title) {
return '%s';
}
add_filter('private_title_format', 'remove_protected_in_title');
add_filter('protected_title_format', 'remove_protected_in_title');
?>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment