public function testBeginAuthentication() { $this->initializeManager(); // Immutable session list($provider, $reset) = $this->getMockSessionProvider(false); $this->hook('UserLoggedIn', $this->never()); $this->request->getSession()->setSecret('AuthManager::authnState', 'test'); try { $this->manager->beginAuthentication([], 'http://localhost/'); $this->fail('Expected exception not thrown'); } catch (\LogicException $ex) { $this->assertSame('Authentication is not possible now', $ex->getMessage()); } $this->unhook('UserLoggedIn'); $this->assertNull($this->request->getSession()->getSecret('AuthManager::authnState')); \ScopedCallback::consume($reset); $this->initializeManager(true); // CreatedAccountAuthenticationRequest $user = \User::newFromName('UTSysop'); $reqs = [new CreatedAccountAuthenticationRequest($user->getId(), $user->getName())]; $this->hook('UserLoggedIn', $this->never()); try { $this->manager->beginAuthentication($reqs, 'http://localhost/'); $this->fail('Expected exception not thrown'); } catch (\LogicException $ex) { $this->assertSame('CreatedAccountAuthenticationRequests are only valid on the same AuthManager ' . 'that created the account', $ex->getMessage()); } $this->unhook('UserLoggedIn'); $this->request->getSession()->clear(); $this->request->getSession()->setSecret('AuthManager::authnState', 'test'); $this->managerPriv->createdAccountAuthenticationRequests = [$reqs[0]]; $this->hook('UserLoggedIn', $this->once())->with($this->callback(function ($u) use($user) { return $user->getId() === $u->getId() && $user->getName() === $u->getName(); })); $this->hook('AuthManagerLoginAuthenticateAudit', $this->once()); $this->logger->setCollect(true); $ret = $this->manager->beginAuthentication($reqs, 'http://localhost/'); $this->logger->setCollect(false); $this->unhook('UserLoggedIn'); $this->unhook('AuthManagerLoginAuthenticateAudit'); $this->assertSame(AuthenticationResponse::PASS, $ret->status); $this->assertSame($user->getName(), $ret->username); $this->assertSame($user->getId(), $this->request->getSessionData('AuthManager:lastAuthId')); $this->assertEquals(time(), $this->request->getSessionData('AuthManager:lastAuthTimestamp'), 'timestamp ±1', 1); $this->assertNull($this->request->getSession()->getSecret('AuthManager::authnState')); $this->assertSame($user->getId(), $this->request->getSession()->getUser()->getId()); $this->assertSame([[LogLevel::INFO, 'Logging in {user} after account creation']], $this->logger->getBuffer()); }
/** * Internal implementation for self::getEditToken() and * self::matchEditToken(). * * @param string|array $salt * @param WebRequest $request * @param string|int $timestamp * @return string */ private function getEditTokenAtTimestamp($salt, $request, $timestamp) { if ($this->isAnon()) { return self::EDIT_TOKEN_SUFFIX; } else { $token = $request->getSessionData('wsEditToken'); if ($token === null) { $token = MWCryptRand::generateHex(32); $request->setSessionData('wsEditToken', $token); } if (is_array($salt)) { $salt = implode('|', $salt); } return hash_hmac('md5', $timestamp . $salt, $token, false) . dechex($timestamp) . self::EDIT_TOKEN_SUFFIX; } }