From 842668ee69e096237f794c506ecc1d51792edccd Mon Sep 17 00:00:00 2001 From: jonathantisseau Date: Thu, 5 Nov 2020 09:31:20 +0100 Subject: [PATCH] add renew route, add filters --- .gitignore | 3 +- includes/vendor/autoload.php | 2 +- includes/vendor/composer/ClassLoader.php | 10 +- includes/vendor/composer/autoload_real.php | 11 +- includes/vendor/composer/autoload_static.php | 6 +- public/class-jwt-auth-public.php | 136 +++++++++++++------ 6 files changed, 112 insertions(+), 56 deletions(-) diff --git a/.gitignore b/.gitignore index 600d2d3..f314852 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ -.vscode \ No newline at end of file +.vscode +includes/vendor/* \ No newline at end of file diff --git a/includes/vendor/autoload.php b/includes/vendor/autoload.php index 049f748..11170c9 100644 --- a/includes/vendor/autoload.php +++ b/includes/vendor/autoload.php @@ -4,4 +4,4 @@ require_once __DIR__ . '/composer/autoload_real.php'; -return ComposerAutoloaderInit6ba6ee55693d165c056f65e51c5383a5::getLoader(); +return ComposerAutoloaderInit40cfd0a9f9226ef22fe5cc2931190b98::getLoader(); diff --git a/includes/vendor/composer/ClassLoader.php b/includes/vendor/composer/ClassLoader.php index 2c72175..03b9bb9 100644 --- a/includes/vendor/composer/ClassLoader.php +++ b/includes/vendor/composer/ClassLoader.php @@ -60,7 +60,7 @@ class ClassLoader public function getPrefixes() { if (!empty($this->prefixesPsr0)) { - return call_user_func_array('array_merge', $this->prefixesPsr0); + return call_user_func_array('array_merge', array_values($this->prefixesPsr0)); } return array(); @@ -279,7 +279,7 @@ public function isClassMapAuthoritative() */ public function setApcuPrefix($apcuPrefix) { - $this->apcuPrefix = function_exists('apcu_fetch') && ini_get('apc.enabled') ? $apcuPrefix : null; + $this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null; } /** @@ -377,11 +377,11 @@ private function findFileWithExtension($class, $ext) $subPath = $class; while (false !== $lastPos = strrpos($subPath, '\\')) { $subPath = substr($subPath, 0, $lastPos); - $search = $subPath.'\\'; + $search = $subPath . '\\'; if (isset($this->prefixDirsPsr4[$search])) { + $pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1); foreach ($this->prefixDirsPsr4[$search] as $dir) { - $length = $this->prefixLengthsPsr4[$first][$search]; - if (file_exists($file = $dir . DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $length))) { + if (file_exists($file = $dir . $pathEnd)) { return $file; } } diff --git a/includes/vendor/composer/autoload_real.php b/includes/vendor/composer/autoload_real.php index 390d38a..f026c65 100644 --- a/includes/vendor/composer/autoload_real.php +++ b/includes/vendor/composer/autoload_real.php @@ -2,7 +2,7 @@ // autoload_real.php @generated by Composer -class ComposerAutoloaderInit6ba6ee55693d165c056f65e51c5383a5 +class ComposerAutoloaderInit40cfd0a9f9226ef22fe5cc2931190b98 { private static $loader; @@ -13,21 +13,24 @@ public static function loadClassLoader($class) } } + /** + * @return \Composer\Autoload\ClassLoader + */ public static function getLoader() { if (null !== self::$loader) { return self::$loader; } - spl_autoload_register(array('ComposerAutoloaderInit6ba6ee55693d165c056f65e51c5383a5', 'loadClassLoader'), true, true); + spl_autoload_register(array('ComposerAutoloaderInit40cfd0a9f9226ef22fe5cc2931190b98', 'loadClassLoader'), true, true); self::$loader = $loader = new \Composer\Autoload\ClassLoader(); - spl_autoload_unregister(array('ComposerAutoloaderInit6ba6ee55693d165c056f65e51c5383a5', 'loadClassLoader')); + spl_autoload_unregister(array('ComposerAutoloaderInit40cfd0a9f9226ef22fe5cc2931190b98', 'loadClassLoader')); $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded()); if ($useStaticLoader) { require_once __DIR__ . '/autoload_static.php'; - call_user_func(\Composer\Autoload\ComposerStaticInit6ba6ee55693d165c056f65e51c5383a5::getInitializer($loader)); + call_user_func(\Composer\Autoload\ComposerStaticInit40cfd0a9f9226ef22fe5cc2931190b98::getInitializer($loader)); } else { $map = require __DIR__ . '/autoload_namespaces.php'; foreach ($map as $namespace => $path) { diff --git a/includes/vendor/composer/autoload_static.php b/includes/vendor/composer/autoload_static.php index 301f2b6..a6ef8bd 100644 --- a/includes/vendor/composer/autoload_static.php +++ b/includes/vendor/composer/autoload_static.php @@ -4,7 +4,7 @@ namespace Composer\Autoload; -class ComposerStaticInit6ba6ee55693d165c056f65e51c5383a5 +class ComposerStaticInit40cfd0a9f9226ef22fe5cc2931190b98 { public static $prefixLengthsPsr4 = array ( 'F' => @@ -23,8 +23,8 @@ class ComposerStaticInit6ba6ee55693d165c056f65e51c5383a5 public static function getInitializer(ClassLoader $loader) { return \Closure::bind(function () use ($loader) { - $loader->prefixLengthsPsr4 = ComposerStaticInit6ba6ee55693d165c056f65e51c5383a5::$prefixLengthsPsr4; - $loader->prefixDirsPsr4 = ComposerStaticInit6ba6ee55693d165c056f65e51c5383a5::$prefixDirsPsr4; + $loader->prefixLengthsPsr4 = ComposerStaticInit40cfd0a9f9226ef22fe5cc2931190b98::$prefixLengthsPsr4; + $loader->prefixDirsPsr4 = ComposerStaticInit40cfd0a9f9226ef22fe5cc2931190b98::$prefixDirsPsr4; }, null, ClassLoader::class); } diff --git a/public/class-jwt-auth-public.php b/public/class-jwt-auth-public.php index bcfe2e1..6ebd3c3 100755 --- a/public/class-jwt-auth-public.php +++ b/public/class-jwt-auth-public.php @@ -75,11 +75,29 @@ public function add_api_routes() register_rest_route($this->namespace, 'token', array( 'methods' => 'POST', 'callback' => array($this, 'generate_token'), + 'permission_callback' => '__return_true', + 'args' => array( + 'username' => array( + 'type' => 'string', + 'required' => true, + ), + 'password' => array( + 'type' => 'string', + 'required' => true, + ), + ) )); register_rest_route($this->namespace, 'token/validate', array( 'methods' => 'POST', 'callback' => array($this, 'validate_token'), + 'permission_callback' => '__return_true' + )); + + register_rest_route($this->namespace, 'token/renew', array( + 'methods' => 'POST', + 'callback' => array($this, 'renew_token'), + 'permission_callback' => '__return_true' )); } @@ -93,22 +111,19 @@ public function add_cors_support() $headers = apply_filters('jwt_auth_cors_allow_headers', 'Access-Control-Allow-Headers, Content-Type, Authorization'); header(sprintf('Access-Control-Allow-Headers: %s', $headers)); } - } - - /** - * Get the user and password in the request body and generate a JWT - * - * @param [type] $request [description] - * - * @return [type] [description] - */ - public function generate_token($request) - { - $secret_key = defined('JWT_AUTH_SECRET_KEY') ? JWT_AUTH_SECRET_KEY : false; - $username = $request->get_param('username'); - $password = $request->get_param('password'); + } + /** + * Create a token and return a rest response. + * + * @param WP_User $user + * + * @return WP_REST_Response|WP_Error + */ + protected function get_token($user) + { /** First thing, check the secret key if not exist return a error*/ + $secret_key = defined('JWT_AUTH_SECRET_KEY') ? JWT_AUTH_SECRET_KEY : false; if (!$secret_key) { return new WP_Error( 'jwt_auth_bad_config', @@ -117,29 +132,14 @@ public function generate_token($request) 'status' => 403, ) ); - } - /** Try to authenticate the user with the passed credentials*/ - $user = wp_authenticate($username, $password); - - /** If the authentication fails return a error*/ - if (is_wp_error($user)) { - $error_code = $user->get_error_code(); - return new WP_Error( - '[jwt_auth] ' . $error_code, - $user->get_error_message($error_code), - array( - 'status' => 403, - ) - ); - } + } - /** Valid credentials, the user exists create the according Token */ - $issuedAt = time(); + $issuedAt = apply_filters('jwt_auth_issued_at', time()); $notBefore = apply_filters('jwt_auth_not_before', $issuedAt, $issuedAt); $expire = apply_filters('jwt_auth_expire', $issuedAt + (DAY_IN_SECONDS * 7), $issuedAt); $token = array( - 'iss' => get_bloginfo('url'), + 'iss' => apply_filters('jwt_auth_issuer', get_bloginfo('url')), 'iat' => $issuedAt, 'nbf' => $notBefore, 'exp' => $expire, @@ -163,15 +163,67 @@ public function generate_token($request) /** Let the user modify the data before send it back */ return apply_filters('jwt_auth_token_before_dispatch', $data, $user); + } + + /** + * Get the user and password in the request body and generate a JWT + * + * @param WP_REST_Request $request + * + * @return WP_REST_Response|WP_Error + */ + public function generate_token($request) + { + /** Try to authenticate the user with the passed credentials*/ + $username = $request->get_param('username'); + $password = $request->get_param('password'); + $user = wp_authenticate($username, $password); + + /** If the authentication fails return a error*/ + if (is_wp_error($user)) { + $error_code = $user->get_error_code(); + return new WP_Error( + '[jwt_auth] ' . $error_code, + $user->get_error_message($error_code), + array( + 'status' => 403, + ) + ); + } + + /** Valid credentials, the user exists create the according Token */ + return $this->get_token($user); } + /** + * Get the current JWT token in the request and renew it + * + * @param WP_REST_Request $request + * + * @return array + */ + public function renew_token($request) + { + $token = $this->validate_token(false); + if (is_wp_error($token)) { + return $token; + } + + /** Valid credentials, the user exists create the according Token */ + $user = get_user_by('ID', $token->data->user->id); + if (!$user) { + return new WP_Error('[jwt_auth] unknown user', __('User unknown', 'wp-api-jwt-auth'), ['status' => 403]); + } + return $this->get_token($user); + } + /** * This is our Middleware to try to authenticate the user according to the * token send. * - * @param (int|bool) $user Logged User ID + * @param int|bool $user Logged User ID * - * @return (int|bool) + * @return int|bool */ public function determine_current_user($user) { @@ -216,9 +268,9 @@ public function determine_current_user($user) * Main validation function, this function try to get the Autentication * headers and decoded. * - * @param bool $output + * @param bool $output False to return the token, false to get a WP_Rest_Response * - * @return WP_Error | Object | Array + * @return WP_Error|WP_Rest_Response|object */ public function validate_token($output = true) { @@ -236,7 +288,7 @@ public function validate_token($output = true) if (!$auth) { return new WP_Error( 'jwt_auth_no_auth_header', - 'Authorization header not found.', + __('Authorization header not found.', 'wp-api-jwt-auth'), array( 'status' => 403, ) @@ -251,7 +303,7 @@ public function validate_token($output = true) if (!$token) { return new WP_Error( 'jwt_auth_bad_auth_header', - 'Authorization header malformed.', + __('Authorization header malformed.', 'wp-api-jwt-auth'), array( 'status' => 403, ) @@ -263,7 +315,7 @@ public function validate_token($output = true) if (!$secret_key) { return new WP_Error( 'jwt_auth_bad_config', - 'JWT is not configurated properly, please contact the admin', + __('JWT is not configurated properly, please contact the admin', 'wp-api-jwt-auth'), array( 'status' => 403, ) @@ -274,11 +326,11 @@ public function validate_token($output = true) try { $token = JWT::decode($token, $secret_key, array('HS256')); /** The Token is decoded now validate the iss */ - if ($token->iss != get_bloginfo('url')) { + if ($token->iss != apply_filters('jwt_auth_issuer', get_bloginfo('url'))) { /** The iss do not match, return error */ return new WP_Error( 'jwt_auth_bad_iss', - 'The iss do not match with this server', + __('The iss do not match with this server', 'wp-api-jwt-auth'), array( 'status' => 403, ) @@ -289,7 +341,7 @@ public function validate_token($output = true) /** No user id in the token, abort!! */ return new WP_Error( 'jwt_auth_bad_request', - 'User ID not found in the token', + __('User ID not found in the token', 'wp-api-jwt-auth'), array( 'status' => 403, )