Skip to content

Conversation

@aldevv
Copy link
Contributor

@aldevv aldevv commented Jan 23, 2026

Summary by CodeRabbit

  • New Features

    • Added Multi-Factor Authentication (MFA) support when creating Tableau user accounts.
    • Added option to specify which SAML identity provider configuration to use, with automatic selection when only one exists.
    • Improved handling and clearer errors for environments with multiple identity provider configurations.
  • Style

    • Minor formatting cleanup to an existing role description.

✏️ Tip: You can customize this high-level summary in your review settings.

@linear
Copy link

linear bot commented Jan 23, 2026

@coderabbitai
Copy link

coderabbitai bot commented Jan 23, 2026

Walkthrough

Adds Tableau MFA and SAML IDP selection: new account schema fields, IDP discovery/selection logic during account creation, a client API to list site IDP configurations, and model changes to carry auth settings and IDP ids. Also a minor formatting tweak to the siteRole description.

Changes

Cohort / File(s) Summary
Connector Schema
pkg/connector/connector.go
Added account creation fields withMFA (bool) and idpConfigurationName (string) to the Tableau connector schema; minor formatting adjustment to the siteRole description.
Account Creation & IDP Selection
pkg/connector/user.go
Added selectIDPConfiguration() and helpers (findIDPByName, buildMultipleIDPError), read withMFA, set auth_setting when MFA is requested, resolve and include idpConfigurationId when appropriate, and wrap related errors with uhttp codes.
Tableau API Client
pkg/tableau/client.go
Refactored AddUserToSite() to build a user payload including conditional idpConfigurationId or authSetting. Added ListIdpConfigurations(ctx) to fetch site auth configurations.
Data Models
pkg/tableau/models.go
Added AuthSetting to User, extended CreateUserRequest with AuthSetting and IdpConfigurationId, and introduced IdpConfiguration type with IdpConfigurationId, IdpConfigurationName, AuthSetting, and Enabled.

Sequence Diagram

sequenceDiagram
    participant U as User
    participant C as Connector
    participant T as Tableau API Client
    participant S as Tableau Site

    U->>C: Create account (email, siteRole, withMFA?, idpConfigurationName?)
    C->>C: read withMFA & idpConfigurationName

    alt withMFA == true
        C->>C: set authSetting = "TableauIDWithMFA"
    else withMFA == false
        C->>T: ListIdpConfigurations(ctx)
        T->>S: GET /sites/{siteId}/site-auth-configurations
        S-->>T: return configurations
        T-->>C: IdpConfiguration list
        alt single enabled SAML IDP
            C->>C: choose that IdP id
        else idpConfigurationName provided
            C->>C: find matching IdP by name
        else multiple IDPs & no name
            C-->>U: error (specify idpConfigurationName)
        end
    end

    C->>T: AddUserToSite(user{email, siteRole, authSetting?, idpConfigurationId?})
    T->>S: POST /sites/{siteId}/users
    S-->>T: user created
    T-->>C: success
    C-->>U: account created / error
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Poem

🐇 I nibble on configs by moonlit code,
MFA whispers down the new road,
I sniff the IDPs, one or a crowd,
Give a name or choose the lone cloud,
Hooray — users land safe and proud. 🥕

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 20.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately reflects the main objective: adding SAML as a default authentication method when creating users, which is demonstrated through the new idpConfigurationName field and IDP selection logic.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@pkg/connector/user.go`:
- Around line 224-233: The function buildMultipleIDPError builds a dynamic error
message into builder and then calls fmt.Errorf(builder.String()), which is
unsafe for non-constant format strings; replace the final
fmt.Errorf(builder.String()) with errors.New(builder.String()) (or
fmt.Errorf("%s", builder.String())) and add the "errors" import to the file so
the function returns a plain error created from the constructed string;
reference buildMultipleIDPError and the final return statement to locate and
update the code.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@pkg/connector/user.go`:
- Around line 178-195: The code currently returns the sole
enabledSAMLConfigs[0].IdpConfigurationId without honoring idpConfigName; change
the logic in the selection block so that when len(enabledSAMLConfigs) == 1 you
still check idpConfigName: if idpConfigName is empty, return
enabledSAMLConfigs[0].IdpConfigurationId, otherwise call
findIDPByName(enabledSAMLConfigs, idpConfigName) and return an InvalidArgument
error (use uhttp.WrapErrors with buildMultipleIDPError) if the name doesn't
match, otherwise return the matched selectedConfig.IdpConfigurationId; this
preserves current behavior for empty names but surfaces typos/misconfigurations
when a name is provided.

Comment on lines +178 to +195
if len(enabledSAMLConfigs) == 0 {
return "", fmt.Errorf("baton-tableau: you need to pass the MFA flag since no IDP is configured in Tableau")
}

if len(enabledSAMLConfigs) == 1 {
return enabledSAMLConfigs[0].IdpConfigurationId, nil
}

if idpConfigName == "" {
return "", uhttp.WrapErrors(codes.InvalidArgument, "multiple SAML IDPs available", buildMultipleIDPError(enabledSAMLConfigs))
}

selectedConfig, err := findIDPByName(enabledSAMLConfigs, idpConfigName)
if err != nil {
return "", uhttp.WrapErrors(codes.InvalidArgument, fmt.Sprintf("IDP configuration '%s' not found", idpConfigName), buildMultipleIDPError(enabledSAMLConfigs))
}

return selectedConfig.IdpConfigurationId, nil
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Honor explicit idpConfigurationName even when only one config exists.
If a caller provides idpConfigurationName but there’s only one enabled SAML config, the current logic ignores the name and silently selects the only config. That can mask typos or misconfigurations.

🔧 Suggested adjustment
-	if len(enabledSAMLConfigs) == 1 {
-		return enabledSAMLConfigs[0].IdpConfigurationId, nil
-	}
-
-	if idpConfigName == "" {
-		return "", uhttp.WrapErrors(codes.InvalidArgument, "multiple SAML IDPs available", buildMultipleIDPError(enabledSAMLConfigs))
-	}
-
-	selectedConfig, err := findIDPByName(enabledSAMLConfigs, idpConfigName)
-	if err != nil {
-		return "", uhttp.WrapErrors(codes.InvalidArgument, fmt.Sprintf("IDP configuration '%s' not found", idpConfigName), buildMultipleIDPError(enabledSAMLConfigs))
-	}
-
-	return selectedConfig.IdpConfigurationId, nil
+	if idpConfigName != "" {
+		selectedConfig, err := findIDPByName(enabledSAMLConfigs, idpConfigName)
+		if err != nil {
+			return "", uhttp.WrapErrors(codes.InvalidArgument, fmt.Sprintf("IDP configuration '%s' not found", idpConfigName), buildMultipleIDPError(enabledSAMLConfigs))
+		}
+		return selectedConfig.IdpConfigurationId, nil
+	}
+
+	if len(enabledSAMLConfigs) == 1 {
+		return enabledSAMLConfigs[0].IdpConfigurationId, nil
+	}
+
+	return "", uhttp.WrapErrors(codes.InvalidArgument, "multiple SAML IDPs available", buildMultipleIDPError(enabledSAMLConfigs))
🤖 Prompt for AI Agents
In `@pkg/connector/user.go` around lines 178 - 195, The code currently returns the
sole enabledSAMLConfigs[0].IdpConfigurationId without honoring idpConfigName;
change the logic in the selection block so that when len(enabledSAMLConfigs) ==
1 you still check idpConfigName: if idpConfigName is empty, return
enabledSAMLConfigs[0].IdpConfigurationId, otherwise call
findIDPByName(enabledSAMLConfigs, idpConfigName) and return an InvalidArgument
error (use uhttp.WrapErrors with buildMultipleIDPError) if the name doesn't
match, otherwise return the matched selectedConfig.IdpConfigurationId; this
preserves current behavior for empty names but surfaces typos/misconfigurations
when a name is provided.

@aldevv aldevv requested review from a team and btipling January 23, 2026 21:32
@aldevv aldevv requested a review from a team January 26, 2026 15:57
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.

3 participants