sansmoraxz commented on code in PR #4055:
URL: https://github.com/apache/iggy/pull/4055#discussion_r3982900841


##########
core/server/src/dispatch/session_ops.rs:
##########
@@ -1309,6 +1312,192 @@ pub(in crate::dispatch) async fn 
handle_login_register_request<B, MJ, S, SB>(
     }
 
     let body_tail = &body[prefix_len..];
+
+    if external_auth.enabled {
+        let ext_request = if let Ok((wire_request, _)) =
+            LoginRegisterRequest::decode_after_prefix(version_info.clone(), 
body_tail)
+        {
+            crate::external_auth::ExternalAuthRequest {
+                credential_type: 
crate::external_auth::CredentialType::Password,
+                credential: if external_auth.forward_credentials {
+                    Some(wire_request.password.expose_secret().to_owned())
+                } else {
+                    None
+                },
+                username: wire_request.username.to_string(),
+                transport: "binary".to_owned(),
+                client_address: sessions
+                    .borrow()
+                    .connection_address(transport_client_id)
+                    .map_or_else(String::new, |a| a.to_string()),
+            }
+        } else if let Ok((wire_request, _)) =
+            
LoginRegisterWithPatRequest::decode_after_prefix(version_info.clone(), 
body_tail)
+        {
+            crate::external_auth::ExternalAuthRequest {
+                credential_type: 
crate::external_auth::CredentialType::PersonalAccessToken,
+                credential: if external_auth.forward_credentials {
+                    Some(wire_request.token.expose_secret().to_owned())
+                } else {
+                    None
+                },
+                username: String::new(),
+                transport: "binary".to_owned(),
+                client_address: sessions
+                    .borrow()
+                    .connection_address(transport_client_id)
+                    .map_or_else(String::new, |a| a.to_string()),
+            }
+        } else {
+            warn!(
+                transport_client_id,
+                "rejecting register request with unsupported payload shape"
+            );
+            send_login_eviction(
+                shard,
+                transport_client_id,
+                vsr_client_id,
+                EvictionReason::MalformedLogin,
+            )
+            .await;
+            return;
+        };
+
+        match crate::external_auth::try_external_auth(external_auth, 
ext_request).await {
+            Ok(Some(crate::external_auth::ExternalAuthDecision::IggyUser { 
user_id })) => {
+                if user_id == 0 {
+                    warn!(
+                        transport_client_id,
+                        "external auth attempted to map login to root user"
+                    );
+                    send_login_eviction(
+                        shard,
+                        transport_client_id,
+                        vsr_client_id,
+                        EvictionReason::InvalidCredentials,
+                    )
+                    .await;
+                    return;
+                }
+                if crate::external_auth::is_synthetic_user_id(user_id) {
+                    warn!(
+                        transport_client_id,
+                        user_id, "external auth returned synthetic user_id; 
rejecting"
+                    );
+                    send_login_eviction(
+                        shard,
+                        transport_client_id,
+                        vsr_client_id,
+                        EvictionReason::InvalidCredentials,
+                    )
+                    .await;
+                    return;
+                }
+                if let Err(error) = complete_login_register(
+                    shard,
+                    sessions,
+                    transport_client_id,
+                    vsr_client_id,
+                    request.header(),
+                    user_id,
+                    &version_info,
+                )
+                .await
+                {
+                    warn!(transport_client_id, error = %error, "external auth 
login failed");
+                    surface_login_failure(shard, transport_client_id, 
request.header(), &error)
+                        .await;
+                }
+                return;
+            }
+            Ok(Some(crate::external_auth::ExternalAuthDecision::InlineGrant {
+                principal,
+                permissions,
+                expires_at,
+            })) => {
+                let synthetic_id = 
sessions.borrow_mut().mint_synthetic_user_id();
+                let Some(synthetic_id) = synthetic_id else {
+                    warn!(
+                        transport_client_id,
+                        "synthetic user id pool exhausted; rejecting external 
auth login"
+                    );
+                    send_login_eviction(
+                        shard,
+                        transport_client_id,
+                        vsr_client_id,
+                        EvictionReason::InvalidCredentials,
+                    )
+                    .await;
+                    return;
+                };
+                // Set permissions BEFORE binding the session so that any
+                // request arriving immediately after bind already sees the
+                // grants. On bind failure we roll back.
+                sessions.borrow_mut().set_session_permissions(
+                    transport_client_id,
+                    synthetic_id,
+                    crate::external_auth::SessionPermissions {
+                        principal,
+                        permissions,
+                        expires_at,
+                    },
+                );
+                if let Err(error) = complete_login_register(
+                    shard,
+                    sessions,
+                    transport_client_id,
+                    vsr_client_id,
+                    request.header(),
+                    synthetic_id,
+                    &version_info,
+                )
+                .await
+                {
+                    warn!(transport_client_id, error = %error, "external auth 
inline grant login failed");
+                    sessions
+                        .borrow_mut()
+                        .clear_session_permissions(transport_client_id, 
synthetic_id);
+                    surface_login_failure(shard, transport_client_id, 
request.header(), &error)
+                        .await;
+                }
+                return;
+            }
+            Ok(Some(crate::external_auth::ExternalAuthDecision::Deny { reason 
})) => {
+                warn!(
+                    transport_client_id,
+                    reason = reason,
+                    "external auth denied login"
+                );
+                surface_login_failure(
+                    shard,
+                    transport_client_id,
+                    request.header(),
+                    &LoginRegisterError::ExternalAuthDenied(reason),
+                )
+                .await;
+                return;
+            }
+            Ok(None) => {
+                // on_error = fallback: fall through to built-in credential 
check
+            }
+            Err(error) => {
+                warn!(

Review Comment:
   External auth is now fallen through if local validation fails.



-- 
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]

Reply via email to