Add filter capability to keys section in realm settings (#666)
* rebase * fix empty state text
This commit is contained in:
parent
f322edec10
commit
d77d9a2a63
5 changed files with 155 additions and 8 deletions
|
@ -30,7 +30,17 @@ describe("Realm settings", () => {
|
||||||
await new AdminClient().deleteRealm(realmName);
|
await new AdminClient().deleteRealm(realmName);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Go to general tab", () => {
|
const goToKeys = () => {
|
||||||
|
const keysUrl = "/auth/admin/realms/master/keys";
|
||||||
|
cy.intercept(keysUrl).as("keysFetch");
|
||||||
|
cy.getId("rs-keys-tab").click();
|
||||||
|
cy.wait(10000);
|
||||||
|
cy.getId("rs-keys-list-tab").click();
|
||||||
|
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
it("Go to general tab", function () {
|
||||||
sidebarPage.goToRealmSettings();
|
sidebarPage.goToRealmSettings();
|
||||||
realmSettingsPage.toggleSwitch(realmSettingsPage.managedAccessSwitch);
|
realmSettingsPage.toggleSwitch(realmSettingsPage.managedAccessSwitch);
|
||||||
realmSettingsPage.save(realmSettingsPage.generalSaveBtn);
|
realmSettingsPage.save(realmSettingsPage.generalSaveBtn);
|
||||||
|
@ -134,21 +144,18 @@ describe("Realm settings", () => {
|
||||||
|
|
||||||
cy.getId("option-aes-generated").click();
|
cy.getId("option-aes-generated").click();
|
||||||
realmSettingsPage.enterConsoleDisplayName("test_aes-generated");
|
realmSettingsPage.enterConsoleDisplayName("test_aes-generated");
|
||||||
cy.wait(200);
|
|
||||||
realmSettingsPage.addProvider();
|
realmSettingsPage.addProvider();
|
||||||
|
|
||||||
realmSettingsPage.toggleAddProviderDropdown();
|
realmSettingsPage.toggleAddProviderDropdown();
|
||||||
|
|
||||||
cy.getId("option-ecdsa-generated").click();
|
cy.getId("option-ecdsa-generated").click();
|
||||||
realmSettingsPage.enterConsoleDisplayName("test_ecdsa-generated");
|
realmSettingsPage.enterConsoleDisplayName("test_ecdsa-generated");
|
||||||
cy.wait(200);
|
|
||||||
realmSettingsPage.addProvider();
|
realmSettingsPage.addProvider();
|
||||||
|
|
||||||
realmSettingsPage.toggleAddProviderDropdown();
|
realmSettingsPage.toggleAddProviderDropdown();
|
||||||
|
|
||||||
cy.getId("option-hmac-generated").click();
|
cy.getId("option-hmac-generated").click();
|
||||||
realmSettingsPage.enterConsoleDisplayName("test_hmac-generated");
|
realmSettingsPage.enterConsoleDisplayName("test_hmac-generated");
|
||||||
cy.wait(200);
|
|
||||||
realmSettingsPage.addProvider();
|
realmSettingsPage.addProvider();
|
||||||
|
|
||||||
realmSettingsPage.toggleAddProviderDropdown();
|
realmSettingsPage.toggleAddProviderDropdown();
|
||||||
|
@ -157,4 +164,11 @@ describe("Realm settings", () => {
|
||||||
realmSettingsPage.enterConsoleDisplayName("test_rsa-generated");
|
realmSettingsPage.enterConsoleDisplayName("test_rsa-generated");
|
||||||
realmSettingsPage.addProvider();
|
realmSettingsPage.addProvider();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("Test keys", function () {
|
||||||
|
sidebarPage.goToRealmSettings();
|
||||||
|
goToKeys();
|
||||||
|
|
||||||
|
realmSettingsPage.testSelectFilter();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -32,6 +32,9 @@ export default class RealmSettingsPage {
|
||||||
enableEvents = "eventsEnabled";
|
enableEvents = "eventsEnabled";
|
||||||
eventsUserSave = "save-user";
|
eventsUserSave = "save-user";
|
||||||
eventTypeColumn = 'tbody > tr > [data-label="Event saved type"]';
|
eventTypeColumn = 'tbody > tr > [data-label="Event saved type"]';
|
||||||
|
filterSelectMenu = ".kc-filter-type-select";
|
||||||
|
passiveKeysOption = "passive-keys-option";
|
||||||
|
disabledKeysOption = "disabled-keys-option";
|
||||||
|
|
||||||
selectLoginThemeType(themeType: string) {
|
selectLoginThemeType(themeType: string) {
|
||||||
const themesUrl = "/auth/admin/realms/master/themes";
|
const themesUrl = "/auth/admin/realms/master/themes";
|
||||||
|
@ -89,6 +92,13 @@ export default class RealmSettingsPage {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
testSelectFilter() {
|
||||||
|
cy.get(this.filterSelectMenu).first().click();
|
||||||
|
cy.getId(this.passiveKeysOption).click();
|
||||||
|
cy.get(this.filterSelectMenu).first().click();
|
||||||
|
cy.getId(this.disabledKeysOption).click();
|
||||||
|
}
|
||||||
|
|
||||||
toggleSwitch(switchName: string) {
|
toggleSwitch(switchName: string) {
|
||||||
cy.getId(switchName).click({ force: true });
|
cy.getId(switchName).click({ force: true });
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,14 @@
|
||||||
import React, { useState } from "react";
|
import React, { useState } from "react";
|
||||||
import { useHistory, useRouteMatch } from "react-router-dom";
|
import { useHistory, useRouteMatch } from "react-router-dom";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { Button, ButtonVariant, PageSection } from "@patternfly/react-core";
|
import {
|
||||||
|
Button,
|
||||||
|
ButtonVariant,
|
||||||
|
PageSection,
|
||||||
|
Select,
|
||||||
|
SelectOption,
|
||||||
|
SelectVariant,
|
||||||
|
} from "@patternfly/react-core";
|
||||||
import { cellWidth } from "@patternfly/react-table";
|
import { cellWidth } from "@patternfly/react-table";
|
||||||
|
|
||||||
import type { KeyMetadataRepresentation } from "keycloak-admin/lib/defs/keyMetadataRepresentation";
|
import type { KeyMetadataRepresentation } from "keycloak-admin/lib/defs/keyMetadataRepresentation";
|
||||||
|
@ -14,6 +21,7 @@ import { useAdminClient } from "../context/auth/AdminClient";
|
||||||
import { useRealm } from "../context/realm-context/RealmContext";
|
import { useRealm } from "../context/realm-context/RealmContext";
|
||||||
|
|
||||||
import "./RealmSettingsSection.css";
|
import "./RealmSettingsSection.css";
|
||||||
|
import { FilterIcon } from "@patternfly/react-icons";
|
||||||
|
|
||||||
type KeyData = KeyMetadataRepresentation & {
|
type KeyData = KeyMetadataRepresentation & {
|
||||||
provider?: string;
|
provider?: string;
|
||||||
|
@ -28,8 +36,15 @@ export const KeysListTab = ({ realmComponents }: KeysListTabProps) => {
|
||||||
const history = useHistory();
|
const history = useHistory();
|
||||||
const { url } = useRouteMatch();
|
const { url } = useRouteMatch();
|
||||||
|
|
||||||
|
const [key, setKey] = useState(0);
|
||||||
const [publicKey, setPublicKey] = useState("");
|
const [publicKey, setPublicKey] = useState("");
|
||||||
const [certificate, setCertificate] = useState("");
|
const [certificate, setCertificate] = useState("");
|
||||||
|
const [filterDropdownOpen, setFilterDropdownOpen] = useState(false);
|
||||||
|
const [filterType, setFilterType] = useState("Active keys");
|
||||||
|
|
||||||
|
const refresh = () => {
|
||||||
|
setKey(new Date().getTime());
|
||||||
|
};
|
||||||
|
|
||||||
const adminClient = useAdminClient();
|
const adminClient = useAdminClient();
|
||||||
const { realm: realmName } = useRealm();
|
const { realm: realmName } = useRealm();
|
||||||
|
@ -38,6 +53,7 @@ export const KeysListTab = ({ realmComponents }: KeysListTabProps) => {
|
||||||
const keysMetaData = await adminClient.realms.getKeys({
|
const keysMetaData = await adminClient.realms.getKeys({
|
||||||
realm: realmName,
|
realm: realmName,
|
||||||
});
|
});
|
||||||
|
|
||||||
const keys = keysMetaData.keys;
|
const keys = keysMetaData.keys;
|
||||||
|
|
||||||
return keys?.map((key) => {
|
return keys?.map((key) => {
|
||||||
|
@ -48,6 +64,54 @@ export const KeysListTab = ({ realmComponents }: KeysListTabProps) => {
|
||||||
})!;
|
})!;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const activeKeysLoader = async () => {
|
||||||
|
const keysMetaData = await adminClient.realms.getKeys({
|
||||||
|
realm: realmName,
|
||||||
|
});
|
||||||
|
const keys = keysMetaData.keys;
|
||||||
|
|
||||||
|
const activeKeysCopy = keys!.filter((i) => i.status === "ACTIVE");
|
||||||
|
|
||||||
|
return activeKeysCopy?.map((key) => {
|
||||||
|
const provider = realmComponents!.find(
|
||||||
|
(component: ComponentRepresentation) => component.id === key.providerId
|
||||||
|
);
|
||||||
|
return { ...key, provider: provider?.name } as KeyData;
|
||||||
|
})!;
|
||||||
|
};
|
||||||
|
|
||||||
|
const passiveKeysLoader = async () => {
|
||||||
|
const keysMetaData = await adminClient.realms.getKeys({
|
||||||
|
realm: realmName,
|
||||||
|
});
|
||||||
|
const keys = keysMetaData.keys;
|
||||||
|
|
||||||
|
const passiveKeys = keys!.filter((i) => i.status === "PASSIVE");
|
||||||
|
|
||||||
|
return passiveKeys?.map((key) => {
|
||||||
|
const provider = realmComponents!.find(
|
||||||
|
(component: ComponentRepresentation) => component.id === key.providerId
|
||||||
|
);
|
||||||
|
return { ...key, provider: provider?.name } as KeyData;
|
||||||
|
})!;
|
||||||
|
};
|
||||||
|
|
||||||
|
const disabledKeysLoader = async () => {
|
||||||
|
const keysMetaData = await adminClient.realms.getKeys({
|
||||||
|
realm: realmName,
|
||||||
|
});
|
||||||
|
const keys = keysMetaData.keys;
|
||||||
|
|
||||||
|
const disabledKeys = keys!.filter((i) => i.status === "DISABLED");
|
||||||
|
|
||||||
|
return disabledKeys?.map((key) => {
|
||||||
|
const provider = realmComponents!.find(
|
||||||
|
(component: ComponentRepresentation) => component.id === key.providerId
|
||||||
|
);
|
||||||
|
return { ...key, provider: provider?.name } as KeyData;
|
||||||
|
})!;
|
||||||
|
};
|
||||||
|
|
||||||
const [togglePublicKeyDialog, PublicKeyDialog] = useConfirmDialog({
|
const [togglePublicKeyDialog, PublicKeyDialog] = useConfirmDialog({
|
||||||
titleKey: t("realm-settings:publicKeys").slice(0, -1),
|
titleKey: t("realm-settings:publicKeys").slice(0, -1),
|
||||||
messageKey: publicKey,
|
messageKey: publicKey,
|
||||||
|
@ -116,6 +180,25 @@ export const KeysListTab = ({ realmComponents }: KeysListTabProps) => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const options = [
|
||||||
|
<SelectOption
|
||||||
|
key={1}
|
||||||
|
data-testid="active-keys-option"
|
||||||
|
value={t("realm-settings:activeKeys")}
|
||||||
|
isPlaceholder
|
||||||
|
/>,
|
||||||
|
<SelectOption
|
||||||
|
data-testid="passive-keys-option"
|
||||||
|
key={2}
|
||||||
|
value={t("realm-settings:passiveKeys")}
|
||||||
|
/>,
|
||||||
|
<SelectOption
|
||||||
|
data-testid="disabled-keys-option"
|
||||||
|
key={3}
|
||||||
|
value={t("realm-settings:disabledKeys")}
|
||||||
|
/>,
|
||||||
|
];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<PageSection variant="light" padding={{ default: "noPadding" }}>
|
<PageSection variant="light" padding={{ default: "noPadding" }}>
|
||||||
|
@ -123,9 +206,37 @@ export const KeysListTab = ({ realmComponents }: KeysListTabProps) => {
|
||||||
<CertificateDialog />
|
<CertificateDialog />
|
||||||
<KeycloakDataTable
|
<KeycloakDataTable
|
||||||
isNotCompact={true}
|
isNotCompact={true}
|
||||||
loader={loader}
|
key={key}
|
||||||
|
loader={
|
||||||
|
filterType === "Active keys"
|
||||||
|
? activeKeysLoader
|
||||||
|
: filterType === "Passive keys"
|
||||||
|
? passiveKeysLoader
|
||||||
|
: filterType === "Disabled keys"
|
||||||
|
? disabledKeysLoader
|
||||||
|
: loader
|
||||||
|
}
|
||||||
ariaLabelKey="realm-settings:keysList"
|
ariaLabelKey="realm-settings:keysList"
|
||||||
searchPlaceholderKey="realm-settings:searchKey"
|
searchPlaceholderKey="realm-settings:searchKey"
|
||||||
|
searchTypeComponent={
|
||||||
|
<Select
|
||||||
|
width={300}
|
||||||
|
data-testid="filter-type-select"
|
||||||
|
isOpen={filterDropdownOpen}
|
||||||
|
className="kc-filter-type-select"
|
||||||
|
variant={SelectVariant.single}
|
||||||
|
onToggle={() => setFilterDropdownOpen(!filterDropdownOpen)}
|
||||||
|
toggleIcon={<FilterIcon />}
|
||||||
|
onSelect={(_, value) => {
|
||||||
|
setFilterType(value as string);
|
||||||
|
refresh();
|
||||||
|
setFilterDropdownOpen(false);
|
||||||
|
}}
|
||||||
|
selections={filterType}
|
||||||
|
>
|
||||||
|
{options}
|
||||||
|
</Select>
|
||||||
|
}
|
||||||
canSelectAll
|
canSelectAll
|
||||||
columns={[
|
columns={[
|
||||||
{
|
{
|
||||||
|
@ -144,25 +255,31 @@ export const KeysListTab = ({ realmComponents }: KeysListTabProps) => {
|
||||||
name: "kid",
|
name: "kid",
|
||||||
displayKey: "realm-settings:kid",
|
displayKey: "realm-settings:kid",
|
||||||
cellFormatters: [emptyFormatter()],
|
cellFormatters: [emptyFormatter()],
|
||||||
|
transforms: [cellWidth(10)],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "provider",
|
name: "provider",
|
||||||
displayKey: "realm-settings:provider",
|
displayKey: "realm-settings:provider",
|
||||||
cellRenderer: ProviderRenderer,
|
cellRenderer: ProviderRenderer,
|
||||||
cellFormatters: [emptyFormatter()],
|
cellFormatters: [emptyFormatter()],
|
||||||
|
transforms: [cellWidth(10)],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "publicKeys",
|
name: "publicKeys",
|
||||||
displayKey: "realm-settings:publicKeys",
|
displayKey: "realm-settings:publicKeys",
|
||||||
cellRenderer: ButtonRenderer,
|
cellRenderer: ButtonRenderer,
|
||||||
cellFormatters: [],
|
cellFormatters: [],
|
||||||
|
transforms: [cellWidth(20)],
|
||||||
},
|
},
|
||||||
]}
|
]}
|
||||||
emptyState={
|
emptyState={
|
||||||
<ListEmptyState
|
<ListEmptyState
|
||||||
hasIcon={true}
|
hasIcon={true}
|
||||||
message={t("noRoles")}
|
message={t("realm-settings:noKeys")}
|
||||||
instructions={t("noRolesInstructions")}
|
instructions={
|
||||||
|
t(`realm-settings:noKeysDescription`) +
|
||||||
|
`${filterType.toLocaleLowerCase()}.`
|
||||||
|
}
|
||||||
primaryActionText={t("createRole")}
|
primaryActionText={t("createRole")}
|
||||||
onPrimaryAction={goToCreate}
|
onPrimaryAction={goToCreate}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -279,6 +279,7 @@ export const RealmSettingsSection = () => {
|
||||||
<Tab
|
<Tab
|
||||||
id="keysList"
|
id="keysList"
|
||||||
eventKey={0}
|
eventKey={0}
|
||||||
|
data-testid="rs-keys-list-tab"
|
||||||
title={<TabTitleText>{t("keysList")}</TabTitleText>}
|
title={<TabTitleText>{t("keysList")}</TabTitleText>}
|
||||||
>
|
>
|
||||||
<KeysListTab realmComponents={realmComponents} />
|
<KeysListTab realmComponents={realmComponents} />
|
||||||
|
|
|
@ -75,6 +75,11 @@
|
||||||
"providerDescription": "Provider description",
|
"providerDescription": "Provider description",
|
||||||
"addProvider": "Add provider",
|
"addProvider": "Add provider",
|
||||||
"publicKeys": "Public keys",
|
"publicKeys": "Public keys",
|
||||||
|
"activeKeys": "Active keys",
|
||||||
|
"passiveKeys": "Passive keys",
|
||||||
|
"disabledKeys": "Disabled keys",
|
||||||
|
"noKeys": "No keys",
|
||||||
|
"noKeysDescription": "You haven't created any ",
|
||||||
"certificate": "Certificate",
|
"certificate": "Certificate",
|
||||||
"userRegistration": "User registration",
|
"userRegistration": "User registration",
|
||||||
"userRegistrationHelpText": "Enable/disable the registration page. A link for registration will show on login page too.",
|
"userRegistrationHelpText": "Enable/disable the registration page. A link for registration will show on login page too.",
|
||||||
|
|
Loading…
Reference in a new issue