Skip to content

test: add full OIDC fake IDP #9317

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

Merged
merged 20 commits into from
Aug 25, 2023
Merged

test: add full OIDC fake IDP #9317

merged 20 commits into from
Aug 25, 2023

Conversation

Emyrk
Copy link
Member

@Emyrk Emyrk commented Aug 24, 2023

What this does

This adds the new fake OIDC provider and refactors existing tests, however we should still write more tests!

This creates a realistic IDP for OIDC testing. It handles all the endpoints expected of an IDP, and enforces the codes/states/tokens it returns. This was implemented because our OIDC logic is growing in complexity, and we need a proper IDP to run tests against. The existing mock was very relaxed, and did not support some features like refreshing.

Our old fake was lacking a few areas:

  • Always succeeded, even if the OIDC client passed invalid creds
  • Did not validate client_id and client_secrets
  • Did not support refreshing (fix(coderd): prevent oidc refresh being ignored #9293) (This PR adds a unit test for this!)
  • Did not test actual oauth2 ctx. We have to pass a certain oauth2.HTTPClient context value for proper auth in some cases (PKI)
  • Didn't actually test the full OIDC flow. It always started after the user clicks "allow" on the OIDC page, skipping the initial redirect.

The new fake is essentially an IDP that we can continue to expand to cover more cases and more regressions.

Existing unit tests

All existing OIDC unit tests were moved to the new fake.

Future Work

More tests

We should write more tests around our oauth httpmw handler and api key extract. We can probably do it without starting a full Coderd and getting much faster tests.

I think our current tests do not test all of the possible edge cases and combinations.

Quicker Tests

The new IDP supports a complete in memory HTTP client that never makes HTTP calls. This makes things quicker and easier to debug. Unfortunately making coderdtest.New use this HTTP client was non-trivial without refactoring that. To avoid touching more things, I am using the oidctest.WithServing() to spin up a httptest.Server which handles real network requests.

Make refresh tokens sync settings

I discovered in doing this that our group and role syncs do not happen on oauth refresh tokens. This should be remedied. Unit tests that check this have been skipped.

@Emyrk Emyrk marked this pull request as ready for review August 24, 2023 21:07
Copy link
Member

@johnstcn johnstcn left a comment

Choose a reason for hiding this comment

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

Really nice work @Emyrk ! I think this will really help us improve our confidence in our OIDC flows.

Some comments, see below:

"access_token": f.newToken(email),
"refresh_token": refreshToken,
"token_type": "Bearer",
"expires_in": int64((time.Minute * 5).Seconds()),
Copy link
Member

Choose a reason for hiding this comment

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

Follow-up: this could be a useful config knob down the line.

Copy link
Member Author

Choose a reason for hiding this comment

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

Agreed. We can add more knobs as we make more unit tests. At the moment, the time stuff can be a bit tricky, so instead I just made that ExpireOauthToken which just changes the expiry to the past.

It was easier than trying to sync some clock manipulation in the various places we need.

@Emyrk Emyrk merged commit d9d4d74 into main Aug 25, 2023
@Emyrk Emyrk deleted the stevenmasley/full_oidc_fake branch August 25, 2023 19:34
@github-actions github-actions bot locked and limited conversation to collaborators Aug 25, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants