Geen omschrijving

class-wc-admin-api-keys.php 7.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275
  1. <?php
  2. /**
  3. * WooCommerce Admin API Keys Class
  4. *
  5. * @package WooCommerce\Admin
  6. * @version 2.4.0
  7. */
  8. defined( 'ABSPATH' ) || exit;
  9. /**
  10. * WC_Admin_API_Keys.
  11. */
  12. class WC_Admin_API_Keys {
  13. /**
  14. * Initialize the API Keys admin actions.
  15. */
  16. public function __construct() {
  17. add_action( 'admin_init', array( $this, 'actions' ) );
  18. add_action( 'woocommerce_settings_page_init', array( $this, 'screen_option' ) );
  19. add_filter( 'woocommerce_save_settings_advanced_keys', array( $this, 'allow_save_settings' ) );
  20. }
  21. /**
  22. * Check if should allow save settings.
  23. * This prevents "Your settings have been saved." notices on the table list.
  24. *
  25. * @param bool $allow If allow save settings.
  26. * @return bool
  27. */
  28. public function allow_save_settings( $allow ) {
  29. if ( ! isset( $_GET['create-key'], $_GET['edit-key'] ) ) { // WPCS: input var okay, CSRF ok.
  30. return false;
  31. }
  32. return $allow;
  33. }
  34. /**
  35. * Check if is API Keys settings page.
  36. *
  37. * @return bool
  38. */
  39. private function is_api_keys_settings_page() {
  40. return isset( $_GET['page'], $_GET['tab'], $_GET['section'] ) && 'wc-settings' === $_GET['page'] && 'advanced' === $_GET['tab'] && 'keys' === $_GET['section']; // WPCS: input var okay, CSRF ok.
  41. }
  42. /**
  43. * Page output.
  44. */
  45. public static function page_output() {
  46. // Hide the save button.
  47. $GLOBALS['hide_save_button'] = true;
  48. if ( isset( $_GET['create-key'] ) || isset( $_GET['edit-key'] ) ) {
  49. $key_id = isset( $_GET['edit-key'] ) ? absint( $_GET['edit-key'] ) : 0; // WPCS: input var okay, CSRF ok.
  50. $key_data = self::get_key_data( $key_id );
  51. $user_id = (int) $key_data['user_id'];
  52. if ( $key_id && $user_id && ! current_user_can( 'edit_user', $user_id ) ) {
  53. if ( get_current_user_id() !== $user_id ) {
  54. wp_die( esc_html__( 'You do not have permission to edit this API Key', 'woocommerce' ) );
  55. }
  56. }
  57. include dirname( __FILE__ ) . '/settings/views/html-keys-edit.php';
  58. } else {
  59. self::table_list_output();
  60. }
  61. }
  62. /**
  63. * Add screen option.
  64. */
  65. public function screen_option() {
  66. global $keys_table_list;
  67. if ( ! isset( $_GET['create-key'] ) && ! isset( $_GET['edit-key'] ) && $this->is_api_keys_settings_page() ) { // WPCS: input var okay, CSRF ok.
  68. $keys_table_list = new WC_Admin_API_Keys_Table_List();
  69. // Add screen option.
  70. add_screen_option(
  71. 'per_page',
  72. array(
  73. 'default' => 10,
  74. 'option' => 'woocommerce_keys_per_page',
  75. )
  76. );
  77. }
  78. }
  79. /**
  80. * Table list output.
  81. */
  82. private static function table_list_output() {
  83. global $wpdb, $keys_table_list;
  84. echo '<h2 class="wc-table-list-header">' . esc_html__( 'REST API', 'woocommerce' ) . ' <a href="' . esc_url( admin_url( 'admin.php?page=wc-settings&tab=advanced&section=keys&create-key=1' ) ) . '" class="add-new-h2">' . esc_html__( 'Add key', 'woocommerce' ) . '</a></h2>';
  85. // Get the API keys count.
  86. $count = $wpdb->get_var( "SELECT COUNT(key_id) FROM {$wpdb->prefix}woocommerce_api_keys WHERE 1 = 1;" );
  87. if ( absint( $count ) && $count > 0 ) {
  88. $keys_table_list->prepare_items();
  89. echo '<input type="hidden" name="page" value="wc-settings" />';
  90. echo '<input type="hidden" name="tab" value="advanced" />';
  91. echo '<input type="hidden" name="section" value="keys" />';
  92. $keys_table_list->views();
  93. $keys_table_list->search_box( __( 'Search key', 'woocommerce' ), 'key' );
  94. $keys_table_list->display();
  95. } else {
  96. echo '<div class="woocommerce-BlankState woocommerce-BlankState--api">';
  97. ?>
  98. <h2 class="woocommerce-BlankState-message"><?php esc_html_e( 'The WooCommerce REST API allows external apps to view and manage store data. Access is granted only to those with valid API keys.', 'woocommerce' ); ?></h2>
  99. <a class="woocommerce-BlankState-cta button-primary button" href="<?php echo esc_url( admin_url( 'admin.php?page=wc-settings&tab=advanced&section=keys&create-key=1' ) ); ?>"><?php esc_html_e( 'Create an API key', 'woocommerce' ); ?></a>
  100. <style type="text/css">#posts-filter .wp-list-table, #posts-filter .tablenav.top, .tablenav.bottom .actions { display: none; }</style>
  101. <?php
  102. }
  103. }
  104. /**
  105. * Get key data.
  106. *
  107. * @param int $key_id API Key ID.
  108. * @return array
  109. */
  110. private static function get_key_data( $key_id ) {
  111. global $wpdb;
  112. $empty = array(
  113. 'key_id' => 0,
  114. 'user_id' => '',
  115. 'description' => '',
  116. 'permissions' => '',
  117. 'truncated_key' => '',
  118. 'last_access' => '',
  119. );
  120. if ( 0 === $key_id ) {
  121. return $empty;
  122. }
  123. $key = $wpdb->get_row(
  124. $wpdb->prepare(
  125. "SELECT key_id, user_id, description, permissions, truncated_key, last_access
  126. FROM {$wpdb->prefix}woocommerce_api_keys
  127. WHERE key_id = %d",
  128. $key_id
  129. ),
  130. ARRAY_A
  131. );
  132. if ( is_null( $key ) ) {
  133. return $empty;
  134. }
  135. return $key;
  136. }
  137. /**
  138. * API Keys admin actions.
  139. */
  140. public function actions() {
  141. if ( $this->is_api_keys_settings_page() ) {
  142. // Revoke key.
  143. if ( isset( $_REQUEST['revoke-key'] ) ) { // WPCS: input var okay, CSRF ok.
  144. $this->revoke_key();
  145. }
  146. // Bulk actions.
  147. if ( isset( $_REQUEST['action'] ) && isset( $_REQUEST['key'] ) ) { // WPCS: input var okay, CSRF ok.
  148. $this->bulk_actions();
  149. }
  150. }
  151. }
  152. /**
  153. * Notices.
  154. */
  155. public static function notices() {
  156. if ( isset( $_GET['revoked'] ) ) { // WPCS: input var okay, CSRF ok.
  157. $revoked = absint( $_GET['revoked'] ); // WPCS: input var okay, CSRF ok.
  158. /* translators: %d: count */
  159. WC_Admin_Settings::add_message( sprintf( _n( '%d API key permanently revoked.', '%d API keys permanently revoked.', $revoked, 'woocommerce' ), $revoked ) );
  160. }
  161. }
  162. /**
  163. * Revoke key.
  164. */
  165. private function revoke_key() {
  166. global $wpdb;
  167. check_admin_referer( 'revoke' );
  168. if ( isset( $_REQUEST['revoke-key'] ) ) { // WPCS: input var okay, CSRF ok.
  169. $key_id = absint( $_REQUEST['revoke-key'] ); // WPCS: input var okay, CSRF ok.
  170. $user_id = (int) $wpdb->get_var( $wpdb->prepare( "SELECT user_id FROM {$wpdb->prefix}woocommerce_api_keys WHERE key_id = %d", $key_id ) );
  171. if ( $key_id && $user_id && ( current_user_can( 'edit_user', $user_id ) || get_current_user_id() === $user_id ) ) {
  172. $this->remove_key( $key_id );
  173. } else {
  174. wp_die( esc_html__( 'You do not have permission to revoke this API Key', 'woocommerce' ) );
  175. }
  176. }
  177. wp_safe_redirect( esc_url_raw( add_query_arg( array( 'revoked' => 1 ), admin_url( 'admin.php?page=wc-settings&tab=advanced&section=keys' ) ) ) );
  178. exit();
  179. }
  180. /**
  181. * Bulk actions.
  182. */
  183. private function bulk_actions() {
  184. check_admin_referer( 'woocommerce-settings' );
  185. if ( ! current_user_can( 'manage_woocommerce' ) ) {
  186. wp_die( esc_html__( 'You do not have permission to edit API Keys', 'woocommerce' ) );
  187. }
  188. if ( isset( $_REQUEST['action'] ) ) { // WPCS: input var okay, CSRF ok.
  189. $action = sanitize_text_field( wp_unslash( $_REQUEST['action'] ) ); // WPCS: input var okay, CSRF ok.
  190. $keys = isset( $_REQUEST['key'] ) ? array_map( 'absint', (array) $_REQUEST['key'] ) : array(); // WPCS: input var okay, CSRF ok.
  191. if ( 'revoke' === $action ) {
  192. $this->bulk_revoke_key( $keys );
  193. }
  194. }
  195. }
  196. /**
  197. * Bulk revoke key.
  198. *
  199. * @param array $keys API Keys.
  200. */
  201. private function bulk_revoke_key( $keys ) {
  202. if ( ! current_user_can( 'remove_users' ) ) {
  203. wp_die( esc_html__( 'You do not have permission to revoke API Keys', 'woocommerce' ) );
  204. }
  205. $qty = 0;
  206. foreach ( $keys as $key_id ) {
  207. $result = $this->remove_key( $key_id );
  208. if ( $result ) {
  209. $qty++;
  210. }
  211. }
  212. // Redirect to webhooks page.
  213. wp_safe_redirect( esc_url_raw( add_query_arg( array( 'revoked' => $qty ), admin_url( 'admin.php?page=wc-settings&tab=advanced&section=keys' ) ) ) );
  214. exit();
  215. }
  216. /**
  217. * Remove key.
  218. *
  219. * @param int $key_id API Key ID.
  220. * @return bool
  221. */
  222. private function remove_key( $key_id ) {
  223. global $wpdb;
  224. $delete = $wpdb->delete( $wpdb->prefix . 'woocommerce_api_keys', array( 'key_id' => $key_id ), array( '%d' ) );
  225. return $delete;
  226. }
  227. }
  228. new WC_Admin_API_Keys();