}
/**
- * Bug 37963
+ * T39963
* Make sure defaults are loaded when setOption is called.
* @covers User::loadOptions
*/
$this->setMwGlobals( [
'wgCookieSetOnAutoblock' => true,
'wgCookiePrefix' => 'wmsitetitle',
+ 'wgSecretKey' => MWCryptRand::generateHex( 64, true ),
] );
// 1. Log in a test user, and block them.
// Test for the desired cookie name, value, and expiry.
$cookies = $request1->response()->getCookies();
$this->assertArrayHasKey( 'wmsitetitleBlockID', $cookies );
- $this->assertEquals( $block->getId(), $cookies['wmsitetitleBlockID']['value'] );
$this->assertEquals( $expiryFiveHours, $cookies['wmsitetitleBlockID']['expire'] );
+ $cookieValue = Block::getIdFromCookieValue( $cookies['wmsitetitleBlockID']['value'] );
+ $this->assertEquals( $block->getId(), $cookieValue );
// 2. Create a new request, set the cookies, and see if the (anon) user is blocked.
$request2 = new FauxRequest();
- $request2->setCookie( 'BlockID', $block->getId() );
+ $request2->setCookie( 'BlockID', $block->getCookieValue() );
$user2 = User::newFromSession( $request2 );
$user2->load();
$this->assertNotEquals( $user1->getId(), $user2->getId() );
$this->setMwGlobals( [
'wgCookieSetOnAutoblock' => false,
'wgCookiePrefix' => 'wm_no_cookies',
+ 'wgSecretKey' => MWCryptRand::generateHex( 64, true ),
] );
// 1. Log in a test user, and block them.
$this->setMwGlobals( [
'wgCookieSetOnAutoblock' => true,
'wgCookiePrefix' => 'wm_infinite_block',
+ 'wgSecretKey' => MWCryptRand::generateHex( 64, true ),
] );
// 1. Log in a test user, and block them indefinitely.
$user1Tmp = $this->getTestUser()->getUser();
$this->assertNull( $wgUser->getBlock() );
}
+ /**
+ * Test that a modified BlockID cookie doesn't actually load the relevant block (T152951).
+ */
+ public function testAutoblockCookieInauthentic() {
+ // Set up the bits of global configuration that we use.
+ $this->setMwGlobals( [
+ 'wgCookieSetOnAutoblock' => true,
+ 'wgCookiePrefix' => 'wmsitetitle',
+ 'wgSecretKey' => MWCryptRand::generateHex( 64, true ),
+ ] );
+
+ // 1. Log in a blocked test user.
+ $user1tmp = $this->getTestUser()->getUser();
+ $request1 = new FauxRequest();
+ $request1->getSession()->setUser( $user1tmp );
+ $block = new Block( [ 'enableAutoblock' => true ] );
+ $block->setTarget( $user1tmp );
+ $block->insert();
+ $user1 = User::newFromSession( $request1 );
+ $user1->mBlock = $block;
+ $user1->load();
+
+ // 2. Create a new request, set the cookie to an invalid value, and make sure the (anon)
+ // user not blocked.
+ $request2 = new FauxRequest();
+ $request2->setCookie( 'BlockID', $block->getId() . '!zzzzzzz' );
+ $user2 = User::newFromSession( $request2 );
+ $user2->load();
+ $this->assertTrue( $user2->isAnon() );
+ $this->assertFalse( $user2->isLoggedIn() );
+ $this->assertFalse( $user2->isBlocked() );
+
+ // Clean up.
+ $block->delete();
+ }
+
+ /**
+ * The BlockID cookie is normally verified with a HMAC, but not if wgSecretKey is not set.
+ * This checks that a non-authenticated cookie still works.
+ */
+ public function testAutoblockCookieNoSecretKey() {
+ // Set up the bits of global configuration that we use.
+ $this->setMwGlobals( [
+ 'wgCookieSetOnAutoblock' => true,
+ 'wgCookiePrefix' => 'wmsitetitle',
+ 'wgSecretKey' => null,
+ ] );
+
+ // 1. Log in a blocked test user.
+ $user1tmp = $this->getTestUser()->getUser();
+ $request1 = new FauxRequest();
+ $request1->getSession()->setUser( $user1tmp );
+ $block = new Block( [ 'enableAutoblock' => true ] );
+ $block->setTarget( $user1tmp );
+ $block->insert();
+ $user1 = User::newFromSession( $request1 );
+ $user1->mBlock = $block;
+ $user1->load();
+ $this->assertTrue( $user1->isBlocked() );
+
+ // 2. Create a new request, set the cookie to just the block ID, and the user should
+ // still get blocked when they log in again.
+ $request2 = new FauxRequest();
+ $request2->setCookie( 'BlockID', $block->getId() );
+ $user2 = User::newFromSession( $request2 );
+ $user2->load();
+ $this->assertNotEquals( $user1->getId(), $user2->getId() );
+ $this->assertNotEquals( $user1->getToken(), $user2->getToken() );
+ $this->assertTrue( $user2->isAnon() );
+ $this->assertFalse( $user2->isLoggedIn() );
+ $this->assertTrue( $user2->isBlocked() );
+ $this->assertEquals( true, $user2->getBlock()->isAutoblocking() ); // Non-strict type-check.
+
+ // Clean up.
+ $block->delete();
+ }
}