| @@ -6,8 +6,13 @@ | ||
| 6 | 6 | */ |
| 7 | 7 | |
| 8 | 8 | namespace MainWP\Dashboard; |
| 9 | 9 | |
| 10 | +// Exit if accessed directly. | |
| 11 | +if ( ! defined( 'ABSPATH' ) ) { | |
| 12 | + exit; | |
| 13 | +} | |
| 14 | + | |
| 10 | 15 | /** |
| 11 | 16 | * Class MainWP_Extensions_Handler |
| 12 | 17 | */ |
| 13 | 18 | class MainWP_Extensions_Handler { // phpcs:ignore Generic.Classes.OpeningBraceSameLine.ContentAfterBrace -- NOSONAR. |
| @@ -104,10 +109,10 @@ | ||
| 104 | 109 | |
| 105 | 110 | /** |
| 106 | 111 | * Clean up MainWP Extention names. |
| 107 | 112 | * |
| 108 | - * @param array $extension Array of MainWP Extentsions. | |
| 109 | - * @param array $forced forced polish. | |
| 113 | + * @param string $extension Array of MainWP Extentsions. | |
| 114 | + * @param bool $forced forced polish. | |
| 110 | 115 | * |
| 111 | 116 | * @return string $menu_name Final Menu Name. |
| 112 | 117 | */ |
| 113 | 118 | public static function polish_ext_name( $extension, $forced = false ) { |
| @@ -135,8 +140,9 @@ | ||
| 135 | 140 | 'Extensions', |
| 136 | 141 | 'Mainwp', |
| 137 | 142 | 'Extension', |
| 138 | 143 | 'MainWP', |
| 144 | + 'Add-on', | |
| 139 | 145 | ), |
| 140 | 146 | '', |
| 141 | 147 | $name |
| 142 | 148 | ); |
| @@ -157,10 +163,10 @@ | ||
| 157 | 163 | static::$extensions = array(); |
| 158 | 164 | $extensions = get_option( 'mainwp_extensions', array() ); |
| 159 | 165 | foreach ( $extensions as $extension ) { |
| 160 | 166 | $slug = $extension['slug']; |
| 161 | - if ( function_exists( 'mainwp_current_user_have_right' ) ) { // to fix later init, it's ok to check user have right. | |
| 162 | - if ( mainwp_current_user_have_right( 'extension', dirname( $slug ) ) ) { | |
| 167 | + if ( function_exists( '\mainwp_current_user_can' ) ) { // to fix later init, it's ok to check user have right. | |
| 168 | + if ( \mainwp_current_user_can( 'extension', dirname( $slug ) ) ) { | |
| 163 | 169 | static::$extensions[] = $extension; |
| 164 | 170 | } |
| 165 | 171 | } else { |
| 166 | 172 | static::$extensions[] = $extension; |
| @@ -426,8 +432,13 @@ | ||
| 426 | 432 | include_once ABSPATH . '/wp-admin/includes/misc.php'; // NOSONAR - WP compatible. |
| 427 | 433 | include_once ABSPATH . '/wp-admin/includes/class-wp-upgrader.php'; // NOSONAR - WP compatible. |
| 428 | 434 | include_once ABSPATH . '/wp-admin/includes/plugin.php'; // NOSONAR - WP compatible. |
| 429 | 435 | |
| 436 | + // To fix conflict. | |
| 437 | + if ( is_plugin_active( 'git-updater/git-updater.php' ) ) { | |
| 438 | + remove_all_filters( 'upgrader_source_selection' ); | |
| 439 | + } | |
| 440 | + | |
| 430 | 441 | $installer = new \WP_Upgrader(); |
| 431 | 442 | $ssl_verifyhost = get_option( 'mainwp_sslVerifyCertificate' ); |
| 432 | 443 | $ssl_api_verifyhost = ( ( false === get_option( 'mainwp_api_sslVerifyCertificate' ) ) || ( 1 === (int) get_option( 'mainwp_api_sslVerifyCertificate' ) ) ) ? 1 : 0; |
| 433 | 444 | |
| @@ -651,8 +662,18 @@ | ||
| 651 | 662 | public static function hook_fetch_url_authed( $pluginFile, $key, $websiteId, $what, $params, $rawResponse = null ) { |
| 652 | 663 | if ( ! static::hook_verify( $pluginFile, $key ) ) { |
| 653 | 664 | return false; |
| 654 | 665 | } |
| 666 | + | |
| 667 | + $website = MainWP_DB::instance()->get_website_by_id( $websiteId ); | |
| 668 | + | |
| 669 | + if ( $website && $website->suspended && ( ! defined( 'DOING_CRON' ) || true !== DOING_CRON ) && ( ! defined( 'WP_CLI' ) || true !== WP_CLI ) ) { | |
| 670 | + return array( | |
| 671 | + 'error' => esc_html__( 'Suspended site.', 'mainwp' ), | |
| 672 | + 'errorCode' => 'SUSPENDED_SITE', | |
| 673 | + ); | |
| 674 | + } | |
| 675 | + | |
| 655 | 676 | return static::fetch_url_authed( $websiteId, $what, $params, $rawResponse ); |
| 656 | 677 | } |
| 657 | 678 | |
| 658 | 679 | /** |
| @@ -684,22 +705,29 @@ | ||
| 684 | 705 | } |
| 685 | 706 | } |
| 686 | 707 | |
| 687 | 708 | /** |
| 688 | - * Get DB Sites. | |
| 709 | + * Retrieves database sites based on provided parameters. | |
| 689 | 710 | * |
| 690 | - * @param mixed $pluginFile Extension plugin file to verify. | |
| 691 | - * @param mixed $key The child-key. | |
| 692 | - * @param mixed $sites Child Sites. | |
| 693 | - * @param string $groups Groups. | |
| 694 | - * @param bool $options Options. | |
| 711 | + * This method verifies the hook using the plugin file and key, then retrieves | |
| 712 | + * sites from the database according to the specified criteria. | |
| 695 | 713 | * |
| 696 | - * @return array $dbwebsites. | |
| 714 | + * @param string $pluginFile The path to the plugin file for verification. | |
| 715 | + * @param string $key The key used for hook verification. | |
| 716 | + * @param array|string $sites Site IDs to retrieve. Can be an array of IDs or a comma-separated string. | |
| 717 | + * @param array|string $groups Optional. Group IDs to filter sites by. Can be an array or comma-separated string. | |
| 718 | + * Default is empty string. | |
| 719 | + * @param array|bool $options Optional. Fields to return or additional query options. | |
| 720 | + * Set to false to return all fields. Default is false. | |
| 721 | + * @param array|string $clients Optional. Client IDs to filter sites by. Can be an array or comma-separated string. | |
| 722 | + * Default is empty string. | |
| 697 | 723 | * |
| 698 | - * @uses \MainWP\Dashboard\MainWP_Utility::ctype_digit() | |
| 699 | - * @uses \MainWP\Dashboard\MainWP_Utility::map_site() | |
| 724 | + * @return array|bool Array of site objects on success, or false if hook verification fails. | |
| 725 | + * | |
| 726 | + * @uses \MainWP\Dashboard\MainWP_Utility::ctype_digit() | |
| 727 | + * @uses \MainWP\Dashboard\MainWP_Utility::map_site() | |
| 700 | 728 | */ |
| 701 | - public static function hook_get_db_sites( $pluginFile, $key, $sites, $groups = '', $options = false ) { | |
| 729 | + public static function hook_get_db_sites( $pluginFile, $key, $sites, $groups = '', $options = false, $clients = '' ) { | |
| 702 | 730 | if ( ! static::hook_verify( $pluginFile, $key ) ) { |
| 703 | 731 | return false; |
| 704 | 732 | } |
| 705 | 733 | |
| @@ -704,11 +732,12 @@ | ||
| 704 | 732 | } |
| 705 | 733 | |
| 706 | 734 | MainWP_Deprecated_Hooks::maybe_handle_deprecated_hook(); |
| 707 | 735 | $params = array( |
| 708 | - 'fields' => $options, | |
| 709 | - 'sites' => $sites, | |
| 710 | - 'groups' => $groups, | |
| 736 | + 'fields' => $options, | |
| 737 | + 'sites' => $sites, | |
| 738 | + 'groups' => $groups, | |
| 739 | + 'clients' => $clients, | |
| 711 | 740 | ); |
| 712 | 741 | return MainWP_DB::instance()->get_db_sites( $params ); |
| 713 | 742 | } |
| 714 | 743 | |
| @@ -753,9 +782,9 @@ | ||
| 753 | 782 | if ( ! static::hook_verify( $pluginFile, $key ) ) { |
| 754 | 783 | return false; |
| 755 | 784 | } |
| 756 | 785 | |
| 757 | - if ( $for_manager && ( ! defined( 'MWP_TEAMCONTROL_PLUGIN_SLUG' ) || ! mainwp_current_user_have_right( 'extension', dirname( MWP_TEAMCONTROL_PLUGIN_SLUG ) ) ) ) { | |
| 786 | + if ( $for_manager && ( ! defined( 'MWP_TEAMCONTROL_PLUGIN_SLUG' ) || ! \mainwp_current_user_can( 'extension', dirname( MWP_TEAMCONTROL_PLUGIN_SLUG ) ) ) ) { | |
| 758 | 787 | return false; |
| 759 | 788 | } |
| 760 | 789 | MainWP_Deprecated_Hooks::maybe_handle_deprecated_hook(); |
| 761 | 790 | |
| @@ -778,9 +807,9 @@ | ||
| 778 | 807 | if ( ! static::hook_verify( $pluginFile, $key ) ) { |
| 779 | 808 | return false; |
| 780 | 809 | } |
| 781 | 810 | |
| 782 | - if ( $for_manager && ( ! defined( 'MWP_TEAMCONTROL_PLUGIN_SLUG' ) || ! mainwp_current_user_have_right( 'extension', dirname( MWP_TEAMCONTROL_PLUGIN_SLUG ) ) ) ) { | |
| 811 | + if ( $for_manager && ( ! defined( 'MWP_TEAMCONTROL_PLUGIN_SLUG' ) || ! \mainwp_current_user_can( 'extension', dirname( MWP_TEAMCONTROL_PLUGIN_SLUG ) ) ) ) { | |
| 783 | 812 | return false; |
| 784 | 813 | } |
| 785 | 814 | |
| 786 | 815 | MainWP_Deprecated_Hooks::maybe_handle_deprecated_hook(); |
| @@ -885,8 +914,17 @@ | ||
| 885 | 914 | $clone_sites = MainWP_DB::instance()->get_websites_by_url( $clone_url ); |
| 886 | 915 | if ( $clone_sites ) { |
| 887 | 916 | $clone_site = current( $clone_sites ); |
| 888 | 917 | if ( $clone_site && $clone_site->is_staging ) { |
| 918 | + | |
| 919 | + // try to decrypt priv key. | |
| 920 | + $de_privkey = MainWP_Encrypt_Data_Lib::instance()->decrypt_privkey( base64_decode( $website->privkey ), $website->id ); // phpcs:ignore -- NOSONAR - base64_encode trust. | |
| 921 | + if ( ! empty( $de_privkey ) ) { | |
| 922 | + $en_privkey = MainWP_Encrypt_Data_Lib::instance()->encrypt_privkey( $de_privkey, $clone_site->id, true ); // create encrypt priv key for clone site. | |
| 923 | + } else { | |
| 924 | + $en_privkey = base64_decode( $website->privkey ); // phpcs:ignore -- NOSONAR -trust - compatible. | |
| 925 | + } | |
| 926 | + | |
| 889 | 927 | if ( $force_update ) { |
| 890 | 928 | MainWP_DB::instance()->update_website_values( |
| 891 | 929 | $clone_site->id, |
| 892 | 930 | array( |
| @@ -891,14 +929,18 @@ | ||
| 891 | 929 | $clone_site->id, |
| 892 | 930 | array( |
| 893 | 931 | 'adminname' => $website->adminname, |
| 894 | 932 | 'pubkey' => $website->pubkey, |
| 895 | - 'privkey' => $website->privkey, | |
| 933 | + 'privkey' => is_array( $en_privkey ) ? base64_encode( json_encode( $en_privkey ) ) : base64_encode( $en_privkey ), //phpcs:ignore -- NOSONAR -ok. | |
| 896 | 934 | 'verify_certificate' => $website->verify_certificate, |
| 897 | 935 | 'uniqueId' => ( null !== $website->uniqueId ? $website->uniqueId : '' ), |
| 898 | - 'http_user' => $website->http_user, | |
| 899 | - 'http_pass' => $website->http_pass, | |
| 936 | + // MWP-1548: decrypt the source's credentials and let | |
| 937 | + // update_website_values re-encrypt under a fresh keyfile, | |
| 938 | + // so the cloned site doesn't share the source row's file_key. | |
| 939 | + 'http_user' => MainWP_Credential_Storage::decrypt_credential( $website->http_user ), | |
| 940 | + 'http_pass' => MainWP_Credential_Storage::decrypt_credential( $website->http_pass ), | |
| 900 | 941 | 'ssl_version' => $website->ssl_version, |
| 942 | + 'force_use_ipv4' => $website->force_use_ipv4, | |
| 901 | 943 | ) |
| 902 | 944 | ); |
| 903 | 945 | } |
| 904 | 946 | $ret['siteid'] = $clone_site->id; |
| @@ -919,16 +961,29 @@ | ||
| 919 | 961 | 'groupids' => array(), |
| 920 | 962 | 'groupnames' => array(), |
| 921 | 963 | 'verifyCertificate' => $website->verify_certificate, |
| 922 | 964 | 'addUniqueId' => ( null !== $website->uniqueId ? $website->uniqueId : '' ), |
| 923 | - 'http_user' => $website->http_user, | |
| 924 | - 'http_pass' => $website->http_pass, | |
| 965 | + // MWP-1548: same pattern as the force_update branch above -- | |
| 966 | + // decrypt the source's credentials, let add_website re-encrypt | |
| 967 | + // for the new clone with a fresh keyfile. | |
| 968 | + 'http_user' => MainWP_Credential_Storage::decrypt_credential( $website->http_user ), | |
| 969 | + 'http_pass' => MainWP_Credential_Storage::decrypt_credential( $website->http_pass ), | |
| 925 | 970 | 'sslVersion' => $website->ssl_version, |
| 971 | + 'force_use_ipv4' => $website->force_use_ipv4, | |
| 926 | 972 | 'wpe' => $website->wpe, |
| 927 | 973 | 'isStaging' => 1, |
| 928 | 974 | ); |
| 929 | 975 | |
| 930 | - $id = MainWP_DB::instance()->add_website( $current_user->ID, $clone_name, $clone_url, $website->adminname, $website->pubkey, $website->privkey, $others ); | |
| 976 | + $de_privkey = base64_decode( $website->privkey ); //phpcs:ignore -- NOSONAR -trust - compatible. | |
| 977 | + $de_privkey = MainWP_Encrypt_Data_Lib::instance()->decrypt_privkey( $de_privkey, $website->id ); | |
| 978 | + | |
| 979 | + if ( ! empty( $de_privkey ) ) { | |
| 980 | + $de_privkey = base64_encode( $de_privkey ); //phpcs:ignore -- NOSONAR -ok. | |
| 981 | + } else { | |
| 982 | + $de_privkey = $website->privkey; // compatible - encoded. | |
| 983 | + } | |
| 984 | + | |
| 985 | + $id = MainWP_DB::instance()->add_website( $current_user->ID, $clone_name, $clone_url, $website->adminname, $website->pubkey, $de_privkey, $others ); | |
| 931 | 986 | |
| 932 | 987 | /** This action is documented in class\class-mainwp-manage-sites-view.php */ |
| 933 | 988 | do_action( 'mainwp_added_new_site', $id, $website ); |
| 934 | 989 | |