public function testAbstractSecondaryAuthenticationProvider() { $user = \User::newFromName('UTSysop'); $provider = $this->getMockForAbstractClass(AbstractSecondaryAuthenticationProvider::class); try { $provider->continueSecondaryAuthentication($user, []); $this->fail('Expected exception not thrown'); } catch (\BadMethodCallException $ex) { } try { $provider->continueSecondaryAccountCreation($user, $user, []); $this->fail('Expected exception not thrown'); } catch (\BadMethodCallException $ex) { } $req = $this->getMockForAbstractClass(AuthenticationRequest::class); $this->assertTrue($provider->providerAllowsPropertyChange('foo')); $this->assertEquals(\StatusValue::newGood('ignored'), $provider->providerAllowsAuthenticationDataChange($req)); $this->assertEquals(\StatusValue::newGood(), $provider->testForAccountCreation($user, $user, [])); $this->assertEquals(\StatusValue::newGood(), $provider->testUserForCreation($user, AuthManager::AUTOCREATE_SOURCE_SESSION)); $this->assertEquals(\StatusValue::newGood(), $provider->testUserForCreation($user, false)); $provider->providerChangeAuthenticationData($req); $provider->autoCreatedAccount($user, AuthManager::AUTOCREATE_SOURCE_SESSION); $res = AuthenticationResponse::newPass(); $provider->postAuthentication($user, $res); $provider->postAccountCreation($user, $user, $res); }
public function testAbstractPrimaryAuthenticationProvider() { $user = \User::newFromName('UTSysop'); $provider = $this->getMockForAbstractClass(AbstractPrimaryAuthenticationProvider::class); try { $provider->continuePrimaryAuthentication([]); $this->fail('Expected exception not thrown'); } catch (\BadMethodCallException $ex) { } try { $provider->continuePrimaryAccountCreation($user, $user, []); $this->fail('Expected exception not thrown'); } catch (\BadMethodCallException $ex) { } $req = $this->getMockForAbstractClass(AuthenticationRequest::class); $this->assertTrue($provider->providerAllowsPropertyChange('foo')); $this->assertEquals(\StatusValue::newGood(), $provider->testForAccountCreation($user, $user, [])); $this->assertEquals(\StatusValue::newGood(), $provider->testUserForCreation($user, AuthManager::AUTOCREATE_SOURCE_SESSION)); $this->assertEquals(\StatusValue::newGood(), $provider->testUserForCreation($user, false)); $this->assertNull($provider->finishAccountCreation($user, $user, AuthenticationResponse::newPass())); $provider->autoCreatedAccount($user, AuthManager::AUTOCREATE_SOURCE_SESSION); $res = AuthenticationResponse::newPass(); $provider->postAuthentication($user, $res); $provider->postAccountCreation($user, $user, $res); $provider->postAccountLink($user, $res); $provider->expects($this->once())->method('testUserExists')->with($this->equalTo('foo'))->will($this->returnValue(true)); $this->assertTrue($provider->testUserCanAuthenticate('foo')); }
public function testBeginSecondaryAuthentication() { $unblockedUser = \User::newFromName('UTSysop'); $blockedUser = $this->getBlockedUser(); $provider = new CheckBlocksSecondaryAuthenticationProvider(['blockDisablesLogin' => false]); $this->assertEquals(AuthenticationResponse::newAbstain(), $provider->beginSecondaryAuthentication($unblockedUser, [])); $this->assertEquals(AuthenticationResponse::newAbstain(), $provider->beginSecondaryAuthentication($blockedUser, [])); $provider = new CheckBlocksSecondaryAuthenticationProvider(['blockDisablesLogin' => true]); $this->assertEquals(AuthenticationResponse::newPass(), $provider->beginSecondaryAuthentication($unblockedUser, [])); $ret = $provider->beginSecondaryAuthentication($blockedUser, []); $this->assertEquals(AuthenticationResponse::FAIL, $ret->status); }
public function testAbstractPreAuthenticationProvider() { $user = \User::newFromName('UTSysop'); $provider = $this->getMockForAbstractClass(AbstractPreAuthenticationProvider::class); $this->assertEquals([], $provider->getAuthenticationRequests(AuthManager::ACTION_LOGIN, [])); $this->assertEquals(\StatusValue::newGood(), $provider->testForAuthentication([])); $this->assertEquals(\StatusValue::newGood(), $provider->testForAccountCreation($user, $user, [])); $this->assertEquals(\StatusValue::newGood(), $provider->testUserForCreation($user, AuthManager::AUTOCREATE_SOURCE_SESSION)); $this->assertEquals(\StatusValue::newGood(), $provider->testUserForCreation($user, false)); $this->assertEquals(\StatusValue::newGood(), $provider->testForAccountLink($user)); $res = AuthenticationResponse::newPass(); $provider->postAuthentication($user, $res); $provider->postAccountCreation($user, $user, $res); $provider->postAccountLink($user, $res); }
public function testAccountCreation() { $user = \User::newFromName('foo'); $user->setEmail('email'); $user->setRealName('realname'); $req = new PasswordAuthenticationRequest(); $req->action = AuthManager::ACTION_CREATE; $reqs = [PasswordAuthenticationRequest::class => $req]; $plugin = $this->getMock('AuthPlugin'); $plugin->expects($this->any())->method('domainList')->willReturn([]); $plugin->expects($this->any())->method('canCreateAccounts')->will($this->returnValue(false)); $plugin->expects($this->never())->method('addUser'); $provider = new AuthPluginPrimaryAuthenticationProvider($plugin); try { $provider->beginPrimaryAccountCreation($user, $user, []); $this->fail('Expected exception was not thrown'); } catch (\BadMethodCallException $ex) { $this->assertSame('Shouldn\'t call this when accountCreationType() is NONE', $ex->getMessage()); } $plugin = $this->getMock('AuthPlugin'); $plugin->expects($this->any())->method('domainList')->willReturn([]); $plugin->expects($this->any())->method('canCreateAccounts')->will($this->returnValue(true)); $plugin->expects($this->never())->method('addUser'); $provider = new AuthPluginPrimaryAuthenticationProvider($plugin); $this->assertEquals(AuthenticationResponse::newAbstain(), $provider->beginPrimaryAccountCreation($user, $user, [])); $req->username = '******'; $req->password = null; $this->assertEquals(AuthenticationResponse::newAbstain(), $provider->beginPrimaryAccountCreation($user, $user, $reqs)); $req->username = null; $req->password = '******'; $this->assertEquals(AuthenticationResponse::newAbstain(), $provider->beginPrimaryAccountCreation($user, $user, $reqs)); $req->username = '******'; $req->password = '******'; $plugin = $this->getMock('AuthPlugin'); $plugin->expects($this->any())->method('domainList')->willReturn([]); $plugin->expects($this->any())->method('canCreateAccounts')->will($this->returnValue(true)); $plugin->expects($this->once())->method('addUser')->with($this->callback(function ($u) { return $u instanceof \User && $u->getName() === 'Foo'; }), $this->equalTo('bar'), $this->equalTo('email'), $this->equalTo('realname'))->will($this->returnValue(true)); $provider = new AuthPluginPrimaryAuthenticationProvider($plugin); $this->assertEquals(AuthenticationResponse::newPass(), $provider->beginPrimaryAccountCreation($user, $user, $reqs)); $plugin = $this->getMock('AuthPlugin'); $plugin->expects($this->any())->method('domainList')->willReturn([]); $plugin->expects($this->any())->method('canCreateAccounts')->will($this->returnValue(true)); $plugin->expects($this->once())->method('addUser')->with($this->callback(function ($u) { return $u instanceof \User && $u->getName() === 'Foo'; }), $this->equalTo('bar'), $this->equalTo('email'), $this->equalTo('realname'))->will($this->returnValue(false)); $provider = new AuthPluginPrimaryAuthenticationProvider($plugin); $ret = $provider->beginPrimaryAccountCreation($user, $user, $reqs); $this->assertSame(AuthenticationResponse::FAIL, $ret->status); $this->assertSame('authmanager-authplugin-create-fail', $ret->message->getKey()); $plugin = $this->getMock('AuthPlugin'); $plugin->expects($this->any())->method('canCreateAccounts')->will($this->returnValue(true)); $plugin->expects($this->any())->method('domainList')->will($this->returnValue(['Domain1', 'Domain2'])); $plugin->expects($this->any())->method('validDomain')->will($this->returnCallback(function ($domain) { return in_array($domain, ['Domain1', 'Domain2']); })); $plugin->expects($this->once())->method('setDomain')->with($this->equalTo('Domain2')); $plugin->expects($this->once())->method('addUser')->with($this->callback(function ($u) { return $u instanceof \User && $u->getName() === 'Foo'; }), $this->equalTo('bar'))->will($this->returnValue(true)); $provider = new AuthPluginPrimaryAuthenticationProvider($plugin); list($req) = $provider->getAuthenticationRequests(AuthManager::ACTION_CREATE, []); $req->username = '******'; $req->password = '******'; $req->domain = 'Domain2'; $provider->beginPrimaryAccountCreation($user, $user, [$req]); }
/** * Try to reset the password * @param \User $user * @param AuthenticationRequest[] $reqs * @return AuthenticationResponse */ protected function tryReset(\User $user, array $reqs) { $data = $this->manager->getAuthenticationSessionData('reset-pass'); if (!$data) { return AuthenticationResponse::newAbstain(); } if (is_array($data)) { $data = (object) $data; } if (!is_object($data)) { throw new \UnexpectedValueException('reset-pass is not valid'); } if (!isset($data->msg)) { throw new \UnexpectedValueException('reset-pass msg is missing'); } elseif (!$data->msg instanceof \Message) { throw new \UnexpectedValueException('reset-pass msg is not valid'); } elseif (!isset($data->hard)) { throw new \UnexpectedValueException('reset-pass hard is missing'); } elseif (isset($data->req) && (!$data->req instanceof PasswordAuthenticationRequest || !array_key_exists('retype', $data->req->getFieldInfo()))) { throw new \UnexpectedValueException('reset-pass req is not valid'); } if (!$data->hard) { $req = ButtonAuthenticationRequest::getRequestByName($reqs, 'skipReset'); if ($req) { $this->manager->removeAuthenticationSessionData('reset-pass'); return AuthenticationResponse::newPass(); } } $needReq = isset($data->req) ? $data->req : new PasswordAuthenticationRequest(); if (!$needReq->action) { $needReq->action = AuthManager::ACTION_CHANGE; } $needReq->required = $data->hard ? AuthenticationRequest::REQUIRED : AuthenticationRequest::OPTIONAL; $needReqs = [$needReq]; if (!$data->hard) { $needReqs[] = new ButtonAuthenticationRequest('skipReset', wfMessage('authprovider-resetpass-skip-label'), wfMessage('authprovider-resetpass-skip-help')); } $req = AuthenticationRequest::getRequestByClass($reqs, get_class($needReq)); if (!$req || !array_key_exists('retype', $req->getFieldInfo())) { return AuthenticationResponse::newUI($needReqs, $data->msg, 'warning'); } if ($req->password !== $req->retype) { return AuthenticationResponse::newUI($needReqs, new \Message('badretype'), 'error'); } $req->username = $user->getName(); $status = $this->manager->allowsAuthenticationDataChange($req); if (!$status->isGood()) { return AuthenticationResponse::newUI($needReqs, $status->getMessage(), 'error'); } $this->manager->changeAuthenticationData($req); $this->manager->removeAuthenticationSessionData('reset-pass'); return AuthenticationResponse::newPass(); }
public function testPostAuthentication() { $provider = new ThrottlePreAuthenticationProvider(['passwordAttemptThrottle' => [], 'cache' => new \HashBagOStuff()]); $provider->setLogger(new \TestLogger()); $provider->setConfig(new \HashConfig(['AccountCreationThrottle' => null, 'PasswordAttemptThrottle' => null])); $provider->setManager(AuthManager::singleton()); $provider->postAuthentication(\User::newFromName('SomeUser'), AuthenticationResponse::newPass()); $provider = new ThrottlePreAuthenticationProvider(['passwordAttemptThrottle' => [['count' => 2, 'seconds' => 86400]], 'cache' => new \HashBagOStuff()]); $logger = new \TestLogger(true); $provider->setLogger($logger); $provider->setConfig(new \HashConfig(['AccountCreationThrottle' => null, 'PasswordAttemptThrottle' => null])); $provider->setManager(AuthManager::singleton()); $provider->postAuthentication(\User::newFromName('SomeUser'), AuthenticationResponse::newPass()); $this->assertSame([[\Psr\Log\LogLevel::ERROR, 'throttler data not found for {user}']], $logger->getBuffer()); }
public function testContinueLinkAttempt() { $user = \User::newFromName('UTSysop'); $obj = new \stdClass(); $reqs = $this->getLinkRequests(); $done = [false, false, false]; // First, test the pass-through for not containing the ConfirmLinkAuthenticationRequest $mock = $this->getMockBuilder(ConfirmLinkSecondaryAuthenticationProvider::class)->setMethods(['beginLinkAttempt'])->getMock(); $mock->expects($this->once())->method('beginLinkAttempt')->with($this->identicalTo($user), $this->identicalTo('state'))->will($this->returnValue($obj)); $this->assertSame($obj, \TestingAccessWrapper::newFromObject($mock)->continueLinkAttempt($user, 'state', $reqs)); // Now test the actual functioning $provider = $this->getMockBuilder(ConfirmLinkSecondaryAuthenticationProvider::class)->setMethods(['beginLinkAttempt', 'providerAllowsAuthenticationDataChange', 'providerChangeAuthenticationData'])->getMock(); $provider->expects($this->never())->method('beginLinkAttempt'); $provider->expects($this->any())->method('providerAllowsAuthenticationDataChange')->will($this->returnCallback(function ($req) use($reqs) { return $req->getUniqueId() === 'Request3' ? \StatusValue::newFatal('foo') : \StatusValue::newGood(); })); $provider->expects($this->any())->method('providerChangeAuthenticationData')->will($this->returnCallback(function ($req) use(&$done) { $done[$req->id] = true; })); $config = new \HashConfig(['AuthManagerConfig' => ['preauth' => [], 'primaryauth' => [], 'secondaryauth' => [['factory' => function () use($provider) { return $provider; }]]]]); $request = new \FauxRequest(); $manager = new AuthManager($request, $config); $provider->setManager($manager); $provider = \TestingAccessWrapper::newFromObject($provider); $req = new ConfirmLinkAuthenticationRequest($reqs); $this->assertEquals(AuthenticationResponse::newAbstain(), $provider->continueLinkAttempt($user, 'state', [$req])); $request->getSession()->setSecret('state', ['maybeLink' => []]); $this->assertEquals(AuthenticationResponse::newAbstain(), $provider->continueLinkAttempt($user, 'state', [$req])); $request->getSession()->setSecret('state', ['maybeLink' => $reqs]); $this->assertEquals(AuthenticationResponse::newPass(), $res = $provider->continueLinkAttempt($user, 'state', [$req])); $this->assertSame([false, false, false], $done); $request->getSession()->setSecret('state', ['maybeLink' => [$reqs['Request2']]]); $req->confirmedLinkIDs = ['Request1', 'Request2']; $res = $provider->continueLinkAttempt($user, 'state', [$req]); $this->assertEquals(AuthenticationResponse::newPass(), $res); $this->assertSame([false, true, false], $done); $done = [false, false, false]; $request->getSession()->setSecret('state', ['maybeLink' => $reqs]); $req->confirmedLinkIDs = ['Request1', 'Request2']; $res = $provider->continueLinkAttempt($user, 'state', [$req]); $this->assertEquals(AuthenticationResponse::newPass(), $res); $this->assertSame([true, true, false], $done); $done = [false, false, false]; $request->getSession()->setSecret('state', ['maybeLink' => $reqs]); $req->confirmedLinkIDs = ['Request1', 'Request3']; $res = $provider->continueLinkAttempt($user, 'state', [$req]); $this->assertEquals(AuthenticationResponse::UI, $res->status); $this->assertCount(1, $res->neededRequests); $this->assertInstanceOf(ButtonAuthenticationRequest::class, $res->neededRequests[0]); $this->assertSame([true, false, false], $done); $done = [false, false, false]; $res = $provider->continueLinkAttempt($user, 'state', [$res->neededRequests[0]]); $this->assertEquals(AuthenticationResponse::newPass(), $res); $this->assertSame([false, false, false], $done); }
public function testAccountCreationEmail() { $creator = \User::newFromName('Foo'); $user = \User::newFromName('UTSysop'); $reset = new \ScopedCallback(function ($email) use($user) { $user->setEmail($email); $user->saveSettings(); }, [$user->getEmail()]); $user->setEmail(null); $req = TemporaryPasswordAuthenticationRequest::newRandom(); $req->username = $user->getName(); $req->mailpassword = true; $provider = $this->getProvider(['emailEnabled' => false]); $status = $provider->testForAccountCreation($user, $creator, [$req]); $this->assertEquals(\StatusValue::newFatal('emaildisabled'), $status); $req->hasBackchannel = true; $status = $provider->testForAccountCreation($user, $creator, [$req]); $this->assertFalse($status->hasMessage('emaildisabled')); $req->hasBackchannel = false; $provider = $this->getProvider(['emailEnabled' => true]); $status = $provider->testForAccountCreation($user, $creator, [$req]); $this->assertEquals(\StatusValue::newFatal('noemailcreate'), $status); $req->hasBackchannel = true; $status = $provider->testForAccountCreation($user, $creator, [$req]); $this->assertFalse($status->hasMessage('noemailcreate')); $req->hasBackchannel = false; $user->setEmail('*****@*****.**'); $status = $provider->testForAccountCreation($user, $creator, [$req]); $this->assertEquals(\StatusValue::newGood(), $status); $mailed = false; $resetMailer = $this->hookMailer(function ($headers, $to, $from, $subject, $body) use(&$mailed, $req) { $mailed = true; $this->assertSame('*****@*****.**', $to[0]->address); $this->assertContains($req->password, $body); return false; }); $expect = AuthenticationResponse::newPass('UTSysop'); $expect->createRequest = clone $req; $expect->createRequest->username = '******'; $res = $provider->beginPrimaryAccountCreation($user, $creator, [$req]); $this->assertEquals($expect, $res); $this->assertTrue($this->manager->getAuthenticationSessionData('no-email')); $this->assertFalse($mailed); $this->assertSame('byemail', $provider->finishAccountCreation($user, $creator, $res)); $this->assertTrue($mailed); \ScopedCallback::consume($resetMailer); $this->assertTrue($mailed); }
public function testAccountCreation() { $user = \User::newFromName('Foo'); $req = new PasswordAuthenticationRequest(); $req->action = AuthManager::ACTION_CREATE; $reqs = [PasswordAuthenticationRequest::class => $req]; $provider = $this->getProvider(true); try { $provider->beginPrimaryAccountCreation($user, $user, []); $this->fail('Expected exception was not thrown'); } catch (\BadMethodCallException $ex) { $this->assertSame('Shouldn\'t call this when accountCreationType() is NONE', $ex->getMessage()); } try { $provider->finishAccountCreation($user, $user, AuthenticationResponse::newPass()); $this->fail('Expected exception was not thrown'); } catch (\BadMethodCallException $ex) { $this->assertSame('Shouldn\'t call this when accountCreationType() is NONE', $ex->getMessage()); } $provider = $this->getProvider(false); $this->assertEquals(AuthenticationResponse::newAbstain(), $provider->beginPrimaryAccountCreation($user, $user, [])); $req->username = '******'; $req->password = null; $this->assertEquals(AuthenticationResponse::newAbstain(), $provider->beginPrimaryAccountCreation($user, $user, $reqs)); $req->username = null; $req->password = '******'; $this->assertEquals(AuthenticationResponse::newAbstain(), $provider->beginPrimaryAccountCreation($user, $user, $reqs)); $req->username = '******'; $req->password = '******'; $expect = AuthenticationResponse::newPass('Foo'); $expect->createRequest = clone $req; $expect->createRequest->username = '******'; $this->assertEquals($expect, $provider->beginPrimaryAccountCreation($user, $user, $reqs)); // We have to cheat a bit to avoid having to add a new user to // the database to test the actual setting of the password works right $dbw = wfGetDB(DB_MASTER); $user = \User::newFromName('UTSysop'); $req->username = $user->getName(); $req->password = '******'; $expect = AuthenticationResponse::newPass('UTSysop'); $expect->createRequest = $req; $res2 = $provider->beginPrimaryAccountCreation($user, $user, $reqs); $this->assertEquals($expect, $res2, 'Sanity check'); $ret = $provider->beginPrimaryAuthentication($reqs); $this->assertEquals(AuthenticationResponse::FAIL, $ret->status, 'sanity check'); $this->assertNull($provider->finishAccountCreation($user, $user, $res2)); $ret = $provider->beginPrimaryAuthentication($reqs); $this->assertEquals(AuthenticationResponse::PASS, $ret->status, 'new password is set'); }
public function testTryReset() { $user = \User::newFromName('UTSysop'); $provider = $this->getMockBuilder(ResetPasswordSecondaryAuthenticationProvider::class)->setMethods(['providerAllowsAuthenticationDataChange', 'providerChangeAuthenticationData'])->getMock(); $provider->expects($this->any())->method('providerAllowsAuthenticationDataChange')->will($this->returnCallback(function ($req) { $this->assertSame('UTSysop', $req->username); return $req->allow; })); $provider->expects($this->any())->method('providerChangeAuthenticationData')->will($this->returnCallback(function ($req) { $this->assertSame('UTSysop', $req->username); $req->done = true; })); $config = new \HashConfig(['AuthManagerConfig' => ['preauth' => [], 'primaryauth' => [], 'secondaryauth' => [['factory' => function () use($provider) { return $provider; }]]]]); $manager = new AuthManager(new \FauxRequest(), $config); $provider->setManager($manager); $provider = \TestingAccessWrapper::newFromObject($provider); $msg = wfMessage('foo'); $skipReq = new ButtonAuthenticationRequest('skipReset', wfMessage('authprovider-resetpass-skip-label'), wfMessage('authprovider-resetpass-skip-help')); $passReq = new PasswordAuthenticationRequest(); $passReq->action = AuthManager::ACTION_CHANGE; $passReq->password = '******'; $passReq->retype = 'Bar'; $passReq->allow = \StatusValue::newGood(); $passReq->done = false; $passReq2 = $this->getMockBuilder(PasswordAuthenticationRequest::class)->enableProxyingToOriginalMethods()->getMock(); $passReq2->action = AuthManager::ACTION_CHANGE; $passReq2->password = '******'; $passReq2->retype = 'Foo'; $passReq2->allow = \StatusValue::newGood(); $passReq2->done = false; $passReq3 = new PasswordAuthenticationRequest(); $passReq3->action = AuthManager::ACTION_LOGIN; $passReq3->password = '******'; $passReq3->retype = 'Foo'; $passReq3->allow = \StatusValue::newGood(); $passReq3->done = false; $this->assertEquals(AuthenticationResponse::newAbstain(), $provider->tryReset($user, [])); $manager->setAuthenticationSessionData('reset-pass', 'foo'); try { $provider->tryReset($user, []); $this->fail('Expected exception not thrown'); } catch (\UnexpectedValueException $ex) { $this->assertSame('reset-pass is not valid', $ex->getMessage()); } $manager->setAuthenticationSessionData('reset-pass', (object) []); try { $provider->tryReset($user, []); $this->fail('Expected exception not thrown'); } catch (\UnexpectedValueException $ex) { $this->assertSame('reset-pass msg is missing', $ex->getMessage()); } $manager->setAuthenticationSessionData('reset-pass', ['msg' => 'foo']); try { $provider->tryReset($user, []); $this->fail('Expected exception not thrown'); } catch (\UnexpectedValueException $ex) { $this->assertSame('reset-pass msg is not valid', $ex->getMessage()); } $manager->setAuthenticationSessionData('reset-pass', ['msg' => $msg]); try { $provider->tryReset($user, []); $this->fail('Expected exception not thrown'); } catch (\UnexpectedValueException $ex) { $this->assertSame('reset-pass hard is missing', $ex->getMessage()); } $manager->setAuthenticationSessionData('reset-pass', ['msg' => $msg, 'hard' => true, 'req' => 'foo']); try { $provider->tryReset($user, []); $this->fail('Expected exception not thrown'); } catch (\UnexpectedValueException $ex) { $this->assertSame('reset-pass req is not valid', $ex->getMessage()); } $manager->setAuthenticationSessionData('reset-pass', ['msg' => $msg, 'hard' => false, 'req' => $passReq3]); try { $provider->tryReset($user, [$passReq]); $this->fail('Expected exception not thrown'); } catch (\UnexpectedValueException $ex) { $this->assertSame('reset-pass req is not valid', $ex->getMessage()); } $manager->setAuthenticationSessionData('reset-pass', ['msg' => $msg, 'hard' => true]); $res = $provider->tryReset($user, []); $this->assertInstanceOf(AuthenticationResponse::class, $res); $this->assertSame(AuthenticationResponse::UI, $res->status); $this->assertEquals($msg, $res->message); $this->assertCount(1, $res->neededRequests); $this->assertInstanceOf(PasswordAuthenticationRequest::class, $res->neededRequests[0]); $this->assertNotNull($manager->getAuthenticationSessionData('reset-pass')); $this->assertFalse($passReq->done); $manager->setAuthenticationSessionData('reset-pass', ['msg' => $msg, 'hard' => false, 'req' => $passReq]); $res = $provider->tryReset($user, []); $this->assertInstanceOf(AuthenticationResponse::class, $res); $this->assertSame(AuthenticationResponse::UI, $res->status); $this->assertEquals($msg, $res->message); $this->assertCount(2, $res->neededRequests); $this->assertEquals($passReq, $res->neededRequests[0]); $this->assertEquals($skipReq, $res->neededRequests[1]); $this->assertNotNull($manager->getAuthenticationSessionData('reset-pass')); $this->assertFalse($passReq->done); $passReq->retype = 'Bad'; $manager->setAuthenticationSessionData('reset-pass', ['msg' => $msg, 'hard' => false, 'req' => $passReq]); $res = $provider->tryReset($user, [$skipReq, $passReq]); $this->assertEquals(AuthenticationResponse::newPass(), $res); $this->assertNull($manager->getAuthenticationSessionData('reset-pass')); $this->assertFalse($passReq->done); $passReq->retype = 'Bad'; $manager->setAuthenticationSessionData('reset-pass', ['msg' => $msg, 'hard' => true]); $res = $provider->tryReset($user, [$skipReq, $passReq]); $this->assertSame(AuthenticationResponse::UI, $res->status); $this->assertSame('badretype', $res->message->getKey()); $this->assertCount(1, $res->neededRequests); $this->assertInstanceOf(PasswordAuthenticationRequest::class, $res->neededRequests[0]); $this->assertNotNull($manager->getAuthenticationSessionData('reset-pass')); $this->assertFalse($passReq->done); $manager->setAuthenticationSessionData('reset-pass', ['msg' => $msg, 'hard' => true]); $res = $provider->tryReset($user, [$skipReq, $passReq3]); $this->assertSame(AuthenticationResponse::UI, $res->status); $this->assertEquals($msg, $res->message); $this->assertCount(1, $res->neededRequests); $this->assertInstanceOf(PasswordAuthenticationRequest::class, $res->neededRequests[0]); $this->assertNotNull($manager->getAuthenticationSessionData('reset-pass')); $this->assertFalse($passReq->done); $passReq->retype = $passReq->password; $passReq->allow = \StatusValue::newFatal('arbitrary-fail'); $res = $provider->tryReset($user, [$skipReq, $passReq]); $this->assertSame(AuthenticationResponse::UI, $res->status); $this->assertSame('arbitrary-fail', $res->message->getKey()); $this->assertCount(1, $res->neededRequests); $this->assertInstanceOf(PasswordAuthenticationRequest::class, $res->neededRequests[0]); $this->assertNotNull($manager->getAuthenticationSessionData('reset-pass')); $this->assertFalse($passReq->done); $passReq->allow = \StatusValue::newGood(); $res = $provider->tryReset($user, [$skipReq, $passReq]); $this->assertEquals(AuthenticationResponse::newPass(), $res); $this->assertNull($manager->getAuthenticationSessionData('reset-pass')); $this->assertTrue($passReq->done); $manager->setAuthenticationSessionData('reset-pass', ['msg' => $msg, 'hard' => false, 'req' => $passReq2]); $res = $provider->tryReset($user, [$passReq2]); $this->assertEquals(AuthenticationResponse::newPass(), $res); $this->assertNull($manager->getAuthenticationSessionData('reset-pass')); $this->assertTrue($passReq2->done); $passReq->done = false; $passReq2->done = false; $manager->setAuthenticationSessionData('reset-pass', ['msg' => $msg, 'hard' => false, 'req' => $passReq2]); $res = $provider->tryReset($user, [$passReq]); $this->assertInstanceOf(AuthenticationResponse::class, $res); $this->assertSame(AuthenticationResponse::UI, $res->status); $this->assertEquals($msg, $res->message); $this->assertCount(2, $res->neededRequests); $this->assertEquals($passReq2, $res->neededRequests[0]); $this->assertEquals($skipReq, $res->neededRequests[1]); $this->assertNotNull($manager->getAuthenticationSessionData('reset-pass')); $this->assertFalse($passReq->done); $this->assertFalse($passReq2->done); }