Page MenuHomePhabricator

OAuth test failure on REL1_39
Closed, ResolvedPublic

Description

https://gerrit.wikimedia.org/r/c/mediawiki/extensions/OAuth/+/834540 is a no-op

https://integration.wikimedia.org/ci/job/quibble-composer-mysql-php74-noselenium-docker/23123/console

15:06:49 There were 2 errors:
15:06:49 
15:06:49 1) MediaWiki\Extension\OAuth\Tests\Rest\RequestClientEndpointTest::testHandlerExecute with data set "Successful request owner only" (array('POST', GuzzleHttp\Psr7\Uri Object (...), array('TestName', '1.0', 'TestDescription', '*', true, 'https://test.com', false, 'test@test.com', false, array('client_credentials'), array()), array('application/json')), array(200, 'OK', '1.1'), Closure Object (...), Closure Object (...))
15:06:49 Lcobucci\JWT\Signer\InvalidKeyProvided: Key cannot be empty
15:06:49 
15:06:49 /workspace/src/vendor/lcobucci/jwt/src/Signer/InvalidKeyProvided.php:34
15:06:49 /workspace/src/vendor/lcobucci/jwt/src/Signer/Key/InMemory.php:25
15:06:49 /workspace/src/vendor/lcobucci/jwt/src/Signer/Key/InMemory.php:44
15:06:49 /workspace/src/vendor/league/oauth2-server/src/Entities/Traits/AccessTokenTrait.php:51
15:06:49 /workspace/src/vendor/league/oauth2-server/src/Entities/Traits/AccessTokenTrait.php:62
15:06:49 /workspace/src/vendor/league/oauth2-server/src/Entities/Traits/AccessTokenTrait.php:91
15:06:49 /workspace/src/extensions/OAuth/src/Rest/Handler/AbstractClientHandler.php:56
15:06:49 /workspace/src/tests/phpunit/unit/includes/Rest/Handler/HandlerTestTrait.php:158
15:06:49 /workspace/src/extensions/OAuth/tests/phpunit/Rest/EndpointTest.php:136
15:06:49 /workspace/src/extensions/OAuth/tests/phpunit/Rest/EndpointTest.php:76
15:06:49 /workspace/src/tests/phpunit/MediaWikiIntegrationTestCase.php:500
15:06:49 === Logs generated by test case
15:06:49 [objectcache] [debug] MainWANObjectCache using store {class} {"class":"EmptyBagOStuff"}
15:06:49 [localisation] [debug] LocalisationCache using store LCStoreNull []
15:06:49 [MessageCache] [debug] MessageCache using store {class} {"class":"HashBagOStuff"}
15:06:49 [objectcache] [debug] MainWANObjectCache using store {class} {"class":"EmptyBagOStuff"}
15:06:49 [localisation] [debug] LocalisationCache::isExpired(en): cache missing, need to make one []
15:06:49 [localisation] [debug] LocalisationCache using store LCStoreNull []
15:06:49 [objectcache] [debug] MainWANObjectCache using store {class} {"class":"EmptyBagOStuff"}
15:06:49 [CentralAuth] [debug] Loading state for global user {user} from DB {"user":"RequestClientTestUser10"}
15:06:49 [CentralAuth] [debug] Loading attached wiki list for global user RequestClientTestUser10 from DB []
15:06:49 [CentralAuth] [debug] Loading groups for global user {user} {"user":"RequestClientTestUser10"}
15:06:49 [objectcache] [debug] fetchOrRegenerate(global:centralauth-user:f78f739014e330197b356e345da64e46): miss, new value computed []
15:06:49 [CentralAuth] [debug] Loading CentralAuthUser for user {user} from cache object {"user":"RequestClientTestUser10"}
15:06:49 [CentralAuth] [debug] Loading state for global user {user} from DB {"user":"RequestClientTestUser10"}
15:06:49 [objectcache] [debug] MainObjectStash using store {class} {"class":"HashBagOStuff"}
15:06:49 [localisation] [debug] LocalisationCache::isExpired(en): cache missing, need to make one []
15:06:49 [OAuth] [debug] MediaWiki\Extension\OAuth\Entity\ClientEntity: performing DB update; new object. []
15:06:49 [wfDebug] [debug] User::getBlockedStatus: checking blocked status for RequestClientTestUser10 {"private":false}
15:06:49 [OAuth] [info] {user} performed action {action} on consumer {consumer} {"action":"create-owner-only","user":"RequestClientTestUser10","consumer":"799bed8388659190dcef14e931c0d486","target":"RequestClientTestUser10","comment":"TestDescription","clientip":"127.0.0.1"}
15:06:49 [OAuth] [debug] MediaWiki\Extension\OAuth\Backend\ConsumerAcceptance: performing DB update; new object. []
15:06:49 ===
15:06:49 
15:06:49 2) MediaWiki\Extension\OAuth\Tests\Rest\ResetClientSecretEndpointTest::testHandlerExecute with data set "Successful Request OAuth 2 Owner Only" (array('POST', GuzzleHttp\Psr7\Uri Object (...), array('55555555555555555555555555555555'), array('application/json')), array(200, 'OK', '1.1'), Closure Object (...), Closure Object (...))
15:06:49 Lcobucci\JWT\Signer\InvalidKeyProvided: Key cannot be empty
15:06:49 
15:06:49 /workspace/src/vendor/lcobucci/jwt/src/Signer/InvalidKeyProvided.php:34
15:06:49 /workspace/src/vendor/lcobucci/jwt/src/Signer/Key/InMemory.php:25
15:06:49 /workspace/src/vendor/lcobucci/jwt/src/Signer/Key/InMemory.php:44
15:06:49 /workspace/src/vendor/league/oauth2-server/src/Entities/Traits/AccessTokenTrait.php:51
15:06:49 /workspace/src/vendor/league/oauth2-server/src/Entities/Traits/AccessTokenTrait.php:62
15:06:49 /workspace/src/vendor/league/oauth2-server/src/Entities/Traits/AccessTokenTrait.php:91
15:06:49 /workspace/src/extensions/OAuth/src/Rest/Handler/AbstractClientHandler.php:56
15:06:49 /workspace/src/tests/phpunit/unit/includes/Rest/Handler/HandlerTestTrait.php:158
15:06:49 /workspace/src/extensions/OAuth/tests/phpunit/Rest/EndpointTest.php:136
15:06:49 /workspace/src/extensions/OAuth/tests/phpunit/Rest/EndpointTest.php:76
15:06:49 /workspace/src/tests/phpunit/MediaWikiIntegrationTestCase.php:500
15:06:49 === Logs generated by test case
15:06:49 [objectcache] [debug] MainWANObjectCache using store {class} {"class":"EmptyBagOStuff"}
15:06:49 [localisation] [debug] LocalisationCache using store LCStoreNull []
15:06:49 [MessageCache] [debug] MessageCache using store {class} {"class":"HashBagOStuff"}
15:06:49 [objectcache] [debug] MainWANObjectCache using store {class} {"class":"EmptyBagOStuff"}
15:06:49 [localisation] [debug] LocalisationCache::isExpired(en): cache missing, need to make one []
15:06:49 [localisation] [debug] LocalisationCache using store LCStoreNull []
15:06:49 [objectcache] [debug] MainWANObjectCache using store {class} {"class":"EmptyBagOStuff"}
15:06:49 [OAuth] [debug] MediaWiki\Extension\OAuth\Entity\ClientEntity: performing DB update; new object. []
15:06:49 [objectcache] [debug] MainObjectStash using store {class} {"class":"HashBagOStuff"}
15:06:49 [CentralAuth] [debug] Loading state for global user {user} from DB {"user":"ResetClientSecretTestUser5"}
15:06:49 [CentralAuth] [debug] Loading attached wiki list for global user ResetClientSecretTestUser5 from DB []
15:06:49 [CentralAuth] [debug] Loading groups for global user {user} {"user":"ResetClientSecretTestUser5"}
15:06:49 [objectcache] [debug] fetchOrRegenerate(global:centralauth-user:01ff10c2fd63337b9728e2829fe6c084): miss, new value computed []
15:06:49 [CentralAuth] [debug] Loading CentralAuthUser for user {user} from cache object {"user":"ResetClientSecretTestUser5"}
15:06:49 [UserOptionsManager] [debug] Loading options from database {"user_id":80}
15:06:49 [OAuth] [debug] MediaWiki\Extension\OAuth\Entity\ClientEntity: performing DB update; object changed. []
15:06:49 [wfDebug] [debug] User::getBlockedStatus: checking blocked status for ResetClientSecretTestUser5 {"private":false}
15:06:49 [localisation] [debug] LocalisationCache::isExpired(en): cache missing, need to make one []
15:06:49 [OAuth] [info] {user} performed action {action} on consumer {consumer} {"action":"update","user":"ResetClientSecretTestUser5","consumer":"55555555555555555555555555555555","target":"ResetClientSecretTestUser5","comment":"","clientip":"127.0.0.1"}
15:06:49 [OAuth] [debug] MediaWiki\Extension\OAuth\Backend\ConsumerAcceptance: performing DB update; new object. []
15:06:49 ===

Event Timeline

This is an upstream issue with league/oauth2-server that has already been reported at https://github.com/thephpleague/oauth2-server/pull/1282. The problem is that due to REL1_39 running php 7.4 it now uses a newer version of the lcobucci/jwt lib.

Since we can't upgrade league/oauth2-server without further thoughts (I am not familiar with T302757 and https://github.com/thephpleague/oauth2-server/issues/1266 / https://github.com/thephpleague/oauth2-server/pull/1267), the simplest solution for now seems to be pinning the version of lcobucci/jwt.

4.1.5 says "php": "^7.4 || ^8.0" so there should be no problem backporting it to supported branches, right?
(It does break PHP 8.1 support, not sure if we care. If this is a PHP 7.4 only issue we could pin to 4.1.5 || ^4.4.0 as 4.4 only supports PHP 8.1+.)

At a glance all supported branches are affected.

4.1.5 says "php": "^7.4 || ^8.0" so there should be no problem backporting it to supported branches, right?
(It does break PHP 8.1 support, not sure if we care. If this is a PHP 7.4 only issue we could pin to 4.1.5 || ^4.4.0 as 4.4 only supports PHP 8.1+.)

It'd be fine for REL1_39, but not REL1_38 (nearly EOL, so we probably don't care a great deal) or REL1_35 as both need PHP 7.3 support...

It'd be fine for REL1_39, but not REL1_38 (nearly EOL, so we probably don't care a great deal) or REL1_35 as both need PHP 7.3 support...

Could we just pin to "no larger than 4.1.5"?

MediaWiki 1.35 and 1.38 support PHP 7.3-7.4 officially, although the docs say Other release branches like MediaWiki 1.35.x may have minor issues and warnings on PHP 8 but generally work.
1.35 uses league/oauth2-server 8.2.4, which uses lcobucci/jwt ^3.4 || ^4.0.
1.38 uses the same league/oauth2-server version as master (a custom pin of a snapshot from the in-development 9.0.0), which also uses lcobucci/jwt ^3.4 || ^4.0.
The B/C break (lcobucci/jwt#833 was introduced in 4.2.0 and wasn't backported.

So I think for 1.35/1.38 we could just pin ^3.4 || ^4.0.0 || ^4.1.0?

It'd be fine for REL1_39, but not REL1_38 (nearly EOL, so we probably don't care a great deal) or REL1_35 as both need PHP 7.3 support...

Could we just pin to "no larger than 4.1.5"?

MediaWiki 1.35 and 1.38 support PHP 7.3-7.4 officially, although the docs say Other release branches like MediaWiki 1.35.x may have minor issues and warnings on PHP 8 but generally work.
1.35 uses league/oauth2-server 8.2.4, which uses lcobucci/jwt ^3.4 || ^4.0.
1.38 uses the same league/oauth2-server version as master (a custom pin of a snapshot from the in-development 9.0.0), which also uses lcobucci/jwt ^3.4 || ^4.0.
The B/C break (lcobucci/jwt#833 was introduced in 4.2.0 and wasn't backported.

So I think for 1.35/1.38 we could just pin ^3.4 || ^4.0.0 || ^4.1.0?

^4.0.0 would cover ^4.1.0?

Or do you mean something like ^3.4 || ~4.0.0 || ~4.1.0?

Or do you mean something like ^3.4 || ~4.0.0 || ~4.1.0?

Right, that.