Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
- update firebase/php-jwt to v6.1.0
- change message about defining JWT Secret from exception to graphql_debug message
- update encode/decode signatures to use new Key method
- remove HTTP_AUTHORIZATION from test setup
- update some tests
  • Loading branch information
jasonbahl committed Apr 15, 2022
commit 44f7e1d50852749f3af1b4ef2a06ef4702ae4994
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
"wpunit-test": "vendor/bin/codecept run wpunit"
},
"require": {
"firebase/php-jwt": "^5.0"
"firebase/php-jwt": "6.1.0"
},
"require-dev": {
"lucatume/wp-browser": "3.1.0",
Expand Down
32 changes: 16 additions & 16 deletions src/Auth.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@

namespace WPGraphQL\JWT_Authentication;

use Exception;
use Firebase\JWT\JWT;
use Firebase\JWT\Key;
use GraphQL\Error\UserError;
use WPGraphQL\Data\DataSource;
use WPGraphQL\Model\User;

class Auth {

Expand Down Expand Up @@ -35,7 +37,7 @@ public static function get_secret_key() {
* @param string $password
*
* @return mixed
* @throws \Exception
* @throws Exception
* @since 0.0.1
*/
public static function login_and_get_token( $username, $password ) {
Expand All @@ -44,7 +46,7 @@ public static function login_and_get_token( $username, $password ) {
* First thing, check the secret key if not exist return a error
*/
if ( empty( self::get_secret_key() ) ) {
throw new UserError( __( 'JWT Auth is not configured correctly. Please contact a site administrator.', 'wp-graphql-jwt-authentication' ) );
return new UserError( __( 'JWT Auth is not configured correctly. Please contact a site administrator.', 'wp-graphql-jwt-authentication' ) );
}

/**
Expand Down Expand Up @@ -78,7 +80,7 @@ public static function login_and_get_token( $username, $password ) {
$response = [
'authToken' => self::get_signed_token( wp_get_current_user() ),
'refreshToken' => self::get_refresh_token( wp_get_current_user() ),
'user' => DataSource::resolve_user( $user->data->ID, \WPGraphQL::get_app_context() ),
'user' => new User( $user ),
'id' => $user->data->ID,
];

Expand All @@ -88,7 +90,7 @@ public static function login_and_get_token( $username, $password ) {
* @param \WP_User $user The authenticated user
* @param array $response The default response
*/
$response = apply_filters( 'graphql_jwt_auth_after_authenticate', $user, $response );
$response = apply_filters( 'graphql_jwt_auth_after_authenticate', $response, $user );

return ! empty( $response ) ? $response : [];
}
Expand Down Expand Up @@ -186,7 +188,7 @@ protected static function get_signed_token( $user, $cap_check = true ) {
* Encode the token
*/
JWT::$leeway = 60;
$token = JWT::encode( $token, self::get_secret_key() );
$token = JWT::encode( $token, self::get_secret_key(), 'HS256' );

/**
* Filter the token before returning it, allowing for individual systems to override what's returned.
Expand Down Expand Up @@ -392,7 +394,7 @@ protected static function authenticate_user( $username, $password ) {
* @param (int|bool) $user Logged User ID
*
* @return mixed|false|\WP_User
* @throws \Exception
* @throws Exception
*/
public static function filter_determine_current_user( $user ) {

Expand Down Expand Up @@ -531,7 +533,7 @@ protected static function set_status( $status_code ) {
*
* @param string $token The encoded JWT Token
*
* @throws \Exception
* @throws Exception
* @return mixed|boolean|string
*/
public static function validate_token( $token = null, $refresh = false ) {
Expand Down Expand Up @@ -577,26 +579,24 @@ public static function validate_token( $token = null, $refresh = false ) {
return new \WP_Error( 'invalid-secret-key', __( 'JWT is not configured properly', 'wp-graphql-jwt-authentication' ) );
}



/**
* Decode the Token
*/
JWT::$leeway = 60;

$secret = self::get_secret_key();
codecept_debug( [ 'tokenYo' => $token ] );

try {
$token = ! empty( $token ) ? JWT::decode( $token, $secret, [ 'HS256' ] ) : null;
} catch ( \Exception $exception ) {
return new \WP_Error( 'invalid-secret-key', $exception->getMessage() );
$token = ! empty( $token ) ? JWT::decode( $token, new Key( self::get_secret_key(), 'HS256') ) : null;
} catch ( Exception $exception ) {
$token = new \WP_Error( 'invalid-secret-key', $exception->getMessage() );
}

/**
* If there's no token listed, just bail now before validating an empty token.
* This will treat the request as a public request
*/
if ( empty( $token ) ) {
if ( empty( $token ) || is_wp_error( $token ) ) {
return $token;
}

Expand All @@ -614,7 +614,7 @@ public static function validate_token( $token = null, $refresh = false ) {
* The Token is decoded now validate the iss
*/

if ( ! isset( $token->iss ) || !in_array($token->iss, $allowed_domains) ) {
if ( ! isset( $token->iss ) || ! in_array( $token->iss, $allowed_domains ) ) {
// See https://github.com/wp-graphql/wp-graphql-jwt-authentication/issues/111
self::set_status(401);
return new \WP_Error( 'invalid-jwt', __( 'The iss do not match with this server', 'wp-graphql-jwt-authentication' ) );
Expand Down
84 changes: 59 additions & 25 deletions tests/wpunit/AuthenticationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,15 @@ class AuthenticationTest extends \Codeception\TestCase\WPTestCase {

public $admin;
public $login_mutation;
public $admin_username;
public $admin_password;

/**
* This function is run before each method
* @since 0.0.5
*/
public function setUp(): void {

$_SERVER['HTTP_AUTHORIZATION'] = 'Bearer goo';

add_filter( 'graphql_debug_enabled', '__return_true' );
add_filter( 'graphql_jwt_auth_secret_key', function() {
Expand All @@ -28,10 +29,13 @@ public function setUp(): void {

parent::setUp();

$this->admin_password = 'testPassword';
$this->admin_username = 'testuser';

$this->admin = $this->factory->user->create( [
'role' => 'administrator',
'user_login' => 'testuser',
'user_pass' => 'testPassword',
'user_login' => $this->admin_username,
'user_pass' => $this->admin_password,
] );


Expand All @@ -44,9 +48,13 @@ public function setUp(): void {
pages{
edges{
node{
id
title
content
author {
node {
databaseId
}
}
}
}
}
Expand Down Expand Up @@ -77,9 +85,9 @@ public function testLoginWithBadCredentials() {
'query' => $this->login_mutation,
'variables' => [
'input' => [
'username' => 'testuser',
'username' => $this->admin_username,
'password' => 'badPassword',
'clientMutationId' => uniqid(),
'clientMutationId' => uniqid( '', true ),
]
]
]);
Expand Down Expand Up @@ -125,9 +133,8 @@ public function testLoginWithPage() {
'query' => $this->login_mutation,
'variables' => [
'input' => [
'username' => 'testuser',
'password' => 'testPassword',
'clientMutationId' => uniqid(),
'username' => $this->admin_username,
'password' => $this->admin_password,
]
]
]);
Expand All @@ -138,14 +145,18 @@ public function testLoginWithPage() {
* Establish the expectation for the output of the query
*/
$expected_user = [
'username' => 'testuser',
'username' => $this->admin_username,
'pages' => [
'edges' => [
[
'node' => [
'id' => $global_id,
'title' => 'Test Page Title',
'content' => apply_filters( 'the_content', $args['post_content'] ),
'author' => [
'node' => [
'databaseId' => $this->admin
],
],
],
],
],
Expand Down Expand Up @@ -175,9 +186,9 @@ public function testLoginWithNoSecretKeyConfigured() {
'query' => $this->login_mutation,
'variables' => [
'input' => [
'username' => 'testuser',
'password' => 'testPassword',
'clientMutationId' => uniqid(),
'username' => $this->admin_username,
'password' => $this->admin_password,
'clientMutationId' => uniqid( '', true ),
]
]
] );
Expand All @@ -189,14 +200,16 @@ public function testLoginWithNoSecretKeyConfigured() {

}

public function filter_authentication () {
return 'goo';
}

public function testLoginWithValidUserThatWasJustDeleted() {

/**
* Filter the authentication to make sure it returns an error
*/
add_filter( 'authenticate', function() {
return 'goo';
}, 9999 );
add_filter( 'authenticate', [ $this, 'filter_authentication'], 9999 );

/**
* Run the GraphQL query
Expand All @@ -205,9 +218,9 @@ public function testLoginWithValidUserThatWasJustDeleted() {
'query' => $this->login_mutation,
'variables' => [
'input' => [
'username' => 'testuser',
'password' => 'testPassword',
'clientMutationId' => uniqid(),
'username' => $this->admin_username,
'password' => $this->admin_password,
'clientMutationId' => uniqid( '', true ),
]
]
]);
Expand All @@ -217,6 +230,8 @@ public function testLoginWithValidUserThatWasJustDeleted() {
*/
$this->assertArrayHasKey( 'errors', $actual );

remove_filter( 'authenticate', [ $this, 'filter_authentication'], 9999 );

}

public function testNonAuthenticatedRequest() {
Expand Down Expand Up @@ -267,6 +282,8 @@ public function testRequestWithNoToken() {

public function testRequestWithInvalidToken() {

wp_set_current_user( $this->admin );

add_filter( 'graphql_jwt_auth_token_before_sign', function( $token ) {
$token['iss'] = null;
return $token;
Expand All @@ -279,11 +296,15 @@ public function testRequestWithInvalidToken() {
return 'Bearer ' . $token;
} );

codecept_debug( [ 'invalidToken' => $token ]);

/**
* Validate the token (should not work because we filtered the iss to make it invalid)
*/
$token = \WPGraphQL\JWT_Authentication\Auth::validate_token( $token );

codecept_debug( $token );

/**
* Validate token should return nothing if it can't be validated properly
*/
Expand All @@ -296,27 +317,40 @@ public function testRequestWithInvalidToken() {
*/
public function testNoSecretKey() {

// $_SERVER['HTTP_AUTHORIZATION'] = 'Bearer goo';

/**
* Filter the secret key to return null, which should cause an exception to be thrown
*/
add_filter( 'graphql_jwt_auth_secret_key', function() {
return null;
} );

/**
* Set our expected exception
*/
$this->expectException( 'Exception', 'JWT is not configured properly' );

/**
* Run the function to determine the current user
*/
$user = \WPGraphQL\JWT_Authentication\Auth::filter_determine_current_user( 0 );

codecept_debug( [ 'user' => $user ] );

$actual = graphql([
'query' => $this->login_mutation,
'variables' => [
'input' => [
'username' => $this->admin_username,
'password' => $this->admin_password,
]
]
]);

codecept_debug( $actual );

/**
* Ensure that the Exception prevented any user from being authenticated
*/
$this->assertEquals( 0, $user );
$this->assertNull( $actual['data']['login'] );
$this->assertArrayHasKey( 'errors', $actual );

}

Expand Down
10 changes: 5 additions & 5 deletions vendor/composer/InstalledVersions.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ class InstalledVersions
'aliases' =>
array (
),
'reference' => 'e09174b283f67cd17517d966c90d8800f66e1854',
'reference' => 'f4518357b5349b7325e8c974f5deec2cdcf1ae1a',
'name' => 'wp-graphql/wp-graphql-jwt-authentication',
),
'versions' =>
Expand Down Expand Up @@ -215,12 +215,12 @@ class InstalledVersions
),
'firebase/php-jwt' =>
array (
'pretty_version' => 'v5.5.1',
'version' => '5.5.1.0',
'pretty_version' => 'v6.1.0',
'version' => '6.1.0.0',
'aliases' =>
array (
),
'reference' => '83b609028194aa042ea33b5af2d41a7427de80e6',
'reference' => 'fbb2967a3a68b07e37678c00c0cf51165051495f',
),
'flow/jsonpath' =>
array (
Expand Down Expand Up @@ -971,7 +971,7 @@ class InstalledVersions
'aliases' =>
array (
),
'reference' => 'e09174b283f67cd17517d966c90d8800f66e1854',
'reference' => 'f4518357b5349b7325e8c974f5deec2cdcf1ae1a',
),
'zordius/lightncandy' =>
array (
Expand Down
Loading