Skip to content

Commit

Permalink
Support updatePassword in lazy connections, reconnections and cloning
Browse files Browse the repository at this point in the history
  • Loading branch information
kratkyzobak committed Feb 9, 2024
1 parent db34834 commit 2f37647
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 2 deletions.
8 changes: 8 additions & 0 deletions PhpAmqpLib/Connection/AMQPStreamConnection.php
Original file line number Diff line number Diff line change
Expand Up @@ -131,4 +131,12 @@ protected static function try_create_connection($host, $port, $user, $password,
$channel_rpc_timeout
);
}

/**
* @param string $password
*/
protected function replace_password_in_construct_params($password)
{
$this->construct_params[3] = $password;
}
}
22 changes: 20 additions & 2 deletions PhpAmqpLib/Connection/AbstractConnection.php
Original file line number Diff line number Diff line change
Expand Up @@ -323,8 +323,26 @@ public function reconnect()
*/
public function updatePassword($password): void
{
// send new secret to broker
$this->x_update_secret($password);
if ($this->login_method !== 'EXTERNAL') {
// password is always latest in response for PLAIN and AMQPPLAIN
// for EXTERNAL mechanism this has to be handled by calling user
$login_response_parts = explode("\0", $this->login_response);
$login_response_parts[count($login_response_parts) - 1] = $password;
$this->login_response = implode("\0", $login_response_parts);
}

if ($this->is_connected) {
// send new secret to broker if currently connected
$this->x_update_secret($password);
}
}

/**
* @param string $password
*/
protected function replace_password_in_construct_params($password)
{
$this->construct_params[1] = $password;
}

/**
Expand Down
2 changes: 2 additions & 0 deletions demo/oauth2_authorization.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ function getNextOauth2Token() {
pcntl_signal(SIGALRM, function () use ($connection) {
echo "Refreshing token...\n";
$connection->updatePassword(getNextOauth2Token()); // this will fail on 2nd attempt - see getNextOauth2Token
sleep(1);
$connection->reconnect(); // reconnect should use new token too so this is working for lazy connections too!
pcntl_alarm(5);
}, true);
pcntl_alarm(5);
Expand Down
32 changes: 32 additions & 0 deletions tests/Functional/Connection/OAuth2ConnectionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,38 @@ public function update_password()
self::assertTrue($conn->isConnected());
}

/**
* @test
* @covers \PhpAmqpLib\Connection\AbstractConnection::updatePassword()
*/
public function update_password_should_replace_password_for_reconnect()
{
$conn = new AMQPStreamConnection(HOST, PORT, 'oauth', JWT_TOKEN_1, '/', false, 'PLAIN', null, 'en_US', 1);
$conn->updatePassword(JWT_TOKEN_2);

$loginResponse = (new \ReflectionClass($conn))->getProperty('login_response');
$loginResponse->setAccessible(true);

self::assertContains(JWT_TOKEN_2, $loginResponse->getValue($conn);
self::assertNotContains(JWT_TOKEN_1, $loginResponse->getValue($conn);
}

/**
* @test
* @covers \PhpAmqpLib\Connection\AbstractConnection::updatePassword()
*/
public function update_password_should_replace_password_for_clone()
{
$conn = new AMQPStreamConnection(HOST, PORT, 'oauth', JWT_TOKEN_1, '/', false, 'PLAIN', null, 'en_US', 1);
$conn->updatePassword(JWT_TOKEN_2);

$constructorParams = (new \ReflectionClass($conn))->getProperty('constructor_param');
$constructorParams->setAccessible(true);

self::assertContains(JWT_TOKEN_2, $constructorParams->getValue($conn);
self::assertNotContains(JWT_TOKEN_1, $constructorParams->getValue($conn);
}

/**
* @test
* @covers \PhpAmqpLib\Connection\AbstractConnection::x_update_secret()
Expand Down

0 comments on commit 2f37647

Please sign in to comment.