Merge pull request #4501 from Infisical/ENG-3677

improvement(google-oauth-enforcement): prevent conflicting sso enforcement configuration
This commit is contained in:
Scott Wilson
2025-09-09 14:44:01 -07:00
committed by GitHub
12 changed files with 251 additions and 46 deletions
@@ -127,6 +127,20 @@ export const ldapConfigServiceFactory = ({
message: message:
"Failed to create LDAP configuration due to plan restriction. Upgrade plan to create LDAP configuration." "Failed to create LDAP configuration due to plan restriction. Upgrade plan to create LDAP configuration."
}); });
const org = await orgDAL.findOrgById(orgId);
if (!org) {
throw new NotFoundError({ message: `Could not find organization with ID "${orgId}"` });
}
if (org.googleSsoAuthEnforced && isActive) {
throw new BadRequestError({
message:
"You cannot enable LDAP SSO while Google OAuth is enforced. Disable Google OAuth enforcement to enable LDAP SSO."
});
}
const { encryptor } = await kmsService.createCipherPairWithDataKey({ const { encryptor } = await kmsService.createCipherPairWithDataKey({
type: KmsDataKey.Organization, type: KmsDataKey.Organization,
orgId orgId
@@ -233,6 +247,19 @@ export const ldapConfigServiceFactory = ({
"Failed to update LDAP configuration due to plan restriction. Upgrade plan to update LDAP configuration." "Failed to update LDAP configuration due to plan restriction. Upgrade plan to update LDAP configuration."
}); });
const org = await orgDAL.findOrgById(orgId);
if (!org) {
throw new NotFoundError({ message: `Could not find organization with ID "${orgId}"` });
}
if (org.googleSsoAuthEnforced && isActive) {
throw new BadRequestError({
message:
"You cannot enable LDAP SSO while Google OAuth is enforced. Disable Google OAuth enforcement to enable LDAP SSO."
});
}
const updateQuery: TLdapConfigsUpdate = { const updateQuery: TLdapConfigsUpdate = {
isActive, isActive,
url, url,
@@ -499,6 +499,13 @@ export const oidcConfigServiceFactory = ({
); );
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Edit, OrgPermissionSubjects.Sso); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Edit, OrgPermissionSubjects.Sso);
if (org.googleSsoAuthEnforced && isActive) {
throw new BadRequestError({
message:
"You cannot enable OIDC SSO while Google OAuth is enforced. Disable Google OAuth enforcement to enable OIDC SSO."
});
}
const { encryptor } = await kmsService.createCipherPairWithDataKey({ const { encryptor } = await kmsService.createCipherPairWithDataKey({
type: KmsDataKey.Organization, type: KmsDataKey.Organization,
orgId: org.id orgId: org.id
@@ -586,6 +593,13 @@ export const oidcConfigServiceFactory = ({
); );
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Create, OrgPermissionSubjects.Sso); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Create, OrgPermissionSubjects.Sso);
if (org.googleSsoAuthEnforced && isActive) {
throw new BadRequestError({
message:
"You cannot enable OIDC SSO while Google OAuth is enforced. Disable Google OAuth enforcement to enable OIDC SSO."
});
}
const { encryptor } = await kmsService.createCipherPairWithDataKey({ const { encryptor } = await kmsService.createCipherPairWithDataKey({
type: KmsDataKey.Organization, type: KmsDataKey.Organization,
orgId: org.id orgId: org.id
@@ -82,6 +82,19 @@ export const samlConfigServiceFactory = ({
"Failed to create SAML SSO configuration due to plan restriction. Upgrade plan to create SSO configuration." "Failed to create SAML SSO configuration due to plan restriction. Upgrade plan to create SSO configuration."
}); });
const org = await orgDAL.findOrgById(orgId);
if (!org) {
throw new NotFoundError({ message: `Could not find organization with ID "${orgId}"` });
}
if (org.googleSsoAuthEnforced && isActive) {
throw new BadRequestError({
message:
"You cannot enable SAML SSO while Google OAuth is enforced. Disable Google OAuth enforcement to enable SAML SSO."
});
}
const { encryptor } = await kmsService.createCipherPairWithDataKey({ const { encryptor } = await kmsService.createCipherPairWithDataKey({
type: KmsDataKey.Organization, type: KmsDataKey.Organization,
orgId orgId
@@ -120,6 +133,19 @@ export const samlConfigServiceFactory = ({
"Failed to update SAML SSO configuration due to plan restriction. Upgrade plan to update SSO configuration." "Failed to update SAML SSO configuration due to plan restriction. Upgrade plan to update SSO configuration."
}); });
const org = await orgDAL.findOrgById(orgId);
if (!org) {
throw new NotFoundError({ message: `Could not find organization with ID "${orgId}"` });
}
if (org.googleSsoAuthEnforced && isActive) {
throw new BadRequestError({
message:
"Cannot enable SAML SSO while Google OAuth is enforced. Disable Google OAuth enforcement to enable SAML SSO."
});
}
const updateQuery: TSamlConfigsUpdate = { authProvider, isActive, lastUsed: null }; const updateQuery: TSamlConfigsUpdate = { authProvider, isActive, lastUsed: null };
const { encryptor } = await kmsService.createCipherPairWithDataKey({ const { encryptor } = await kmsService.createCipherPairWithDataKey({
type: KmsDataKey.Organization, type: KmsDataKey.Organization,
+2 -1
View File
@@ -1,9 +1,10 @@
import { Cluster, Redis } from "ioredis";
import { buildRedisFromConfig, TRedisConfigKeys } from "@app/lib/config/redis"; import { buildRedisFromConfig, TRedisConfigKeys } from "@app/lib/config/redis";
import { pgAdvisoryLockHashText } from "@app/lib/crypto/hashtext"; import { pgAdvisoryLockHashText } from "@app/lib/crypto/hashtext";
import { applyJitter } from "@app/lib/dates"; import { applyJitter } from "@app/lib/dates";
import { delay as delayMs } from "@app/lib/delay"; import { delay as delayMs } from "@app/lib/delay";
import { ExecutionResult, Redlock, Settings } from "@app/lib/red-lock"; import { ExecutionResult, Redlock, Settings } from "@app/lib/red-lock";
import { Redis, Cluster } from "ioredis";
export const PgSqlLock = { export const PgSqlLock = {
BootUpMigration: 2023, BootUpMigration: 2023,
+1
View File
@@ -807,6 +807,7 @@ export const registerRoutes = async (
groupDAL, groupDAL,
orgBotDAL, orgBotDAL,
oidcConfigDAL, oidcConfigDAL,
ldapConfigDAL,
loginService, loginService,
projectBotService, projectBotService,
reminderService reminderService
+38 -3
View File
@@ -9,11 +9,14 @@ import {
ProjectMembershipRole, ProjectMembershipRole,
ProjectVersion, ProjectVersion,
TableName, TableName,
TOidcConfigs,
TProjectMemberships, TProjectMemberships,
TProjectUserMembershipRolesInsert, TProjectUserMembershipRolesInsert,
TSamlConfigs,
TUsers TUsers
} from "@app/db/schemas"; } from "@app/db/schemas";
import { TGroupDALFactory } from "@app/ee/services/group/group-dal"; import { TGroupDALFactory } from "@app/ee/services/group/group-dal";
import { TLdapConfigDALFactory } from "@app/ee/services/ldap-config/ldap-config-dal";
import { TLicenseServiceFactory } from "@app/ee/services/license/license-service"; import { TLicenseServiceFactory } from "@app/ee/services/license/license-service";
import { TOidcConfigDALFactory } from "@app/ee/services/oidc/oidc-config-dal"; import { TOidcConfigDALFactory } from "@app/ee/services/oidc/oidc-config-dal";
import { import {
@@ -125,6 +128,7 @@ type TOrgServiceFactoryDep = {
incidentContactDAL: TIncidentContactsDALFactory; incidentContactDAL: TIncidentContactsDALFactory;
samlConfigDAL: Pick<TSamlConfigDALFactory, "findOne">; samlConfigDAL: Pick<TSamlConfigDALFactory, "findOne">;
oidcConfigDAL: Pick<TOidcConfigDALFactory, "findOne">; oidcConfigDAL: Pick<TOidcConfigDALFactory, "findOne">;
ldapConfigDAL: Pick<TLdapConfigDALFactory, "findOne">;
smtpService: TSmtpService; smtpService: TSmtpService;
tokenService: TAuthTokenServiceFactory; tokenService: TAuthTokenServiceFactory;
permissionService: TPermissionServiceFactory; permissionService: TPermissionServiceFactory;
@@ -165,6 +169,7 @@ export const orgServiceFactory = ({
projectRoleDAL, projectRoleDAL,
samlConfigDAL, samlConfigDAL,
oidcConfigDAL, oidcConfigDAL,
ldapConfigDAL,
projectUserMembershipRoleDAL, projectUserMembershipRoleDAL,
identityMetadataDAL, identityMetadataDAL,
projectBotService, projectBotService,
@@ -446,16 +451,20 @@ export const orgServiceFactory = ({
}); });
} }
if (authEnforced) { let samlCfg: TSamlConfigs | undefined;
const samlCfg = await samlConfigDAL.findOne({ let oidcCfg: TOidcConfigs | undefined;
if (authEnforced || googleSsoAuthEnforced) {
samlCfg = await samlConfigDAL.findOne({
orgId, orgId,
isActive: true isActive: true
}); });
const oidcCfg = await oidcConfigDAL.findOne({ oidcCfg = await oidcConfigDAL.findOne({
orgId, orgId,
isActive: true isActive: true
}); });
}
if (authEnforced) {
if (!samlCfg && !oidcCfg) if (!samlCfg && !oidcCfg)
throw new NotFoundError({ throw new NotFoundError({
message: `SAML or OIDC configuration for organization with ID '${orgId}' not found` message: `SAML or OIDC configuration for organization with ID '${orgId}' not found`
@@ -483,6 +492,32 @@ export const orgServiceFactory = ({
}); });
} }
if (samlCfg) {
throw new BadRequestError({
message:
"Cannot enable Google OAuth enforcement while SAML SSO is configured. Disable SAML SSO to enforce Google OAuth."
});
}
if (oidcCfg) {
throw new BadRequestError({
message:
"Cannot enable Google OAuth enforcement while OIDC SSO is configured. Disable OIDC SSO to enforce Google OAuth."
});
}
const ldapCfg = await ldapConfigDAL.findOne({
orgId,
isActive: true
});
if (ldapCfg) {
throw new BadRequestError({
message:
"Cannot enable Google OAuth enforcement while LDAP SSO is configured. Disable LDAP SSO to enforce Google OAuth."
});
}
if (!currentOrg.googleSsoAuthLastUsed) { if (!currentOrg.googleSsoAuthLastUsed) {
throw new BadRequestError({ throw new BadRequestError({
message: message:
@@ -1,6 +1,7 @@
import { FunctionComponent, ReactNode } from "react"; import { FunctionComponent, ReactNode } from "react";
import { BoundCanProps, Can } from "@casl/react"; import { BoundCanProps, Can } from "@casl/react";
import { TooltipProps } from "@app/components/v2/Tooltip/Tooltip";
import { TOrgPermission, useOrgPermission } from "@app/context/OrgPermissionContext"; import { TOrgPermission, useOrgPermission } from "@app/context/OrgPermissionContext";
import { AccessRestrictedBanner, Tooltip } from "../v2"; import { AccessRestrictedBanner, Tooltip } from "../v2";
@@ -20,6 +21,7 @@ type Props = {
renderTooltip?: boolean; renderTooltip?: boolean;
allowedLabel?: string; allowedLabel?: string;
renderGuardBanner?: boolean; renderGuardBanner?: boolean;
tooltipProps?: Omit<TooltipProps, "children">;
} & BoundCanProps<TOrgPermission>; } & BoundCanProps<TOrgPermission>;
export const OrgPermissionCan: FunctionComponent<Props> = ({ export const OrgPermissionCan: FunctionComponent<Props> = ({
@@ -29,6 +31,7 @@ export const OrgPermissionCan: FunctionComponent<Props> = ({
renderTooltip, renderTooltip,
allowedLabel, allowedLabel,
renderGuardBanner, renderGuardBanner,
tooltipProps,
...props ...props
}) => { }) => {
const { permission } = useOrgPermission(); const { permission } = useOrgPermission();
@@ -43,11 +46,19 @@ export const OrgPermissionCan: FunctionComponent<Props> = ({
: children; : children;
if (!isAllowed && passThrough) { if (!isAllowed && passThrough) {
return <Tooltip content={label}>{finalChild}</Tooltip>; return (
<Tooltip content={label} {...tooltipProps}>
{finalChild}
</Tooltip>
);
} }
if (isAllowed && renderTooltip && allowedLabel) { if (isAllowed && renderTooltip && allowedLabel) {
return <Tooltip content={allowedLabel}>{finalChild}</Tooltip>; return (
<Tooltip content={allowedLabel} {...tooltipProps}>
{finalChild}
</Tooltip>
);
} }
if (!isAllowed && renderGuardBanner) { if (!isAllowed && renderGuardBanner) {
@@ -24,11 +24,17 @@ enum EnforceAuthType {
export const OrgGeneralAuthSection = ({ export const OrgGeneralAuthSection = ({
isSamlConfigured, isSamlConfigured,
isOidcConfigured, isOidcConfigured,
isGoogleConfigured isGoogleConfigured,
isSamlActive,
isOidcActive,
isLdapActive
}: { }: {
isSamlConfigured: boolean; isSamlConfigured: boolean;
isOidcConfigured: boolean; isOidcConfigured: boolean;
isGoogleConfigured: boolean; isGoogleConfigured: boolean;
isSamlActive: boolean;
isOidcActive: boolean;
isLdapActive: boolean;
}) => { }) => {
const { currentOrg } = useOrganization(); const { currentOrg } = useOrganization();
const { subscription } = useSubscription(); const { subscription } = useSubscription();
@@ -126,6 +132,15 @@ export const OrgGeneralAuthSection = ({
} }
}; };
const isGoogleOAuthEnforced = currentOrg.googleSsoAuthEnforced;
const getActiveSsoLabel = () => {
if (isSamlActive) return "SAML";
if (isOidcActive) return "OIDC";
if (isLdapActive) return "LDAP";
return "";
};
return ( return (
<div className="rounded-lg border border-mineshaft-600 bg-mineshaft-900 p-6"> <div className="rounded-lg border border-mineshaft-600 bg-mineshaft-900 p-6">
<div> <div>
@@ -135,7 +150,7 @@ export const OrgGeneralAuthSection = ({
</p> </p>
</div> </div>
<div className="flex flex-col gap-2 py-4"> <div className="flex flex-col gap-2 py-4">
<div className={twMerge("mt-4", !isSamlConfigured && "hidden")}> <div className={twMerge("mt-4", (!isSamlConfigured || isGoogleOAuthEnforced) && "hidden")}>
<div className="mb-2 flex justify-between"> <div className="mb-2 flex justify-between">
<div className="flex items-center gap-1"> <div className="flex items-center gap-1">
<span className="text-md text-mineshaft-100">Enforce SAML SSO</span> <span className="text-md text-mineshaft-100">Enforce SAML SSO</span>
@@ -160,7 +175,7 @@ export const OrgGeneralAuthSection = ({
</p> </p>
</div> </div>
<div className={twMerge("mt-4", !isOidcConfigured && "hidden")}> <div className={twMerge("mt-4", (!isOidcConfigured || isGoogleOAuthEnforced) && "hidden")}>
<div className="mb-2 flex justify-between"> <div className="mb-2 flex justify-between">
<div className="flex items-center gap-1"> <div className="flex items-center gap-1">
<span className="text-md text-mineshaft-100">Enforce OIDC SSO</span> <span className="text-md text-mineshaft-100">Enforce OIDC SSO</span>
@@ -188,26 +203,47 @@ export const OrgGeneralAuthSection = ({
<div className={twMerge("mt-2", !isGoogleConfigured && "hidden")}> <div className={twMerge("mt-2", !isGoogleConfigured && "hidden")}>
<div className="mb-2 flex justify-between"> <div className="mb-2 flex justify-between">
<div className="flex items-center gap-1"> <div className="flex items-center gap-1">
<span className="text-md text-mineshaft-100">Enforce Google SSO</span> <span className="text-md text-mineshaft-100">Enforce Google OAuth</span>
</div> </div>
<OrgPermissionCan I={OrgPermissionActions.Edit} a={OrgPermissionSubjects.Sso}> <OrgPermissionCan
I={OrgPermissionActions.Edit}
a={OrgPermissionSubjects.Sso}
tooltipProps={{
className: "max-w-sm",
side: "left"
}}
allowedLabel={
isOidcActive || isSamlActive || isLdapActive
? `You cannot enforce Google OAuth while ${getActiveSsoLabel()} SSO is enabled. Disable ${getActiveSsoLabel()} SSO to enforce Google OAuth.`
: undefined
}
renderTooltip={isOidcActive || isSamlActive || isLdapActive}
>
{(isAllowed) => ( {(isAllowed) => (
<Switch <div>
id="enforce-google-sso" <Switch
onCheckedChange={(value) => id="enforce-google-sso"
handleEnforceOrgAuthToggle(value, EnforceAuthType.GOOGLE) onCheckedChange={(value) =>
} handleEnforceOrgAuthToggle(value, EnforceAuthType.GOOGLE)
isChecked={currentOrg?.googleSsoAuthEnforced ?? false} }
isDisabled={!isAllowed || currentOrg?.authEnforced} isChecked={currentOrg?.googleSsoAuthEnforced ?? false}
/> isDisabled={
!isAllowed ||
currentOrg?.authEnforced ||
isOidcActive ||
isSamlActive ||
isLdapActive
}
/>
</div>
)} )}
</OrgPermissionCan> </OrgPermissionCan>
</div> </div>
<p className="text-sm text-mineshaft-300"> <p className="text-sm text-mineshaft-300">
Enforce users to authenticate via Google OAuth SSO to access this organization. Enforce users to authenticate via Google OAuth to access this organization.
<br /> <br />
When this is enabled your organization members will only be able to login with Google When this is enabled your organization members will only be able to login with Google
SSO (not Google SAML). OAuth (not Google SAML).
</p> </p>
</div> </div>
</div> </div>
@@ -267,8 +303,8 @@ export const OrgGeneralAuthSection = ({
</div> </div>
<p className="text-sm text-mineshaft-300"> <p className="text-sm text-mineshaft-300">
<span> <span>
Allow organization admins to bypass SAML enforcement when SSO is unavailable, Allow organization admins to bypass SSO login enforcement when your SSO provider is
misconfigured, or inaccessible. unavailable, misconfigured, or inaccessible.
</span> </span>
</p> </p>
</div> </div>
@@ -94,6 +94,8 @@ export const OrgLDAPSection = (): JSX.Element => {
handlePopUpOpen("ldapGroupMap"); handlePopUpOpen("ldapGroupMap");
}; };
const isGoogleOAuthEnabled = currentOrg.googleSsoAuthEnforced;
return ( return (
<div className="mb-4"> <div className="mb-4">
<div className="py-4"> <div className="py-4">
@@ -116,16 +118,31 @@ export const OrgLDAPSection = (): JSX.Element => {
<div className="pt-4"> <div className="pt-4">
<div className="mb-2 flex items-center justify-between"> <div className="mb-2 flex items-center justify-between">
<h2 className="text-md text-mineshaft-100">Enable LDAP</h2> <h2 className="text-md text-mineshaft-100">Enable LDAP</h2>
<OrgPermissionCan I={OrgPermissionActions.Edit} a={OrgPermissionSubjects.Ldap}> <OrgPermissionCan
I={OrgPermissionActions.Edit}
a={OrgPermissionSubjects.Ldap}
tooltipProps={{
className: "max-w-sm",
side: "left"
}}
allowedLabel={
isGoogleOAuthEnabled
? "You cannot enable LDAP SSO while Google OAuth is enforced. Disable Google OAuth enforcement to enable LDAP SSO."
: undefined
}
renderTooltip={isGoogleOAuthEnabled}
>
{(isAllowed) => ( {(isAllowed) => (
<Switch <div>
id="enable-saml-sso" <Switch
onCheckedChange={(value) => handleLDAPToggle(value)} id="enable-ldap-sso"
isChecked={data ? data.isActive : false} onCheckedChange={(value) => handleLDAPToggle(value)}
isDisabled={!isAllowed} isChecked={data ? data.isActive : false}
> isDisabled={!isAllowed || isGoogleOAuthEnabled}
Enable >
</Switch> Enable
</Switch>
</div>
)} )}
</OrgPermissionCan> </OrgPermissionCan>
</div> </div>
@@ -83,6 +83,8 @@ export const OrgOIDCSection = (): JSX.Element => {
} }
}; };
const isGoogleOAuthEnabled = currentOrg.googleSsoAuthEnforced;
return ( return (
<div className="mb-4 rounded-lg border-mineshaft-600 bg-mineshaft-900"> <div className="mb-4 rounded-lg border-mineshaft-600 bg-mineshaft-900">
<div className="mb-4 flex items-center justify-between"> <div className="mb-4 flex items-center justify-between">
@@ -106,14 +108,29 @@ export const OrgOIDCSection = (): JSX.Element => {
<div className="mb-2 flex items-center justify-between"> <div className="mb-2 flex items-center justify-between">
<h2 className="text-md text-mineshaft-100">Enable OIDC</h2> <h2 className="text-md text-mineshaft-100">Enable OIDC</h2>
{!isPending && ( {!isPending && (
<OrgPermissionCan I={OrgPermissionActions.Edit} a={OrgPermissionSubjects.Sso}> <OrgPermissionCan
I={OrgPermissionActions.Edit}
a={OrgPermissionSubjects.Sso}
tooltipProps={{
className: "max-w-sm",
side: "left"
}}
allowedLabel={
isGoogleOAuthEnabled
? "You cannot enable OIDC SSO while Google OAuth is enforced. Disable Google OAuth enforcement to enable OIDC SSO."
: undefined
}
renderTooltip={isGoogleOAuthEnabled}
>
{(isAllowed) => ( {(isAllowed) => (
<Switch <div>
id="enable-oidc-sso" <Switch
onCheckedChange={(value) => handleOIDCToggle(value)} id="enable-oidc-sso"
isChecked={data ? data.isActive : false} onCheckedChange={(value) => handleOIDCToggle(value)}
isDisabled={!isAllowed} isChecked={data ? data.isActive : false}
/> isDisabled={!isAllowed || isGoogleOAuthEnabled}
/>
</div>
)} )}
</OrgPermissionCan> </OrgPermissionCan>
)} )}
@@ -78,6 +78,8 @@ export const OrgSSOSection = (): JSX.Element => {
} }
}; };
const isGoogleOAuthEnabled = currentOrg.googleSsoAuthEnforced;
return ( return (
<div className="space-y-4"> <div className="space-y-4">
<div className="mb-4 flex items-center justify-between"> <div className="mb-4 flex items-center justify-between">
@@ -99,14 +101,29 @@ export const OrgSSOSection = (): JSX.Element => {
<div className="mb-2 flex items-center justify-between pt-4"> <div className="mb-2 flex items-center justify-between pt-4">
<h2 className="text-md text-mineshaft-100">Enable SAML</h2> <h2 className="text-md text-mineshaft-100">Enable SAML</h2>
{!isPending && ( {!isPending && (
<OrgPermissionCan I={OrgPermissionActions.Edit} a={OrgPermissionSubjects.Sso}> <OrgPermissionCan
I={OrgPermissionActions.Edit}
a={OrgPermissionSubjects.Sso}
tooltipProps={{
className: "max-w-sm",
side: "left"
}}
allowedLabel={
isGoogleOAuthEnabled
? "You cannot enable SAML SSO while Google OAuth is enforced. Disable Google OAuth enforcement to enable SAML SSO."
: undefined
}
renderTooltip={isGoogleOAuthEnabled}
>
{(isAllowed) => ( {(isAllowed) => (
<Switch <div>
id="enable-saml-sso" <Switch
onCheckedChange={(value) => handleSamlSSOToggle(value)} id="enable-saml-sso"
isChecked={data ? data.isActive : false} onCheckedChange={(value) => handleSamlSSOToggle(value)}
isDisabled={!isAllowed} isChecked={data ? data.isActive : false}
/> isDisabled={!isAllowed || isGoogleOAuthEnabled}
/>
</div>
)} )}
</OrgPermissionCan> </OrgPermissionCan>
)} )}
@@ -184,6 +184,9 @@ export const OrgSsoTab = withPermission(
isSamlConfigured={isSamlConfigured} isSamlConfigured={isSamlConfigured}
isOidcConfigured={isOidcConfigured} isOidcConfigured={isOidcConfigured}
isGoogleConfigured={isGoogleConfigured} isGoogleConfigured={isGoogleConfigured}
isSamlActive={Boolean(samlConfig?.isActive)}
isOidcActive={Boolean(oidcConfig?.isActive)}
isLdapActive={Boolean(ldapConfig?.isActive)}
/> />
)} )}