Skip to content

[PECOBLR-2089] fix(rust/oauth): Test suite fixes from final validation#324

Draft
vikrantpuppala wants to merge 20 commits intoadbc-drivers:mainfrom
vikrantpuppala:stack/pr-final-validation
Draft

[PECOBLR-2089] fix(rust/oauth): Test suite fixes from final validation#324
vikrantpuppala wants to merge 20 commits intoadbc-drivers:mainfrom
vikrantpuppala:stack/pr-final-validation

Conversation

@vikrantpuppala
Copy link
Collaborator

@vikrantpuppala vikrantpuppala commented Mar 8, 2026

🥞 Stacked PR

Use this link to review incremental changes.


Summary

Minor fixes discovered while running the full test suite:

  • Fixed callback server HTML response formatting
  • Fixed M2M provider error handling edge case
  • Updated database.rs auth provider creation to use AuthConfig consistently
  • Removed E2E OAuth test instructions from CLAUDE.md

vikrantpuppala and others added 9 commits March 7, 2026 08:48
Design for OAuth 2.0 authentication in the Rust ADBC driver covering
Authorization Code + PKCE (U2M) and Client Credentials (M2M) flows,
including token refresh state machine, file-based caching, and OIDC
discovery.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Use oauth2 crate for PKCE, token exchange, client credentials,
  and refresh token flows. Eliminates hand-rolled pkce.rs module.
- Reuse DatabricksHttpClient for token endpoint calls via
  execute_without_auth(), giving unified retry/timeout/pooling.
- Two-phase initialization: HTTP client created first, auth provider
  set later via OnceLock (matching SeaClient's reader_factory pattern).
- OAuth providers route token requests through the shared HTTP client
  with a custom oauth2 HTTP function adapter.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add AuthMechanism enum: 0=Pat, 11=OAuth (matches ODBC AuthMech)
- Add AuthFlow enum: 0=TokenPassthrough, 1=ClientCredentials, 2=Browser
  (matches ODBC Auth_Flow)
- Both mechanism and flow are mandatory, no auto-detection
- Accept numeric values only, parsed via TryFrom
- Use unified DatabricksHttpClient with two-phase init
- Adopt oauth2 crate for protocol-level operations

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Fixes:
- databricks.oauth.token_endpoint -> databricks.auth.token_endpoint
- Config type Int/String -> Int (numeric only)
- Clarify oauth2 HTTP adapter needs thin conversion layer
- Architecture diagram shows M2M/U2M using execute_without_auth()
- Token passthrough (flow=0) documents no auto-refresh
- Stale threshold uses initial_TTL computed once at acquisition
- Deduplicate http.rs changes (reference Concurrency section)

Test strategy additions:
- Wiremock integration tests for full M2M flow with mocked HTTP
- Database config validation tests for enum parsing and new_connection
- HTTP client two-phase init tests for OnceLock lifecycle

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
3-task breakdown covering foundation + HTTP client changes,
M2M provider, and U2M provider with full test coverage.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
scopes: Vec<String>,
}

#[allow(dead_code)] // Used in Phase 3 (U2M)
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

why this? i think this is used now? we should fix all such instances across

<p>You can close this tab and return to your application.</p>
</div>
</body>
</html>"#;
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

let's make this page simpler, no need for fancy fonts colours, check marks, etc.

<p>An error occurred during authentication. You can close this tab and try again.</p>
</div>
</body>
</html>"#;
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

use simple pages

// Use block_in_place to avoid blocking the runtime if we're in one,
// and get the handle to block_on the async operation
tokio::task::block_in_place(|| {
tokio::runtime::Handle::current().block_on(async {
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

shouldn't this happen async? check all instances and see if we're handling this correctly

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

should we just remove this?

Comment on lines +35 to +88
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[repr(u8)]
pub enum AuthMechanism {
/// Personal access token (no OAuth). Config value: 0
Pat = 0,
/// OAuth 2.0 -- requires AuthFlow to select the specific flow. Config value: 11
OAuth = 11,
}

impl TryFrom<i64> for AuthMechanism {
type Error = crate::error::Error;

fn try_from(value: i64) -> std::result::Result<Self, Self::Error> {
match value {
0 => Ok(AuthMechanism::Pat),
11 => Ok(AuthMechanism::OAuth),
_ => Err(DatabricksErrorHelper::invalid_argument().message(format!(
"Invalid auth mechanism value: {}. Valid values are 0 (PAT) or 11 (OAuth)",
value
))),
}
}
}

/// OAuth authentication flow -- selects the specific OAuth grant type.
/// Config values match the ODBC driver's Auth_Flow numeric codes.
/// Only applicable when AuthMechanism is OAuth.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[repr(u8)]
pub enum AuthFlow {
/// Use a pre-obtained OAuth access token directly. Config value: 0
TokenPassthrough = 0,
/// M2M: client credentials grant for service principals. Config value: 1
ClientCredentials = 1,
/// U2M: browser-based authorization code + PKCE. Config value: 2
Browser = 2,
}

impl TryFrom<i64> for AuthFlow {
type Error = crate::error::Error;

fn try_from(value: i64) -> std::result::Result<Self, Self::Error> {
match value {
0 => Ok(AuthFlow::TokenPassthrough),
1 => Ok(AuthFlow::ClientCredentials),
2 => Ok(AuthFlow::Browser),
_ => Err(DatabricksErrorHelper::invalid_argument().message(format!(
"Invalid auth flow value: {}. Valid values are 0 (token passthrough), 1 (client credentials), or 2 (browser)",
value
))),
}
}
}

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

is this the right place to define this? seems like database is becoming bloated?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

overall would be great if we can abstract out the auth related stuff in this file so that it is less bloated

rust/CLAUDE.md Outdated
- Test names: `test_<function>_<scenario>`
- E2E tests that require real Databricks connection should be marked with `#[ignore]`

#### Running E2E OAuth Tests
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

don't think we need this section

@vikrantpuppala vikrantpuppala force-pushed the stack/pr-final-validation branch from 0e69f4a to 13f8c28 Compare March 9, 2026 05:18
@vikrantpuppala vikrantpuppala changed the title Run full test suite and fix any failures\n\nTask ID: task-5.1-final-validation [PECOBLR-2089] fix(rust/oauth): Test suite fixes from final validation Mar 9, 2026
@vikrantpuppala vikrantpuppala force-pushed the stack/pr-final-validation branch from 13f8c28 to f87df69 Compare March 9, 2026 09:47
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.

1 participant