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

feat(NODE-5191): OIDC Auth Updates #3637

Merged
merged 93 commits into from May 4, 2023
Merged

feat(NODE-5191): OIDC Auth Updates #3637

merged 93 commits into from May 4, 2023

Conversation

durran
Copy link
Member

@durran durran commented Apr 13, 2023

Description

Updates OIDC implementation to the latest changes in mongodb/specifications#1381

What is changing?

  • Adds ALLOWED_HOSTS validation for connections using callback workflows.
  • OIDCMechanismServerStep1 becomes IdPServerInfo, removing endpoint fields.
  • OIDCRequestTokenResult becomes IdPServerResponse.
  • OIDCCallbackContext created to pass to the request and refresh callbacks.
  • Request and refresh functions now only take 2 arguments.
  • CallbackWorkflow is refactored to split behaviour around server commands and callbacks.
  • CallbackLockCache implements the locking of callbacks and function hashing.
  • TokenResultCache is simplified and is passed function hashes.
  • Updates to implement all new prose tests.
  • Added unit tests where applicable.
Is there new documentation needed for these changes?

None, this is still considered public preview, not stable.

What is the motivation for this change?

NODE-5191/DRIVERS-2415

mongodb/specifications#1381

Double check the following

  • Ran npm run check:lint script
  • Self-review completed using the steps outlined here
  • PR title follows the correct format: type(NODE-xxxx)[!]: description
    • Example: feat(NODE-1234)!: rewriting everything in coffeescript
  • Changes are covered by tests
  • New TODOs have a related JIRA ticket

src/cmap/auth/mongodb_oidc.ts Outdated Show resolved Hide resolved
src/utils.ts Outdated Show resolved Hide resolved
@durran durran force-pushed the NODE-5191 branch 2 times, most recently from 1c249b3 to fbc8550 Compare April 14, 2023 12:48
src/connection_string.ts Outdated Show resolved Hide resolved
src/utils.ts Outdated Show resolved Hide resolved
src/utils.ts Outdated Show resolved Hide resolved
@@ -1,16 +1,31 @@
import { Binary, BSON, type Document } from 'bson';
Copy link
Member Author

@durran durran Apr 27, 2023

Choose a reason for hiding this comment

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

Note to reviewers. This file is probably better off reviewing as a whole instead of looking at the diff. The entire class is pretty much refactored to separate the request/refresh function logic when dealing with the token cache and the actual saslStart/saslContinue commands sent to the server. It made more sense to separate them then to have them intertwined - I think the result is easier to understand.

src/utils.ts Outdated Show resolved Hide resolved
src/cmap/auth/mongodb_oidc.ts Outdated Show resolved Hide resolved
src/cmap/auth/mongodb_oidc.ts Outdated Show resolved Hide resolved
src/cmap/auth/mongodb_oidc/callback_workflow.ts Outdated Show resolved Hide resolved
@durran durran marked this pull request as ready for review April 28, 2023 17:15
@durran durran requested a review from addaleax April 28, 2023 17:15
Copy link
Contributor

@addaleax addaleax left a comment

Choose a reason for hiding this comment

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

Locking looks good! 🚀

src/cmap/auth/mongodb_oidc/callback_lock_cache.ts Outdated Show resolved Hide resolved
@@ -73,19 +81,10 @@ export class MongoDBOIDC extends AuthProvider {
* Authenticate using OIDC
*/
override async auth(authContext: AuthContext): Promise<void> {
const { connection, credentials, response, reauthenticating } = authContext;

if (response?.speculativeAuthenticate) {
Copy link
Member Author

Choose a reason for hiding this comment

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

Speculative auth is implemented in the the workflows.

/**
* A cache of request and refresh callbacks per server/user.
*/
export class CallbackLockCache {
Copy link
Member Author

Choose a reason for hiding this comment

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

This cache is now responsible for the hashing of the request and refresh functions, which is also then used by the TokenEntryCache. It also is responsible for wrapping the callbacks in a lock and storing them by the same cache key as the token results in the other cache. Main reasoning for not storing these in the other cache and creating a new one is that the callback functions have no expiration.

/**
* Ensure the callback is only executed one at a time.
*/
function withLock(callback: OIDCRequestFunction | OIDCRefreshFunction) {
Copy link
Member Author

@durran durran Apr 28, 2023

Choose a reason for hiding this comment

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

This ensures a request or refresh function cannot be entered simultaneously by different code paths, by chaining on to the end of each previous promise. Inspired by those clever dev tools folks: https://github.com/mongodb-js/oidc-plugin/blob/ca6bb4fdddabfd651ea2d544b2f9bdcf2095fe71/src/util.ts#L62-L80

/**
* Get the hash string for the request and refresh functions.
*/
function hashFunctions(requestFn: OIDCRequestFunction, refreshFn?: OIDCRefreshFunction): string {
Copy link
Member Author

Choose a reason for hiding this comment

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

This is the same as before, just moved to this cache impl from the other.

@@ -3,6 +3,9 @@ import { readFile } from 'fs/promises';
import { MongoAWSError } from '../../../error';
import { ServiceWorkflow } from './service_workflow';

/** Error for when the token is missing in the environment. */
const TOKEN_MISSING_ERROR = 'AWS_WEB_IDENTITY_TOKEN_FILE must be set in the environment.';
Copy link
Member Author

Choose a reason for hiding this comment

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

This and other string constants just a simple refactoring of any non-interpolated string being a constant.

@nbbeeken nbbeeken self-assigned this May 2, 2023
@nbbeeken nbbeeken added the Primary Review In Review with primary reviewer, not yet ready for team's eyes label May 2, 2023
src/cmap/auth/mongodb_oidc/callback_lock_cache.ts Outdated Show resolved Hide resolved
src/cmap/auth/mongodb_oidc/callback_lock_cache.ts Outdated Show resolved Hide resolved
src/cmap/auth/mongodb_oidc/callback_lock_cache.ts Outdated Show resolved Hide resolved
src/cmap/auth/mongodb_oidc/callback_lock_cache.ts Outdated Show resolved Hide resolved
test/manual/mongodb_oidc.prose.test.ts Outdated Show resolved Hide resolved
test/manual/mongodb_oidc.prose.test.ts Show resolved Hide resolved
test/manual/mongodb_oidc.prose.test.ts Outdated Show resolved Hide resolved
test/manual/mongodb_oidc.prose.test.ts Outdated Show resolved Hide resolved
Copy link
Contributor

@nbbeeken nbbeeken left a comment

Choose a reason for hiding this comment

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

just username and sleep outstanding comments

@nbbeeken nbbeeken added Team Review Needs review from team and removed Primary Review In Review with primary reviewer, not yet ready for team's eyes labels May 3, 2023
@durran
Copy link
Member Author

durran commented May 3, 2023

Patch on latest commit without all the other clutter: https://spruce.mongodb.com/version/6452c353a4cf47cc42d9b7f5/tasks?sorts=STATUS%3AASC%3BBASE_STATUS%3ADESC

@nbbeeken nbbeeken merged commit c52a4ed into main May 4, 2023
18 of 21 checks passed
@nbbeeken nbbeeken deleted the NODE-5191 branch May 4, 2023 14:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Team Review Needs review from team
Projects
None yet
3 participants