diff --git a/portal-ui/src/screens/Console/Configurations/utils.tsx b/portal-ui/src/screens/Console/Configurations/utils.tsx
index a1cfa298e..5a0575e4c 100644
--- a/portal-ui/src/screens/Console/Configurations/utils.tsx
+++ b/portal-ui/src/screens/Console/Configurations/utils.tsx
@@ -20,8 +20,6 @@ import CodeIcon from "@mui/icons-material/Code";
import LocalHospitalIcon from "@mui/icons-material/LocalHospital";
import FindReplaceIcon from "@mui/icons-material/FindReplace";
import VpnKeyIcon from "@mui/icons-material/VpnKey";
-import LockOpenIcon from "@mui/icons-material/LockOpen";
-import LoginIcon from "@mui/icons-material/Login";
import PendingActionsIcon from "@mui/icons-material/PendingActions";
import CallToActionIcon from "@mui/icons-material/CallToAction";
import { IElement, IElementValue } from "./types";
@@ -57,16 +55,6 @@ export const configurationElements: IElement[] = [
configuration_id: "etcd",
configuration_label: "Etcd",
},
- {
- icon: ,
- configuration_id: "identity_openid",
- configuration_label: "Identity Openid",
- },
- {
- icon: ,
- configuration_id: "identity_ldap",
- configuration_label: "Identity LDAP",
- },
{
icon: ,
configuration_id: "logger_webhook",
@@ -261,158 +249,6 @@ export const fieldsConfigurations: any = {
placeholder: "Enter custom notes if any",
},
],
- identity_openid: [
- {
- name: "config_url",
- required: false,
- label: "Config URL",
- tooltip: "Config URL for identity provider configuration",
- type: "string",
- placeholder:
- "https://identity-provider-url/.well-known/openid-configuration",
- },
- {
- name: "client_id",
- required: false,
- label: "Client ID",
- type: "string",
- placeholder: "Enter Client ID",
- },
- {
- name: "client_secret",
- required: false,
- label: "Secret ID",
- type: "string",
- placeholder: "Enter Secret ID",
- },
- {
- name: "claim_name",
- required: false,
- label: "Claim Name",
- tooltip: "Claim from which MinIO will read the policy or role to use",
- type: "string",
- placeholder: "Enter Claim Name",
- },
- {
- name: "claim_prefix",
- required: false,
- label: "Claim Prefix",
- tooltip: "Claim Prefix",
- type: "string",
- placeholder: "Enter Claim Prefix",
- },
- {
- name: "claim_userinfo",
- required: false,
- label: "Claim UserInfo",
- type: "on|off",
- },
- {
- name: "redirect_uri",
- required: false,
- label: "Redirect URI",
- type: "string",
- placeholder: "https://console-endpoint-url/oauth_callback",
- },
- {
- name: "scopes",
- required: false,
- label: "Scopes",
- type: "string",
- placeholder: "openid,profile,email",
- },
- ],
- identity_ldap: [
- {
- name: "server_addr",
- required: true,
- label: "Server Addr",
- tooltip: 'AD/LDAP server address e.g. "myldapserver.com:636"',
- type: "string",
- placeholder: "myldapserver.com:636",
- },
- {
- name: "tls_skip_verify",
- required: false,
- label: "TLS Skip Verify",
- tooltip:
- 'Trust server TLS without verification, defaults to "off" (verify)',
- type: "on|off",
- },
- {
- name: "server_insecure",
- required: false,
- label: "Server Insecure",
- tooltip:
- 'Allow plain text connection to AD/LDAP server, defaults to "off"',
- type: "on|off",
- },
- {
- name: "server_starttls",
- required: false,
- label: "Start TLS connection to AD/LDAP server",
- tooltip: "Use StartTLS connection to AD/LDAP server",
- type: "on|off",
- },
- {
- name: "lookup_bind_dn",
- required: true,
- label: "Lookup Bind DN",
- tooltip:
- "DN for LDAP read-only service account used to perform DN and group lookups",
- type: "string",
- placeholder: "cn=admin,dc=min,dc=io",
- },
- {
- name: "lookup_bind_password",
- required: false,
- label: "Lookup Bind Password",
- tooltip:
- "Password for LDAP read-only service account used to perform DN and group lookups",
- type: "string",
- placeholder: "admin",
- },
- {
- name: "user_dn_search_base_dn",
- required: false,
- label: "User DN Search Base DN",
- tooltip: "Base LDAP DN to search for user DN",
- type: "csv",
- placeholder: "dc=myldapserver",
- },
- {
- name: "user_dn_search_filter",
- required: false,
- label: "User DN Search Filter",
- tooltip: "Search filter to lookup user DN",
- type: "string",
- placeholder: "(sAMAcountName=%s)",
- },
- {
- name: "group_search_filter",
- required: false,
- label: "Group Search Filter",
- tooltip: "Search filter for groups",
- type: "string",
- placeholder: "(&(objectclass=groupOfNames)(member=%d))",
- },
- {
- name: "group_search_base_dn",
- required: false,
- label: "Group Search Base DN",
- tooltip: "List of group search base DNs",
- type: "csv",
- placeholder: "dc=minioad,dc=local",
- },
- {
- name: "comment",
- required: false,
- label: "Comment",
- tooltip: "Optionally add a comment to this setting",
- type: "comment",
- placeholder: "Enter custom notes if any",
- },
- ],
logger_webhook: [
{
name: "endpoint",
diff --git a/portal-ui/src/screens/Console/IDP/AddIDPConfiguration.tsx b/portal-ui/src/screens/Console/IDP/AddIDPConfiguration.tsx
index e30b6bb43..af38575df 100644
--- a/portal-ui/src/screens/Console/IDP/AddIDPConfiguration.tsx
+++ b/portal-ui/src/screens/Console/IDP/AddIDPConfiguration.tsx
@@ -38,6 +38,7 @@ import PageHeader from "../Common/PageHeader/PageHeader";
import BackLink from "../../../common/BackLink";
import PageLayout from "../Common/Layout/PageLayout";
import SectionTitle from "../Common/SectionTitle";
+import FormSwitchWrapper from "../Common/FormComponents/FormSwitchWrapper/FormSwitchWrapper";
type AddIDPConfigurationProps = {
classes?: any;
@@ -127,6 +128,44 @@ const AddIDPConfiguration = ({
invokeApi("POST", endpoint, { name, input });
};
+ const renderFormField = (key: string, value: any) => {
+ switch (value.type) {
+ case "toggle":
+ return (
+
+ setFields({ ...fields, [key]: e.target.checked ? "on" : "off" })
+ }
+ description=""
+ />
+ );
+ default:
+ return (
+ ) =>
+ setFields({ ...fields, [key]: e.target.value })
+ }
+ placeholder={value.placeholder}
+ type={value.type}
+ />
+ );
+ }
+ };
+
return (
} />
@@ -161,20 +200,7 @@ const AddIDPConfiguration = ({
className={classes.formFieldRow}
key={key}
>
- ) =>
- setFields({ ...fields, [key]: e.target.value })
- }
- placeholder={value.placeholder}
- type={value.type}
- />
+ {renderFormField(key, value)}
))}
diff --git a/portal-ui/src/screens/Console/IDP/AddIDPLDAPConfiguration.tsx b/portal-ui/src/screens/Console/IDP/AddIDPLDAPConfiguration.tsx
index ecbab547a..569d1fea8 100644
--- a/portal-ui/src/screens/Console/IDP/AddIDPLDAPConfiguration.tsx
+++ b/portal-ui/src/screens/Console/IDP/AddIDPLDAPConfiguration.tsx
@@ -26,7 +26,7 @@ import {
} from "../Common/FormComponents/common/styleLibrary";
import { IAM_PAGES } from "../../../common/SecureComponent/permissions";
import AddIDPConfiguration from "./AddIDPConfiguration";
-import { ldapFormFields } from "./utils";
+import { ldapFormFields, ldapHelpBoxContents } from "./utils";
import AddIDPConfigurationHelpBox from "./AddIDPConfigurationHelpbox";
type AddIDPLDAPConfigurationProps = {
@@ -43,31 +43,13 @@ const styles = (theme: Theme) =>
});
const AddIDPLDAPConfiguration = ({ classes }: AddIDPLDAPConfigurationProps) => {
- const helpBoxContents = [
- {
- text: "MinIO supports using an Active Directory or LDAP (AD/LDAP) service for external management of user identities. Configuring an external IDentity Provider (IDP) enables Single-Sign On (SSO) workflows, where applications authenticate against the external IDP before accessing MinIO.",
- icon: ,
- iconDescription: "Create Configurations",
- },
- {
- text: "MinIO queries the configured Active Directory / LDAP server to verify the credentials specified by the application and optionally return a list of groups in which the user has membership. MinIO supports two modes (Lookup-Bind Mode and Username-Bind Mode) for performing these queries",
- icon: null,
- iconDescription: "",
- },
- {
- text: "MinIO recommends using Lookup-Bind mode as the preferred method for verifying AD/LDAP credentials. Username-Bind mode is a legacy method retained for backwards compatibility only.",
- icon: null,
- iconDescription: "",
- },
- ];
-
return (
}
helpBox={
createStyles({});
const AddIDPOpenIDConfiguration = ({
classes,
}: AddIDPOpenIDConfigurationProps) => {
- const helpBoxContents = [
- {
- text: "MinIO supports using an OpenID Connect (OIDC) compatible IDentity Provider (IDP) such as Okta, KeyCloak, Dex, Google, or Facebook for external management of user identities.",
- icon: ,
- iconDescription: "Create Configurations",
- },
- {
- text: "Configuring an external IDP enables Single-Sign On workflows, where applications authenticate against the external IDP before accessing MinIO.",
- icon: null,
- iconDescription: "",
- },
- ];
return (
}
helpBox={
{
const dispatch = useAppDispatch();
const navigate = useNavigate();
@@ -229,6 +232,144 @@ const IDPConfigurationDetails = ({
invokeEnabledApi("PUT", `${endpoint}${configurationName}`, { input });
};
+ const renderFormField = (key: string, value: any) => {
+ switch (value.type) {
+ case "toggle":
+ return (
+
+ setFields({ ...fields, [key]: e.target.checked ? "on" : "off" })
+ }
+ description=""
+ disabled={!editMode}
+ />
+ );
+ default:
+ return (
+ ) =>
+ setFields({ ...fields, [key]: e.target.value })
+ }
+ placeholder={value.placeholder}
+ disabled={!editMode}
+ type={value.type}
+ />
+ );
+ }
+ };
+
+ const renderEditForm = () => {
+ return (
+
+
+ {helpBox}
+
+ );
+ };
+ const renderViewForm = () => {
+ return (
+
+ {Object.entries(formFields).map(([key, value]) => (
+
+ ))}
+
+ );
+ };
+
return (
{deleteOpen && configurationName && (
@@ -239,24 +380,9 @@ const IDPConfigurationDetails = ({
closeDeleteModalAndRefresh={closeDeleteModalAndRefresh}
/>
)}
- }
- actions={
- toggleConfiguration(e.target.checked)}
- description=""
- disabled={loadingEnabledSave}
- />
- }
- />
+ } />
-
+
)}
+ {!editMode && (
+ }
+ onClick={toggleEditMode}
+ label={"Edit"}
+ />
+ )}
+
-
+ {editMode ? renderEditForm() : renderViewForm()}
+
);
diff --git a/portal-ui/src/screens/Console/IDP/IDPLDAPConfigurationDetails.tsx b/portal-ui/src/screens/Console/IDP/IDPLDAPConfigurationDetails.tsx
index bc514afd0..0ba4cdc81 100644
--- a/portal-ui/src/screens/Console/IDP/IDPLDAPConfigurationDetails.tsx
+++ b/portal-ui/src/screens/Console/IDP/IDPLDAPConfigurationDetails.tsx
@@ -19,10 +19,11 @@ import React from "react";
import { Theme } from "@mui/material/styles";
import createStyles from "@mui/styles/createStyles";
import withStyles from "@mui/styles/withStyles";
-import { ldapFormFields } from "./utils";
+import { ldapFormFields, ldapHelpBoxContents } from "./utils";
import LoginIcon from "@mui/icons-material/Login";
import IDPConfigurationDetails from "./IDPConfigurationDetails";
import { IAM_PAGES } from "../../../common/SecureComponent/permissions";
+import AddIDPConfigurationHelpBox from "./AddIDPConfigurationHelpbox";
type IDPLDAPConfigurationDetailsProps = {
classes?: any;
@@ -39,6 +40,16 @@ const IDPLDAPConfigurationDetails = ({
header={"LDAP Configurations"}
endpoint={"/api/v1/idp/ldap/"}
idpType={"ldap"}
+ helpBox={
+
+ }
formFields={ldapFormFields}
icon={}
/>
diff --git a/portal-ui/src/screens/Console/IDP/IDPOpenIDConfigurationDetails.tsx b/portal-ui/src/screens/Console/IDP/IDPOpenIDConfigurationDetails.tsx
index f61d09fa8..137cf9e6a 100644
--- a/portal-ui/src/screens/Console/IDP/IDPOpenIDConfigurationDetails.tsx
+++ b/portal-ui/src/screens/Console/IDP/IDPOpenIDConfigurationDetails.tsx
@@ -21,8 +21,9 @@ import createStyles from "@mui/styles/createStyles";
import withStyles from "@mui/styles/withStyles";
import { IAM_PAGES } from "../../../common/SecureComponent/permissions";
import { LockIcon } from "../../../icons";
-import { openIDFormFields } from "./utils";
+import { openIDFormFields, openIDHelpBoxContents } from "./utils";
import IDPConfigurationDetails from "./IDPConfigurationDetails";
+import AddIDPConfigurationHelpBox from "./AddIDPConfigurationHelpbox";
type IDPOpenIDConfigurationDetailsProps = {
classes?: any;
@@ -39,6 +40,16 @@ const IDPOpenIDConfigurationDetails = ({
header={"OpenID Configurations"}
endpoint={"/api/v1/idp/openid/"}
idpType={"openid"}
+ helpBox={
+
+ }
formFields={openIDFormFields}
icon={}
/>
diff --git a/portal-ui/src/screens/Console/IDP/utils.tsx b/portal-ui/src/screens/Console/IDP/utils.tsx
index 4e43f75b1..7139d98d2 100644
--- a/portal-ui/src/screens/Console/IDP/utils.tsx
+++ b/portal-ui/src/screens/Console/IDP/utils.tsx
@@ -14,6 +14,40 @@
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see .
+import LoginIcon from "@mui/icons-material/Login";
+import { LockIcon } from "../../../icons";
+
+export const ldapHelpBoxContents = [
+ {
+ text: "MinIO supports using an Active Directory or LDAP (AD/LDAP) service for external management of user identities. Configuring an external IDentity Provider (IDP) enables Single-Sign On (SSO) workflows, where applications authenticate against the external IDP before accessing MinIO.",
+ icon: ,
+ iconDescription: "Create Configurations",
+ },
+ {
+ text: "MinIO queries the configured Active Directory / LDAP server to verify the credentials specified by the application and optionally return a list of groups in which the user has membership. MinIO supports two modes (Lookup-Bind Mode and Username-Bind Mode) for performing these queries",
+ icon: null,
+ iconDescription: "",
+ },
+ {
+ text: "MinIO recommends using Lookup-Bind mode as the preferred method for verifying AD/LDAP credentials. Username-Bind mode is a legacy method retained for backwards compatibility only.",
+ icon: null,
+ iconDescription: "",
+ },
+];
+
+export const openIDHelpBoxContents = [
+ {
+ text: "MinIO supports using an OpenID Connect (OIDC) compatible IDentity Provider (IDP) such as Okta, KeyCloak, Dex, Google, or Facebook for external management of user identities.",
+ icon: ,
+ iconDescription: "Create Configurations",
+ },
+ {
+ text: "Configuring an external IDP enables Single-Sign On workflows, where applications authenticate against the external IDP before accessing MinIO.",
+ icon: null,
+ iconDescription: "",
+ },
+];
+
export const openIDFormFields = {
config_url: {
required: true,
@@ -46,14 +80,6 @@ export const openIDFormFields = {
placeholder: "Enter Client Secret",
type: "password",
},
- display_name: {
- required: false,
- label: "Display Name",
- tooltip: "Display Name",
- placeholder: "Enter Display Name",
- type: "text",
- hasError: (s: string, editMode: boolean) => "",
- },
claim_name: {
required: false,
label: "Claim Name",
@@ -62,10 +88,18 @@ export const openIDFormFields = {
type: "text",
hasError: (s: string, editMode: boolean) => "",
},
+ display_name: {
+ required: false,
+ label: "Display Name",
+ tooltip: "",
+ placeholder: "Enter Display Name",
+ type: "text",
+ hasError: (s: string, editMode: boolean) => "",
+ },
claim_prefix: {
required: false,
label: "Claim Prefix",
- tooltip: "Claim Prefix",
+ tooltip: "",
placeholder: "Enter Claim Prefix",
type: "text",
hasError: (s: string, editMode: boolean) => "",
@@ -73,7 +107,7 @@ export const openIDFormFields = {
scopes: {
required: false,
label: "Scopes",
- tooltip: "Scopes",
+ tooltip: "",
placeholder: "openid,profile,email",
type: "text",
hasError: (s: string, editMode: boolean) => "",
@@ -81,7 +115,7 @@ export const openIDFormFields = {
redirect_uri: {
required: false,
label: "Redirect URI",
- tooltip: "Redirect URI",
+ tooltip: "",
placeholder: "https://console-endpoint-url/oauth_callback",
type: "text",
hasError: (s: string, editMode: boolean) => "",
@@ -89,11 +123,27 @@ export const openIDFormFields = {
role_policy: {
required: false,
label: "Role Policy",
- tooltip: "Role Policy",
+ tooltip: "",
placeholder: "readonly",
type: "text",
hasError: (s: string, editMode: boolean) => "",
},
+ claim_userinfo: {
+ required: false,
+ label: "Claim User Info",
+ tooltip: "",
+ placeholder: "Claim User Info",
+ type: "toggle",
+ hasError: (s: string, editMode: boolean) => "",
+ },
+ redirect_uri_dynamic: {
+ required: false,
+ label: "Redirect URI Dynamic",
+ tooltip: "",
+ placeholder: "Redirect URI Dynamic",
+ type: "toggle",
+ hasError: (s: string, editMode: boolean) => "",
+ },
};
export const ldapFormFields = {
@@ -135,7 +185,7 @@ export const ldapFormFields = {
return !s && editMode ? "User DN Search Base DN is required" : "";
},
label: "User DN Search Base",
- tooltip: "Base LDAP DN to search for user DN",
+ tooltip: "",
placeholder: "DC=example,DC=net",
type: "text",
},
@@ -145,14 +195,14 @@ export const ldapFormFields = {
return !s && editMode ? "User DN Search Filter is required" : "";
},
label: "User DN Search Filter",
- tooltip: "Search filter to lookup user DN",
+ tooltip: "",
placeholder: "(sAMAcountName=%s)",
type: "text",
},
display_name: {
required: false,
label: "Display Name",
- tooltip: "Display Name",
+ tooltip: "",
placeholder: "Enter Display Name",
type: "text",
hasError: (s: string, editMode: boolean) => "",
@@ -161,7 +211,7 @@ export const ldapFormFields = {
required: false,
hasError: (s: string, editMode: boolean) => "",
label: "Group Search Base DN",
- tooltip: "Group Search Base DN",
+ tooltip: "",
placeholder: "ou=swengg,dc=min,dc=io",
type: "text",
},
@@ -169,7 +219,7 @@ export const ldapFormFields = {
required: false,
hasError: (s: string, editMode: boolean) => "",
label: "Group Search Filter",
- tooltip: "Group Search Filter",
+ tooltip: "",
placeholder: "(&(objectclass=groupofnames)(member=%d))",
type: "text",
},
diff --git a/portal-ui/tests/permissions-2/settings.ts b/portal-ui/tests/permissions-2/settings.ts
index 0fe44f4a5..b2810f0dc 100644
--- a/portal-ui/tests/permissions-2/settings.ts
+++ b/portal-ui/tests/permissions-2/settings.ts
@@ -62,10 +62,6 @@ test("All vertical tab items exist", async (t) => {
.ok()
.expect(settingsEtcdTabExists)
.ok()
- .expect(settingsOpenIdTabExists)
- .ok()
- .expect(settingsLdapTabExists)
- .ok()
.expect(settingsLoggerWebhookTabExists)
.ok()
.expect(settingsAuditWebhookTabExists)