PluginProbe
MainWP Dashboard: Self-hosted WordPress Management for Agencies / 6.2.1
MainWP Dashboard: Self-hosted WordPress Management for Agencies v6.2.1
6.2.2 6.2.1 6.2 6.1.8 6.1.7 6.1.6 6.1.5 6.1.4 6.1.3 6.1.2 6.1.1 6.1 6.0.12 6.0.11 4.6.0.1 5.0 5.0.1 5.0.2 5.0.3 5.0.3.1 5.0.3.2 5.1 5.1.1 5.2 5.2.1 All 155 releases
← All changes | pages/page-mainwp-extensions-handler.php +80 -25 5.1 → 6.2.1 View file →
@@ -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