From 82e5de4919f86bfc1afbe8896fce9b83c9abcb94 Mon Sep 17 00:00:00 2001 From: Hoang Huu Date: Sat, 12 Oct 2019 09:59:54 +0700 Subject: [PATCH] Update API --- inc/admin/class-api-keys-table.php | 329 --------------- inc/ajax-functions.php | 6 +- inc/api/class-opalestate-api-admin.php | 547 ------------------------- inc/api/class-opalestate-api.php | 5 - inc/api/functions.php | 23 ++ opal-estate-pro.php | 1 - 6 files changed, 26 insertions(+), 885 deletions(-) delete mode 100755 inc/admin/class-api-keys-table.php delete mode 100644 inc/api/class-opalestate-api-admin.php diff --git a/inc/admin/class-api-keys-table.php b/inc/admin/class-api-keys-table.php deleted file mode 100755 index 82c175cb..00000000 --- a/inc/admin/class-api-keys-table.php +++ /dev/null @@ -1,329 +0,0 @@ - esc_html__( 'API Key', 'opalestate-pro' ), // Singular name of the listed records - 'plural' => esc_html__( 'API Keys', 'opalestate-pro' ), // Plural name of the listed records - 'ajax' => false // Does this table support ajax? - ] ); - - $this->query(); - } - - /** - * This function renders most of the columns in the list table. - * - * @access public - * @param array $item Contains all the data of the keys - * @param string $column_name The name of the column - * - * @return string Column Name - * @since 1.1 - * - */ - public function column_default( $item, $column_name ) { - return $item[ $column_name ]; - } - - /** - * Displays the public key rows - * - * @access public - * @param array $item Contains all the data of the keys - * @param string $column_name The name of the column - * - * @return string Column Name - * @since 1.1 - * - */ - public function column_key( $item ) { - return ''; - } - - /** - * Displays the token rows - * - * @access public - * @param array $item Contains all the data of the keys - * @param string $column_name The name of the column - * - * @return string Column Name - * @since 1.1 - * - */ - public function column_token( $item ) { - return ''; - } - - /** - * Displays the secret key rows - * - * @access public - * @param array $item Contains all the data of the keys - * @param string $column_name The name of the column - * - * @return string Column Name - * @since 1.1 - * - */ - public function column_secret( $item ) { - return ''; - } - - /** - * Renders the column for the user field - * - * @access public - * @return void - * @since 1.1 - */ - public function column_user( $item ) { - - $actions = []; - - if ( apply_filters( 'opalestate_api_log_requests', true ) ) { - $actions['view'] = sprintf( - '%s', - esc_url( add_query_arg( [ - 'view' => 'api_requests', - 'post_type' => 'opalestate_forms', - 'page' => 'opalestate-reports', - 'tab' => 'logs', - 's' => $item['email'], - ], 'edit.php' ) ), - esc_html__( 'View API Log', 'opalestate-pro' ) - ); - } - - $actions['reissue'] = sprintf( - '%s', - esc_url( wp_nonce_url( add_query_arg( [ - 'user_id' => $item['id'], - 'opalestate_action' => 'process_api_key', - 'opalestate_api_process' => 'regenerate', - ] ), 'opalestate-api-nonce' ) ), - esc_html__( 'Reissue', 'opalestate-pro' ) - ); - $actions['revoke'] = sprintf( - '%s', - esc_url( wp_nonce_url( add_query_arg( [ - 'user_id' => $item['id'], - 'opalestate_action' => 'process_api_key', - 'opalestate_api_process' => 'revoke', - ] ), 'opalestate-api-nonce' ) ), - esc_html__( 'Revoke', 'opalestate-pro' ) - ); - - $actions = apply_filters( 'opalestate_api_row_actions', array_filter( $actions ) ); - - return sprintf( '%1$s %2$s', $item['user'], $this->row_actions( $actions ) ); - } - - /** - * Retrieve the table columns - * - * @access public - * @return array $columns Array of all the list table columns - * @since 1.1 - */ - public function get_columns() { - $columns = [ - 'user' => esc_html__( 'Username', 'opalestate-pro' ), - 'key' => esc_html__( 'Public Key', 'opalestate-pro' ), - 'token' => esc_html__( 'Token', 'opalestate-pro' ), - 'secret' => esc_html__( 'Secret Key', 'opalestate-pro' ), - ]; - - return $columns; - } - - /** - * Generate the table navigation above or below the table - * - * @param string $which - * @since 3.1.0 - * @access protected - */ - protected function display_tablenav( $which ) { - if ( 'top' === $which ) { - wp_nonce_field( 'bulk-' . $this->_args['plural'] ); - } - ?> -
- -
- bulk_actions( $which ); ?> -
- extra_tablenav( $which ); - $this->pagination( $which ); - ?> - -
-
- - - - - html->ajax_user_search( [ - 'name' => esc_html__( 'User', 'opalestate-pro' ), - ] ); ?> - - 'opalestate_user_secret_key', - 'number' => $this->per_page, - 'offset' => $this->per_page * ( $this->get_paged() - 1 ), - ] ); - - $keys = []; - - foreach ( $users as $user ) { - $keys[ $user->ID ]['id'] = $user->ID; - $keys[ $user->ID ]['email'] = $user->user_email; - $keys[ $user->ID ]['user'] = '' . $user->user_login . ''; - $keys[ $user->ID ]['key'] = OpalEstate()->api_admin->get_user_public_key( $user->ID ); - $keys[ $user->ID ]['secret'] = OpalEstate()->api_admin->get_user_secret_key( $user->ID ); - $keys[ $user->ID ]['token'] = OpalEstate()->api_admin->get_token( $user->ID ); - } - - return $keys; - } - - - /** - * Retrieve count of total users with keys - * - * @access public - * @return int - * @since 1.1 - */ - public function total_items() { - global $wpdb; - - if ( ! get_transient( 'opalestate_total_api_keys' ) ) { - $total_items = $wpdb->get_var( "SELECT count(user_id) FROM $wpdb->usermeta WHERE meta_value='opalestate_user_secret_key'" ); - - set_transient( 'opalestate_total_api_keys', $total_items, 60 * 60 ); - } - - return get_transient( 'opalestate_total_api_keys' ); - } - - /** - * Setup the final data for the table - * - * @access public - * @return void - * @since 1.1 - */ - public function prepare_items() { - $columns = $this->get_columns(); - - $hidden = []; // No hidden columns - $sortable = []; // Not sortable... for now - - $this->_column_headers = [ $columns, $hidden, $sortable, 'id' ]; - - $data = $this->query(); - - $total_items = $this->total_items(); - - $this->items = $data; - - $this->set_pagination_args( [ - 'total_items' => $total_items, - 'per_page' => $this->per_page, - 'total_pages' => ceil( $total_items / $this->per_page ), - ] - ); - } -} diff --git a/inc/ajax-functions.php b/inc/ajax-functions.php index 8c1afef8..4764d779 100755 --- a/inc/ajax-functions.php +++ b/inc/ajax-functions.php @@ -360,14 +360,14 @@ function opalestate_update_api_key() { $response['consumer_secret'] = ''; $response['message'] = __( 'API Key updated successfully.', 'opalestate-pro' ); } else { - $consumer_key = 'ck_' . wc_rand_hash(); - $consumer_secret = 'cs_' . wc_rand_hash(); + $consumer_key = 'ck_' . opalestate_rand_hash(); + $consumer_secret = 'cs_' . opalestate_rand_hash(); $data = [ 'user_id' => $user_id, 'description' => $description, 'permissions' => $permissions, - 'consumer_key' => wc_api_hash( $consumer_key ), + 'consumer_key' => opalestate_api_hash( $consumer_key ), 'consumer_secret' => $consumer_secret, 'truncated_key' => substr( $consumer_key, -7 ), ]; diff --git a/inc/api/class-opalestate-api-admin.php b/inc/api/class-opalestate-api-admin.php deleted file mode 100644 index 2121ab59..00000000 --- a/inc/api/class-opalestate-api-admin.php +++ /dev/null @@ -1,547 +0,0 @@ -register_actions(); - } - } - - /** - * Registers query vars for API access - * - * @access public - * @param array $vars Query vars - * - * @return string[] $vars New query vars - * @since 1.1 - * - */ - public function register_actions() { - add_action( 'admin_init', [ $this, 'process_action' ] ); - add_action( 'show_user_profile', [ $this, 'user_key_field' ] ); - add_action( 'edit_user_profile', [ $this, 'user_key_field' ] ); - add_action( 'personal_options_update', [ $this, 'update_key' ] ); - add_action( 'edit_user_profile_update', [ $this, 'update_key' ] ); - add_action( 'opalestate_action', [ $this, 'process_api_key' ] ); - - // Setup a backwards compatibility check for user API Keys - add_filter( 'get_user_metadata', [ $this, 'api_key_backwards_compat' ], 10, 4 ); - // Determine if JSON_PRETTY_PRINT is available - $this->pretty_print = defined( 'JSON_PRETTY_PRINT' ) ? JSON_PRETTY_PRINT : null; - // Allow API request logging to be turned off - $this->log_requests = apply_filters( 'opalestate_api_log_requests', $this->log_requests ); - } - - /** - * Registers query vars for API access - * - * @access public - * @param array $vars Query vars - * - * @return string[] $vars New query vars - * @since 1.1 - * - */ - public function process_action() { - if ( isset( $_REQUEST['opalestate_action'] ) ) { - $args = [ - 'user_id' => isset( $_REQUEST['user_id'] ) ? sanitize_text_field( $_REQUEST['user_id'] ) : 0, - 'key_permissions' => isset( $_REQUEST['key_permissions'] ) ? sanitize_text_field( $_REQUEST['key_permissions'] ) : 'read', - 'description' => isset( $_REQUEST['description'] ) ? sanitize_text_field( $_REQUEST['description'] ) : '', - 'opalestate_api_process' => isset( $_REQUEST['opalestate_api_process'] ) ? sanitize_text_field( $_REQUEST['opalestate_api_process'] ) : '', - ]; - - do_action( 'opalestate_action', $args ); - } - } - - /** - * Retrieve the user ID based on the public key provided - * - * @access public - * @param string $key Public Key - * - * @return bool if user ID is found, false otherwise - * @since 1.1 - * @global WPDB $wpdb Used to query the database using the WordPress - * Database API - * - */ - public function get_user( $key = '' ) { - global $wpdb, $wp_query; - - if ( empty( $key ) ) { - $key = urldecode( $wp_query->query_vars['key'] ); - } - - if ( empty( $key ) ) { - return false; - } - - $user = get_transient( md5( 'opalestate_api_user_' . $key ) ); - - if ( false === $user ) { - $user = $wpdb->get_var( $wpdb->prepare( "SELECT user_id FROM $wpdb->usermeta WHERE meta_key = %s LIMIT 1", $key ) ); - set_transient( md5( 'opalestate_api_user_' . $key ), $user, DAY_IN_SECONDS ); - } - - if ( $user != null ) { - $this->user_id = $user; - - return $user; - } - - return false; - } - - public function get_user_public_key( $user_id = 0 ) { - global $wpdb; - - if ( empty( $user_id ) ) { - return ''; - } - $cache_key = md5( 'opalestate_api_user_public_key' . $user_id ); - $user_public_key = get_transient( $cache_key ); - - if ( empty( $user_public_key ) ) { - $user_public_key = $wpdb->get_var( $wpdb->prepare( "SELECT meta_key FROM $wpdb->usermeta WHERE meta_value = 'opalestate_user_public_key' AND user_id = %d", $user_id ) ); - set_transient( $cache_key, $user_public_key, HOUR_IN_SECONDS ); - } - - return $user_public_key; - } - - public function get_user_secret_key( $user_id = 0 ) { - global $wpdb; - if ( empty( $user_id ) ) { - return ''; - } - $cache_key = md5( 'opalestate_api_user_secret_key' . $user_id ); - $user_secret_key = get_transient( $cache_key ); - if ( empty( $user_secret_key ) ) { - $user_secret_key = $wpdb->get_var( $wpdb->prepare( "SELECT meta_key FROM $wpdb->usermeta WHERE meta_value = 'opalestate_user_secret_key' AND user_id = %d", $user_id ) ); - set_transient( $cache_key, $user_secret_key, HOUR_IN_SECONDS ); - } - - return $user_secret_key; - } - - /** - * Modify User Profile - * - * Modifies the output of profile.php to add key generation/revocation - * - * @access public - * @param object $user Current user info - * - * @return void - * @since 1.1 - * - */ - public function user_key_field( $user ) { - if ( ( opalestate_get_option( 'api_allow_user_keys', false ) || current_user_can( 'manage_opalestate_settings' ) ) && current_user_can( 'edit_user', $user->ID ) ) { - $user = get_userdata( $user->ID ); - ?> -
- - - - - - - -
- - - get_user_public_key( $user->ID ); - $secret_key = $this->get_user_secret_key( $user->ID ); - ?> - opalestate_user_public_key ) ) { ?> - - - -   - -
-   - -
-   - -
- - - -
- 403 ] ); - } - if ( empty( $args['user_id'] ) ) { - wp_die( esc_html__( 'User ID Required.', 'opalestate-pro' ), esc_html__( 'Error', 'opalestate-pro' ), [ 'response' => 401 ] ); - } - - if ( is_numeric( $args['user_id'] ) ) { - $user_id = isset( $args['user_id'] ) ? absint( $args['user_id'] ) : get_current_user_id(); - } else { - $userdata = get_user_by( 'login', $args['user_id'] ); - $user_id = $userdata->ID; - } - $process = isset( $args['opalestate_api_process'] ) ? strtolower( $args['opalestate_api_process'] ) : false; - - if ( $user_id == get_current_user_id() && ! opalestate_options( 'allow_user_api_keys' ) && ! current_user_can( 'manage_opalestate_settings' ) ) { - wp_die( - sprintf( - /* translators: %s: process */ - esc_html__( 'You do not have permission to %s API keys for this user.', 'opalestate-pro' ), - $process - ), - esc_html__( 'Error', 'opalestate-pro' ), - [ 'response' => 403 ] - ); - } elseif ( ! current_user_can( 'manage_opalestate_settings' ) ) { - wp_die( - sprintf( - /* translators: %s: process */ - esc_html__( 'You do not have permission to %s API keys for this user.', 'opalestate-pro' ), - $process - ), - esc_html__( 'Error', 'opalestate-pro' ), - [ 'response' => 403 ] - ); - } - - switch ( $process ) { - case 'generate': - if ( $this->generate_api_key( $user_id ) ) { - delete_transient( 'opalestate_total_api_keys' ); - wp_redirect( add_query_arg( 'opalestate-message', 'api-key-generated', 'edit.php?post_type=opalestate_property&page=opalestate-settings&tab=api_keys' ) ); - exit(); - } else { - wp_redirect( add_query_arg( 'opalestate-message', 'api-key-failed', 'edit.php?post_type=opalestate_property&page=opalestate-settings&tab=api_keys' ) ); - exit(); - } - break; - case 'regenerate': - $this->generate_api_key( $user_id, true ); - delete_transient( 'opalestate_total_api_keys' ); - wp_redirect( add_query_arg( 'opalestate-message', 'api-key-regenerated', 'edit.php?post_type=opalestate_property&page=opalestate-settings&tab=api_keys' ) ); - exit(); - break; - case 'revoke': - $this->revoke_api_key( $user_id ); - delete_transient( 'opalestate_total_api_keys' ); - wp_redirect( add_query_arg( 'opalestate-message', 'api-key-revoked', 'edit.php?post_type=opalestate_property&page=opalestate-settings&tab=api_keys' ) ); - exit(); - break; - default; - break; - } - } - - /** - * Generate new API keys for a user - * - * @access public - * @param int $user_id User ID the key is being generated for - * @param boolean $regenerate Regenerate the key for the user - * - * @return boolean True if (re)generated succesfully, false otherwise. - * @since 1.1 - * - */ - public function generate_api_key( $user_id = 0, $regenerate = false ) { - if ( empty( $user_id ) ) { - return false; - } - $user = get_userdata( $user_id ); - if ( ! $user ) { - return false; - } - $public_key = $this->get_user_public_key( $user_id ); - $secret_key = $this->get_user_secret_key( $user_id ); - - if ( empty( $public_key ) || $regenerate == true ) { - $new_public_key = $this->generate_public_key( $user->user_email ); - $new_secret_key = $this->generate_private_key( $user->ID ); - } else { - return false; - } - - if ( $regenerate == true ) { - $this->revoke_api_key( $user->ID ); - } - - update_user_meta( $user_id, $new_public_key, 'opalestate_user_public_key' ); - update_user_meta( $user_id, $new_secret_key, 'opalestate_user_secret_key' ); - - return true; - } - - /** - * Revoke a users API keys - * - * @access public - * @param int $user_id User ID of user to revoke key for - * - * @return string - * @since 1.1 - * - */ - public function revoke_api_key( $user_id = 0 ) { - if ( empty( $user_id ) ) { - return false; - } - $user = get_userdata( $user_id ); - if ( ! $user ) { - return false; - } - $public_key = $this->get_user_public_key( $user_id ); - $secret_key = $this->get_user_secret_key( $user_id ); - - if ( ! empty( $public_key ) ) { - delete_transient( md5( 'opalestate_api_user_' . $public_key ) ); - delete_transient( md5( 'opalestate_api_user_public_key' . $user_id ) ); - delete_transient( md5( 'opalestate_api_user_secret_key' . $user_id ) ); - delete_user_meta( $user_id, $public_key ); - delete_user_meta( $user_id, $secret_key ); - } else { - return false; - } - - return true; - } - - /** - * Get version. - * - * @return int - */ - public function get_version() { - return self::VERSION; - } - - /** - * Generate and Save API key - * - * Generates the key requested by user_key_field and stores it in the database - * - * @access public - * @param int $user_id - * - * @return void - * @since 1.1 - * - */ - public function update_key( $user_id ) { - if ( current_user_can( 'edit_user', $user_id ) && isset( $_POST['opalestate_set_api_key'] ) ) { - $user = get_userdata( $user_id ); - $public_key = $this->get_user_public_key( $user_id ); - $secret_key = $this->get_user_secret_key( $user_id ); - if ( empty( $public_key ) ) { - $new_public_key = $this->generate_public_key( $user->user_email ); - $new_secret_key = $this->generate_private_key( $user->ID ); - update_user_meta( $user_id, $new_public_key, 'opalestate_user_public_key' ); - update_user_meta( $user_id, $new_secret_key, 'opalestate_user_secret_key' ); - } else { - $this->revoke_api_key( $user_id ); - } - } - } - - /** - * Generate the public key for a user - * - * @access private - * @param string $user_email - * - * @return string - * @since 1.1 - * - */ - private function generate_public_key( $user_email = '' ) { - $auth_key = defined( 'AUTH_KEY' ) ? AUTH_KEY : ''; - $public = hash( 'md5', $user_email . $auth_key . date( 'U' ) ); - - return $public; - } - - /** - * Generate the secret key for a user - * - * @access private - * @param int $user_id - * - * @return string - * @since 1.1 - * - */ - private function generate_private_key( $user_id = 0 ) { - $auth_key = defined( 'AUTH_KEY' ) ? AUTH_KEY : ''; - $secret = hash( 'md5', $user_id . $auth_key . date( 'U' ) ); - - return $secret; - } - - /** - * Retrieve the user's token - * - * @access private - * @param int $user_id - * - * @return string - * @since 1.1 - * - */ - public function get_token( $user_id = 0 ) { - return hash( 'md5', $this->get_user_secret_key( $user_id ) . $this->get_user_public_key( $user_id ) ); - } - - /** - * API Key Backwards Compatibility - * - * A Backwards Compatibility call for the change of meta_key/value for users API Keys - * - * @param string $check Whether to check the cache or not - * @param int $object_id The User ID being passed - * @param string $meta_key The user meta key - * @param bool $single If it should return a single value or array - * - * @return string The API key/secret for the user supplied - * @since 1.3.6 - * - */ - public function api_key_backwards_compat( $check, $object_id, $meta_key, $single ) { - if ( $meta_key !== 'opalestate_user_public_key' && $meta_key !== 'opalestate_user_secret_key' ) { - return $check; - } - - $return = $check; - - switch ( $meta_key ) { - case 'opalestate_user_public_key': - $return = $this->get_user_public_key( $object_id ); - break; - case 'opalestate_user_secret_key': - $return = $this->get_user_secret_key( $object_id ); - break; - } - - if ( ! $single ) { - $return = [ $return ]; - } - - return $return; - } -} diff --git a/inc/api/class-opalestate-api.php b/inc/api/class-opalestate-api.php index d6c64cc2..3d316dab 100755 --- a/inc/api/class-opalestate-api.php +++ b/inc/api/class-opalestate-api.php @@ -23,10 +23,6 @@ class Opalestate_API { public function __construct() { $this->init(); - - if ( is_admin() ) { - new Opalestate_API_Admin(); - } } /** @@ -42,7 +38,6 @@ class Opalestate_API { $this->includes( [ 'class-opalestate-admin-api-keys.php', 'class-opalestate-admin-api-keys-table-list.php', - 'class-opalestate-api-admin.php', 'class-opalestate-base-api.php', 'v1/property.php', 'v1/agent.php', diff --git a/inc/api/functions.php b/inc/api/functions.php index 5f709cef..1d910df4 100644 --- a/inc/api/functions.php +++ b/inc/api/functions.php @@ -95,3 +95,26 @@ function opalestate_api_get_property_data( $property_info ) { return apply_filters( 'opalestate_api_properties_property', $property ); } + +/** + * Generate a rand hash. + * + * @return string + */ +function opalestate_rand_hash() { + if ( ! function_exists( 'openssl_random_pseudo_bytes' ) ) { + return sha1( wp_rand() ); + } + + return bin2hex( openssl_random_pseudo_bytes( 20 ) ); // @codingStandardsIgnoreLine +} + +/** + * Opalestate API - Hash. + * + * @param string $data Message to be hashed. + * @return string + */ +function opalestate_api_hash( $data ) { + return hash_hmac( 'sha256', $data, 'opalestate-api' ); +} diff --git a/opal-estate-pro.php b/opal-estate-pro.php index c1f4bb2d..3cb02e2b 100755 --- a/opal-estate-pro.php +++ b/opal-estate-pro.php @@ -128,7 +128,6 @@ if ( ! class_exists( 'OpalEstate' ) ) { self::$instance->roles = new Opalestate_Roles(); self::$instance->html = new Opalestate_HTML_Elements(); self::$instance->api = new Opalestate_API(); - self::$instance->api_admin = new Opalestate_API_Admin(); self::$instance->session = new Opalestate_Session(); /**