mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-23 00:41:40 +00:00
fixing duplicated provider detection
This commit is contained in:
parent
daa6ab6cdb
commit
bffcc0ee0b
4 changed files with 86 additions and 48 deletions
|
|
@ -2,7 +2,7 @@ import React, { useEffect, useState } from "react";
|
|||
import { Modal, Form, Input, Button as Button2, Select, Checkbox } from "antd";
|
||||
import { Text, TextInput } from "@tremor/react";
|
||||
import { getSSOSettings, updateSSOSettings } from "./networking";
|
||||
import { detectSSOProvider } from "./Settings/AdminSettings/SSOSettings/utils";
|
||||
import { detectSSOProvider, extractRoleMappingFields } from "./Settings/AdminSettings/SSOSettings/utils";
|
||||
import NotificationsManager from "./molecules/notifications_manager";
|
||||
import { parseErrorMessage } from "./shared/errorUtils";
|
||||
|
||||
|
|
@ -116,28 +116,7 @@ const SSOModals: React.FC<SSOModalsProps> = ({
|
|||
const ssoData = await getSSOSettings(accessToken);
|
||||
if (ssoData && ssoData.values) {
|
||||
const selectedProvider = detectSSOProvider(ssoData.values);
|
||||
|
||||
// Extract role mappings if they exist
|
||||
let roleMappingFields = {};
|
||||
if (ssoData.values.role_mappings) {
|
||||
const roleMappings = ssoData.values.role_mappings;
|
||||
|
||||
// Helper function to join arrays into comma-separated strings
|
||||
const joinTeams = (teams: string[] | undefined): string => {
|
||||
if (!teams || teams.length === 0) return "";
|
||||
return teams.join(", ");
|
||||
};
|
||||
|
||||
roleMappingFields = {
|
||||
use_role_mappings: true,
|
||||
group_claim: roleMappings.group_claim,
|
||||
default_role: roleMappings.default_role || "internal_user",
|
||||
proxy_admin_teams: joinTeams(roleMappings.roles?.proxy_admin),
|
||||
admin_viewer_teams: joinTeams(roleMappings.roles?.proxy_admin_viewer),
|
||||
internal_user_teams: joinTeams(roleMappings.roles?.internal_user),
|
||||
internal_viewer_teams: joinTeams(roleMappings.roles?.internal_user_viewer),
|
||||
};
|
||||
}
|
||||
const roleMappingFields = extractRoleMappingFields(ssoData.values.role_mappings);
|
||||
|
||||
// Set form values with existing data (excluding UI access control fields)
|
||||
const formValues = {
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import React, { useEffect } from "react";
|
|||
import BaseSSOSettingsForm from "./BaseSSOSettingsForm";
|
||||
import NotificationsManager from "@/components/molecules/notifications_manager";
|
||||
import { parseErrorMessage } from "@/components/shared/errorUtils";
|
||||
import { detectSSOProvider, processSSOSettingsPayload } from "../utils";
|
||||
import { detectSSOProvider, extractRoleMappingFields, processSSOSettingsPayload } from "../utils";
|
||||
import { useSSOSettings } from "@/app/(dashboard)/hooks/sso/useSSOSettings";
|
||||
import { useEditSSOSettings } from "@/app/(dashboard)/hooks/sso/useEditSSOSettings";
|
||||
|
||||
|
|
@ -27,28 +27,7 @@ const EditSSOSettingsModal: React.FC<EditSSOSettingsModalProps> = ({ isVisible,
|
|||
|
||||
// Determine which SSO provider is configured
|
||||
const selectedProvider = detectSSOProvider(ssoData.values);
|
||||
|
||||
// Extract role mappings if they exist
|
||||
let roleMappingFields = {};
|
||||
if (ssoData.values.role_mappings) {
|
||||
const roleMappings = ssoData.values.role_mappings;
|
||||
|
||||
// Helper function to join arrays into comma-separated strings
|
||||
const joinTeams = (teams: string[] | undefined): string => {
|
||||
if (!teams || teams.length === 0) return "";
|
||||
return teams.join(", ");
|
||||
};
|
||||
|
||||
roleMappingFields = {
|
||||
use_role_mappings: true,
|
||||
group_claim: roleMappings.group_claim,
|
||||
default_role: roleMappings.default_role || "internal_user",
|
||||
proxy_admin_teams: joinTeams(roleMappings.roles?.proxy_admin),
|
||||
admin_viewer_teams: joinTeams(roleMappings.roles?.proxy_admin_viewer),
|
||||
internal_user_teams: joinTeams(roleMappings.roles?.internal_user),
|
||||
internal_viewer_teams: joinTeams(roleMappings.roles?.internal_user_viewer),
|
||||
};
|
||||
}
|
||||
const roleMappingFields = extractRoleMappingFields(ssoData.values.role_mappings);
|
||||
|
||||
// Extract team mappings if they exist
|
||||
let teamMappingFields = {};
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import { processSSOSettingsPayload } from "./utils";
|
||||
import { extractRoleMappingFields, processSSOSettingsPayload } from "./utils";
|
||||
import { RoleMappings } from "@/app/(dashboard)/hooks/sso/useSSOSettings";
|
||||
import { describe, it, expect } from "vitest";
|
||||
|
||||
describe("processSSOSettingsPayload", () => {
|
||||
|
|
@ -429,3 +430,60 @@ describe("processSSOSettingsPayload", () => {
|
|||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("extractRoleMappingFields", () => {
|
||||
it("returns an empty object when role_mappings is null/undefined", () => {
|
||||
expect(extractRoleMappingFields(null)).toEqual({});
|
||||
expect(extractRoleMappingFields(undefined)).toEqual({});
|
||||
});
|
||||
|
||||
it("joins role arrays into comma-separated strings", () => {
|
||||
const roleMappings: RoleMappings = {
|
||||
provider: "okta",
|
||||
group_claim: "groups",
|
||||
default_role: "internal_user",
|
||||
roles: {
|
||||
proxy_admin: ["admin1", "admin2"],
|
||||
proxy_admin_viewer: ["viewer1"],
|
||||
internal_user: ["user1", "user2"],
|
||||
internal_user_viewer: ["ro1"],
|
||||
},
|
||||
};
|
||||
|
||||
expect(extractRoleMappingFields(roleMappings)).toEqual({
|
||||
use_role_mappings: true,
|
||||
group_claim: "groups",
|
||||
default_role: "internal_user",
|
||||
proxy_admin_teams: "admin1, admin2",
|
||||
admin_viewer_teams: "viewer1",
|
||||
internal_user_teams: "user1, user2",
|
||||
internal_viewer_teams: "ro1",
|
||||
});
|
||||
});
|
||||
|
||||
it("emits empty strings for missing role arrays", () => {
|
||||
const roleMappings = {
|
||||
provider: "generic",
|
||||
group_claim: "groups",
|
||||
default_role: "proxy_admin",
|
||||
roles: {},
|
||||
} as unknown as RoleMappings;
|
||||
|
||||
const result = extractRoleMappingFields(roleMappings);
|
||||
expect(result.proxy_admin_teams).toBe("");
|
||||
expect(result.admin_viewer_teams).toBe("");
|
||||
expect(result.internal_user_teams).toBe("");
|
||||
expect(result.internal_viewer_teams).toBe("");
|
||||
});
|
||||
|
||||
it("falls back to internal_user when default_role is missing", () => {
|
||||
const roleMappings = {
|
||||
provider: "okta",
|
||||
group_claim: "groups",
|
||||
default_role: "",
|
||||
roles: { proxy_admin: [], proxy_admin_viewer: [], internal_user: [], internal_user_viewer: [] },
|
||||
} as unknown as RoleMappings;
|
||||
|
||||
expect(extractRoleMappingFields(roleMappings).default_role).toBe("internal_user");
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { SSOSettingsValues } from "@/app/(dashboard)/hooks/sso/useSSOSettings";
|
||||
import { RoleMappings, SSOSettingsValues } from "@/app/(dashboard)/hooks/sso/useSSOSettings";
|
||||
|
||||
/**
|
||||
* Processes SSO settings form values and transforms them into the payload format expected by the API
|
||||
|
|
@ -67,6 +67,28 @@ export const processSSOSettingsPayload = (formValues: Record<string, any>): Reco
|
|||
return payload;
|
||||
};
|
||||
|
||||
// Build form fields to prefill the role mappings section from existing SSO settings.
|
||||
// Shared by Add (SSOModals) and Edit (EditSSOSettingsModal) flows so detection and
|
||||
// extraction rules stay in one place.
|
||||
export const extractRoleMappingFields = (roleMappings: RoleMappings | null | undefined): Record<string, any> => {
|
||||
if (!roleMappings) return {};
|
||||
|
||||
const joinTeams = (teams: string[] | undefined): string => {
|
||||
if (!teams || teams.length === 0) return "";
|
||||
return teams.join(", ");
|
||||
};
|
||||
|
||||
return {
|
||||
use_role_mappings: true,
|
||||
group_claim: roleMappings.group_claim,
|
||||
default_role: roleMappings.default_role || "internal_user",
|
||||
proxy_admin_teams: joinTeams(roleMappings.roles?.proxy_admin),
|
||||
admin_viewer_teams: joinTeams(roleMappings.roles?.proxy_admin_viewer),
|
||||
internal_user_teams: joinTeams(roleMappings.roles?.internal_user),
|
||||
internal_viewer_teams: joinTeams(roleMappings.roles?.internal_user_viewer),
|
||||
};
|
||||
};
|
||||
|
||||
// Determine the SSO provider based on the configuration
|
||||
export const detectSSOProvider = (values: SSOSettingsValues): string | null => {
|
||||
if (values.google_client_id) return "google";
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue