From 86b5a848e720f0070a79893066f0469d91360bc8 Mon Sep 17 00:00:00 2001 From: Mark Wallsgrove Date: Tue, 2 Jul 2019 12:31:25 +0100 Subject: [PATCH] PLAT-2949 - Support Regenerate OAuth Secret (#14) * regenerate oauth client method * tests and new exceptions * docblock update * tailor exception * typo * add admin version const * fix imports * fixes * add integration test * remove integration test * pr * remove admin host * remove old test * fix tests * tidy * move to new url * add integration test * fix test * Cleanup * add log statement --- composer.json | 2 +- .../Client/InvalidPayloadException.php | 9 ++ src/Talis/Persona/Client/OAuthClients.php | 33 ++++++ .../Persona/OAuthClientsIntegrationTest.php | 38 +++++++ test/unit/Persona/OAuthClientsTest.php | 104 ++++++++++++++++++ 5 files changed, 185 insertions(+), 1 deletion(-) create mode 100644 src/Talis/Persona/Client/InvalidPayloadException.php diff --git a/composer.json b/composer.json index 46a6fd8..23654ff 100644 --- a/composer.json +++ b/composer.json @@ -1,7 +1,7 @@ { "name": "talis/talis-php", "description": "This is a php client library for talis api's", - "version": "0.3.0", + "version": "0.3.1", "keywords": [ "persona", "echo", diff --git a/src/Talis/Persona/Client/InvalidPayloadException.php b/src/Talis/Persona/Client/InvalidPayloadException.php new file mode 100644 index 0000000..53c878b --- /dev/null +++ b/src/Talis/Persona/Client/InvalidPayloadException.php @@ -0,0 +1,9 @@ +performRequest($url, ['bearerToken' => $token]); } + + /** + * Generate and append or replace a oauth client's secret. + * @param string $clientId oauth client (persona user guid is also a oauth client id) + * @param string $token Persona oauth token + * @return string new oauth client secret + * @throws \Exception Persona communication issues + */ + public function regenerateSecret($clientId, $token) + { + $host = $this->getPersonaHost(); + $resp = $this->performRequest( + "$host/clients/$clientId/secret", + [ + 'method' => 'POST', + 'bearerToken' => $token, + 'expectResponse' => true, + ] + ); + + if (isset($resp['secret'])) { + return $resp['secret']; + } else { + $this->getLogger()->error( + 'invalid payload format from persona', + ['payload' => $resp] + ); + + throw new InvalidPayloadException( + 'invalid payload format from persona' + ); + } + } } diff --git a/test/integration/Persona/OAuthClientsIntegrationTest.php b/test/integration/Persona/OAuthClientsIntegrationTest.php index 62f6362..3f84988 100644 --- a/test/integration/Persona/OAuthClientsIntegrationTest.php +++ b/test/integration/Persona/OAuthClientsIntegrationTest.php @@ -181,4 +181,42 @@ public function testGetOAuthClientInvalidTokenThrowsException() $personaClient->getOAuthClient('123', '456'); } + + public function testGenerateSecretForUser() + { + $tokenDetails = $this->personaClientTokens->obtainNewToken( + $this->clientId, + $this->clientSecret, + ['useCache' => false] + ); + + $this->assertArrayHasKey('access_token', $tokenDetails); + $token = $tokenDetails['access_token']; + + $gupid = uniqid('trapdoor:'); + $email = uniqid() . '@example.com'; + $user = $this->personaClientUser->createUser( + $gupid, + ['name' => 'Sarah Connor', 'email' => $email], + $token + ); + + $client = $this->personaClientOAuthClient->getOAuthClient( + $user['guid'], + $token + ); + + $secret = $this->personaClientOAuthClient->regenerateSecret( + $user['guid'], + $token + ); + + $userTokenDetails = $this->personaClientTokens->obtainNewToken( + $user['guid'], + $secret, + ['useCache' => false] + ); + + $this->assertArrayHasKey('access_token', $userTokenDetails); + } } diff --git a/test/unit/Persona/OAuthClientsTest.php b/test/unit/Persona/OAuthClientsTest.php index 894c710..39b3551 100644 --- a/test/unit/Persona/OAuthClientsTest.php +++ b/test/unit/Persona/OAuthClientsTest.php @@ -1,6 +1,7 @@ getMock( + 'Talis\Persona\Client\OAuthClients', + ['performRequest'], + [ + [ + 'userAgent' => 'unittest', + 'persona_host' => 'localhost', + 'persona_admin_host' => 'localhost', + 'cacheBackend' => $this->cacheBackend, + ] + ] + ); + + $oauthClient->expects($this->once()) + ->method('performRequest') + ->with( + 'localhost/3/clients/clientId/secret', + [ + 'method' => 'POST', + 'bearerToken' => 'token', + 'expectResponse' => true, + ] + ) + ->will( + $this->throwException( + new \Exception('Did not retrieve successful response code') + ) + ); + + $this->setExpectedException( + 'Exception', + 'Did not retrieve successful response code' + ); + $oauthClient->regenerateSecret('clientId', 'token'); + } + + public function testRegenerateSecretInvalidResponsePayload() + { + $oauthClient = $this->getMock( + 'Talis\Persona\Client\OAuthClients', + ['performRequest'], + [ + [ + 'userAgent' => 'unittest', + 'persona_host' => 'localhost', + 'persona_admin_host' => 'localhost', + 'cacheBackend' => $this->cacheBackend, + ] + ] + ); + + $oauthClient->expects($this->once()) + ->method('performRequest') + ->with( + 'localhost/3/clients/clientId/secret', + [ + 'method' => 'POST', + 'bearerToken' => 'token', + 'expectResponse' => true, + ] + ) + ->willReturn(['invalid' => 'body']); + + $this->setExpectedException( + 'Talis\Persona\Client\InvalidPayloadException', + 'invalid payload format from persona' + ); + $oauthClient->regenerateSecret('clientId', 'token'); + } + + public function testRegenerateSecretHappyPath() + { + $oauthClient = $this->getMock( + 'Talis\Persona\Client\OAuthClients', + ['performRequest'], + [ + [ + 'userAgent' => 'unittest', + 'persona_host' => 'localhost', + 'persona_admin_host' => 'localhost', + 'cacheBackend' => $this->cacheBackend, + ] + ] + ); + + $oauthClient->expects($this->once()) + ->method('performRequest') + ->with( + 'localhost/3/clients/clientId/secret', + [ + 'method' => 'POST', + 'bearerToken' => 'token', + 'expectResponse' => true, + ] + ) + ->willReturn(['secret' => 'new secret']); + + $secret = $oauthClient->regenerateSecret('clientId', 'token'); + $this->assertEquals('new secret', $secret); + } }