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

Internal server error if there are multiple matching callbacks #269

Closed
wants to merge 4 commits into from

Conversation

frobijn
Copy link
Contributor

@frobijn frobijn commented Oct 6, 2024

Description

If a developer has created multiple methods of controller(s) that match the same web request, an internal server error is generated with the names of the matching methods.

Plus: .editorconfig added. This also changes the header comment of the modified code files.

Motivation and Context

It is a protection against coding errors. In the current code, if multiple callbacks match, both are executed with results in an exception in an unexpected place in the code. With the change applied, it is impossible to miss that there is a problem.

Assuming a developer/tester tests new or modified code the internal server error will not be generated in a production situation, so no data is leaked that may be considered a security risk.

I list it as "improvement", as one type of error (exception in the second callback) is replaced by another (internal server error).

How Has This Been Tested?

Postman, as prescribed.

Types of changes

  • Improvement (non-breaking change that improves a feature, code or algorithm)
  • Bug fix (non-breaking change which fixes an issue with code or algorithm)
  • New feature (non-breaking change which adds functionality to code)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Config and build (change in the configuration and build system, has no impact on code or features)
  • Dependencies (update dependencies and changes associated, has no impact on code or features)
  • Unit Tests (add new Unit Test(s) or improved existing one(s), has no impact on code or features)
  • Documentation (changes or updates in the documentation, has no impact on code or features)

Checklist:

  • My code follows the code style of this project (only if there are changes in source code).
  • My changes require an update to the documentation (there are changes that require the docs website to be updated).
  • I have updated the documentation accordingly (the changes require an update on the docs in this repo).
  • I have read the CONTRIBUTING document.
  • I have tested everything locally and all new and existing tests passed (only if there are changes in source code).
  • I have added new tests to cover my changes.

Summary by CodeRabbit

  • New Features

    • Introduced multiple new test cases to enhance API testing, including SimpleRouteController_MultipleCallback and various scenarios under the MixedController category.
    • Added new variables to support enhanced test cases for authentication methods.
  • Bug Fixes

    • Improved error handling to ensure appropriate server responses for specific scenarios, including validation of status codes and response content.

Copy link

coderabbitai bot commented Oct 6, 2024

Walkthrough

The changes introduce several new test cases to the Postman collection for the nanoFramework WebServer end-to-end tests. A new test case named SimpleRouteController_MultipleCallback is added to validate the server's response when multiple callbacks are matched, checking for a status code of 500 and a specific error message. Additionally, multiple new test cases under the MixedController category are included, focusing on various authentication scenarios and expecting a status code of 200. Two new variables are also introduced to support these tests.

Changes

File Change Summary
tests/WebServerE2ETests/nanoFramework WebServer E2E Tests.postman_collection.json Added new test cases: SimpleRouteController_MultipleCallback, MixedController_ApiKeyPublic_ApiKey, MixedController_ApiKeyPublic_Public, MixedController_BasicPublic_Basic, MixedController_BasicPublic_Public, MixedController_ApiKeyBasicPublic_ApiKey, MixedController_ApiKeyBasicPublic_ApiKey2, MixedController_ApiKeyBasicPublic_Basic, MixedController_ApiKeyBasicPublic_Public. Added variables: auth_basic_username2, auth_apikey2.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant Server
    Client->>Server: GET /multiplecallback
    Server-->>Client: 500 Internal Server Error
    Note right of Server: Response includes error message about multiple callbacks
Loading

📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between bc0dcc4 and c8588c3.

⛔ Files ignored due to path filters (9)
  • .editorconfig is excluded by none and included by none
  • README.md is excluded by !**/*.md and included by none
  • nanoFramework.WebServer/WebServer.cs is excluded by none and included by none
  • spelling_exclusion.dic is excluded by none and included by none
  • tests/WebServerE2ETests/AuthController.cs is excluded by none and included by none
  • tests/WebServerE2ETests/MixedController.cs is excluded by none and included by none
  • tests/WebServerE2ETests/Program.cs is excluded by none and included by none
  • tests/WebServerE2ETests/SimpleRouteController.cs is excluded by none and included by none
  • tests/WebServerE2ETests/WebServerE2ETests.nfproj is excluded by none and included by none
📒 Files selected for processing (1)
  • tests/WebServerE2ETests/nanoFramework WebServer E2E Tests.postman_collection.json (4 hunks)
🧰 Additional context used
🔇 Additional comments (10)
tests/WebServerE2ETests/nanoFramework WebServer E2E Tests.postman_collection.json (10)

217-247: LGTM: New test case for multiple matching callbacks.

This new test case effectively checks the server's response when multiple callbacks match a single request. It verifies both the expected 500 status code and the specific error message, which aligns well with the PR's objective of improving error handling for this scenario.


909-954: LGTM: New test case for API key authentication in mixed controller.

This test case effectively verifies the server's response when using API key authentication in a mixed controller scenario. It checks for the correct status code and response body, enhancing the test coverage for authentication handling.


955-985: LGTM: New test case for public access in mixed controller.

This test case properly verifies the server's response for public access in a mixed authentication scenario. It checks for the correct status code and response body, complementing the API key test and ensuring comprehensive coverage of the authentication methods.


986-1031: LGTM: New test case for basic authentication in mixed controller.

This test case effectively verifies the server's response when using basic authentication in a mixed controller scenario. It checks for the correct status code and response body, further enhancing the test coverage for various authentication methods.


1032-1062: LGTM: New test case for public access in basic+public mixed controller.

This test case properly verifies the server's response for public access in a mixed authentication scenario with basic and public methods. It checks for the correct status code and response body, complementing the basic authentication test and ensuring comprehensive coverage of the access methods.


1063-1277: LGTM: Comprehensive test cases for mixed controller with API key, basic, and public access.

These test cases provide excellent coverage for a complex mixed authentication scenario. They verify:

  1. API key authentication (including multiple API keys)
  2. Basic authentication (with multiple users)
  3. Public access

Each test checks for the correct status code and response body, ensuring that the server correctly handles and distinguishes between different authentication methods. This comprehensive set of tests will help maintain the integrity of the authentication system as the codebase evolves.


1278-1399: LGTM: Test cases for multiple callbacks with different authentication methods.

These test cases effectively verify the server's behavior when multiple callbacks match for different authentication methods (API key, Basic, and Public). They check for:

  1. The correct 500 status code
  2. The appropriate error message indicating multiple matching callbacks

These tests directly address the main objective of the PR, ensuring that the server properly handles and reports situations with multiple matching callbacks. This will help prevent unexpected behavior and improve error reporting in the application.


1432-1436: LGTM: New variable for additional basic auth user.

The addition of the auth_basic_username2 variable with the value "user3" supports the new test cases for multiple basic authentication users. This allows for more comprehensive testing of basic auth scenarios.


1447-1450: LGTM: New variable for additional API key.

The addition of the auth_apikey2 variable with the value "superKey42" supports the new test cases for multiple API key authentication scenarios. This enhances the test coverage by allowing verification of different API key handling.


Line range hint 1-1453: Overall assessment: Excellent additions to the test suite.

The changes in this file significantly improve the test coverage for the nanoFramework WebServer, particularly in the areas of:

  1. Multiple matching callbacks error handling
  2. Mixed authentication scenarios (API key, Basic, and Public)
  3. Various edge cases in authentication

These additions align perfectly with the PR objectives and will help ensure the robustness of the server's request handling and authentication mechanisms. The new test cases and variables are well-structured and comprehensive.

Great job on enhancing the test suite!


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.

}
else if (selectedRoute is null)
{
if (CommandReceived != null)
Copy link
Member

Choose a reason for hiding this comment

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

You still need to check auth. So, you should have to adjust with the previous logic.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Authentication! That is a use case for multiple methods. Same route, but different method depending on whether credentials have been passed or not.

Changed the logic and documented the change in the README.md. Added extra unit tests.

Also put the WiFi data in a separate WiFi.cs file (not in git) and WiFi.TEMPLATE.cs (in git) as I almost committed my WAN credentials.

Copy link
Member

@josesimoes josesimoes left a comment

Choose a reason for hiding this comment

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

@frobijn let's have atomic PRs please. Change only what is meant to be changed on the PR. In this case the fix for the multiple matching callbacks.

If there is an issue with the way wifi credentials are being stored, lets discuss a way to address that and add those changes on another PR.

@frobijn
Copy link
Contributor Author

frobijn commented Oct 7, 2024

@frobijn let's have atomic PRs please. Change only what is meant to be changed on the PR. In this case the fix for the multiple matching callbacks.

If there is an issue with the way wifi credentials are being stored, lets discuss a way to address that and add those changes on another PR.

But that should then have been in a PR before this one. I made the change of multiple callbacks before having issues with the WiFi credentials. If I would have to make the WiFi change before I could continue with the multiple callback change. Given the wait times between initiating a PR and having it closed, that makes it quite hard to do some small work. I would almost have to work on as many branches as there are code changes. Please please please allow for small improvements that make life easier for a contributor.

@josesimoes
Copy link
Member

In this case it's a simple matter of not including the changes with wifi.cs, nothing complicated.

Please understand that this is not to make developers life complicated, is to improve project maintainability.
If we need to revert this set of changes for any reason, and if includes other unrelated changes, it's more work and one has to remember to address that.
Plus, change log is generated from the PR title. If that includes multiple unrelated changes it has impact on formatting and clarity.

FYI: I've just extracted these changes and added them in #270 . Updating this branch now so these are not part of the PR anymore.

Our contribution guideline suggests that for breaking or large changes, these are discussed beforehand. That is to prevent waste of time/work and even frustration. No one likes to see it's work changed or the effort dismissed. No one here wants to bash developers willing to contribute. Quite the oposite. Still there are aspects that require a broader and 10.000ft view that (most likely) only maintainers have.

Also know that for simple changes and fixes, you can do that right on the github webpage. No need to branch, github offers to start a PR for you.

@frobijn
Copy link
Contributor Author

frobijn commented Oct 7, 2024

Well, I like to test stuff before starting a PR. Then a local branch is more practical. My point was not the local branch, but having multiple changes as PR in parallel. Keeping the PR-branches in sync is sometimes a hassle. But sequential PRs is a bit of a start-and-stop type of development.

Checked the part that was separated in #270, the remaining part is in #271.

@josesimoes
Copy link
Member

I understand your point. Sometimes it can hinder productivity, but it's required for the greater good. 😉
Merging and rebasing when one is working on the same change set is usually not painful. Things do get complicated when there is active development and even more if several developers are working in the same files. That requires a more frequent coordination. Thank you for your understanding! 👍🏻

Frank Robijn added 4 commits October 7, 2024 23:45
Copy link

sonarqubecloud bot commented Oct 7, 2024

Copy link
Member

@Ellerbach Ellerbach left a comment

Choose a reason for hiding this comment

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

Looks great now. Few comments on the readme, then I think we will be good to go

}
}
```
The webserver selects the route for a request:
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
The webserver selects the route for a request:
The webserver selects the route for a request:

- If one of the methods does not require authentication, that method is called.
- Otherwise a non-authorized response (401) will be returned. If one of the methods requires basic authentication, the `WWW-Authenticate` header is included to request credentials.

If two or more methods match the authentication method and credentials of the request, an internal server error is returned with a list of the methods.
Copy link
Member

Choose a reason for hiding this comment

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

then from the previous posted experience, can you be a bit more explicit on what will happen?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

In the new PR, the line last line is replaced by:

The webserver does not support more than one matching method. Calling multiple methods most likely results in an exception as a subsequent method tries to modify a response that is already processed by the first method. The webserver does not know what to do and returns an internal server error (500). The body of the response lists the matching methods.

Having multiple matching methods is considered a programming error. One way this occurs is if two methods in a controller accidentally have the same route. Returning an internal server error with the names of the methods makes it easy to discover the error. It is expected that the error is discovered and fixed in testing. Then the internal error will not occur in the application that is deployed to a device.

@frobijn frobijn closed this Oct 8, 2024
@frobijn frobijn deleted the MultipleCallbacks branch October 8, 2024 11:19
@frobijn
Copy link
Contributor Author

frobijn commented Oct 8, 2024

I tried to clean up my local git repository and create a cleaner MultipleCallbacks branch. I'm a bit surprised that this PR got closed by it. A new PR is on its way: #272

@josesimoes
Copy link
Member

@frobijn this PR was closed the moment you've deleted the branch that originated it. It can be restored and reopened. If you prefer.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants