2015-04-17 20:41:25 +00:00
< ? php
/**
* WooCommerce Auth
*
* Handles wc - auth endpoint requests
*
* @ author WooThemes
* @ category API
* @ package WooCommerce / API
* @ since 2.4 . 0
*/
if ( ! defined ( 'ABSPATH' ) ) {
exit ;
}
if ( ! class_exists ( 'WC_Auth' ) ) :
class WC_Auth {
/**
* Version
*/
const VERSION = 1 ;
/**
* Setup class
*
* @ since 2.4 . 0
*/
public function __construct () {
2015-04-23 19:58:15 +00:00
// Add query vars
add_filter ( 'query_vars' , array ( $this , 'add_query_vars' ), 0 );
2015-04-17 20:41:25 +00:00
// Register auth endpoint
add_action ( 'init' , array ( __CLASS__ , 'add_endpoint' ), 0 );
// Handle auth requests
add_action ( 'parse_request' , array ( $this , 'handle_auth_requests' ), 0 );
}
2015-04-23 19:58:15 +00:00
/**
* Add query vars
*
* @ since 2.4 . 0
*
* @ param $vars
*
* @ return string []
*/
public function add_query_vars ( $vars ) {
$vars [] = 'wc-auth-version' ;
$vars [] = 'wc-auth-route' ;
return $vars ;
}
2015-04-17 20:41:25 +00:00
/**
* Add auth endpoint
*
* @ since 2.4 . 0
*/
public static function add_endpoint () {
2015-04-23 19:58:15 +00:00
add_rewrite_rule ( '^wc-auth/v([1]{1})/(.*)?' , 'index.php?wc-auth-version=$matches[1]&wc-auth-route=$matches[2]' , 'top' );
2015-04-17 20:41:25 +00:00
}
2015-04-22 20:02:15 +00:00
/**
2015-04-23 19:37:59 +00:00
* Get scope name .
2015-04-22 20:48:39 +00:00
*
* @ since 2.4 . 0
*
2015-04-23 19:37:59 +00:00
* @ param string $scope
2015-04-22 20:48:39 +00:00
*
* @ return string
2015-04-22 20:02:15 +00:00
*/
2015-04-23 19:37:59 +00:00
protected function get_i18n_scope ( $scope ) {
2015-04-22 20:48:39 +00:00
$permissions = array (
'read' => __ ( 'Read' , 'woocommerce' ),
'write' => __ ( 'Write' , 'woocommerce' ),
'read_write' => __ ( 'Read/Write' , 'woocommerce' ),
);
2015-04-23 19:37:59 +00:00
return $permissions [ $scope ];
2015-04-22 20:48:39 +00:00
}
2015-05-14 15:58:34 +00:00
/**
* Return a list of permissions a scope allows
2015-05-18 19:46:52 +00:00
*
* @ since 2.4 . 0
*
2015-05-14 15:58:34 +00:00
* @ param string $scope
2015-05-18 19:46:52 +00:00
*
2015-05-14 15:58:34 +00:00
* @ return array
*/
protected function get_permissions_in_scope ( $scope ) {
$permissions = array ();
switch ( $scope ) {
case 'read' :
$permissions [] = __ ( 'View coupons' , 'woocommerce' );
$permissions [] = __ ( 'View customers' , 'woocommerce' );
$permissions [] = __ ( 'View orders and sales reports' , 'woocommerce' );
$permissions [] = __ ( 'View products' , 'woocommerce' );
break ;
case 'write' :
$permissions [] = __ ( 'Create webhooks' , 'woocommerce' );
$permissions [] = __ ( 'Create coupons' , 'woocommerce' );
$permissions [] = __ ( 'Create customers' , 'woocommerce' );
$permissions [] = __ ( 'Create orders' , 'woocommerce' );
$permissions [] = __ ( 'Create products' , 'woocommerce' );
break ;
case 'read_write' :
$permissions [] = __ ( 'Create webhooks' , 'woocommerce' );
$permissions [] = __ ( 'View and manage coupons' , 'woocommerce' );
$permissions [] = __ ( 'View and manage customers' , 'woocommerce' );
$permissions [] = __ ( 'View and manage orders and sales reports' , 'woocommerce' );
$permissions [] = __ ( 'View and manage products' , 'woocommerce' );
break ;
}
return $permissions ;
}
2015-04-22 20:48:39 +00:00
/**
* Build auth urls
*
* @ since 2.4 . 0
*
* @ param array $data
* @ param string $endpoint
*
* @ return string
*/
protected function build_url ( $data , $endpoint ) {
2015-04-23 19:58:15 +00:00
$url = wc_get_endpoint_url ( 'wc-auth/v' . self :: VERSION , $endpoint , get_home_url ( '/' ) );
2015-04-22 20:48:39 +00:00
2015-04-22 20:02:15 +00:00
return add_query_arg ( array (
2015-04-23 19:37:59 +00:00
'app_name' => wc_clean ( $data [ 'app_name' ] ),
'user_id' => wc_clean ( $data [ 'user_id' ] ),
'return_url' => urlencode ( $data [ 'return_url' ] ),
'callback_url' => urlencode ( $data [ 'callback_url' ] ),
'scope' => wc_clean ( $data [ 'scope' ] ),
2015-04-22 20:02:15 +00:00
), $url );
}
2015-04-22 21:12:40 +00:00
/**
* Make validation
2015-05-18 19:46:52 +00:00
*
* @ since 2.4 . 0
2015-04-22 21:12:40 +00:00
*/
protected function make_validation () {
2015-04-23 20:43:38 +00:00
$params = array (
'app_name' ,
'user_id' ,
'return_url' ,
'callback_url' ,
'scope'
);
2015-04-23 19:37:59 +00:00
2015-04-23 20:43:38 +00:00
foreach ( $params as $param ) {
if ( empty ( $_REQUEST [ $param ] ) ) {
throw new Exception ( sprintf ( __ ( 'Missing parameter %s' , 'woocommerce' ), $param ) );
}
2015-04-22 21:12:40 +00:00
}
2015-04-23 20:45:38 +00:00
if ( ! in_array ( $_REQUEST [ 'scope' ], array ( 'read' , 'write' , 'read_write' ) ) ) {
throw new Exception ( sprintf ( __ ( 'Invalid scope %s' , 'woocommerce' ), wc_clean ( $_REQUEST [ 'scope' ] ) ) );
2015-04-22 21:12:40 +00:00
}
2015-04-23 20:45:38 +00:00
foreach ( array ( 'return_url' , 'callback_url' ) as $param ) {
2015-04-23 20:51:49 +00:00
if ( false === filter_var ( urldecode ( $_REQUEST [ $param ] ), FILTER_VALIDATE_URL ) ) {
2015-04-23 20:45:38 +00:00
throw new Exception ( sprintf ( __ ( 'The %s is not a valid URL' , 'woocommerce' ), $param ) );
}
2015-04-22 21:12:40 +00:00
}
2015-04-23 20:45:38 +00:00
if ( 0 !== stripos ( urldecode ( $_REQUEST [ 'callback_url' ] ), 'https://' ) ) {
throw new Exception ( __ ( 'The callback_url need to be over SSL' , 'woocommerce' ) );
2015-04-22 21:12:40 +00:00
}
}
2015-04-23 19:37:59 +00:00
/**
2015-05-18 19:46:52 +00:00
* Create keys .
2015-04-23 19:37:59 +00:00
*
* @ since 2.4 . 0
*
* @ param string $app_name
2015-05-18 19:46:52 +00:00
* @ param string $app_user_id
2015-04-23 19:37:59 +00:00
* @ param string $scope
*
* @ return array
*/
2015-05-18 19:46:52 +00:00
protected function create_keys ( $app_name , $app_user_id , $scope ) {
global $wpdb ;
2015-04-23 19:37:59 +00:00
2015-05-18 19:46:52 +00:00
$description = sprintf ( __ ( '%s - API %s (created on %s at %s).' , 'woocommerce' ), wc_clean ( $app_name ), $this -> get_i18n_scope ( $scope ), date_i18n ( wc_date_format () ), date_i18n ( wc_time_format () ) );
$user = wp_get_current_user ();
2015-04-23 19:37:59 +00:00
// Created API keys.
2015-05-18 19:46:52 +00:00
$permissions = ( in_array ( $scope , array ( 'read' , 'write' , 'read_write' ) ) ) ? sanitize_text_field ( $scope ) : 'read' ;
2015-06-08 15:01:54 +00:00
$consumer_key = 'ck_' . wc_rand_hash ();
$consumer_secret = 'cs_' . wc_rand_hash ();
2015-05-18 19:46:52 +00:00
$wpdb -> insert (
$wpdb -> prefix . 'woocommerce_api_keys' ,
array (
'user_id' => $user -> ID ,
'description' => $description ,
'permissions' => $permissions ,
2015-06-08 15:57:19 +00:00
'consumer_key' => wc_api_hash ( $consumer_key ),
2015-07-16 18:42:00 +00:00
'consumer_secret' => $consumer_secret ,
'truncated_key' => substr ( $consumer_key , - 7 )
2015-05-18 19:46:52 +00:00
),
array (
'%d' ,
'%s' ,
'%s' ,
'%s' ,
2015-08-07 00:31:21 +00:00
'%s' ,
2015-05-18 19:46:52 +00:00
'%s'
)
);
2015-04-23 19:37:59 +00:00
return array (
2015-05-18 19:46:52 +00:00
'key_id' => $wpdb -> insert_id ,
'user_id' => $app_user_id ,
2015-04-23 19:37:59 +00:00
'consumer_key' => $consumer_key ,
'consumer_secret' => $consumer_secret ,
'key_permissions' => $permissions
);
}
/**
* Post consumer data .
*
* @ since 2.4 . 0
*
* @ param array $consumer_data
* @ param string $url
*
* @ return bool
*/
protected function post_consumer_data ( $consumer_data , $url ) {
$params = array (
'body' => json_encode ( $consumer_data ),
'timeout' => 60 ,
'headers' => array (
'Content-Type' => 'application/xml;charset=' . get_bloginfo ( 'charset' ),
)
);
2015-05-20 17:24:44 +00:00
$response = wp_safe_remote_post ( esc_url_raw ( urldecode ( $url ) ), $params );
2015-04-23 19:37:59 +00:00
if ( is_wp_error ( $response ) ) {
throw new Exception ( $response -> get_error_message () );
} else if ( 200 != $response [ 'response' ][ 'code' ] ) {
throw new Exception ( __ ( 'An error occurred in the request and at the time were unable to send the consumer data' , 'woocommerce' ) );
}
return true ;
}
2015-04-17 20:41:25 +00:00
/**
* Handle auth requests
*
* @ since 2.4 . 0
*/
public function handle_auth_requests () {
global $wp ;
2015-04-23 19:58:15 +00:00
if ( ! empty ( $_GET [ 'wc-auth-version' ] ) ) {
$wp -> query_vars [ 'wc-auth-version' ] = $_GET [ 'wc-auth-version' ];
}
if ( ! empty ( $_GET [ 'wc-auth-route' ] ) ) {
$wp -> query_vars [ 'wc-auth-route' ] = $_GET [ 'wc-auth-route' ];
2015-04-17 20:41:25 +00:00
}
// wc-auth endpoint requests
2015-04-23 19:58:15 +00:00
if ( ! empty ( $wp -> query_vars [ 'wc-auth-version' ] ) && ! empty ( $wp -> query_vars [ 'wc-auth-route' ] ) ) {
2015-04-23 20:48:56 +00:00
$this -> auth_endpoint ( $wp -> query_vars [ 'wc-auth-route' ] );
}
}
2015-04-23 19:37:59 +00:00
2015-04-23 20:48:56 +00:00
/**
* Auth endpoint
*
2015-07-16 18:42:00 +00:00
* @ since 2.4 . 0
2015-05-18 19:46:52 +00:00
*
* @ param string $route
2015-04-23 20:48:56 +00:00
*/
protected function auth_endpoint ( $route ) {
ob_start ();
2015-05-18 19:46:52 +00:00
$consumer_data = array ();
2015-04-23 20:48:56 +00:00
try {
2015-05-18 19:46:52 +00:00
if ( 'yes' !== get_option ( 'woocommerce_api_enabled' ) ) {
throw new Exception ( __ ( 'API disabled!' , 'woocommerce' ) );
}
2015-04-23 20:48:56 +00:00
$route = strtolower ( wc_clean ( $route ) );
$this -> make_validation ();
// Login endpoint
if ( 'login' == $route && ! is_user_logged_in () ) {
wc_get_template ( 'auth/form-login.php' , array (
'app_name' => $_REQUEST [ 'app_name' ],
'return_url' => add_query_arg ( array ( 'success' => 0 , 'user_id' => wc_clean ( $_REQUEST [ 'user_id' ] ) ), urldecode ( $_REQUEST [ 'return_url' ] ) ),
'redirect_url' => $this -> build_url ( $_REQUEST , 'authorize' ),
) );
exit ;
// Redirect with user is logged in
} else if ( 'login' == $route && is_user_logged_in () ) {
wp_redirect ( esc_url_raw ( $this -> build_url ( $_REQUEST , 'authorize' ) ) );
exit ;
// Redirect with user is not logged in and trying to access the authorize endpoint
} else if ( 'authorize' == $route && ! is_user_logged_in () ) {
wp_redirect ( esc_url_raw ( $this -> build_url ( $_REQUEST , 'login' ) ) );
exit ;
// Authorize endpoint
} else if ( 'authorize' == $route && current_user_can ( 'manage_woocommerce' ) ) {
wc_get_template ( 'auth/form-grant-access.php' , array (
'app_name' => $_REQUEST [ 'app_name' ],
'return_url' => add_query_arg ( array ( 'success' => 0 , 'user_id' => wc_clean ( $_REQUEST [ 'user_id' ] ) ), urldecode ( $_REQUEST [ 'return_url' ] ) ),
'scope' => $this -> get_i18n_scope ( wc_clean ( $_REQUEST [ 'scope' ] ) ),
2015-05-14 15:58:34 +00:00
'permissions' => $this -> get_permissions_in_scope ( wc_clean ( $_REQUEST [ 'scope' ] ) ),
2015-04-23 20:48:56 +00:00
'granted_url' => wp_nonce_url ( $this -> build_url ( $_REQUEST , 'access_granted' ), 'wc_auth_grant_access' , 'wc_auth_nonce' ),
2015-05-14 15:58:34 +00:00
'logout_url' => wp_logout_url ( $this -> build_url ( $_REQUEST , 'login' ) ),
'user' => wp_get_current_user ()
2015-04-23 20:48:56 +00:00
) );
exit ;
// Granted access endpoint
} else if ( 'access_granted' == $route && current_user_can ( 'manage_woocommerce' ) ) {
if ( ! isset ( $_GET [ 'wc_auth_nonce' ] ) || ! wp_verify_nonce ( $_GET [ 'wc_auth_nonce' ], 'wc_auth_grant_access' ) ) {
throw new Exception ( __ ( 'Invalid nonce verification' , 'woocommerce' ) );
}
2015-04-23 19:46:28 +00:00
2015-05-18 19:46:52 +00:00
$consumer_data = $this -> create_keys ( $_REQUEST [ 'app_name' ], $_REQUEST [ 'user_id' ], $_REQUEST [ 'scope' ] );
2015-04-23 20:48:56 +00:00
$response = $this -> post_consumer_data ( $consumer_data , $_REQUEST [ 'callback_url' ] );
2015-04-22 20:02:15 +00:00
2015-04-23 20:48:56 +00:00
if ( $response ) {
wp_redirect ( esc_url_raw ( add_query_arg ( array ( 'success' => 1 , 'user_id' => wc_clean ( $_REQUEST [ 'user_id' ] ) ), urldecode ( $_REQUEST [ 'return_url' ] ) ) ) );
2015-04-22 20:02:15 +00:00
exit ;
}
2015-05-18 19:46:52 +00:00
} else {
throw new Exception ( __ ( 'You do not have permissions to access this page!' , 'woocommerce' ) );
2015-04-22 20:02:15 +00:00
}
2015-04-23 20:48:56 +00:00
} catch ( Exception $e ) {
2015-05-18 19:46:52 +00:00
$this -> maybe_delete_key ( $consumer_data );
2015-04-23 20:48:56 +00:00
wp_die ( sprintf ( __ ( 'Error: %s' , 'woocommerce' ), $e -> getMessage () ), __ ( 'Access Denied' , 'woocommerce' ), array ( 'response' => 401 ) );
2015-04-17 20:41:25 +00:00
}
}
2015-05-18 19:46:52 +00:00
/**
* Maybe delete key
*
* @ since 2.4 . 0
*
* @ param array $key
*/
private function maybe_delete_key ( $key ) {
global $wpdb ;
if ( isset ( $key [ 'key_id' ] ) ) {
$wpdb -> delete ( $wpdb -> prefix . 'woocommerce_api_keys' , array ( 'key_id' => $key [ 'key_id' ] ), array ( '%d' ) );
}
}
2015-04-17 20:41:25 +00:00
}
endif ;
return new WC_Auth ();