Cache
2 years ago
DBPermissions.php
2 years ago
DataEncoder.php
2 years ago
Escape.php
2 years ago
Glob.php
2 years ago
Hooks.php
2 years ago
Math.php
2 years ago
PluginInfo.php
2 years ago
Sanitize.php
2 years ago
ServerVars.php
2 years ago
SlashMode.php
5 years ago
Strings.php
2 years ago
Times.php
2 years ago
Urls.php
2 years ago
Version.php
2 years ago
WpDefaultDirectories.php
2 years ago
DBPermissions.php
137 lines
| 1 | <?php |
| 2 | |
| 3 | namespace WPStaging\Framework\Utils; |
| 4 | |
| 5 | use wpdb; |
| 6 | use ArrayIterator; |
| 7 | use WPStaging\Framework\Security\Auth; |
| 8 | |
| 9 | /** |
| 10 | * Class Check user permissions on DB |
| 11 | * @package WPStaging\Framework\Utils |
| 12 | */ |
| 13 | class DBPermissions |
| 14 | { |
| 15 | /** @var wpdb */ |
| 16 | protected $wpdb; |
| 17 | |
| 18 | /** @var Auth */ |
| 19 | private $auth; |
| 20 | |
| 21 | public function __construct(wpdb $wpdb, Auth $auth) |
| 22 | { |
| 23 | $this->wpdb = $wpdb; |
| 24 | $this->auth = $auth; |
| 25 | } |
| 26 | |
| 27 | /** |
| 28 | * Ajax check user permissions on DB before push process start |
| 29 | */ |
| 30 | public function ajaxCheckDBPermissions() |
| 31 | { |
| 32 | if (!$this->isAuthenticated()) { |
| 33 | return; |
| 34 | } |
| 35 | |
| 36 | $type = isset($_POST['type']) ? sanitize_text_field($_POST['type']) : ''; |
| 37 | $grantsToCheck = ['CREATE', 'UPDATE', 'INSERT', 'DROP']; |
| 38 | if ($type === 'push') { |
| 39 | $grantsToCheck[] = 'ALTER'; |
| 40 | } |
| 41 | |
| 42 | if ($this->isAllowed(['ALL PRIVILEGES']) || $this->isAllowed($grantsToCheck)) { |
| 43 | wp_send_json_success(); |
| 44 | } |
| 45 | |
| 46 | $message = __("The database user might not have sufficient permissions to use the restore action. Continue the process anyway by clicking the 'Proceed' button or change the user's DB permissions and resume the process.<br/><br/> Required permissions are: CREATE, UPDATE, INSERT, DROP.", 'wp-staging'); |
| 47 | if ($type === 'push') { |
| 48 | $message = __("The database user might not have sufficient permissions to use the push action. Continue the process anyway by clicking the 'Proceed' button or alter the user's DB permissions and resume the process.<br/><br/> Required permissions are: CREATE, UPDATE, ALTER, INSERT, DROP.", 'wp-staging'); |
| 49 | } |
| 50 | |
| 51 | $message = '<span id="wpstg-permission-info-output">' . $message . '</span>'; |
| 52 | $message .= '<span id="wpstg-permission-info-data">' . $this->getDebugInfo() . '</span>'; |
| 53 | $message .= '<br/><br/><button type="button" id="wpstg-db-permission-show-full-message" class="wpstg-link-btn wpstg-blue-primary">' . __("Show Full Message", "wp-staging") . '</button>'; |
| 54 | |
| 55 | wp_send_json_error([ |
| 56 | 'message' => wp_kses_post($message), |
| 57 | ]); |
| 58 | } |
| 59 | |
| 60 | /** |
| 61 | * Check if the current user has the grants given in arguments. |
| 62 | * |
| 63 | * @param array $grantsToCheck |
| 64 | * @return bool |
| 65 | */ |
| 66 | public function isAllowed($grantsToCheck) |
| 67 | { |
| 68 | $grants = $this->wpdb->get_results("SHOW GRANTS;"); |
| 69 | if (empty($grants) || $this->wpdb->last_error) { |
| 70 | return false; |
| 71 | } |
| 72 | |
| 73 | $hasGranted = array_filter($grants, function ($grant) use ($grantsToCheck) { |
| 74 | $grant = (new ArrayIterator($grant))->current(); |
| 75 | if (stripos($grant, '`' . DB_NAME . '`') !== false || stripos($grant, '`' . $this->wpdb->esc_like(DB_NAME) . '`') !== false || stripos($grant, '*.*') !== false) { |
| 76 | foreach ($grantsToCheck as $value) { |
| 77 | if (!preg_match("/" . $value . "[,]/", $grant) && !preg_match("/" . $value . " ON/", $grant)) { |
| 78 | return false; |
| 79 | } |
| 80 | } |
| 81 | |
| 82 | return true; |
| 83 | } |
| 84 | }); |
| 85 | |
| 86 | if (!empty($hasGranted)) { |
| 87 | return true; |
| 88 | } |
| 89 | |
| 90 | return false; |
| 91 | } |
| 92 | |
| 93 | /** |
| 94 | * @return string |
| 95 | */ |
| 96 | public function getDebugInfo() |
| 97 | { |
| 98 | $data = '<textarea class="wpstg-permission-info-output wpstg-textbox" readonly="readonly" name="wpstg-permission-info" title="' . __('Please copy and paste this message and report it to us!', 'wp-staging') . '">'; |
| 99 | $data .= PHP_EOL . __('DB Name: ', 'wp-staging') . DB_NAME; |
| 100 | $data .= PHP_EOL . __('DB User: ', 'wp-staging') . DB_USER; |
| 101 | $data .= PHP_EOL . __('DB Host: ', 'wp-staging') . DB_HOST; |
| 102 | |
| 103 | $grants = $this->wpdb->get_results("SHOW GRANTS;"); |
| 104 | if (empty($grants) || $this->wpdb->last_error) { |
| 105 | $data .= PHP_EOL . __('wpdb query error: ', 'wp-staging') . $this->wpdb->last_error; |
| 106 | return wp_kses_post($data); |
| 107 | } |
| 108 | |
| 109 | $grantsHtml = ''; |
| 110 | foreach ($grants as $grant) { |
| 111 | $grantsHtml .= PHP_EOL . (new ArrayIterator($grant))->current() . ';'; |
| 112 | } |
| 113 | |
| 114 | $data .= PHP_EOL . __('User Grants: ', 'wp-staging') . $grantsHtml; |
| 115 | $data .= '</textarea>'; |
| 116 | |
| 117 | return wp_kses_post($data); |
| 118 | } |
| 119 | |
| 120 | /** |
| 121 | * @param wpdb $db |
| 122 | * @return void |
| 123 | */ |
| 124 | public function setDB(wpdb $wpdb) |
| 125 | { |
| 126 | $this->wpdb = $wpdb; |
| 127 | } |
| 128 | |
| 129 | /** |
| 130 | * @return bool Whether the current request is considered to be authenticated. |
| 131 | */ |
| 132 | protected function isAuthenticated() |
| 133 | { |
| 134 | return $this->auth->isAuthenticatedRequest(); |
| 135 | } |
| 136 | } |
| 137 |