sansmoraxz commented on code in PR #4055:
URL: https://github.com/apache/iggy/pull/4055#discussion_r3980364060
##########
core/server/src/http/handlers.rs:
##########
@@ -1799,6 +1866,103 @@ pub(in crate::http) async fn delete_pat(
Ok(StatusCode::NO_CONTENT)
}
+/// Try external auth for an HTTP login. Returns `Some(result)` when the
+/// external service responded (grant or deny) or when a callout failure
+/// produces a terminal deny. Returns `None` when the caller should fall
+/// through to built-in credential verification.
+async fn try_external_auth_http_login(
+ state: &HttpInner,
+ credential_type: CredentialType,
+ username: &str,
+ credential_value: &str,
+ client_address: &str,
+) -> Option<Result<Json<IdentityInfo>, CustomError>> {
+ use configs::external_auth::ExternalAuthErrorStrategy;
+
+ let credential = state
+ .external_auth
+ .forward_credentials
+ .then(|| credential_value.to_owned());
+ let request = ExternalAuthRequest {
+ credential_type,
+ credential,
+ username: username.to_owned(),
+ transport: "http".to_owned(),
+ client_address: client_address.to_owned(),
+ };
+ let decision = match try_external_auth(&state.external_auth,
request).await {
+ Ok(Some(decision)) => decision,
+ Ok(None) => return None,
+ Err(_) => {
+ return match state.external_auth.on_error {
+ ExternalAuthErrorStrategy::Fallback => None,
+ ExternalAuthErrorStrategy::Deny =>
Some(Err(IggyError::Unauthenticated.into())),
+ };
+ }
+ };
+ Some(handle_http_auth_decision(state, decision))
+}
+
+fn handle_http_auth_decision(
+ state: &HttpInner,
+ decision: ExternalAuthDecision,
+) -> Result<Json<IdentityInfo>, CustomError> {
+ use consensus::MetadataHandle;
+
+ match decision {
+ ExternalAuthDecision::IggyUser { user_id } => {
+ if user_id == 0 {
+ tracing::warn!("external auth attempted to map login to root
user");
+ return Err(IggyError::Unauthenticated.into());
+ }
+ if is_synthetic_user_id(user_id) {
+ tracing::warn!(
+ user_id,
+ "external auth returned synthetic user_id in IggyUser
response"
+ );
+ return Err(IggyError::Unauthenticated.into());
+ }
+ let user_valid =
state.shard.plane.metadata().mux_stm.users().read(|users| {
+ users
+ .items
+ .get(user_id as usize)
+ .is_some_and(|u| u.status ==
iggy_common::UserStatus::Active)
+ });
+ if !user_valid {
+ return Err(IggyError::Unauthenticated.into());
+ }
+ issue_identity(state, user_id)
+ }
+ ExternalAuthDecision::InlineGrant {
+ principal: _,
+ permissions,
+ expires_at,
+ } => {
+ let Some(synthetic_user_id) = state.mint_synthetic_user_id() else {
+ tracing::error!("synthetic user ID space exhausted");
+ return Err(IggyError::Unauthenticated.into());
+ };
+ state
+ .synthetic_permissions
+ .borrow_mut()
+ .insert(synthetic_user_id, permissions);
+ let result = issue_identity_capped(state, synthetic_user_id,
expires_at);
Review Comment:
done
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]