diff --git a/cypress/integration/realm_settings_test.spec.ts b/cypress/integration/realm_settings_test.spec.ts index 7445a73fea..22312f4fee 100644 --- a/cypress/integration/realm_settings_test.spec.ts +++ b/cypress/integration/realm_settings_test.spec.ts @@ -30,7 +30,17 @@ describe("Realm settings", () => { 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(); realmSettingsPage.toggleSwitch(realmSettingsPage.managedAccessSwitch); realmSettingsPage.save(realmSettingsPage.generalSaveBtn); @@ -134,21 +144,18 @@ describe("Realm settings", () => { cy.getId("option-aes-generated").click(); realmSettingsPage.enterConsoleDisplayName("test_aes-generated"); - cy.wait(200); realmSettingsPage.addProvider(); realmSettingsPage.toggleAddProviderDropdown(); cy.getId("option-ecdsa-generated").click(); realmSettingsPage.enterConsoleDisplayName("test_ecdsa-generated"); - cy.wait(200); realmSettingsPage.addProvider(); realmSettingsPage.toggleAddProviderDropdown(); cy.getId("option-hmac-generated").click(); realmSettingsPage.enterConsoleDisplayName("test_hmac-generated"); - cy.wait(200); realmSettingsPage.addProvider(); realmSettingsPage.toggleAddProviderDropdown(); @@ -157,4 +164,11 @@ describe("Realm settings", () => { realmSettingsPage.enterConsoleDisplayName("test_rsa-generated"); realmSettingsPage.addProvider(); }); + + it("Test keys", function () { + sidebarPage.goToRealmSettings(); + goToKeys(); + + realmSettingsPage.testSelectFilter(); + }); }); diff --git a/cypress/support/pages/admin_console/manage/realm_settings/RealmSettingsPage.ts b/cypress/support/pages/admin_console/manage/realm_settings/RealmSettingsPage.ts index 40ba9d0180..f30ac56054 100644 --- a/cypress/support/pages/admin_console/manage/realm_settings/RealmSettingsPage.ts +++ b/cypress/support/pages/admin_console/manage/realm_settings/RealmSettingsPage.ts @@ -32,6 +32,9 @@ export default class RealmSettingsPage { enableEvents = "eventsEnabled"; eventsUserSave = "save-user"; eventTypeColumn = 'tbody > tr > [data-label="Event saved type"]'; + filterSelectMenu = ".kc-filter-type-select"; + passiveKeysOption = "passive-keys-option"; + disabledKeysOption = "disabled-keys-option"; selectLoginThemeType(themeType: string) { const themesUrl = "/auth/admin/realms/master/themes"; @@ -89,6 +92,13 @@ export default class RealmSettingsPage { 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) { cy.getId(switchName).click({ force: true }); diff --git a/src/realm-settings/KeysListTab.tsx b/src/realm-settings/KeysListTab.tsx index 254faa6529..00f0a03a89 100644 --- a/src/realm-settings/KeysListTab.tsx +++ b/src/realm-settings/KeysListTab.tsx @@ -1,7 +1,14 @@ import React, { useState } from "react"; import { useHistory, useRouteMatch } from "react-router-dom"; 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 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 "./RealmSettingsSection.css"; +import { FilterIcon } from "@patternfly/react-icons"; type KeyData = KeyMetadataRepresentation & { provider?: string; @@ -28,8 +36,15 @@ export const KeysListTab = ({ realmComponents }: KeysListTabProps) => { const history = useHistory(); const { url } = useRouteMatch(); + const [key, setKey] = useState(0); const [publicKey, setPublicKey] = 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 { realm: realmName } = useRealm(); @@ -38,6 +53,7 @@ export const KeysListTab = ({ realmComponents }: KeysListTabProps) => { const keysMetaData = await adminClient.realms.getKeys({ realm: realmName, }); + const keys = keysMetaData.keys; 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({ titleKey: t("realm-settings:publicKeys").slice(0, -1), messageKey: publicKey, @@ -116,6 +180,25 @@ export const KeysListTab = ({ realmComponents }: KeysListTabProps) => { } }; + const options = [ + , + , + , + ]; + return ( <> @@ -123,9 +206,37 @@ export const KeysListTab = ({ realmComponents }: KeysListTabProps) => { setFilterDropdownOpen(!filterDropdownOpen)} + toggleIcon={} + onSelect={(_, value) => { + setFilterType(value as string); + refresh(); + setFilterDropdownOpen(false); + }} + selections={filterType} + > + {options} + + } canSelectAll columns={[ { @@ -144,25 +255,31 @@ export const KeysListTab = ({ realmComponents }: KeysListTabProps) => { name: "kid", displayKey: "realm-settings:kid", cellFormatters: [emptyFormatter()], + transforms: [cellWidth(10)], }, { name: "provider", displayKey: "realm-settings:provider", cellRenderer: ProviderRenderer, cellFormatters: [emptyFormatter()], + transforms: [cellWidth(10)], }, { name: "publicKeys", displayKey: "realm-settings:publicKeys", cellRenderer: ButtonRenderer, cellFormatters: [], + transforms: [cellWidth(20)], }, ]} emptyState={ diff --git a/src/realm-settings/RealmSettingsSection.tsx b/src/realm-settings/RealmSettingsSection.tsx index fb81bf4197..7d829f18a5 100644 --- a/src/realm-settings/RealmSettingsSection.tsx +++ b/src/realm-settings/RealmSettingsSection.tsx @@ -279,6 +279,7 @@ export const RealmSettingsSection = () => { {t("keysList")}} > diff --git a/src/realm-settings/messages.json b/src/realm-settings/messages.json index cf25a432b2..01d559a1b7 100644 --- a/src/realm-settings/messages.json +++ b/src/realm-settings/messages.json @@ -75,6 +75,11 @@ "providerDescription": "Provider description", "addProvider": "Add provider", "publicKeys": "Public keys", + "activeKeys": "Active keys", + "passiveKeys": "Passive keys", + "disabledKeys": "Disabled keys", + "noKeys": "No keys", + "noKeysDescription": "You haven't created any ", "certificate": "Certificate", "userRegistration": "User registration", "userRegistrationHelpText": "Enable/disable the registration page. A link for registration will show on login page too.",