diff options
author | Yaco <franco@reevo.org> | 2020-06-04 11:01:00 -0300 |
---|---|---|
committer | Yaco <franco@reevo.org> | 2020-06-04 11:01:00 -0300 |
commit | fc7369835258467bf97eb64f184b93691f9a9fd5 (patch) | |
tree | daabd60089d2dd76d9f5fb416b005fbe159c799d /www/wiki/tests/phpunit/includes/auth/ConfirmLinkSecondaryAuthenticationProviderTest.php |
first commit
Diffstat (limited to 'www/wiki/tests/phpunit/includes/auth/ConfirmLinkSecondaryAuthenticationProviderTest.php')
-rw-r--r-- | www/wiki/tests/phpunit/includes/auth/ConfirmLinkSecondaryAuthenticationProviderTest.php | 289 |
1 files changed, 289 insertions, 0 deletions
diff --git a/www/wiki/tests/phpunit/includes/auth/ConfirmLinkSecondaryAuthenticationProviderTest.php b/www/wiki/tests/phpunit/includes/auth/ConfirmLinkSecondaryAuthenticationProviderTest.php new file mode 100644 index 00000000..9222843c --- /dev/null +++ b/www/wiki/tests/phpunit/includes/auth/ConfirmLinkSecondaryAuthenticationProviderTest.php @@ -0,0 +1,289 @@ +<?php + +namespace MediaWiki\Auth; + +use Wikimedia\TestingAccessWrapper; + +/** + * @group AuthManager + * @covers MediaWiki\Auth\ConfirmLinkSecondaryAuthenticationProvider + */ +class ConfirmLinkSecondaryAuthenticationProviderTest extends \MediaWikiTestCase { + /** + * @dataProvider provideGetAuthenticationRequests + * @param string $action + * @param array $response + */ + public function testGetAuthenticationRequests( $action, $response ) { + $provider = new ConfirmLinkSecondaryAuthenticationProvider(); + + $this->assertEquals( $response, $provider->getAuthenticationRequests( $action, [] ) ); + } + + public static function provideGetAuthenticationRequests() { + return [ + [ AuthManager::ACTION_LOGIN, [] ], + [ AuthManager::ACTION_CREATE, [] ], + [ AuthManager::ACTION_LINK, [] ], + [ AuthManager::ACTION_CHANGE, [] ], + [ AuthManager::ACTION_REMOVE, [] ], + ]; + } + + public function testBeginSecondaryAuthentication() { + $user = \User::newFromName( 'UTSysop' ); + $obj = new \stdClass; + + $mock = $this->getMockBuilder( ConfirmLinkSecondaryAuthenticationProvider::class ) + ->setMethods( [ 'beginLinkAttempt', 'continueLinkAttempt' ] ) + ->getMock(); + $mock->expects( $this->once() )->method( 'beginLinkAttempt' ) + ->with( $this->identicalTo( $user ), $this->identicalTo( 'AuthManager::authnState' ) ) + ->will( $this->returnValue( $obj ) ); + $mock->expects( $this->never() )->method( 'continueLinkAttempt' ); + + $this->assertSame( $obj, $mock->beginSecondaryAuthentication( $user, [] ) ); + } + + public function testContinueSecondaryAuthentication() { + $user = \User::newFromName( 'UTSysop' ); + $obj = new \stdClass; + $reqs = [ new \stdClass ]; + + $mock = $this->getMockBuilder( ConfirmLinkSecondaryAuthenticationProvider::class ) + ->setMethods( [ 'beginLinkAttempt', 'continueLinkAttempt' ] ) + ->getMock(); + $mock->expects( $this->never() )->method( 'beginLinkAttempt' ); + $mock->expects( $this->once() )->method( 'continueLinkAttempt' ) + ->with( + $this->identicalTo( $user ), + $this->identicalTo( 'AuthManager::authnState' ), + $this->identicalTo( $reqs ) + ) + ->will( $this->returnValue( $obj ) ); + + $this->assertSame( $obj, $mock->continueSecondaryAuthentication( $user, $reqs ) ); + } + + public function testBeginSecondaryAccountCreation() { + $user = \User::newFromName( 'UTSysop' ); + $obj = new \stdClass; + + $mock = $this->getMockBuilder( ConfirmLinkSecondaryAuthenticationProvider::class ) + ->setMethods( [ 'beginLinkAttempt', 'continueLinkAttempt' ] ) + ->getMock(); + $mock->expects( $this->once() )->method( 'beginLinkAttempt' ) + ->with( $this->identicalTo( $user ), $this->identicalTo( 'AuthManager::accountCreationState' ) ) + ->will( $this->returnValue( $obj ) ); + $mock->expects( $this->never() )->method( 'continueLinkAttempt' ); + + $this->assertSame( $obj, $mock->beginSecondaryAccountCreation( $user, $user, [] ) ); + } + + public function testContinueSecondaryAccountCreation() { + $user = \User::newFromName( 'UTSysop' ); + $obj = new \stdClass; + $reqs = [ new \stdClass ]; + + $mock = $this->getMockBuilder( ConfirmLinkSecondaryAuthenticationProvider::class ) + ->setMethods( [ 'beginLinkAttempt', 'continueLinkAttempt' ] ) + ->getMock(); + $mock->expects( $this->never() )->method( 'beginLinkAttempt' ); + $mock->expects( $this->once() )->method( 'continueLinkAttempt' ) + ->with( + $this->identicalTo( $user ), + $this->identicalTo( 'AuthManager::accountCreationState' ), + $this->identicalTo( $reqs ) + ) + ->will( $this->returnValue( $obj ) ); + + $this->assertSame( $obj, $mock->continueSecondaryAccountCreation( $user, $user, $reqs ) ); + } + + /** + * Get requests for testing + * @return AuthenticationRequest[] + */ + private function getLinkRequests() { + $reqs = []; + + $mb = $this->getMockBuilder( AuthenticationRequest::class ) + ->setMethods( [ 'getUniqueId' ] ); + for ( $i = 1; $i <= 3; $i++ ) { + $req = $mb->getMockForAbstractClass(); + $req->expects( $this->any() )->method( 'getUniqueId' ) + ->will( $this->returnValue( "Request$i" ) ); + $req->id = $i - 1; + $reqs[$req->getUniqueId()] = $req; + } + + return $reqs; + } + + public function testBeginLinkAttempt() { + $badReq = $this->getMockBuilder( AuthenticationRequest::class ) + ->setMethods( [ 'getUniqueId' ] ) + ->getMockForAbstractClass(); + $badReq->expects( $this->any() )->method( 'getUniqueId' ) + ->will( $this->returnValue( "BadReq" ) ); + + $user = \User::newFromName( 'UTSysop' ); + $provider = TestingAccessWrapper::newFromObject( + new ConfirmLinkSecondaryAuthenticationProvider + ); + $request = new \FauxRequest(); + $manager = $this->getMockBuilder( AuthManager::class ) + ->setMethods( [ 'allowsAuthenticationDataChange' ] ) + ->setConstructorArgs( [ $request, \RequestContext::getMain()->getConfig() ] ) + ->getMock(); + $manager->expects( $this->any() )->method( 'allowsAuthenticationDataChange' ) + ->will( $this->returnCallback( function ( $req ) { + return $req->getUniqueId() !== 'BadReq' + ? \StatusValue::newGood() + : \StatusValue::newFatal( 'no' ); + } ) ); + $provider->setManager( $manager ); + + $this->assertEquals( + AuthenticationResponse::newAbstain(), + $provider->beginLinkAttempt( $user, 'state' ) + ); + + $request->getSession()->setSecret( 'state', [ + 'maybeLink' => [], + ] ); + $this->assertEquals( + AuthenticationResponse::newAbstain(), + $provider->beginLinkAttempt( $user, 'state' ) + ); + + $reqs = $this->getLinkRequests(); + $request->getSession()->setSecret( 'state', [ + 'maybeLink' => $reqs + [ 'BadReq' => $badReq ] + ] ); + $res = $provider->beginLinkAttempt( $user, 'state' ); + $this->assertInstanceOf( AuthenticationResponse::class, $res ); + $this->assertSame( AuthenticationResponse::UI, $res->status ); + $this->assertSame( 'authprovider-confirmlink-message', $res->message->getKey() ); + $this->assertCount( 1, $res->neededRequests ); + $req = $res->neededRequests[0]; + $this->assertInstanceOf( ConfirmLinkAuthenticationRequest::class, $req ); + $expectReqs = $this->getLinkRequests(); + foreach ( $expectReqs as $r ) { + $r->action = AuthManager::ACTION_CHANGE; + $r->username = $user->getName(); + } + $this->assertEquals( $expectReqs, TestingAccessWrapper::newFromObject( $req )->linkRequests ); + } + + 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 ); + } + +} |