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

OIDC: allow configuring the request timeout #1177

Merged
merged 2 commits into from
Sep 3, 2024

Conversation

fflorent
Copy link
Collaborator

@fflorent fflorent commented Aug 24, 2024

Context

I take up this PR: #1072 (open by @atropos112)

In some case, the identity provider may take time before responding to requests sent by the OIDC client, leading to difficulties or even impossibility to start the server or to login.

For example, if the issuer discovery takes time, you may fail to start the server with this error:

RPError: outgoing request timed out after 3500ms
    at /home/florentpro/projects/grist-core/node_modules/openid-client/lib/helpers/request.js:137:13
    at async Issuer.discover (/home/florentpro/projects/grist-core/node_modules/openid-client/lib/issuer.js:171:22)
    at async OIDCConfig._initClient (/home/florentpro/projects/grist-core/_build/app/server/lib/OIDCConfig.js:246:24)
    at async OIDCConfig.initOIDC (/home/florentpro/projects/grist-core/_build/app/server/lib/OIDCConfig.js:155:9)
    at async OIDCConfig.build (/home/florentpro/projects/grist-core/_build/app/server/lib/OIDCConfig.js:104:9)
    at async Object.getMiddleware (/home/florentpro/projects/grist-core/_build/app/server/lib/OIDCConfig.js:330:28)
    at async FlexServer.addLoginMiddleware (/home/florentpro/projects/grist-core/_build/app/server/lib/FlexServer.js:1083:33)
    at async main (/home/florentpro/projects/grist-core/_build/app/server/mergedServerMain.js:86:5)
    at async main (/home/florentpro/projects/grist-core/_build/stubs/app/server/server.js:143:20)

Proposed solution

Introduce the GRIST_OIDC_SP_HTTP_TIMEOUT env variable so the user may set a greater value than the default 3500ms, or even set it to 0 to remove any timeout.

How to test it

I use this utility to add latency to the requests, so the openid-client requests may timeout: https://github.com/sitespeedio/throttle

Prerequisites:

  • Install throttle (introduced with a link above): npm i -g @sitespeed.io/throttle
  • Install tc. On Debian-family Linux distros, you must install iproute2 for that: sudo apt install iproute2.

STR:

  • Setup a Keycloak environment and use it
  • Configure Grist to use Keycloak as IdP: https://github.com/gristlabs/grist-help/blob/master/help/en/docs/install/oidc.md#example-keycloak
  • Use throttle to add the latency. I run it this way: throttle --localhost --up 9000 --down 9000 --rtt 5000 (the RTT is what matters here)
  • Then:
    • to reproduce the issue: yarn start, the server should fail to start with a timeout in the logs (see the Context section above)
    • or GRIST_OIDC_SP_HTTP_TIMEOUT=30000 yarn start to check that the problem is solved
  • Once you have finished testing, you may stop the latency: throttle --localhost stop

Related issues

I also pave the way for #942

Has this been tested?

  • 👍 yes, I added tests to the test suite
  • 💭 no, because this PR is a draft and still needs work
  • 🙅 no, because this is not relevant here
  • 🙋 no, because I need help

@fflorent fflorent self-assigned this Aug 24, 2024
@fflorent fflorent marked this pull request as draft August 24, 2024 13:36
@fflorent fflorent marked this pull request as ready for review August 24, 2024 14:12
@fflorent fflorent requested a review from hexaltation August 28, 2024 14:30
Copy link
Collaborator

@hexaltation hexaltation left a comment

Choose a reason for hiding this comment

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

LGTM

Copy link
Member

@dsagal dsagal left a comment

Choose a reason for hiding this comment

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

Looks good, just one cosmetic question.

@@ -173,6 +178,9 @@ export class OIDCConfig {
this._protectionManager = new ProtectionsManager(enabledProtections);

this._redirectUrl = new URL(CALLBACK_URL, spHost).href;
custom.setHttpOptionsDefaults({
...(httpTimeout !== undefined ? {timeout: httpTimeout} : {}),
Copy link
Member

Choose a reason for hiding this comment

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

Why not more simply:

if (httpTimeout !== undefined) {
  custom.setHttpOptionsDefaults({timeout: httpTimeout});
}

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Hi @dsagal!

For slightly convenient reasons:

  1. I don't have to care whether the function should have been called or not in the test, it should if no exception has been raised: https://github.com/gristlabs/grist-core/pull/1177/files#diff-0467f3ff93b79307ee0beb1d72eea81866d60efa1efcfb8937d7154117e895f4R238
  2. I think of passing later more options to fix OIDC issuer behind a proxy cannot be accessed #942

If these are bad reasons to you, I may apply the change you request, I don't have much strong opinions.

Copy link
Member

Choose a reason for hiding this comment

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

Simplifying testing is a fine reason for me.

BTW, it looks like setHttpOptionsDefaults only pays attention to whether a property isn't undefined (rather than rely on hasOwnProperty or similar), so even this should work correctly: custom.setHttpOptionsDefaults({timeout: httpTimeout}) (without any checks). But I guess it's hard to test if this works, since the test only checks how setHttpOptionsDefaults is called, not its effect. Don't know if there is a better way: your call.

Copy link
Collaborator Author

@fflorent fflorent Sep 2, 2024

Choose a reason for hiding this comment

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

Yes, I agree with what you tell (we miss integration tests for this module 😬).
I prefer not taking any assumption (for now and the future) and keep this part as it is.

@fflorent
Copy link
Collaborator Author

fflorent commented Sep 3, 2024

Thanks @dsagal for your review!

I don't have the rights to merge. If there is no other change you expect from me, could you do that for me if that's OK for you?

@paulfitz paulfitz self-requested a review September 3, 2024 21:04
@dsagal dsagal merged commit b1a9e5f into gristlabs:main Sep 3, 2024
11 checks passed
hexaltation pushed a commit to hexaltation/grist-core that referenced this pull request Sep 24, 2024
Add IdP timeout, controlled by env var GRIST_OIDC_SP_HTTP_TIMEOUT

---------

Co-authored-by: atropos <sv7n@pm.me>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

5 participants