Files
dostavka_vodi/wp-content/plugins/all-in-one-wp-security-and-firewall/admin/wp-security-firewall-setup-notice.php
User A0264400 a766acdc90 first commit
2026-04-01 23:20:16 +03:00

651 lines
20 KiB
PHP

<?php
if (!defined('ABSPATH')) {
exit; //Exit if accessed directly
}
class AIOWPSecurity_Firewall_Setup_Notice {
/**
* Holds reference to an instance of itself
*
* @var AIOWPSecurity_Firewall_Setup_Notice
*/
private static $instance = null;
/**
* Holds our wp-config file wrapped in our manager class
*
* @var AIOWPSecurity_Block_WpConfig
*/
private $wpconfig;
/**
* Holds our mu-plugin file wrapped in our manager class
*
* @var AIOWPSecurity_Block_Muplugin
*/
private $muplugin;
/**
* Holds our bootstrap file wrapped in our manager class
*
* @var AIOWPSecurity_Block_Bootstrap
*/
private $bootstrap;
/**
* Constants for the different notice types
*
* @var string
*/
const NOTICE_BOOTSTRAP = 'manual_bootstrap';
const NOTICE_MANUAL = 'manual';
const NOTICE_INSTALLED = 'success';
const NOTICE_DIRECTIVE_SET = 'userini_directive';
/**
* Constructs our object by setting up our essential files
*/
private function __construct() {
$this->bootstrap = AIOWPSecurity_Utility_Firewall::get_bootstrap_file();
$this->wpconfig = AIOWPSecurity_Utility_Firewall::get_wpconfig_file();
$this->muplugin = AIOWPSecurity_Utility_Firewall::get_muplugin_file();
AIOWPSecurity_Utility_Firewall::get_firewall_rules_path(true); // Creates the needed directories for the first time.
}
/**
* Entry point for the dashboard notice
*
* @return void
*/
public function start_firewall_setup() {
global $aio_wp_security;
$firewall_files = array(
'server' => AIOWPSecurity_Utility_Firewall::get_server_file(),
'bootstrap' => $this->bootstrap,
'wpconfig' => $this->wpconfig,
'muplugin' => $this->muplugin,
);
//Check each file and update the contents if necessary
foreach ($firewall_files as $name => $file) {
${'is_firewall_in_'.$name} = false;
if (AIOWPSecurity_Utility_Firewall::MANUAL_SETUP === $file) {
continue;
}
${'is_firewall_in_'.$name} = $file->contains_contents();
if (true === ${'is_firewall_in_'.$name}) {
$file->update_contents();
}
}
if (!$aio_wp_security->is_aiowps_admin_page()) {
return;
}
if (AIOWPSecurity_Utility_Firewall::is_firewall_setup()) {
if (true !== $is_firewall_in_server) { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UndefinedVariable -- variable is set in the foreach loop
$this->render_upgrade_protection_notice();
}
} else {
$this->render_automatic_setup_notice();
}
$this->render_notices();
}
/**
* Will execute when the user presses 'Set up now' button
*
* @return void
*/
public function do_setup() {
$is_inserted_firewall_file = false;
$is_inserted_bootstrap_file = $this->bootstrap->contains_contents();
if (true !== $is_inserted_bootstrap_file) {
$is_inserted_bootstrap_file = $this->bootstrap->insert_contents();
if (true !== $is_inserted_bootstrap_file) {
$this->log_wp_error($is_inserted_bootstrap_file);
$this->show_notice(self::NOTICE_BOOTSTRAP);
return;
}
}
$firewall_file = AIOWPSecurity_Utility_Firewall::get_server_file();
if ($firewall_file instanceof AIOWPSecurity_Block_Userini) {
$directive = AIOWPSecurity_Utility_Firewall::get_already_set_directive($firewall_file);
if (!empty($directive)) {
if (AIOWPSecurity_Utility_Firewall::get_bootstrap_path() === $directive) {
$is_inserted_firewall_file = true;
} else {
$this->show_notice(self::NOTICE_DIRECTIVE_SET, array('directive' => $directive));
}
} else {
$is_inserted_firewall_file = $firewall_file->insert_contents();
}
} else {
if (AIOWPSecurity_Utility_Firewall::MANUAL_SETUP !== $firewall_file) {
$is_inserted_firewall_file = $firewall_file->insert_contents(); // attempts to insert firewall into required file
}
}
//Set up the firewall in the wp-config file
$is_inserted_wpconfig = $this->wpconfig->contains_contents();
if (true !== $is_inserted_wpconfig) {
$is_inserted_wpconfig = $this->wpconfig->insert_contents();
}
$this->log_wp_error($is_inserted_wpconfig);
//Set up the firewall in the mu-plugin
$is_inserted_muplugin = $this->muplugin->contains_contents();
if (true !== $is_inserted_muplugin) {
$is_inserted_muplugin = $this->muplugin->insert_contents();
}
if (false === $is_inserted_muplugin) {
$this->log_wp_error(new \WP_Error(
'file-mu-plugin-failed',
'Unable to create the mu-plugin',
$this->muplugin
));
}
$this->log_wp_error($is_inserted_muplugin);
if (true === $is_inserted_firewall_file) {
$this->show_notice(self::NOTICE_INSTALLED);
} else {
$this->log_wp_error($is_inserted_firewall_file);
$this->show_notice(self::NOTICE_MANUAL);
}
}
/**
* Dismisses the notice.
*
* @return void
*/
private function do_dismiss() {
global $aio_wp_security;
$aio_wp_security->configs->set_value('aios_firewall_dismiss', true, true);
}
/**
* Checks whether the notice is dismissed
*
* @return boolean
*/
private function is_dismissed() {
global $aio_wp_security;
return (true === $aio_wp_security->configs->get_value('aios_firewall_dismiss'));
}
/**
* Handles the form submission for the 'Set up now' notice
*
* @return void
*/
public function handle_setup_form() {
// phpcs:ignore WordPress.Security.NonceVerification.Missing -- Nonce check occurs here.
$nonce = isset($_POST['_wpnonce']) ? sanitize_key(wp_unslash($_POST['_wpnonce'])) : '';
$result = AIOWPSecurity_Utility_Permissions::check_nonce_and_user_cap($nonce, 'aiowpsec-firewall-setup');
if (!is_wp_error($result)) {
$this->do_setup();
$this->do_redirect();
}
}
/**
* Handles the dismiss form
*
* @return void
*/
public function handle_dismiss_form() {
// phpcs:ignore WordPress.Security.NonceVerification.Missing -- Nonce check occurs here.
$nonce = isset($_POST['_wpnonce']) ? sanitize_key(wp_unslash($_POST['_wpnonce'])) : '';
$result = AIOWPSecurity_Utility_Permissions::check_nonce_and_user_cap($nonce, 'aiowpsec-firewall-setup-dismiss');
if (!is_wp_error($result)) {
$this->do_dismiss();
$this->do_redirect();
}
}
/**
* Handles the form that downgrades the firewall's protection.
*
* @return void
*/
public function handle_downgrade_protection_form() {
// phpcs:ignore WordPress.Security.NonceVerification.Missing -- Nonce check occurs here.
$nonce = isset($_POST['_wpnonce']) ? sanitize_key(wp_unslash($_POST['_wpnonce'])) : '';
$result = AIOWPSecurity_Utility_Permissions::check_nonce_and_user_cap($nonce, 'aiowpsec-firewall-downgrade');
if (!is_wp_error($result)) {
AIOWPSecurity_Utility_Firewall::remove_firewall();
$this->do_redirect();
}
}
/**
* Handles the redirect
*
* @return void
*/
private function do_redirect() {
// Go back to the previous page and tab if set
if (isset($_POST['_wp_http_referer'])) { // phpcs:ignore WordPress.Security.NonceVerification.Missing -- No nonce.
$matches = array();
// phpcs:ignore WordPress.Security.NonceVerification.Missing -- No nonce.
if (preg_match('/\?page='.AIOWPSEC_MENU_SLUG_PREFIX.'(?<page>.*)(&tab=(?<tab>.*))?$/m', sanitize_url(wp_unslash($_POST['_wp_http_referer'])), $matches)) {
$url = 'admin.php?page='.AIOWPSEC_MENU_SLUG_PREFIX;
if (isset($matches['page'])) {
$url .= sanitize_text_field($matches['page']);
if (isset($matches['tab'])) {
$url .= '&tab='.sanitize_text_field($matches['tab']);
}
}
AIOWPSecurity_Utility::redirect_to_url(admin_url(sanitize_url($url)));
}
}
AIOWPSecurity_Utility::redirect_to_url(admin_url('admin.php?page='.AIOWPSEC_MENU_SLUG_PREFIX));
}
/**
* Wrapper function to log WP_Errors to debug log
*
* @param WP_Error $wp_error - Our error which gets logged
* @return void
*/
private function log_wp_error($wp_error) {
if (is_wp_error($wp_error)) {
global $aio_wp_security;
$error_message = $wp_error->get_error_message();
$error_message .= ' - ';
$error_message .= $wp_error->get_error_data();
$aio_wp_security->debug_logger->log_debug($error_message, 4);
}
}
/**
* Sets the flags to show notices
*
* @param string $type - the type of notice we want to set
* @param array $values - any values that need to be passed
* @return void
*/
private function show_notice($type, $values = array()) {
global $aio_wp_security;
$aio_wp_security->configs->set_value('firewall_notice_'.$type, true);
if (!empty($values)) {
$aio_wp_security->configs->set_value('firewall_notice_values', $values);
}
$aio_wp_security->configs->save_config();
}
/**
* Renders any necessary notices
*
* @return void
*/
public function render_notices() {
global $aio_wp_security;
$notices = array(
self::NOTICE_BOOTSTRAP,
self::NOTICE_MANUAL,
self::NOTICE_INSTALLED,
self::NOTICE_DIRECTIVE_SET,
);
foreach ($notices as $notice) {
if ($aio_wp_security->configs->get_value('firewall_notice_'.$notice)) {
switch ($notice) {
case self::NOTICE_BOOTSTRAP:
$this->render_bootstrap_notice();
break;
case self::NOTICE_MANUAL:
if (!$this->any_pending_notices(self::NOTICE_MANUAL)) {
$this->render_manual_setup_notice();
}
break;
case self::NOTICE_INSTALLED:
$this->render_firewall_installed_notice();
break;
case self::NOTICE_DIRECTIVE_SET:
$values = $aio_wp_security->configs->get_value('firewall_notice_values');
$this->render_userini_directive_set_notice($values['directive']);
$aio_wp_security->configs->delete_value('firewall_notice_values');
break;
}
$aio_wp_security->configs->delete_value('firewall_notice_'.$notice);
}
}
$aio_wp_security->configs->save_config();
}
/**
* Detects if we have any notices pending to display
*
* @param string ...$exclude - do not check the status of these notices
*
* @return boolean
*/
private function any_pending_notices(...$exclude) {
global $aio_wp_security;
$notices = array(
self::NOTICE_BOOTSTRAP,
self::NOTICE_MANUAL,
self::NOTICE_INSTALLED,
self::NOTICE_DIRECTIVE_SET,
);
$notices = array_diff($notices, $exclude);
foreach ($notices as $notice) {
if (true === $aio_wp_security->configs->get_value('firewall_notice_'.$notice)) {
return true;
}
}
return false;
}
/**
* Notice is shown if we are unable to write to the bootstrap file
*
* @return void
*/
private function render_bootstrap_notice() {
?>
<div class="notice notice-error is-dismissible">
<p>
<strong><?php esc_html_e('All In One Security', 'all-in-one-wp-security-and-firewall'); ?></strong>
</p>
<p><?php esc_html_e('We were unable to create the file necessary to give you the highest level of protection.', 'all-in-one-wp-security-and-firewall');?></p>
<p><?php esc_html_e('Your firewall will have reduced protection which means some of your firewall\'s functionality will be unavailable.', 'all-in-one-wp-security-and-firewall');?></p>
<p><?php esc_html_e('If you would like to manually set up the necessary file, please follow these steps:', 'all-in-one-wp-security-and-firewall');?></p>
<p>
<?php
/* translators: %s Bootstrap file name. */
printf(esc_html__('1. Create a file with the name %s in the same directory as your WordPress install is in, i.e.:', 'all-in-one-wp-security-and-firewall'), esc_html(pathinfo($this->bootstrap, PATHINFO_BASENAME)));
?>
</p>
<pre style='max-width: 100%;background-color: #f0f0f0;border:#ccc solid 1px;padding: 10px;white-space:pre-wrap;'><?php echo esc_html($this->bootstrap); ?></pre>
<p><?php esc_html_e('2. Paste in the following code:', 'all-in-one-wp-security-and-firewall');?></p>
<pre style='max-width: 100%;background-color: #f0f0f0;border:#ccc solid 1px;padding: 10px;white-space:pre-wrap;'><?php echo esc_html(htmlentities($this->bootstrap->get_contents())); ?></pre>
<p><?php esc_html_e('3. Save the file and press the \'Try again\' button below:', 'all-in-one-wp-security-and-firewall');?></p>
<?php
$this->render_try_again_button();
$this->render_manual_notice_footer();
}
/**
* Notice is shown if auto_prepend_file directive is already set in user.ini
*
* @param string $directive_value
* @return void
*/
private function render_userini_directive_set_notice($directive_value) {
$firewall_file = AIOWPSecurity_Utility_Firewall::get_server_file();
$this->render_manual_notice_header();
?>
<p>
<?php esc_html_e('1. Open the following file:', 'all-in-one-wp-security-and-firewall'); ?>
</p>
<p><code><?php echo esc_html($firewall_file); ?></code></p>
<?php if (empty($directive_value)) {?>
<p>
<?php esc_html_e('2. Look for the auto_prepend_file directive.', 'all-in-one-wp-security-and-firewall'); ?>
</p>
<?php } else {?>
<p>
<?php esc_html_e('2. Look for the following:', 'all-in-one-wp-security-and-firewall'); ?>
</p>
<pre style='max-width: 100%;background-color: #f0f0f0;border:#ccc solid 1px;padding: 10px;white-space:pre-wrap;'><?php echo "auto_prepend_file='".esc_html($directive_value)."'";?></pre>
<?php } ?>
<p>
<?php esc_html_e('3. Change it to the following:', 'all-in-one-wp-security-and-firewall'); ?>
</p>
<pre style='max-width: 100%;background-color: #f0f0f0;border:#ccc solid 1px;padding: 10px;white-space:pre-wrap;'><?php echo esc_html(AIOWPSecurity_Utility_Firewall::get_server_file()->get_contents()); ?></pre>
<p>
<?php echo esc_html__('4. Save the file and press the \'Try again\' button below:', 'all-in-one-wp-security-and-firewall').' '.esc_html__('You may have to wait up to 5 minutes before the settings take effect.', 'all-in-one-wp-security-and-firewall'); ?>
</p>
<?php
$this->render_try_again_button();
$this->render_manual_notice_footer();
}
/**
* Shows when the firewall has successfully installed
*
* @return void
*/
private function render_firewall_installed_notice() {
global $aio_wp_security;
$aio_wp_security->include_template('notices/firewall-installed-notice.php', false);
}
/**
* Renders the 'manual setup' dashboard notice
*
* @return void
*/
private function render_manual_setup_notice() {
$firewall_file = AIOWPSecurity_Utility_Firewall::get_server_file();
if (AIOWPSecurity_Utility_Firewall::MANUAL_SETUP === $firewall_file) {
//Show users how to manually add the firewall via php.ini if we can't detect their server
$bootstrap_path = AIOWPSecurity_Utility_Firewall::get_bootstrap_path();
$this->render_manual_notice_header();
?>
<p>
<?php esc_html_e('1. Open your php.ini file.', 'all-in-one-wp-security-and-firewall'); ?>
</p>
<p>
<?php esc_html_e('2. Set the auto_prepend_file directive like below:', 'all-in-one-wp-security-and-firewall'); ?>
</p>
<pre style='max-width: 100%;background-color: #f0f0f0;border:#ccc solid 1px;padding: 10px;white-space:pre-wrap;'><?php echo "auto_prepend_file='".esc_html($bootstrap_path)."'";?></pre>
<p>
<?php echo esc_html__('3. Restart the webserver and refresh the page', 'all-in-one-wp-security-and-firewall') . ' ' . esc_html__('You may have to wait up to 5 minutes before the settings take effect.', 'all-in-one-wp-security-and-firewall'); ?>
</p>
<?php
$this->render_manual_notice_footer();
} else {
//Show users how to manually add the firewall via their own server file
$this->render_manual_notice_header();
$firewall_file_name = pathinfo($firewall_file, PATHINFO_BASENAME);
?>
<p>
<?php
/* translators: %s Firewall file name. */
printf(esc_html__('1. Create a file with the name %s in the same directory as your WordPress install is in, i.e.:', 'all-in-one-wp-security-and-firewall'), esc_html($firewall_file_name));
?>
<p><code><?php echo esc_html($firewall_file); ?></code></p>
</p>
<p>
<?php esc_html_e('2. Paste in the following directives:', 'all-in-one-wp-security-and-firewall'); ?>
</p>
<pre style='max-width: 100%;background-color: #f0f0f0;border:#ccc solid 1px;padding: 10px;white-space:pre-wrap;'><?php echo esc_html(htmlentities($firewall_file->get_contents())); ?></pre>
<p>
<?php echo esc_html__('3. Save the file and press the \'Try again\' button below:', 'all-in-one-wp-security-and-firewall'); ?>
</p>
<?php
$this->render_try_again_button();
$this->render_manual_notice_footer();
}
}
/**
* The header for notices that require manual intervention
*
* @return void
*/
private function render_manual_notice_header() {
?>
<div class="notice notice-warning is-dismissible">
<p>
<strong><?php esc_html_e('All In OneSecurity', 'all-in-one-wp-security-and-firewall'); ?></strong>
</p>
<p>
<?php echo esc_html__('We were unable to set up your firewall with the highest level of protection.', 'all-in-one-wp-security-and-firewall').' '.
esc_html__('Your firewall will have reduced functionality.', 'all-in-one-wp-security-and-firewall');
?>
</p>
<p>
<?php esc_html_e('To give your site the highest level of protection, please follow these steps:', 'all-in-one-wp-security-and-firewall'); ?>
</p>
<?php
}
/**
* The footer for notices that require manual intervention
*
* @return void
*/
private function render_manual_notice_footer() {
?>
<p>
<strong><?php esc_html_e('Note: if you\'re unable to perform any of the aforementioned steps, please ask your web hosting provider for further assistance.', 'all-in-one-wp-security-and-firewall'); ?></strong>
</p>
</div>
<?php
}
/**
* Render Try again button.
*
* @return void
*/
private function render_try_again_button() {
?>
<form action="<?php echo esc_url(admin_url('admin-post.php')); ?>" method="POST">
<?php wp_nonce_field('aiowpsec-firewall-setup'); ?>
<input type="hidden" name="action" value="aiowps_firewall_setup">
<div style="padding-top: 10px; padding-bottom: 10px;">
<input class="button button-primary" type="submit" name="btn_try_again" value="<?php esc_html_e('Try again', 'all-in-one-wp-security-and-firewall'); ?>">
</div>
</form>
<?php
}
/**
* Renders the warning that users do not have the highest level of protection
*
* @return void
*/
private function render_upgrade_protection_notice() {
if ($this->should_not_show_notice()) {
return;
}
?>
<div class="notice notice-warning">
<form action="<?php echo esc_url(admin_url('admin-post.php')); ?>" method="POST">
<?php wp_nonce_field('aiowpsec-firewall-setup'); ?>
<input type="hidden" name="action" value="aiowps_firewall_setup">
<p>
<?php esc_html_e('We have detected that your AIOS firewall is not fully installed, and therefore does not have the highest level of protection.', 'all-in-one-wp-security-and-firewall');?>
<?php echo ' ' . esc_html__('Your firewall will have reduced functionality until it has been upgraded.', 'all-in-one-wp-security-and-firewall');?>
<div style="padding-top: 10px;">
<input class="button button-primary" type="submit" name="btn_upgrade_now" value="<?php esc_html_e('Upgrade your protection now', 'all-in-one-wp-security-and-firewall'); ?>">
</div>
</p>
</form>
</div>
<?php
}
/**
* Whether the firewall notice should not be shown.
*
* @return boolean True if the firewall notice should not be shown otherwise false.
*/
private function should_not_show_notice() {
if (!is_main_site()) {
return true;
}
if (!AIOWPSecurity_Utility_Permissions::has_manage_cap()) {
return true;
}
if ($this->is_dismissed() && !AIOWPSecurity_Utility_Firewall::is_firewall_page()) {
return true;
}
if ($this->any_pending_notices()) {
return true; //only display if there are no other notices waiting to be displayed
}
return false;
}
/**
* Renders the 'Set up now' dashboard notice
*
* @return void
*/
private function render_automatic_setup_notice() {
global $aio_wp_security;
if ($this->should_not_show_notice()) {
return;
}
$aio_wp_security->include_template('notices/firewall-setup-notice.php', false, array('show_dismiss' => !AIOWPSecurity_Utility_Firewall::is_firewall_page()));
}
/**
* Ensures only one instance of the class can be created (singleton)
*
* @return AIOWPSecurity_Firewall_Setup_Notice|null
*/
public static function get_instance() {
if (null === self::$instance) {
self::$instance = new self();
}
return self::$instance;
}
}