diff --git a/js/apps/admin-ui/src/clients/ClientDetails.tsx b/js/apps/admin-ui/src/clients/ClientDetails.tsx index 491cc6dc50..72705d32df 100644 --- a/js/apps/admin-ui/src/clients/ClientDetails.tsx +++ b/js/apps/admin-ui/src/clients/ClientDetails.tsx @@ -38,16 +38,18 @@ import { import { useAccess } from "../context/access/Access"; import { useAdminClient, useFetch } from "../context/auth/AdminClient"; import { useRealm } from "../context/realm-context/RealmContext"; -import { useServerInfo } from "../context/server-info/ServerInfoProvider"; import { convertAttributeNameToForm, convertFormValuesToObject, convertToFormValues, exportClient, } from "../util"; +import useIsFeatureEnabled, { Feature } from "../utils/useIsFeatureEnabled"; import { useParams } from "../utils/useParams"; import useToggle from "../utils/useToggle"; import { AdvancedTab } from "./AdvancedTab"; +import { ClientSessions } from "./ClientSessions"; +import { ClientSettings } from "./ClientSettings"; import { AuthorizationEvaluate } from "./authorization/AuthorizationEvaluate"; import { AuthorizationExport } from "./authorization/AuthorizationExport"; import { AuthorizationPermissions } from "./authorization/Permissions"; @@ -55,8 +57,6 @@ import { AuthorizationPolicies } from "./authorization/Policies"; import { AuthorizationResources } from "./authorization/Resources"; import { AuthorizationScopes } from "./authorization/Scopes"; import { AuthorizationSettings } from "./authorization/Settings"; -import { ClientSessions } from "./ClientSessions"; -import { ClientSettings } from "./ClientSettings"; import { Credentials } from "./credentials/Credentials"; import { Keys } from "./keys/Keys"; import { SamlKeys } from "./keys/SamlKeys"; @@ -66,8 +66,8 @@ import { } from "./routes/AuthenticationTab"; import { ClientParams, ClientTab, toClient } from "./routes/Client"; import { toClientRole } from "./routes/ClientRole"; -import { toClients } from "./routes/Clients"; import { ClientScopesTab, toClientScopesTab } from "./routes/ClientScopeTab"; +import { toClients } from "./routes/Clients"; import { toCreateRole } from "./routes/NewRole"; import { ClientScopes } from "./scopes/ClientScopes"; import { EvaluateScopes } from "./scopes/EvaluateScopes"; @@ -191,17 +191,16 @@ export default function ClientDetails() { const { adminClient } = useAdminClient(); const { addAlert, addError } = useAlerts(); const { realm } = useRealm(); - const { profileInfo } = useServerInfo(); - const { hasAccess } = useAccess(); + const isFeatureEnabled = useIsFeatureEnabled(); + const hasManageAuthorization = hasAccess("manage-authorization"); - const permissionsEnabled = - !profileInfo?.disabledFeatures?.includes("ADMIN_FINE_GRAINED_AUTHZ") && - hasManageAuthorization; const hasManageClients = hasAccess("manage-clients"); const hasViewClients = hasAccess("view-clients"); const hasViewUsers = hasAccess("view-users"); const hasQueryUsers = hasAccess("query-users"); + const permissionsEnabled = + isFeatureEnabled(Feature.AdminFineGrainedAuthz) && hasManageAuthorization; const navigate = useNavigate(); diff --git a/js/apps/admin-ui/src/groups/GroupsSection.tsx b/js/apps/admin-ui/src/groups/GroupsSection.tsx index 713d6c7670..111bbb2092 100644 --- a/js/apps/admin-ui/src/groups/GroupsSection.tsx +++ b/js/apps/admin-ui/src/groups/GroupsSection.tsx @@ -1,41 +1,40 @@ -import { useState } from "react"; -import { useLocation, useNavigate } from "react-router-dom"; -import { useTranslation } from "react-i18next"; +import type GroupRepresentation from "@keycloak/keycloak-admin-client/lib/defs/groupRepresentation"; import { + Drawer, + DrawerContent, + DrawerContentBody, + DrawerHead, + DrawerPanelContent, DropdownItem, PageSection, PageSectionVariants, Tab, TabTitleText, Tabs, - Drawer, - DrawerContent, - DrawerContentBody, - DrawerPanelContent, - DrawerHead, } from "@patternfly/react-core"; -import type GroupRepresentation from "@keycloak/keycloak-admin-client/lib/defs/groupRepresentation"; +import { useState } from "react"; +import { useTranslation } from "react-i18next"; +import { useLocation, useNavigate } from "react-router-dom"; -import { ViewHeader } from "../components/view-header/ViewHeader"; -import { useFetch, useAdminClient } from "../context/auth/AdminClient"; -import { useRealm } from "../context/realm-context/RealmContext"; - -import { useSubGroups } from "./SubGroupsContext"; -import { GroupTable } from "./GroupTable"; -import { getId, getLastId } from "./groupIdUtils"; -import { Members } from "./Members"; -import { GroupAttributes } from "./GroupAttributes"; -import { GroupsModal } from "./GroupsModal"; -import { toGroups } from "./routes/Groups"; -import { GroupRoleMapping } from "./GroupRoleMapping"; -import helpUrls from "../help-urls"; -import { PermissionsTab } from "../components/permission-tab/PermissionTab"; -import { useAccess } from "../context/access/Access"; -import { useServerInfo } from "../context/server-info/ServerInfoProvider"; -import { GroupTree } from "./components/GroupTree"; -import { DeleteGroup } from "./components/DeleteGroup"; -import useToggle from "../utils/useToggle"; import { GroupBreadCrumbs } from "../components/bread-crumb/GroupBreadCrumbs"; +import { PermissionsTab } from "../components/permission-tab/PermissionTab"; +import { ViewHeader } from "../components/view-header/ViewHeader"; +import { useAccess } from "../context/access/Access"; +import { useAdminClient, useFetch } from "../context/auth/AdminClient"; +import { useRealm } from "../context/realm-context/RealmContext"; +import helpUrls from "../help-urls"; +import useIsFeatureEnabled, { Feature } from "../utils/useIsFeatureEnabled"; +import useToggle from "../utils/useToggle"; +import { GroupAttributes } from "./GroupAttributes"; +import { GroupRoleMapping } from "./GroupRoleMapping"; +import { GroupTable } from "./GroupTable"; +import { GroupsModal } from "./GroupsModal"; +import { Members } from "./Members"; +import { useSubGroups } from "./SubGroupsContext"; +import { DeleteGroup } from "./components/DeleteGroup"; +import { GroupTree } from "./components/GroupTree"; +import { getId, getLastId } from "./groupIdUtils"; +import { toGroups } from "./routes/Groups"; import "./GroupsSection.css"; @@ -43,8 +42,6 @@ export default function GroupsSection() { const { t } = useTranslation("groups"); const [activeTab, setActiveTab] = useState(0); - const { profileInfo } = useServerInfo(); - const { adminClient } = useAdminClient(); const { subGroups, setSubGroups, currentGroup } = useSubGroups(); const { realm } = useRealm(); @@ -60,8 +57,9 @@ export default function GroupsSection() { const refresh = () => setKey(key + 1); const { hasAccess } = useAccess(); + const isFeatureEnabled = useIsFeatureEnabled(); const canViewPermissions = - !profileInfo?.disabledFeatures?.includes("ADMIN_FINE_GRAINED_AUTHZ") && + isFeatureEnabled(Feature.AdminFineGrainedAuthz) && hasAccess("manage-authorization", "manage-users", "manage-clients"); const canManageGroup = hasAccess("manage-users") || currentGroup()?.access?.manage; diff --git a/js/apps/admin-ui/src/identity-providers/add/DetailSettings.tsx b/js/apps/admin-ui/src/identity-providers/add/DetailSettings.tsx index 3229ce4865..efaf8a85ad 100644 --- a/js/apps/admin-ui/src/identity-providers/add/DetailSettings.tsx +++ b/js/apps/admin-ui/src/identity-providers/add/DetailSettings.tsx @@ -36,8 +36,8 @@ import { import { ViewHeader } from "../../components/view-header/ViewHeader"; import { useAdminClient, useFetch } from "../../context/auth/AdminClient"; import { useRealm } from "../../context/realm-context/RealmContext"; -import { useServerInfo } from "../../context/server-info/ServerInfoProvider"; import { toUpperCase } from "../../util"; +import useIsFeatureEnabled, { Feature } from "../../utils/useIsFeatureEnabled"; import { useParams } from "../../utils/useParams"; import { ExtendedFieldsForm } from "../component/ExtendedFieldsForm"; import { toIdentityProviderAddMapper } from "../routes/AddMapper"; @@ -156,7 +156,7 @@ const MapperLink = ({ name, mapperId, provider }: MapperLinkProps) => { export default function DetailSettings() { const { t } = useTranslation("identity-providers"); const { alias, providerId } = useParams(); - + const isFeatureEnabled = useIsFeatureEnabled(); const form = useForm(); const { handleSubmit, getValues, reset } = form; const [provider, setProvider] = useState(); @@ -168,7 +168,6 @@ export default function DetailSettings() { const navigate = useNavigate(); const { realm } = useRealm(); const [key, setKey] = useState(0); - const { profileInfo } = useServerInfo(); const refresh = () => setKey(key + 1); useFetch( @@ -496,9 +495,7 @@ export default function DetailSettings() { ]} /> - {!profileInfo?.disabledFeatures?.includes( - "ADMIN_FINE_GRAINED_AUTHZ" - ) && ( + {isFeatureEnabled(Feature.AdminFineGrainedAuthz) && ( ({ mode: "onChange", @@ -67,8 +68,6 @@ export default function RealmRoleTabs() { const [key, setKey] = useState(0); const [attributes, setAttributes] = useState(); - const { profileInfo } = useServerInfo(); - const refresh = () => setKey(key + 1); const { addAlert, addError } = useAlerts(); @@ -391,9 +390,7 @@ export default function RealmRoleTabs() { )} - {!profileInfo?.disabledFeatures?.includes( - "ADMIN_FINE_GRAINED_AUTHZ" - ) && ( + {isFeatureEnabled(Feature.AdminFineGrainedAuthz) && ( {t("common:permissions")}} {...permissionsTab} diff --git a/js/apps/admin-ui/src/realm-settings/RealmSettingsTabs.tsx b/js/apps/admin-ui/src/realm-settings/RealmSettingsTabs.tsx index bc86f5447c..837ac7ee71 100644 --- a/js/apps/admin-ui/src/realm-settings/RealmSettingsTabs.tsx +++ b/js/apps/admin-ui/src/realm-settings/RealmSettingsTabs.tsx @@ -22,33 +22,32 @@ import { useRoutableTab, } from "../components/routable-tabs/RoutableTabs"; import { ViewHeader } from "../components/view-header/ViewHeader"; +import { useRealms } from "../context/RealmsContext"; import { useAdminClient } from "../context/auth/AdminClient"; import { useRealm } from "../context/realm-context/RealmContext"; -import { useRealms } from "../context/RealmsContext"; import { toDashboard } from "../dashboard/routes/Dashboard"; import environment from "../environment"; import helpUrls from "../help-urls"; import { convertFormValuesToObject, convertToFormValues } from "../util"; import useIsFeatureEnabled, { Feature } from "../utils/useIsFeatureEnabled"; import { RealmSettingsEmailTab } from "./EmailTab"; -import { EventsTab } from "./event-config/EventsTab"; import { RealmSettingsGeneralTab } from "./GeneralTab"; -import { KeysTab } from "./keys/KeysTab"; import { LocalizationTab } from "./LocalizationTab"; import { RealmSettingsLoginTab } from "./LoginTab"; import { PartialExportDialog } from "./PartialExport"; import { PartialImportDialog } from "./PartialImport"; import { PoliciesTab } from "./PoliciesTab"; import ProfilesTab from "./ProfilesTab"; -import { ClientPoliciesTab, toClientPolicies } from "./routes/ClientPolicies"; -import { RealmSettingsTab, toRealmSettings } from "./routes/RealmSettings"; -import { SecurityDefenses } from "./security-defences/SecurityDefenses"; import { RealmSettingsSessionsTab } from "./SessionsTab"; import { RealmSettingsThemesTab } from "./ThemesTab"; import { RealmSettingsTokensTab } from "./TokensTab"; -import { UserProfileTab } from "./user-profile/UserProfileTab"; import { UserRegistration } from "./UserRegistration"; -import { useServerInfo } from "../context/server-info/ServerInfoProvider"; +import { EventsTab } from "./event-config/EventsTab"; +import { KeysTab } from "./keys/KeysTab"; +import { ClientPoliciesTab, toClientPolicies } from "./routes/ClientPolicies"; +import { RealmSettingsTab, toRealmSettings } from "./routes/RealmSettings"; +import { SecurityDefenses } from "./security-defences/SecurityDefenses"; +import { UserProfileTab } from "./user-profile/UserProfileTab"; type RealmSettingsHeaderProps = { onChange: (value: boolean) => void; @@ -237,8 +236,6 @@ export const RealmSettingsTabs = ({ const sessionsTab = useTab("sessions"); const tokensTab = useTab("tokens"); const clientPoliciesTab = useTab("client-policies"); - const clientPoliciesDisabled = - useServerInfo().profileInfo?.disabledFeatures?.includes("CLIENT_POLICIES"); const userProfileTab = useTab("user-profile"); const userRegistrationTab = useTab("user-registration"); @@ -353,7 +350,7 @@ export const RealmSettingsTabs = ({ > - {!clientPoliciesDisabled && ( + {isFeatureEnabled(Feature.ClientPolicies) && ( diff --git a/js/apps/admin-ui/src/user-federation/UserFederationLdapForm.tsx b/js/apps/admin-ui/src/user-federation/UserFederationLdapForm.tsx index 4544badfb9..a065f5a098 100644 --- a/js/apps/admin-ui/src/user-federation/UserFederationLdapForm.tsx +++ b/js/apps/admin-ui/src/user-federation/UserFederationLdapForm.tsx @@ -6,6 +6,7 @@ import { useNavigate } from "react-router-dom"; import { ScrollForm } from "../components/scroll-form/ScrollForm"; import { useRealm } from "../context/realm-context/RealmContext"; +import useIsFeatureEnabled, { Feature } from "../utils/useIsFeatureEnabled"; import { LdapSettingsAdvanced } from "./ldap/LdapSettingsAdvanced"; import { LdapSettingsConnection } from "./ldap/LdapSettingsConnection"; import { LdapSettingsGeneral } from "./ldap/LdapSettingsGeneral"; @@ -14,7 +15,6 @@ import { LdapSettingsSearching } from "./ldap/LdapSettingsSearching"; import { LdapSettingsSynchronization } from "./ldap/LdapSettingsSynchronization"; import { toUserFederation } from "./routes/UserFederation"; import { SettingsCache } from "./shared/SettingsCache"; -import { useServerInfo } from "../context/server-info/ServerInfoProvider"; export type LdapComponentRepresentation = ComponentRepresentation & { config?: { @@ -36,8 +36,7 @@ export const UserFederationLdapForm = ({ const form = useFormContext(); const navigate = useNavigate(); const { realm } = useRealm(); - const kerberosDisabled = - useServerInfo().profileInfo?.disabledFeatures?.includes("KERBEROS"); + const isFeatureEnabled = useIsFeatureEnabled(); return ( <> @@ -62,7 +61,7 @@ export const UserFederationLdapForm = ({ { title: t("kerberosIntegration"), panel: , - isHidden: kerberosDisabled, + isHidden: !isFeatureEnabled(Feature.Kerberos), }, { title: t("cacheSettings"), panel: }, { diff --git a/js/apps/admin-ui/src/user-federation/UserFederationLdapWizard.tsx b/js/apps/admin-ui/src/user-federation/UserFederationLdapWizard.tsx index 85e8a4ef09..a9f2c83017 100644 --- a/js/apps/admin-ui/src/user-federation/UserFederationLdapWizard.tsx +++ b/js/apps/admin-ui/src/user-federation/UserFederationLdapWizard.tsx @@ -1,28 +1,26 @@ +import type ComponentRepresentation from "@keycloak/keycloak-admin-client/lib/defs/componentRepresentation"; import { Button, Wizard, WizardContextConsumer, WizardFooter, } from "@patternfly/react-core"; +import { useForm } from "react-hook-form"; +import { useTranslation } from "react-i18next"; -import { LdapSettingsGeneral } from "./ldap/LdapSettingsGeneral"; +import useIsFeatureEnabled, { Feature } from "../utils/useIsFeatureEnabled"; +import { LdapSettingsAdvanced } from "./ldap/LdapSettingsAdvanced"; import { LdapSettingsConnection } from "./ldap/LdapSettingsConnection"; +import { LdapSettingsGeneral } from "./ldap/LdapSettingsGeneral"; +import { LdapSettingsKerberosIntegration } from "./ldap/LdapSettingsKerberosIntegration"; import { LdapSettingsSearching } from "./ldap/LdapSettingsSearching"; import { LdapSettingsSynchronization } from "./ldap/LdapSettingsSynchronization"; -import { LdapSettingsKerberosIntegration } from "./ldap/LdapSettingsKerberosIntegration"; import { SettingsCache } from "./shared/SettingsCache"; -import { LdapSettingsAdvanced } from "./ldap/LdapSettingsAdvanced"; -import { useTranslation } from "react-i18next"; -import type ComponentRepresentation from "@keycloak/keycloak-admin-client/lib/defs/componentRepresentation"; - -import { useForm } from "react-hook-form"; -import { useServerInfo } from "../context/server-info/ServerInfoProvider"; export const UserFederationLdapWizard = () => { const form = useForm(); const { t } = useTranslation("user-federation"); - const kerberosDisabled = - useServerInfo().profileInfo?.disabledFeatures?.includes("KERBEROS"); + const isFeatureEnabled = useIsFeatureEnabled(); const steps = [ { @@ -79,7 +77,7 @@ export const UserFederationLdapWizard = () => { showSectionDescription /> ), - isDisabled: kerberosDisabled, + isDisabled: !isFeatureEnabled(Feature.Kerberos), }, { name: t("cacheSettings"), diff --git a/js/apps/admin-ui/src/user/UsersSection.tsx b/js/apps/admin-ui/src/user/UsersSection.tsx index 6f80eaa3d7..d89bd5c56b 100644 --- a/js/apps/admin-ui/src/user/UsersSection.tsx +++ b/js/apps/admin-ui/src/user/UsersSection.tsx @@ -1,6 +1,3 @@ -import { useState } from "react"; -import { Link, useNavigate } from "react-router-dom"; -import { useTranslation } from "react-i18next"; import { AlertVariant, Button, @@ -29,31 +26,34 @@ import { WarningTriangleIcon, } from "@patternfly/react-icons"; import type { IRowData } from "@patternfly/react-table"; +import { useState } from "react"; +import { useTranslation } from "react-i18next"; +import { Link, useNavigate } from "react-router-dom"; import type ComponentRepresentation from "@keycloak/keycloak-admin-client/lib/defs/componentRepresentation"; -import type UserRepresentation from "@keycloak/keycloak-admin-client/lib/defs/userRepresentation"; import type RealmRepresentation from "@keycloak/keycloak-admin-client/lib/defs/realmRepresentation"; -import { useServerInfo } from "../context/server-info/ServerInfoProvider"; +import type UserRepresentation from "@keycloak/keycloak-admin-client/lib/defs/userRepresentation"; import { useAlerts } from "../components/alert/Alerts"; import { useConfirmDialog } from "../components/confirm-dialog/ConfirmDialog"; -import { ListEmptyState } from "../components/list-empty-state/ListEmptyState"; -import { KeycloakDataTable } from "../components/table-toolbar/KeycloakDataTable"; -import { ViewHeader } from "../components/view-header/ViewHeader"; -import { useAdminClient, useFetch } from "../context/auth/AdminClient"; -import { useRealm } from "../context/realm-context/RealmContext"; -import { emptyFormatter } from "../util"; -import { toUser } from "./routes/User"; -import { toAddUser } from "./routes/AddUser"; -import helpUrls from "../help-urls"; import { KeycloakSpinner } from "../components/keycloak-spinner/KeycloakSpinner"; +import { ListEmptyState } from "../components/list-empty-state/ListEmptyState"; import { PermissionsTab } from "../components/permission-tab/PermissionTab"; -import { toUsers, UserTab } from "./routes/Users"; +import { BruteUser, findUsers } from "../components/role-mapping/resource"; import { RoutableTabs, useRoutableTab, } from "../components/routable-tabs/RoutableTabs"; +import { KeycloakDataTable } from "../components/table-toolbar/KeycloakDataTable"; +import { ViewHeader } from "../components/view-header/ViewHeader"; import { useAccess } from "../context/access/Access"; -import { BruteUser, findUsers } from "../components/role-mapping/resource"; +import { useAdminClient, useFetch } from "../context/auth/AdminClient"; +import { useRealm } from "../context/realm-context/RealmContext"; +import helpUrls from "../help-urls"; +import { emptyFormatter } from "../util"; +import useIsFeatureEnabled, { Feature } from "../utils/useIsFeatureEnabled"; +import { toAddUser } from "./routes/AddUser"; +import { toUser } from "./routes/User"; +import { UserTab, toUsers } from "./routes/Users"; import "./user-section.css"; @@ -68,7 +68,7 @@ export default function UsersSection() { const [realm, setRealm] = useState(); const [kebabOpen, setKebabOpen] = useState(false); const [selectedRows, setSelectedRows] = useState([]); - const { profileInfo } = useServerInfo(); + const isFeatureEnabled = useIsFeatureEnabled(); const [key, setKey] = useState(0); const refresh = () => setKey(key + 1); @@ -420,9 +420,7 @@ export default function UsersSection() { ]} /> - {!profileInfo?.disabledFeatures?.includes( - "ADMIN_FINE_GRAINED_AUTHZ" - ) && ( + {isFeatureEnabled(Feature.AdminFineGrainedAuthz) && ( !disabledFilters.includes(feature) - ); return function isFeatureEnabled(feature: Feature) { - return enabledFeatures.includes(feature); + return !disabledFilters.includes(feature); }; }