| Current Path : /home/k/r/o/krobertfnz/www/wp-content/plugins/wp-defender/src/component/config/ |
| Current File : /home/k/r/o/krobertfnz/www/wp-content/plugins/wp-defender/src/component/config/config-adapter.php |
<?php
namespace WP_Defender\Component\Config;
use WP_Defender\Component;
use WP_Defender\Model\Setting\Blacklist_Lockout as Model_Blacklist_Lockout;
use WP_Defender\Model\Setting\Login_Lockout as Model_Login_Lockout;
use WP_Defender\Model\Setting\Notfound_Lockout as Model_Notfound_Lockout;
use WP_Defender\Model\Setting\User_Agent_Lockout as Model_Ua_Lockout;
use WP_Defender\Model\Setting\Two_Fa;
/**
* Class Config_Adapter
* @package WP_Defender
* @since 2.4.0
*/
class Config_Adapter extends Component {
/**
* @var string
*/
public $status_recipient;
/**
* Upgrade the structure of config data from older versions.
* @param array $old_data
*
* @return array
*/
public function upgrade( array $old_data ): array {
$this->status_recipient = \WP_Defender\Model\Notification::USER_SUBSCRIBED;
return [
'security_tweaks' => $this->update_security_tweaks( $old_data['security_tweaks'] ),
'scan' => empty( $old_data['scan'] ) ? [] : $this->update_scan( $old_data['scan'] ),
'iplockout' => empty( $old_data['iplockout'] )
? []
: $this->update_ip_lockout( $old_data['iplockout'] ),
// Empty data if Audit module is disabled.
'audit' => empty( $old_data['audit'] ) ? [] : $this->update_audit( $old_data['audit'] ),
'two_factor' => empty( $old_data['two_factor'] )
? []
: $this->update_two_factor( $old_data['two_factor'] ),
// Checks for empty values Mask Login and Security Headers inside methods.
'mask_login' => $this->update_mask_login( $old_data['mask_login'] ),
'security_headers' => $this->update_security_headers( $old_data['security_headers'] ),
'settings' => empty( $old_data['settings'] ) ? [] : $old_data['settings'],
'blocklist_monitor' => empty( $old_data['blocklist_monitor'] ) ? [] : $old_data['blocklist_monitor'],
'pwned_passwords' => empty( $old_data['pwned_passwords'] ) ? [] : $old_data['pwned_passwords'],
];
}
/**
* Convert key type from frequency to text.
* Attention: it's NOT translation lines.
*
* @param int $freq
*
* @return string
*/
private function number_frequency_to_text( int $freq ): string {
switch ( $freq ) {
case 1:
$text = 'daily';
break;
case 7:
$text = 'weekly';
break;
case 30:
default:
$text = 'monthly';
break;
}
return $text;
}
/**
* @param string|int $frequency_type
*
* @return string
*/
private function frequency_type( $frequency_type ) {
return is_numeric( $frequency_type )
? $this->number_frequency_to_text( (int) $frequency_type )
: $frequency_type;
}
/**
* Report instance uses the 'day' property if a frequency type is daily and 'day_n' if a frequency type is monthly.
* @param string|int $frequency_type
* @param string $report_day
*
* @return array
*/
private function frequency_day( $frequency_type, $report_day ): array {
$days = [
'day_n' => '1',
'day' => 'sunday',
];
if (
( ( is_numeric( $frequency_type ) && 30 === (int) $frequency_type ) )
|| 'monthly' === $frequency_type
) {
if ( empty( $report_day ) ) {
return $days;
}
if ( is_numeric( $report_day ) ) {
$days['day_n'] = $report_day;
return $days;
}
// Otherwise, get a number of the first day of the month by the day of the week.
$format = sprintf( 'first %s of next month', $report_day );
$days['day_n'] = date( 'j', strtotime( $format ) );
return $days;
}
// Otherwise, we get report day for daily or weekly.
$days['day'] = $report_day;
return $days;
}
/**
* @param array $data
*
* @return array
*/
private function get_subscribers( array $data ): array {
$subscribers = [];
if ( ! empty( $data ) ) {
foreach ( $data as $receipt ) {
$subscribers['out_house_recipients'][] = [
'name' => $receipt['first_name'],
'email' => $receipt['email'],
'status' => $this->status_recipient,
'avatar' => get_avatar_url( $receipt['email'] ),
];
}
}
return $subscribers;
}
/**
* @param array $old_tweaks
*
* @return array
*/
public function update_security_tweaks( $old_tweaks ): array {
$security_tweaks = [
'issues' => $old_tweaks['issues'] ?? [],
'fixed' => $old_tweaks['fixed'] ?? [],
'ignore' => $old_tweaks['ignore'] ?? [],
'automate' => isset( $old_tweaks['automate'] )
// Sometimes string value from old version.
? ( is_bool( $old_tweaks['automate'] ) ? $old_tweaks['automate'] : (bool) $old_tweaks['automate'] )
: true,
'notification' => isset( $old_tweaks['notification'] )
? ( $old_tweaks['notification'] ? 'enabled' : 'disabled' )
: 'disabled',
// Prepare from 'notification_repeat' to configs['reminder'] with default value 'weekly'.
'notification_repeat' => empty( $old_tweaks['notification_repeat'] )
? 'weekly'
: ( $old_tweaks['notification_repeat'] ? 'daily' : 'weekly' ),
'data' => $old_tweaks['data'] ?? [],
];
if ( isset( $old_tweaks['last_sent'] ) ) {
$security_tweaks['last_sent'] = $old_tweaks['last_sent'];
}
$security_tweaks['subscribers'] = isset( $old_tweaks['receipts'] )
? $this->get_subscribers( $old_tweaks['receipts'] )
: [];
return $security_tweaks;
}
/**
* @param array $old_data
*
* @return array
*/
public function update_scan( array $old_data ): array {
$scan = [
'integrity_check' => empty( $old_data['scan_core'] ) ? true : $old_data['scan_core'],
'check_core' => empty( $old_data['check_core'] ) ? true : $old_data['check_core'],
'check_plugins' => empty( $old_data['check_plugins'] ) ? false : $old_data['check_plugins'],
'check_known_vuln' => empty( $old_data['scan_vuln'] ) ? true : $old_data['scan_vuln'],
'scan_malware' => empty( $old_data['scan_content'] ) ? false : $old_data['scan_content'],
'filesize' => empty( $old_data['max_filesize'] ) ? 3 : $old_data['max_filesize'],
// Should get bool value.
'report' => isset( $old_data['report'] ) && $old_data['report'] ? 'enabled' : 'disabled',
'always_send' => empty( $old_data['always_send'] ) ? false : $old_data['always_send'],
'time' => empty( $old_data['time'] ) ? '4:00' : $old_data['time'],
'frequency' => empty( $old_data['frequency'] )
? 'weekly'
: $this->frequency_type( $old_data['frequency'] ),
// Should get bool value.
'notification' => isset( $old_data['notification'] ) && $old_data['notification']
? 'enabled'
: 'disabled',
'always_send_notification' => empty( $old_data['always_send_notification'] )
? false
: $old_data['always_send_notification'],
'error_send' => empty( $old_data['error_send'] ) ? false : $old_data['error_send'],
'email_subject_issue_found' => $old_data['email_subject_issue'] ?? '',
'email_subject_issue_not_found' => $old_data['email_subject'] ?? '',
'email_subject_error' => $old_data['email_subject_error'] ?? '',
'email_content_issue_found' => $old_data['email_has_issue'] ?? '',
'email_content_issue_not_found' => $old_data['email_all_ok'] ?? '',
'email_content_error' => $old_data['email_content_error'] ?? '',
// @since 2.7.0.
'scheduled_scanning' => false,
];
$scan['report_subscribers'] = empty( $old_data['recipients'] )
? []
: $this->get_subscribers( $old_data['recipients'] );
$scan['notification_subscribers'] = empty( $old_data['recipients_notification'] )
? []
: $this->get_subscribers( $old_data['recipients_notification'] );
// Todo: need the key 'last_report_sent'? It's no always in the unixtime format.
if ( empty( $old_data['frequency'] ) ) {
$scan['day'] = 'sunday';
$scan['day_n'] = '1';
return $scan;
} else {
return array_merge( $scan, $this->frequency_day( $old_data['frequency'], $old_data['day'] ) );
}
}
/**
* @param array $old_data
*
* @return array
*/
public function update_ip_lockout( array $old_data ): array {
$merged_bl_file_data = $old_data['detect_404_blacklist'] ?? '';
// Merge blacklist file & filetype data.
if ( isset( $old_data['detect_404_filetypes_blacklist'] ) && '' !== trim( $old_data['detect_404_filetypes_blacklist'] ) ) {
$merged_bl_file_data .= PHP_EOL . $old_data['detect_404_filetypes_blacklist'];
}
$merged_wl_file_data = $old_data['detect_404_whitelist'] ?? '';
// Merge whitelist file & filetype data.
if ( isset( $old_data['detect_404_whitelist'] ) && '' !== trim( $old_data['detect_404_ignored_filetypes'] ) ) {
$merged_wl_file_data .= PHP_EOL . $old_data['detect_404_ignored_filetypes'];
}
$default_login_lockout_values = ( new Model_Login_Lockout() )->get_default_values();
$default_404_lockout_values = ( new Model_Notfound_Lockout() )->get_default_values();
$default_ip_lockout_values = ( new Model_Blacklist_Lockout() )->get_default_values();
$default_ua_lockout_values = ( new Model_Ua_Lockout() )->get_default_values();
$iplockout = [
'login_protection' => empty( $old_data['login_protection'] )
? true : $old_data['login_protection'],
'login_protection_login_attempt' => empty( $old_data['login_protection_login_attempt'] )
? '5' : $old_data['login_protection_login_attempt'],
'login_protection_lockout_timeframe' => empty( $old_data['login_protection_lockout_timeframe'] )
? '300' :$old_data['login_protection_lockout_timeframe'],
'login_protection_lockout_ban' => empty( $old_data['login_protection_lockout_ban'] )
? false : $old_data['login_protection_lockout_ban'],
'login_protection_lockout_duration' => empty( $old_data['login_protection_lockout_duration'] )
? '4' : $old_data['login_protection_lockout_duration'],
'login_protection_lockout_duration_unit' => empty( $old_data['login_protection_lockout_duration_unit'] )
? 'hours' : $old_data['login_protection_lockout_duration_unit'],
'login_protection_lockout_message' => empty( $old_data['login_protection_lockout_message'] )
? $default_login_lockout_values['message']
: $old_data['login_protection_lockout_message'],
'username_blacklist' => empty( $old_data['username_blacklist'] )
? '' : $old_data['username_blacklist'],
'detect_404' => empty( $old_data['detect_404'] )
? true : $old_data['detect_404'],
'detect_404_threshold' => empty( $old_data['detect_404_threshold'] )
? '20' : $old_data['detect_404_threshold'],
'detect_404_timeframe' => empty( $old_data['detect_404_timeframe'] )
? '300' : $old_data['detect_404_timeframe'],
'detect_404_lockout_ban' => empty( $old_data['detect_404_lockout_ban'] )
? false : $old_data['detect_404_lockout_ban'],
'detect_404_lockout_duration' => empty( $old_data['detect_404_lockout_duration'] )
? '4' : $old_data['detect_404_lockout_duration'],
'detect_404_lockout_duration_unit' => empty( $old_data['detect_404_lockout_duration_unit'] )
? 'hours' : $old_data['detect_404_lockout_duration_unit'],
'detect_404_lockout_message' => empty( $old_data['detect_404_lockout_message'] )
? $default_404_lockout_values['message']
: $old_data['detect_404_lockout_message'],
'detect_404_blacklist' => $merged_bl_file_data,
'detect_404_whitelist' => $merged_wl_file_data,
'detect_404_logged' => empty( $old_data['detect_404_logged'] )
? true : $old_data['detect_404_logged'],
'ip_blacklist' => empty( $old_data['ip_blacklist'] )
? '' : $old_data['ip_blacklist'],
'ip_whitelist' => empty( $old_data['ip_whitelist'] )
? '' : $old_data['ip_whitelist'],
'country_blacklist' => empty( $old_data['country_blacklist'] )
? '' : $old_data['country_blacklist'],
'country_whitelist' => empty( $old_data['country_whitelist'] )
? '' : $old_data['country_whitelist'],
'ip_lockout_message' => empty( $old_data['ip_lockout_message'] )
? $default_ip_lockout_values['message']
: $old_data['ip_lockout_message'],
'login_lockout_notification' => empty( $old_data['login_lockout_notification'] )
? true : $old_data['login_lockout_notification'],
'ip_lockout_notification' => empty( $old_data['ip_lockout_notification'] )
? true : $old_data['ip_lockout_notification'],
'notification' => 'enabled',
'cooldown_enabled' => empty( $old_data['cooldown_enabled'] )
? false : $old_data['cooldown_enabled'],
'cooldown_number_lockout' => empty( $old_data['cooldown_number_lockout'] )
? '3' : $old_data['cooldown_number_lockout'],
'cooldown_period' => empty( $old_data['cooldown_period'] )
? '24' : $old_data['cooldown_period'],
'report' => isset( $old_data['report'] ) && $old_data['report'] ? 'enabled' : 'disabled',
'report_frequency' => empty( $old_data['report_frequency'] )
? 'weekly'
: $this->frequency_type( $old_data['report_frequency'] ),
// Data for 'day' below.
'report_time' => empty( $old_data['report_time'] )
? '4:00' : $old_data['report_time'],
'storage_days' => empty( $old_data['storage_days'] )
? '180' : $old_data['storage_days'],
'geoIP_db' => $old_data['geoIP_db'] ?? '',
'ip_blocklist_cleanup_interval' => empty( $old_data['ip_blocklist_cleanup_interval'] )
? 'never' : $old_data['ip_blocklist_cleanup_interval'],
// For UA Banning.
'ua_banning_enabled' => $old_data['ua_banning_enabled'] ?? false,
'ua_banning_message' => $old_data['ua_banning_message'] ?? $default_ua_lockout_values['message'],
'ua_banning_blacklist' => $old_data['ua_banning_blacklist'] ?? $default_ua_lockout_values['blacklist'],
'ua_banning_whitelist' => $old_data['ua_banning_whitelist'] ?? $default_ua_lockout_values['whitelist'],
'ua_banning_empty_headers' => $old_data['ua_banning_empty_headers'] ?? false,
'maxmind_license_key' => $old_data['maxmind_license_key'] ?? '',
// Global IP list.
'global_ip_list' => $old_data['global_ip_list'] ?? false,
];
if ( isset( $old_data['lastReportSent'] ) && ! empty( $old_data['lastReportSent'] ) ) {
$iplockout['last_sent'] = $old_data['lastReportSent'];
}
$iplockout['report_subscribers'] = empty( $old_data['report_receipts'] )
? []
: $this->get_subscribers( $old_data['report_receipts'] );
$iplockout['notification_subscribers'] = empty( $old_data['receipts'] )
? []
: $this->get_subscribers( $old_data['receipts'] );
if ( empty( $old_data['report_frequency'] ) ) {
$iplockout['day'] = 'sunday';
$iplockout['day_n'] = '1';
return $iplockout;
} else {
return array_merge( $iplockout, $this->frequency_day( $old_data['report_frequency'], $old_data['report_day'] ) );
}
}
/**
* @param array $old_data
*
* @return array
*/
public function update_audit( array $old_data ): array {
$audit = [
'enabled' => is_bool( $old_data['enabled'] )
? $old_data['enabled']
: (bool) $old_data['enabled'],
'report' => isset( $old_data['notification'] ) && $old_data['notification'] ? 'enabled' : 'disabled',
'frequency' => empty( $old_data['frequency'] )
? 'weekly'
: $this->frequency_type( $old_data['frequency'] ),
'time' => empty( $old_data['time'] )
? '4:00'
: $old_data['time'],
'storage_days' => empty( $old_data['storage_days'] )
? '6 months'
: $old_data['storage_days'],
];
if ( isset( $old_data['lastReportSent'] ) && ! empty( $old_data['lastReportSent'] ) ) {
$audit['last_sent'] = $old_data['lastReportSent'];
}
$audit['subscribers'] = empty( $old_data['receipts'] )
? []
: $this->get_subscribers( $old_data['receipts'] );
if ( empty( $old_data['frequency'] ) ) {
$audit['day'] = 'sunday';
$audit['day_n'] = '1';
return $audit;
} else {
return array_merge( $audit, $this->frequency_day( $old_data['frequency'], $old_data['day'] ) );
}
}
/**
* @param array $old_data
*
* @return array
*/
public function update_two_factor( array $old_data ): array {
return [
'enabled' => $old_data['enabled'],
'lost_phone' => $old_data['lost_phone'],
'force_auth' => $old_data['force_auth'],
'force_auth_mess' => $old_data['force_auth_mess'],
'user_roles' => $old_data['user_roles'],
'force_auth_roles' => $old_data['force_auth_roles'],
'custom_graphic' => $old_data['custom_graphic'],
'custom_graphic_type' => $old_data['custom_graphic_type'] ?? Two_Fa::CUSTOM_GRAPHIC_TYPE_UPLOAD,
'custom_graphic_url' => $old_data['custom_graphic_url'] ?? '',
'custom_graphic_link' => $old_data['custom_graphic_link'] ?? '',
'email_subject' => $old_data['email_subject'] ?? '',
'email_sender' => $old_data['email_sender'] ?? '',
'email_body' => $old_data['email_body'] ?? '',
'app_title' => '',
];
}
/**
* @param array $old_data
*
* @return array
*/
public function update_mask_login( array $old_data ): array {
if ( empty( $old_data ) ) {
// Sometimes migrated data is empty.
return [
'mask_url' => '',
'redirect_traffic' => 'off',
'redirect_traffic_url' => '',
'enabled' => false,
'redirect_traffic_page_id' => 0,
];
} else {
return [
'enabled' => $old_data['enabled'],
'mask_url' => $old_data['mask_url'] ?? '',
'redirect_traffic' => $old_data['redirect_traffic'] ? 'custom_url' : 'off',
'redirect_traffic_url' => $old_data['redirect_traffic_url'] ?: '',
'redirect_traffic_page_id' => 0,
];
}
}
/**
* @since 2.5.0 Remove 'ALLOW-FROM' directive and move to 'sameorigin' by default.
* Leave 'sh_xframe_urls' for config migration.
* @param array $old_data
*
* @return array
*/
public function update_security_headers( array $old_data ): array {
if ( empty( $old_data ) ) {
// Sometimes migrated data is empty.
$model_sec_headers = new \WP_Defender\Model\Setting\Security_Headers();
return [
'sh_xframe' => $model_sec_headers->sh_xframe,
'sh_xframe_mode' => $model_sec_headers->sh_xframe_mode,
// Leave for migration to 2.5.1.
'sh_xframe_urls' => '',
'sh_xss_protection' => $model_sec_headers->sh_xss_protection,
'sh_xss_protection_mode' => $model_sec_headers->sh_xss_protection_mode,
'sh_content_type_options' => $model_sec_headers->sh_content_type_options,
'sh_content_type_options_mode' => $model_sec_headers->sh_content_type_options_mode,
'sh_strict_transport' => $model_sec_headers->sh_strict_transport,
'hsts_preload' => $model_sec_headers->hsts_preload,
'include_subdomain' => $model_sec_headers->include_subdomain,
'hsts_cache_duration' => $model_sec_headers->hsts_cache_duration,
'sh_referrer_policy' => $model_sec_headers->sh_referrer_policy,
'sh_referrer_policy_mode' => $model_sec_headers->sh_referrer_policy_mode,
'sh_feature_policy' => $model_sec_headers->sh_feature_policy,
'sh_feature_policy_mode' => $model_sec_headers->sh_feature_policy_mode,
'sh_feature_policy_urls' => $model_sec_headers->sh_feature_policy_urls,
];
} else {
return [
'sh_xframe' => (bool) $old_data['sh_xframe'],
'sh_xframe_mode' => $old_data['sh_xframe_mode'],
// Leave for migration to 2.5.1.
'sh_xframe_urls' => $old_data['sh_xframe_urls'] ?? '',
'sh_xss_protection' => (bool) $old_data['sh_xss_protection'],
'sh_xss_protection_mode' => $old_data['sh_xss_protection_mode'],
'sh_content_type_options' => (bool) $old_data['sh_content_type_options'],
'sh_content_type_options_mode' => $old_data['sh_content_type_options_mode'],
'sh_strict_transport' => (bool) $old_data['sh_strict_transport'],
'hsts_preload' => $old_data['hsts_preload'],
'include_subdomain' => $old_data['include_subdomain'],
'hsts_cache_duration' => $old_data['hsts_cache_duration'],
'sh_referrer_policy' => (bool) $old_data['sh_referrer_policy'],
'sh_referrer_policy_mode' => $old_data['sh_referrer_policy_mode'],
'sh_feature_policy' => (bool) $old_data['sh_feature_policy'],
'sh_feature_policy_mode' => $old_data['sh_feature_policy_mode'],
'sh_feature_policy_urls' => $old_data['sh_feature_policy_urls'],
];
}
}
}