Realm Settings(Client Policies): Add policies list (#1201)

* wip client policies: policies tab

* wip switches

* wip client policies: policies tab

* client policies list

* package.json

* revert to enabled
This commit is contained in:
Jenny 2021-09-23 09:41:29 -04:00 committed by GitHub
parent 8fc517f2a0
commit bef9539389
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 187 additions and 15 deletions

View file

@ -129,8 +129,6 @@ describe("Realm settings", () => {
sidebarPage.goToRealmSettings(); sidebarPage.goToRealmSettings();
cy.findByTestId("rs-email-tab").click(); cy.findByTestId("rs-email-tab").click();
cy.wait(1000);
realmSettingsPage.addSenderEmail("example@example.com"); realmSettingsPage.addSenderEmail("example@example.com");
realmSettingsPage.toggleCheck(realmSettingsPage.enableSslCheck); realmSettingsPage.toggleCheck(realmSettingsPage.enableSslCheck);

14
package-lock.json generated
View file

@ -9,7 +9,7 @@
"version": "0.0.1", "version": "0.0.1",
"license": "Apache", "license": "Apache",
"dependencies": { "dependencies": {
"@keycloak/keycloak-admin-client": "^16.0.0-dev.18", "@keycloak/keycloak-admin-client": "^16.0.0-dev.19",
"@patternfly/patternfly": "^4.135.2", "@patternfly/patternfly": "^4.135.2",
"@patternfly/react-code-editor": "^4.3.61", "@patternfly/react-code-editor": "^4.3.61",
"@patternfly/react-core": "4.157.3", "@patternfly/react-core": "4.157.3",
@ -3334,9 +3334,9 @@
} }
}, },
"node_modules/@keycloak/keycloak-admin-client": { "node_modules/@keycloak/keycloak-admin-client": {
"version": "16.0.0-dev.18", "version": "16.0.0-dev.19",
"resolved": "https://registry.npmjs.org/@keycloak/keycloak-admin-client/-/keycloak-admin-client-16.0.0-dev.18.tgz", "resolved": "https://registry.npmjs.org/@keycloak/keycloak-admin-client/-/keycloak-admin-client-16.0.0-dev.19.tgz",
"integrity": "sha512-xGriGt20ZuSr4RNs0zS+EwGqfaL7ivKhHw1p3Y56sKtqmxu5+T8/KxxmAcQkqPu8qeUNL9e/8CqYwM4jqF95Jg==", "integrity": "sha512-sR2v/BK28jvTFvRbxWfeTcENnKTe80oGw1uqA95xFt5neYrFuote+KneFlBNMNSah9B+40QQ8D7D4VAG27q2mw==",
"dependencies": { "dependencies": {
"axios": "^0.21.0", "axios": "^0.21.0",
"camelize": "^1.0.0", "camelize": "^1.0.0",
@ -22472,9 +22472,9 @@
} }
}, },
"@keycloak/keycloak-admin-client": { "@keycloak/keycloak-admin-client": {
"version": "16.0.0-dev.18", "version": "16.0.0-dev.19",
"resolved": "https://registry.npmjs.org/@keycloak/keycloak-admin-client/-/keycloak-admin-client-16.0.0-dev.18.tgz", "resolved": "https://registry.npmjs.org/@keycloak/keycloak-admin-client/-/keycloak-admin-client-16.0.0-dev.19.tgz",
"integrity": "sha512-xGriGt20ZuSr4RNs0zS+EwGqfaL7ivKhHw1p3Y56sKtqmxu5+T8/KxxmAcQkqPu8qeUNL9e/8CqYwM4jqF95Jg==", "integrity": "sha512-sR2v/BK28jvTFvRbxWfeTcENnKTe80oGw1uqA95xFt5neYrFuote+KneFlBNMNSah9B+40QQ8D7D4VAG27q2mw==",
"requires": { "requires": {
"axios": "^0.21.0", "axios": "^0.21.0",
"camelize": "^1.0.0", "camelize": "^1.0.0",

View file

@ -24,7 +24,7 @@
"prepare": "husky install" "prepare": "husky install"
}, },
"dependencies": { "dependencies": {
"@keycloak/keycloak-admin-client": "^16.0.0-dev.18", "@keycloak/keycloak-admin-client": "^16.0.0-dev.19",
"@patternfly/patternfly": "^4.135.2", "@patternfly/patternfly": "^4.135.2",
"@patternfly/react-code-editor": "^4.3.61", "@patternfly/react-code-editor": "^4.3.61",
"@patternfly/react-core": "4.157.3", "@patternfly/react-core": "4.157.3",

View file

@ -1,12 +1,170 @@
import React from "react"; import React, { useMemo, useState } from "react";
import { PageSection } from "@patternfly/react-core"; import {
AlertVariant,
Button,
ButtonVariant,
Divider,
Flex,
FlexItem,
PageSection,
Radio,
Title,
ToolbarItem,
} from "@patternfly/react-core";
import "./RealmSettingsSection.css"; import "./RealmSettingsSection.css";
import { ListEmptyState } from "../components/list-empty-state/ListEmptyState";
import { KeycloakDataTable } from "../components/table-toolbar/KeycloakDataTable";
import { useTranslation } from "react-i18next";
import { useAdminClient } from "../context/auth/AdminClient";
import { upperCaseFormatter } from "../util";
import { CodeEditor, Language } from "@patternfly/react-code-editor";
import { Link } from "react-router-dom";
import type ClientPolicyRepresentation from "@keycloak/keycloak-admin-client/lib/defs/clientPolicyRepresentation";
import { useConfirmDialog } from "../components/confirm-dialog/ConfirmDialog";
import { useAlerts } from "../components/alert/Alerts";
export const PoliciesTab = () => { export const PoliciesTab = () => {
const { t } = useTranslation("realm-settings");
const adminClient = useAdminClient();
const { addAlert, addError } = useAlerts();
const [show, setShow] = useState(false);
const [policies, setPolicies] = useState<ClientPolicyRepresentation[]>([]);
const [selectedPolicy, setSelectedPolicy] =
useState<ClientPolicyRepresentation>();
const loader = async () => {
const policies = await adminClient.clientPolicies.listPolicies();
setPolicies(policies.policies!);
return policies.policies!;
};
const code = useMemo(() => JSON.stringify(policies, null, 2), [policies]);
const [toggleDeleteDialog, DeleteConfirm] = useConfirmDialog({
titleKey: t("deleteClientPolicyConfirmTitle"),
messageKey: t("deleteClientPolicyConfirm", {
policyName: selectedPolicy?.name,
}),
continueButtonLabel: t("delete"),
continueButtonVariant: ButtonVariant.danger,
onConfirm: async () => {
try {
// delete client policy here
addAlert(t("deleteClientPolicySuccess"), AlertVariant.success);
} catch (error) {
addError(t("deleteClientPolicyError"), error);
}
},
});
return ( return (
<PageSection variant="light" padding={{ default: "noPadding" }}> <>
<h1>Policies Tab</h1> <DeleteConfirm />
</PageSection> <PageSection>
<Flex className="kc-policies-config-section">
<FlexItem>
<Title headingLevel="h1" size="md">
{t("policiesConfigType")}
</Title>
</FlexItem>
<FlexItem>
<Radio
isChecked={!show}
name="formView"
onChange={() => setShow(false)}
label={t("policiesConfigTypes.formView")}
id="formView-radioBtn"
className="kc-form-radio-btn pf-u-mr-sm pf-u-ml-sm"
/>
</FlexItem>
<FlexItem>
<Radio
isChecked={show}
name="jsonEditor"
onChange={() => setShow(true)}
label={t("policiesConfigTypes.jsonEditor")}
id="jsonEditor-radioBtn"
className="kc-editor-radio-btn"
/>
</FlexItem>
</Flex>
</PageSection>
<Divider />
{!show ? (
<KeycloakDataTable
emptyState={
<ListEmptyState
message={t("realm-settings:noClientPolicies")}
instructions={t("realm-settings:noClientPoliciesInstructions")}
primaryActionText={t("realm-settings:createClientPolicy")}
/>
}
ariaLabelKey="identity-providers:mappersList"
searchPlaceholderKey="realm-settings:clientPolicySearch"
isPaginated
loader={loader}
toolbarItem={
<ToolbarItem>
<Button
id="createPolicy"
component={Link}
data-testid="createPolicy"
>
{t("createClientPolicy")}
</Button>
</ToolbarItem>
}
actions={[
{
title: t("common:delete"),
onRowClick: (item) => {
toggleDeleteDialog();
setSelectedPolicy(item);
},
},
]}
columns={[
{
name: "name",
displayKey: "common:name",
},
{
name: "enabled",
displayKey: "common:enabled",
cellFormatters: [upperCaseFormatter()],
},
{
name: "description",
displayKey: "common:description",
},
]}
/>
) : (
<>
<div className="pf-u-mt-md pf-u-ml-lg">
<CodeEditor
isLineNumbersVisible
isLanguageLabelVisible
code={code}
language={Language.json}
height="30rem"
/>
</div>
<div className="pf-u-mt-md">
<Button
variant={ButtonVariant.primary}
className="pf-u-mr-md pf-u-ml-lg"
>
{t("save")}
</Button>
<Button variant={ButtonVariant.secondary}> {t("reload")}</Button>
</div>
</>
)}
</>
); );
}; };

View file

@ -191,6 +191,21 @@ export default {
idpAccountEmailVerification: "IdP account email verification", idpAccountEmailVerification: "IdP account email verification",
executeActions: "Execute actions", executeActions: "Execute actions",
clientPolicies: "Client policies", clientPolicies: "Client policies",
noClientPolicies: "No client policies",
noClientPoliciesInstructions:
"There are no client policies. Select 'Create client policy' to create a new client policy.",
createClientPolicy: "Create client policy",
clientPolicySearch: "Search client policy",
policiesConfigType: "Configure via:",
policiesConfigTypes: {
formView: "Form view",
jsonEditor: "JSON editor",
},
deleteClientPolicyConfirmTitle: "Delete policy?",
deleteClientPolicyConfirm:
"This action will permanently delete the policy {{policyName}}. This cannot be undone.",
deleteClientPolicySuccess: "Client policy deleted",
deleteClientPolicyError: "Could not delete policy: {{error}}",
profiles: "Profiles", profiles: "Profiles",
policies: "Policies", policies: "Policies",
clientPoliciesProfilesHelpText: clientPoliciesProfilesHelpText:
@ -230,6 +245,7 @@ export default {
tokens: "Tokens", tokens: "Tokens",
key: "Key", key: "Key",
value: "Value", value: "Value",
status: "Status",
convertedToYearsValue: "{{convertedToYears}}", convertedToYearsValue: "{{convertedToYears}}",
convertedToDaysValue: "{{convertedToDays}}", convertedToDaysValue: "{{convertedToDays}}",
convertedToHoursValue: "{{convertedToHours}}", convertedToHoursValue: "{{convertedToHours}}",