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

API Added CORS pre-flight handler (fixes #66) #69

Merged
merged 1 commit into from
Feb 9, 2017

Conversation

PapaBearNZ
Copy link
Contributor

@PapaBearNZ PapaBearNZ commented Feb 6, 2017

Added code to index() to detect a CORS preflight OPTIONS request.
Added getCorsResponse() to append the correct headers for a CORS request.
Also checks the origin is an allowed domain for cross-origin requests.
Included unittests for invalid origin, valid origin, OPTIONS request type.

@PapaBearNZ PapaBearNZ mentioned this pull request Feb 7, 2017
@PapaBearNZ
Copy link
Contributor Author

Found the bug in this pull request. Fixing. I'll submit a new PR with the fix in place.

@PapaBearNZ PapaBearNZ closed this Feb 8, 2017
@PapaBearNZ
Copy link
Contributor Author

Oops - hit close and comment in error.

@PapaBearNZ PapaBearNZ reopened this Feb 8, 2017
@PapaBearNZ
Copy link
Contributor Author

I think CORS should be disabled by default. This is in line with the idea of assuming all things are as locked down as possible unless the dev chooses to open them up. If no one has any complaints, I'll update the default config. This should then (in conjunction with the above modification) fix the travis build issues.

->addHeader('Content-Type', 'application/json');
$response = new HTTPResponse(json_encode($result));
if ($corsEnabled) {
$response = $this->getCorsResponse($request, $response);
Copy link
Member

Choose a reason for hiding this comment

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

Good catch about including CORS headers in the actual GraphQL response, that seems to be best practice. If you follow https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS#Preflighted_requests, the actual HTTP response (not the OPTIONS call) only has the Access-Control-Allow-Origin header - but the spec says "An HTTP response to a CORS request can include the following headers", listing all available headers (https://fetch.spec.whatwg.org/#http-responses) - so I think we're good

* @param HTTPResponse $response
* @return HTTPResponse
*/
public function getCorsResponse(HTTPRequest $request, HTTPResponse $response = null)
Copy link
Member

Choose a reason for hiding this comment

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

The dual use with/without a $response argument is a bit confusing. Can you create new HTTPResponse() outside of this method, make $response a mandatory argument, and rename the method to addCorsHeaders()?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Understood. I'll make the necessary changes.

@chillu
Copy link
Member

chillu commented Feb 8, 2017

Could you have a look at the failed tests please? Just restarted the build, in case they were temporary

@chillu
Copy link
Member

chillu commented Feb 8, 2017

I think CORS should be disabled by default. This is in line with the idea of assuming all things are as locked down as possible unless the dev chooses to open them up. If no one has any complaints, I'll update the default config. This should then (in conjunction with the above modification) fix the travis build issues.

Agreed. So you're planning to set Enabled: false, meaning an OPTIONS request won't receive any special responses in the controller by default, right?

@PapaBearNZ
Copy link
Contributor Author

PapaBearNZ commented Feb 8, 2017

@chillu Re the CORS Enabled comment. You are correct regarding the response headers. The errors in the tests are due to CORS being enable by default but having no Allowed Origins defined, the CORS response was correctly rejecting the request. By setting CORS to disabled by default, This check never happens and the response is processed normally without the 403 status.

@codecov-io
Copy link

codecov-io commented Feb 8, 2017

Codecov Report

Merging #69 into master will increase coverage by 0.08%.

@@            Coverage Diff             @@
##           master      #69      +/-   ##
==========================================
+ Coverage   90.51%   90.59%   +0.08%     
==========================================
  Files          36       36              
  Lines        1402     1436      +34     
==========================================
+ Hits         1269     1301      +32     
- Misses        133      135       +2
Impacted Files Coverage Δ
src/Controller.php 85.18% <94.44%> (+6.46%)

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 16752a3...cc0a672. Read the comment docs.

@@ -51,6 +51,10 @@ public function index(HTTPRequest $request)
// Process the CORS config and add appropriate headers.
$response = new HTTPResponse();
return $this->addCorsHeaders($request, $response);
} elseif (!$corsEnabled && $request->httpMethod() == 'OPTIONS') {
// CORS is disabled but we have received an OPTIONS request. This is not a valid request method in this
// situation. Return a 405 Method Not Allowed response.
Copy link
Member

Choose a reason for hiding this comment

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

The comments are getting a little bit verbose (repeating the status code), but otherwise all good :)

@chillu
Copy link
Member

chillu commented Feb 8, 2017

Sweet, now it's just missing some docs for the README!

README.md Outdated
Enabled: true
```

Once you have enabled CORS you can then control 4 new headers in the HTTP Response.
Copy link
Member

Choose a reason for hiding this comment

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

"4" should be spelled out as "four" in most common grammar guidelines

Copy link
Contributor Author

Choose a reason for hiding this comment

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

noted and corrected.

README.md Outdated
```

Once you have enabled CORS you can then control 4 new headers in the HTTP Response.
(please refer to the YAML below for examples)
Copy link
Member

Choose a reason for hiding this comment

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

"please refer" sentence is too verbose, given the YAML is two lines below it

Copy link
Contributor Author

Choose a reason for hiding this comment

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

noted and removed.

@chillu
Copy link
Member

chillu commented Feb 8, 2017

Can you rebase on master please? There’s conflicts. Can you please link the first mention of CORS to https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS? I found that guide to be helpful. Otherwise the README looks great!

README.md Outdated
@@ -1449,6 +1440,126 @@ php -r 'echo base64_encode("hello:world");'
# aGVsbG86d29ybGQ=
```

### Defining your own authenticators
Copy link
Member

Choose a reason for hiding this comment

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

Why did you add this section? Merge error?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Argh - That was to resolve a merge conflict after the rebase. It's actually @robbieaverill 's work that's somehow gotten credited to me :( Not sure how to fix that. (lines 1443-1461)

Copy link
Contributor

Choose a reason for hiding this comment

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

Looks like a dodgy merge

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The rebase off upstream master worked well but then when trying to push up my branch there were conflicts there as well. This section got caught in the crossfire :(

What do you suggest to resolve this guys? Should I create a new branch off master, squash my commit tree and then do one single commit as part of a replacement PR?

Copy link
Member

Choose a reason for hiding this comment

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

Whatever works for you - the end goal is that only relevant patches make it into this PR. We can squash on merge, or you can squash - either way is fine.

Copy link
Contributor Author

@PapaBearNZ PapaBearNZ Feb 9, 2017

Choose a reason for hiding this comment

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

How does this look? Better?

master...PapaBearNZ:66-cors-handling

    * Added addCorsHeaders() function to append appropriate headers to response
      if necessary.
    * Added cors section to SilverStripe\GraphQL config object.
    * Added UnitTests.
    * Added README documentation for CORS handling.
@PapaBearNZ PapaBearNZ force-pushed the 66-cors-preflight-handling branch from bc5dcb5 to cc0a672 Compare February 9, 2017 02:57
@chillu chillu merged commit f2190da into silverstripe:master Feb 9, 2017
unclecheese pushed a commit to unclecheese/silverstripe-graphql that referenced this pull request Jan 27, 2021
…fixup

BUG Ensure i18n detects locale from <html lang>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants