Revert "Always use `useIsFeatureEnabled()` hook for feature detection (#19589)" (#19635)

This reverts commit bdb9c140a4.
This commit is contained in:
Jon Koops 2023-04-11 13:28:24 +02:00 committed by GitHub
parent 43025a6d60
commit bcaab0e603
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 104 additions and 83 deletions

View File

@ -38,18 +38,16 @@ 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";
@ -57,6 +55,8 @@ 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 { ClientScopesTab, toClientScopesTab } from "./routes/ClientScopeTab";
import { toClients } from "./routes/Clients";
import { ClientScopesTab, toClientScopesTab } from "./routes/ClientScopeTab";
import { toCreateRole } from "./routes/NewRole";
import { ClientScopes } from "./scopes/ClientScopes";
import { EvaluateScopes } from "./scopes/EvaluateScopes";
@ -191,16 +191,17 @@ export default function ClientDetails() {
const { adminClient } = useAdminClient();
const { addAlert, addError } = useAlerts();
const { realm } = useRealm();
const { hasAccess } = useAccess();
const isFeatureEnabled = useIsFeatureEnabled();
const { profileInfo } = useServerInfo();
const { hasAccess } = useAccess();
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();

View File

@ -1,40 +1,41 @@
import type GroupRepresentation from "@keycloak/keycloak-admin-client/lib/defs/groupRepresentation";
import { useState } from "react";
import { useLocation, useNavigate } from "react-router-dom";
import { useTranslation } from "react-i18next";
import {
Drawer,
DrawerContent,
DrawerContentBody,
DrawerHead,
DrawerPanelContent,
DropdownItem,
PageSection,
PageSectionVariants,
Tab,
TabTitleText,
Tabs,
Drawer,
DrawerContent,
DrawerContentBody,
DrawerPanelContent,
DrawerHead,
} from "@patternfly/react-core";
import { useState } from "react";
import { useTranslation } from "react-i18next";
import { useLocation, useNavigate } from "react-router-dom";
import type GroupRepresentation from "@keycloak/keycloak-admin-client/lib/defs/groupRepresentation";
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 { useFetch, useAdminClient } 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 { 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 "./GroupsSection.css";
@ -42,6 +43,8 @@ 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();
@ -57,9 +60,8 @@ export default function GroupsSection() {
const refresh = () => setKey(key + 1);
const { hasAccess } = useAccess();
const isFeatureEnabled = useIsFeatureEnabled();
const canViewPermissions =
isFeatureEnabled(Feature.AdminFineGrainedAuthz) &&
!profileInfo?.disabledFeatures?.includes("ADMIN_FINE_GRAINED_AUTHZ") &&
hasAccess("manage-authorization", "manage-users", "manage-clients");
const canManageGroup =
hasAccess("manage-users") || currentGroup()?.access?.manage;

View File

@ -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<IdentityProviderParams>();
const isFeatureEnabled = useIsFeatureEnabled();
const form = useForm<IdentityProviderRepresentation>();
const { handleSubmit, getValues, reset } = form;
const [provider, setProvider] = useState<IdentityProviderRepresentation>();
@ -168,6 +168,7 @@ export default function DetailSettings() {
const navigate = useNavigate();
const { realm } = useRealm();
const [key, setKey] = useState(0);
const { profileInfo } = useServerInfo();
const refresh = () => setKey(key + 1);
useFetch(
@ -495,7 +496,9 @@ export default function DetailSettings() {
]}
/>
</Tab>
{isFeatureEnabled(Feature.AdminFineGrainedAuthz) && (
{!profileInfo?.disabledFeatures?.includes(
"ADMIN_FINE_GRAINED_AUTHZ"
) && (
<Tab
id="permissions"
data-testid="permissionsTab"

View File

@ -27,9 +27,9 @@ import {
AttributesForm,
} from "../components/key-value-form/AttributeForm";
import {
KeyValueType,
arrayToKeyValue,
keyValueToArray,
KeyValueType,
} from "../components/key-value-form/key-value-convert";
import { KeycloakSpinner } from "../components/keycloak-spinner/KeycloakSpinner";
import { PermissionsTab } from "../components/permission-tab/PermissionTab";
@ -43,14 +43,13 @@ import {
import { ViewHeader } from "../components/view-header/ViewHeader";
import { useAdminClient, useFetch } from "../context/auth/AdminClient";
import { useRealm } from "../context/realm-context/RealmContext";
import useIsFeatureEnabled, { Feature } from "../utils/useIsFeatureEnabled";
import { useServerInfo } from "../context/server-info/ServerInfoProvider";
import { useParams } from "../utils/useParams";
import { UsersInRoleTab } from "./UsersInRoleTab";
import { RealmRoleRoute, RealmRoleTab, toRealmRole } from "./routes/RealmRole";
import { toRealmRoles } from "./routes/RealmRoles";
import { UsersInRoleTab } from "./UsersInRoleTab";
export default function RealmRoleTabs() {
const isFeatureEnabled = useIsFeatureEnabled();
const { t } = useTranslation("roles");
const form = useForm<AttributeForm>({
mode: "onChange",
@ -68,6 +67,8 @@ export default function RealmRoleTabs() {
const [key, setKey] = useState(0);
const [attributes, setAttributes] = useState<KeyValueType[] | undefined>();
const { profileInfo } = useServerInfo();
const refresh = () => setKey(key + 1);
const { addAlert, addError } = useAlerts();
@ -390,7 +391,9 @@ export default function RealmRoleTabs() {
<UsersInRoleTab data-cy="users-in-role-tab" />
</Tab>
)}
{isFeatureEnabled(Feature.AdminFineGrainedAuthz) && (
{!profileInfo?.disabledFeatures?.includes(
"ADMIN_FINE_GRAINED_AUTHZ"
) && (
<Tab
title={<TabTitleText>{t("common:permissions")}</TabTitleText>}
{...permissionsTab}

View File

@ -22,32 +22,33 @@ 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 { RealmSettingsSessionsTab } from "./SessionsTab";
import { RealmSettingsThemesTab } from "./ThemesTab";
import { RealmSettingsTokensTab } from "./TokensTab";
import { UserRegistration } from "./UserRegistration";
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 { 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";
type RealmSettingsHeaderProps = {
onChange: (value: boolean) => void;
@ -236,6 +237,8 @@ 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");
@ -350,7 +353,7 @@ export const RealmSettingsTabs = ({
>
<RealmSettingsTokensTab save={save} realm={realm} />
</Tab>
{isFeatureEnabled(Feature.ClientPolicies) && (
{!clientPoliciesDisabled && (
<Tab
title={
<TabTitleText>

View File

@ -6,7 +6,6 @@ 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";
@ -15,6 +14,7 @@ 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,7 +36,8 @@ export const UserFederationLdapForm = ({
const form = useFormContext<LdapComponentRepresentation>();
const navigate = useNavigate();
const { realm } = useRealm();
const isFeatureEnabled = useIsFeatureEnabled();
const kerberosDisabled =
useServerInfo().profileInfo?.disabledFeatures?.includes("KERBEROS");
return (
<>
@ -61,7 +62,7 @@ export const UserFederationLdapForm = ({
{
title: t("kerberosIntegration"),
panel: <LdapSettingsKerberosIntegration form={form} />,
isHidden: !isFeatureEnabled(Feature.Kerberos),
isHidden: kerberosDisabled,
},
{ title: t("cacheSettings"), panel: <SettingsCache form={form} /> },
{

View File

@ -1,26 +1,28 @@
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 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 { LdapSettingsConnection } from "./ldap/LdapSettingsConnection";
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<ComponentRepresentation>();
const { t } = useTranslation("user-federation");
const isFeatureEnabled = useIsFeatureEnabled();
const kerberosDisabled =
useServerInfo().profileInfo?.disabledFeatures?.includes("KERBEROS");
const steps = [
{
@ -77,7 +79,7 @@ export const UserFederationLdapWizard = () => {
showSectionDescription
/>
),
isDisabled: !isFeatureEnabled(Feature.Kerberos),
isDisabled: kerberosDisabled,
},
{
name: t("cacheSettings"),

View File

@ -1,3 +1,6 @@
import { useState } from "react";
import { Link, useNavigate } from "react-router-dom";
import { useTranslation } from "react-i18next";
import {
AlertVariant,
Button,
@ -26,34 +29,31 @@ 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 RealmRepresentation from "@keycloak/keycloak-admin-client/lib/defs/realmRepresentation";
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 { useAlerts } from "../components/alert/Alerts";
import { useConfirmDialog } from "../components/confirm-dialog/ConfirmDialog";
import { KeycloakSpinner } from "../components/keycloak-spinner/KeycloakSpinner";
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 { PermissionsTab } from "../components/permission-tab/PermissionTab";
import { BruteUser, findUsers } from "../components/role-mapping/resource";
import { toUsers, UserTab } from "./routes/Users";
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 { 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 { BruteUser, findUsers } from "../components/role-mapping/resource";
import "./user-section.css";
@ -68,7 +68,7 @@ export default function UsersSection() {
const [realm, setRealm] = useState<RealmRepresentation | undefined>();
const [kebabOpen, setKebabOpen] = useState(false);
const [selectedRows, setSelectedRows] = useState<UserRepresentation[]>([]);
const isFeatureEnabled = useIsFeatureEnabled();
const { profileInfo } = useServerInfo();
const [key, setKey] = useState(0);
const refresh = () => setKey(key + 1);
@ -420,7 +420,9 @@ export default function UsersSection() {
]}
/>
</Tab>
{isFeatureEnabled(Feature.AdminFineGrainedAuthz) && (
{!profileInfo?.disabledFeatures?.includes(
"ADMIN_FINE_GRAINED_AUTHZ"
) && (
<Tab
id="permissions"
data-testid="permissionsTab"

View File

@ -1,17 +1,21 @@
import { useServerInfo } from "../context/server-info/ServerInfoProvider";
export enum Feature {
AdminFineGrainedAuthz = "ADMIN_FINE_GRAINED_AUTHZ",
ClientPolicies = "CLIENT_POLICIES",
DeclarativeUserProfile = "DECLARATIVE_USER_PROFILE",
Kerberos = "KERBEROS",
}
export default function useIsFeatureEnabled() {
const { profileInfo } = useServerInfo();
const experimentalFeatures = profileInfo?.experimentalFeatures ?? [];
const previewFeatures = profileInfo?.previewFeatures ?? [];
const disabledFilters = profileInfo?.disabledFeatures ?? [];
const allFeatures = [...experimentalFeatures, ...previewFeatures];
const enabledFeatures = allFeatures.filter(
(feature) => !disabledFilters.includes(feature)
);
return function isFeatureEnabled(feature: Feature) {
return !disabledFilters.includes(feature);
return enabledFeatures.includes(feature);
};
}