Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ECO-4977] Fix/broadcast to others #50

Merged
merged 9 commits into from
Sep 25, 2024
Merged

[ECO-4977] Fix/broadcast to others #50

merged 9 commits into from
Sep 25, 2024

Conversation

sacOO7
Copy link
Collaborator

@sacOO7 sacOO7 commented Sep 24, 2024

Summary by CodeRabbit

  • New Features

    • Introduced new methods for base64 URL encoding/decoding and socket ID decoding in the Utils class.
    • Enhanced JWT handling with improved parsing and generation methods.
    • Added support for constructing messages based on socket ID objects.
  • Bug Fixes

    • Improved error handling for socket ID validation and decoding.
  • Tests

    • Added unit tests for JWT generation, socket ID decoding, and error handling in the Utils class.

Copy link

coderabbitai bot commented Sep 24, 2024

Walkthrough

The changes in this pull request involve enhancements to the Utils class, focusing on JWT handling and socket ID decoding. The base64url_decode method has been introduced, and existing methods for JWT processing have been updated to use base64 URL encoding. Additionally, a new method for decoding socket IDs has been added, improving error handling. Corresponding unit tests have been introduced to validate these functionalities.

Changes

Files Change Summary
src/Utils.php Updated JWT handling methods to use base64 URL encoding/decoding; added decodeSocketId method.
tests/AblyBroadcasterTest.php Removed and renamed tests; added new test for message building based on socket ID.
tests/UtilsTest.php Introduced tests for JWT generation, socket ID decoding, and exception handling.

Assessment against linked issues

Objective Addressed Explanation
Fix malformed message due to invalid connectionKey (issues #38, #48)
Ensure proper base64 URL decoding for JWT (issue #51)
Validate socket ID structure and handle exceptions (issue #51)

Possibly related PRs

  • Update README #49: The changes in this PR are unrelated to the main PR as they focus solely on updating the README documentation and do not involve any code modifications or functionality related to the Utils class or JWT handling.

Suggested reviewers

  • ttypic

Poem

In the meadow, changes bloom,
With socket IDs, there's more room.
JWTs dance in base64 light,
Broadcasting messages, all feels right!
Hops of joy, let's celebrate,
For clearer paths we now create! 🐇✨


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@sacOO7 sacOO7 changed the title Fix/broadcast to others [ECO-4977] Fix/broadcast to others Sep 24, 2024
@sacOO7 sacOO7 force-pushed the fix/broadcast-to-others branch from ed83d16 to 9e94625 Compare September 24, 2024 13:36
@sacOO7 sacOO7 marked this pull request as ready for review September 24, 2024 14:36
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

Outside diff range and nitpick comments (8)
tests/UtilsTest.php (3)

10-29: LGTM! Consider adding edge cases.

The testGenerateAndValidateToken method effectively tests the basic functionality of JWT generation, parsing, and validation. It covers the essential aspects of JWT structure and content verification.

Consider enhancing the test coverage by adding edge cases, such as:

  1. Testing with an expired token
  2. Verifying behavior with an invalid signature
  3. Checking token validation with different algorithms (if supported)

These additions would provide a more comprehensive test suite for the JWT functionality.


34-51: LGTM! Consider adding boundary test cases.

The testDecodeSocketId method effectively covers the main scenarios for socket ID decoding, including null input and socket IDs with and without client IDs. The use of base64url_encode aligns well with the PR objectives.

To further strengthen the test suite, consider adding the following test cases:

  1. Test with an empty string input
  2. Test with a very long socket ID to ensure proper handling of large inputs
  3. Test with special characters in the connection key and client ID to ensure proper encoding/decoding

These additional cases would help ensure robustness in handling various input scenarios.


1-79: Great job on the comprehensive test suite!

The UtilsTest class provides excellent coverage for the Utils class, including:

  1. JWT generation, parsing, and validation
  2. Socket ID decoding for various scenarios
  3. Thorough exception handling tests

The test suite aligns well with the PR objectives, particularly in improving the reliability of the broadcasting feature and enhancing error handling for socket IDs and JWTs.

To further improve the test suite, consider adding a test for the Utils::base64url_encode and Utils::base64url_decode methods. This would ensure complete coverage of all the utility functions and align with the PR objective of correctly handling base64 URL encoding/decoding mentioned in Issue #51.

tests/AblyBroadcasterTest.php (3)

323-345: LGTM! Consider adding an assertion for the encoded socket object.

The test has been updated to reflect the new payload structure and correctly verifies that the 'socket' key is removed from the broadcasted payloads. This aligns well with the changes in the main code.

Consider adding an assertion to verify that the socketIdObject is correctly encoded in the initial payload. This would ensure that the test covers both the encoding and the subsequent removal of the 'socket' key. For example:

$encodedSocket = Utils::base64url_encode(json_encode($socketIdObject));
self::assertEquals($encodedSocket, $payload['socket'], "The socket object should be correctly encoded.");

347-368: LGTM! Consider adding edge case tests.

The new test method effectively covers the behavior of buildAblyMessage with and without a socketIdObject. It verifies the correct structure of the resulting message in both scenarios.

To improve the robustness of the test, consider adding edge cases:

  1. Test with an empty socketIdObject.
  2. Test with a socketIdObject that has only one of the properties set (either connectionKey or clientId).

For example:

$emptySocketIdObject = new \stdClass();
$message = $broadcaster->buildAblyMessage('testEvent', $payload, $emptySocketIdObject);
self::assertNull($message->connectionKey);
self::assertNull($message->clientId);

$partialSocketIdObject = new \stdClass();
$partialSocketIdObject->connectionKey = 'bar';
$message = $broadcaster->buildAblyMessage('testEvent', $payload, $partialSocketIdObject);
self::assertEquals('bar', $message->connectionKey);
self::assertNull($message->clientId);

These additional tests would ensure that the buildAblyMessage method handles various socketIdObject structures correctly.


374-378: LGTM! Consider adding a comment for clarity.

The changes to the AblyBroadcasterExposed class effectively support the new testing requirements. The new payloads property and the modified buildAblyMessage method allow for better inspection of the broadcasting process in tests.

To improve code clarity, consider adding a brief comment explaining the purpose of storing the payload:

public function buildAblyMessage($event, $payload = [], $socketIdObject = null)
{
    // Store the original payload for testing purposes
    $this->payloads[] = $payload;
    return parent::buildAblyMessage($event, $payload, $socketIdObject);
}

This comment would help other developers understand why the payload is being stored before calling the parent method.

src/Utils.php (1)

78-80: Enhance the error message formatting for readability.

The SOCKET_ID_ERROR constant provides a helpful error message. Consider capitalizing the beginning of the sentence and adding punctuation for improved readability.

Apply this diff to improve the error message formatting:

-const SOCKET_ID_ERROR = "please make sure to send base64 url encoded json with "
-    ."'connectionKey' and 'clientId' as keys. 'clientId' is null if connection is not identified";
+const SOCKET_ID_ERROR = "Please make sure to send base64 URL-encoded JSON with "
+    ."'connectionKey' and 'clientId' as keys. 'clientId' is null if connection is not identified.";
src/AblyBroadcaster.php (1)

171-177: Avoid using generic @throws \Exception in docblocks

Adding @throws \Exception in the docblock is too generic and may not provide valuable information. It's better to specify the specific exceptions that the method can throw to enhance clarity and maintainability.

Consider specifying the exact exception classes, such as \Ably\Exceptions\AblyException or any other specific exceptions that might be thrown.

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 7c2eedb and 43a6e89.

Files selected for processing (4)
  • src/AblyBroadcaster.php (2 hunks)
  • src/Utils.php (4 hunks)
  • tests/AblyBroadcasterTest.php (1 hunks)
  • tests/UtilsTest.php (1 hunks)
Additional comments not posted (10)
tests/UtilsTest.php (3)

53-58: LGTM! Proper exception testing.

The testExceptionOnDecodingInvalidSocketId method effectively tests the exception handling for an invalid socket ID. It correctly uses PHPUnit's exception assertion methods and verifies both the exception type and message.


60-68: LGTM! Thorough exception testing for missing client ID.

The testExceptionOnMissingClientIdInSocketId method effectively tests the exception handling when the client ID is missing from the socket ID object. It correctly creates a test case with only the connection key and verifies both the exception type and message.

This test case aligns well with the PR objectives of improving error handling in socket ID processing.


70-79: LGTM! Comprehensive exception testing for socket ID object.

The testExceptionOnMissingConnectionKeyInSocketId method effectively tests the exception handling when the connection key is missing from the socket ID object. It correctly creates a test case with only the client ID and verifies both the exception type and message.

This test, along with the previous ones, provides comprehensive coverage for the Utils::decodeSocketId method, including:

  1. Successful decoding scenarios (null, with/without client ID)
  2. Exception handling for invalid socket ID
  3. Exception handling for missing client ID
  4. Exception handling for missing connection key

This thorough test suite aligns well with the PR objectives of improving the reliability of the broadcasting feature and enhancing error handling.

tests/AblyBroadcasterTest.php (1)

Line range hint 1-399: Overall, the changes look good and align with the PR objectives.

The modifications to the AblyBroadcasterTest class effectively cover the new functionality related to handling socketIdObject in the broadcasting process. The new tests ensure that:

  1. The 'socket' key is removed from payloads before broadcasting.
  2. The buildAblyMessage method correctly handles the presence or absence of a socketIdObject.

The changes to the AblyBroadcasterExposed class support these new testing requirements by allowing inspection of the original payloads.

These updates align well with the objectives of fixing issues related to malformed messages and invalid connection keys when broadcasting events using the ->toOthers() method.

src/Utils.php (5)

5-6: Importing AblyException is necessary for exception handling.

The addition of use Ably\Exceptions\AblyException; is appropriate, as it is required for throwing AblyException in the code below.


17-18: Ensure correct base64 URL decoding for JWT components.

Replacing base64_decode with self::base64url_decode improves the handling of JWT components encoded with base64 URL encoding. This change enhances compatibility with standard JWT token structures.


30-31: Correct JWT generation using base64 URL encoding.

Updating the encoding of headers and payloads in the generateJwt method to use self::base64url_encode ensures that the JWT is correctly formatted according to the base64 URL encoding standard.

Also applies to: 34-34


53-53: Proper decoding of JWT payload when validating the token.

Using self::base64url_decode to decode the JWT payload ensures that tokens encoded with base64 URL encoding are correctly processed during validation.


58-58: Ensure signature comparison uses correct encoding.

Using self::base64url_encode for the signature ensures that the comparison with the token signature is accurate, adhering to the JWT specification.

src/AblyBroadcaster.php (1)

181-186: LGTM: Correct handling of socket IDs in broadcast method

The implementation of Utils::decodeSocketId($socketId) and passing the resulting $socketIdObject to buildAblyMessage enhances the handling of socket IDs. This change addresses the issues related to malformed messages and invalid connection keys when broadcasting events.

src/Utils.php Outdated Show resolved Hide resolved
src/Utils.php Outdated Show resolved Hide resolved
src/AblyBroadcaster.php Show resolved Hide resolved
src/AblyBroadcaster.php Show resolved Hide resolved
@sacOO7 sacOO7 requested a review from ttypic September 24, 2024 15:35
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Outside diff range and nitpick comments (3)
src/Utils.php (3)

14-18: LGTM: Improved parseJwt method

The changes to the parseJwt method are good:

  1. The addition of the return type hint : array improves type safety and code clarity.
  2. Using self::base64urlDecode instead of base64_decode is more appropriate for JWT handling.

Consider adding type hints for the $header and $payload variables:

-        $header = json_decode(self::base64urlDecode($tokenParts[0]), true);
-        $payload = json_decode(self::base64urlDecode($tokenParts[1]), true);
+        $header = json_decode(self::base64urlDecode($tokenParts[0]), true) ?: [];
+        $payload = json_decode(self::base64urlDecode($tokenParts[1]), true) ?: [];

This ensures that $header and $payload are always arrays, even if json_decode fails.


Line range hint 44-53: LGTM: Improved isJwtValid method

The changes to the isJwtValid method are good:

  1. The addition of the return type hint : bool improves type safety and code clarity.
  2. Using self::base64urlDecode instead of base64_decode is more appropriate for JWT handling.

Consider adding a null check before accessing the exp claim:

-        $expiration = json_decode(self::base64urlDecode($payload))->exp;
+        $decodedPayload = json_decode(self::base64urlDecode($payload));
+        if (!$decodedPayload || !isset($decodedPayload->exp)) {
+            return false;
+        }
+        $expiration = $decodedPayload->exp;

This ensures that the method doesn't throw an error if the exp claim is missing.


79-106: LGTM: Added decodeSocketId method and SOCKET_ID_ERROR constant

The addition of the decodeSocketId method and SOCKET_ID_ERROR constant is a good improvement:

  1. The constant provides a standardized error message for socket ID validation failures.
  2. The decodeSocketId method includes comprehensive error handling and validation.
  3. The method uses the new base64urlDecode function and throws AblyException for various error cases.
  4. The return type hint ?object allows for null return when $socketId is falsy.

Consider using type hinting for the $socketId parameter:

-    public static function decodeSocketId($socketId): ?object
+    public static function decodeSocketId(?string $socketId): ?object

This makes it clear that the method expects either a string or null as input.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between baf6820 and f4e2361.

Files selected for processing (3)
  • src/Utils.php (5 hunks)
  • tests/AblyBroadcasterTest.php (1 hunks)
  • tests/UtilsTest.php (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • tests/AblyBroadcasterTest.php
  • tests/UtilsTest.php
🔇 Additional comments not posted (4)
src/Utils.php (4)

5-5: LGTM: Added use statement for AblyException

The addition of the use statement for Ably\Exceptions\AblyException is appropriate, as it's used in the new decodeSocketId method.


28-28: LGTM: Added return type hint to generateJwt

The addition of the return type hint : string to the generateJwt method signature improves type safety and code clarity.


63-66: LGTM: Improved base64urlEncode method

The changes to the base64urlEncode method are good:

  1. The addition of the PHPDoc comment explaining the source of the implementation improves code documentation.
  2. The return type hint : string improves type safety and code clarity.

71-77: LGTM: Added base64urlDecode method

The addition of the base64urlDecode method is a good complement to the existing base64urlEncode method:

  1. The implementation correctly handles base64url decoding.
  2. The PHPDoc comment improves code documentation.
  3. The return type hint : string improves type safety and code clarity.

@sacOO7
Copy link
Collaborator Author

sacOO7 commented Sep 25, 2024

@coderabbitai resolve

Copy link

coderabbitai bot commented Sep 25, 2024

✅ Actions performed

Comments resolved.

Copy link

@ttypic ttypic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@sacOO7 sacOO7 merged commit 12db9dc into main Sep 25, 2024
21 checks passed
@sacOO7 sacOO7 deleted the fix/broadcast-to-others branch September 25, 2024 16:10
@coderabbitai coderabbitai bot mentioned this pull request Sep 25, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
2 participants