Added default group tab to user registration (#1965)
This commit is contained in:
parent
f9d3f9dfa7
commit
90199db346
11 changed files with 386 additions and 14 deletions
54
cypress/integration/realm_user_registration.spec.ts
Normal file
54
cypress/integration/realm_user_registration.spec.ts
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
import ListingPage from "../support/pages/admin_console/ListingPage";
|
||||||
|
import UserRegistration, {
|
||||||
|
GroupPickerDialog,
|
||||||
|
} from "../support/pages/admin_console/manage/realm_settings/UserRegistration";
|
||||||
|
import Masthead from "../support/pages/admin_console/Masthead";
|
||||||
|
import SidebarPage from "../support/pages/admin_console/SidebarPage";
|
||||||
|
import LoginPage from "../support/pages/LoginPage";
|
||||||
|
import AdminClient from "../support/util/AdminClient";
|
||||||
|
import {
|
||||||
|
keycloakBefore,
|
||||||
|
keycloakBeforeEach,
|
||||||
|
} from "../support/util/keycloak_hooks";
|
||||||
|
|
||||||
|
describe("Realm settings - User registration tab", () => {
|
||||||
|
const loginPage = new LoginPage();
|
||||||
|
const sidebarPage = new SidebarPage();
|
||||||
|
const masthead = new Masthead();
|
||||||
|
const adminClient = new AdminClient();
|
||||||
|
|
||||||
|
const listingPage = new ListingPage();
|
||||||
|
const groupPicker = new GroupPickerDialog();
|
||||||
|
const userRegistration = new UserRegistration();
|
||||||
|
|
||||||
|
const groupName = "The default group";
|
||||||
|
|
||||||
|
before(() => {
|
||||||
|
adminClient.createGroup(groupName);
|
||||||
|
keycloakBefore();
|
||||||
|
loginPage.logIn();
|
||||||
|
});
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
keycloakBeforeEach();
|
||||||
|
sidebarPage.goToRealmSettings();
|
||||||
|
userRegistration.goToTab();
|
||||||
|
});
|
||||||
|
|
||||||
|
after(() => adminClient.deleteGroups());
|
||||||
|
|
||||||
|
it("add default role", () => {
|
||||||
|
const role = "admin";
|
||||||
|
userRegistration.addRoleButtonClick();
|
||||||
|
userRegistration.selectRow(role).assign();
|
||||||
|
masthead.checkNotificationMessage("Associated roles have been added");
|
||||||
|
listingPage.searchItem(role, false).itemExist(role);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("add default role", () => {
|
||||||
|
userRegistration.goToDefaultGroupTab().addDefaultGroupClick();
|
||||||
|
groupPicker.checkTitle("Add default groups").clickRow(groupName).clickAdd();
|
||||||
|
masthead.checkNotificationMessage("New group added to the default groups");
|
||||||
|
listingPage.itemExist(groupName);
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,68 @@
|
||||||
|
export default class UserRegistration {
|
||||||
|
private userRegistrationTab = "rs-userRegistration-tab";
|
||||||
|
private defaultGroupTab = "#pf-tab-20-groups";
|
||||||
|
private addRoleButton = "add-role-button";
|
||||||
|
private addDefaultGroup = "no-default-groups-empty-action";
|
||||||
|
private namesColumn = 'td[data-label="Role name"]:visible';
|
||||||
|
private addBtn = "add-associated-roles-button";
|
||||||
|
|
||||||
|
goToTab() {
|
||||||
|
cy.findByTestId(this.userRegistrationTab).click();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
goToDefaultGroupTab() {
|
||||||
|
cy.get(this.defaultGroupTab).click();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
addRoleButtonClick() {
|
||||||
|
cy.findByTestId(this.addRoleButton).click();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
addDefaultGroupClick() {
|
||||||
|
cy.findByTestId(this.addDefaultGroup).click();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
selectRow(name: string) {
|
||||||
|
cy.get(this.namesColumn)
|
||||||
|
.contains(name)
|
||||||
|
.parent()
|
||||||
|
.within(() => {
|
||||||
|
cy.get("input").click();
|
||||||
|
});
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
assign() {
|
||||||
|
cy.findByTestId(this.addBtn).click();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class GroupPickerDialog {
|
||||||
|
private addButton = "common:add-button";
|
||||||
|
private title = ".pf-c-modal-box__title";
|
||||||
|
|
||||||
|
clickRow(groupName: string) {
|
||||||
|
cy.findByTestId(groupName).within(() => cy.get("input").click());
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
clickRoot() {
|
||||||
|
cy.get(".pf-c-breadcrumb__item > button").click();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
checkTitle(title: string) {
|
||||||
|
cy.get(this.title).should("have.text", title);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
clickAdd() {
|
||||||
|
cy.findByTestId(this.addButton).click();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
|
@ -200,7 +200,7 @@ export const WebauthnPolicy = ({
|
||||||
<PageSection variant="light">
|
<PageSection variant="light">
|
||||||
{enabled && (
|
{enabled && (
|
||||||
<Popover bodyContent={t(`authentication-help:${namePrefix}FormHelp`)}>
|
<Popover bodyContent={t(`authentication-help:${namePrefix}FormHelp`)}>
|
||||||
<TextContent className="keycloak__webauthn_policies__intro">
|
<TextContent className="keycloak__section_intro__help">
|
||||||
<Text>
|
<Text>
|
||||||
<QuestionCircleIcon /> {t("authentication-help:webauthnIntro")}
|
<QuestionCircleIcon /> {t("authentication-help:webauthnIntro")}
|
||||||
</Text>
|
</Text>
|
||||||
|
|
|
@ -1,9 +1,3 @@
|
||||||
.keycloak__webauthn_policies__intro {
|
|
||||||
padding: var(--pf-global--spacer--md) 0 var(--pf-global--spacer--lg);
|
|
||||||
color: var(--pf-global--primary-color--100);
|
|
||||||
width: fit-content;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (min-width: 768px) {
|
@media (min-width: 768px) {
|
||||||
.keycloak__webauthn_policies_authentication__form .pf-c-form__group {
|
.keycloak__webauthn_policies_authentication__form .pf-c-form__group {
|
||||||
--pf-c-form--m-horizontal__group-label--md--GridColumnWidth: 10rem;
|
--pf-c-form--m-horizontal__group-label--md--GridColumnWidth: 10rem;
|
||||||
|
|
|
@ -36,6 +36,7 @@ import { useAdminClient, useFetch } from "../../context/auth/AdminClient";
|
||||||
import { useRealm } from "../../context/realm-context/RealmContext";
|
import { useRealm } from "../../context/realm-context/RealmContext";
|
||||||
import { useServerInfo } from "../../context/server-info/ServerInfoProvider";
|
import { useServerInfo } from "../../context/server-info/ServerInfoProvider";
|
||||||
import { prettyPrintJSON } from "../../util";
|
import { prettyPrintJSON } from "../../util";
|
||||||
|
|
||||||
import "./evaluate.css";
|
import "./evaluate.css";
|
||||||
|
|
||||||
export type EvaluateScopesProps = {
|
export type EvaluateScopesProps = {
|
||||||
|
@ -242,7 +243,7 @@ export const EvaluateScopes = ({ clientId, protocol }: EvaluateScopesProps) => {
|
||||||
<>
|
<>
|
||||||
<PageSection variant="light">
|
<PageSection variant="light">
|
||||||
{enabled && (
|
{enabled && (
|
||||||
<TextContent className="keycloak__scopes_evaluate__intro">
|
<TextContent className="keycloak__section_intro__help">
|
||||||
<Text>
|
<Text>
|
||||||
<QuestionCircleIcon /> {t("clients-help:evaluateExplain")}
|
<QuestionCircleIcon /> {t("clients-help:evaluateExplain")}
|
||||||
</Text>
|
</Text>
|
||||||
|
|
|
@ -1,7 +1,3 @@
|
||||||
.keycloak__scopes_evaluate__intro {
|
|
||||||
padding: var(--pf-global--spacer--md) 0 var(--pf-global--spacer--lg);
|
|
||||||
color: var(--pf-global--primary-color--100);
|
|
||||||
}
|
|
||||||
.keycloak__scopes_evaluate__clipboard-copy input {
|
.keycloak__scopes_evaluate__clipboard-copy input {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,3 +59,9 @@ td.pf-c-table__check > input[type="checkbox"] {
|
||||||
.kc-time-select-dropdown {
|
.kc-time-select-dropdown {
|
||||||
min-width: 170px;
|
min-width: 170px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.keycloak__section_intro__help {
|
||||||
|
padding: var(--pf-global--spacer--md) 0 var(--pf-global--spacer--lg);
|
||||||
|
color: var(--pf-global--primary-color--100);
|
||||||
|
width: fit-content;
|
||||||
|
}
|
232
src/realm-settings/DefaultGroupsTab.tsx
Normal file
232
src/realm-settings/DefaultGroupsTab.tsx
Normal file
|
@ -0,0 +1,232 @@
|
||||||
|
import React, { useState } from "react";
|
||||||
|
import { Link } from "react-router-dom";
|
||||||
|
import { Trans, useTranslation } from "react-i18next";
|
||||||
|
import {
|
||||||
|
AlertVariant,
|
||||||
|
Button,
|
||||||
|
ButtonVariant,
|
||||||
|
Dropdown,
|
||||||
|
DropdownItem,
|
||||||
|
KebabToggle,
|
||||||
|
Popover,
|
||||||
|
Text,
|
||||||
|
TextContent,
|
||||||
|
ToolbarItem,
|
||||||
|
} from "@patternfly/react-core";
|
||||||
|
import { QuestionCircleIcon } from "@patternfly/react-icons";
|
||||||
|
|
||||||
|
import type GroupRepresentation from "@keycloak/keycloak-admin-client/lib/defs/groupRepresentation";
|
||||||
|
import { KeycloakDataTable } from "../components/table-toolbar/KeycloakDataTable";
|
||||||
|
import { useAdminClient, useFetch } from "../context/auth/AdminClient";
|
||||||
|
import { ListEmptyState } from "../components/list-empty-state/ListEmptyState";
|
||||||
|
import useToggle from "../utils/useToggle";
|
||||||
|
import { useConfirmDialog } from "../components/confirm-dialog/ConfirmDialog";
|
||||||
|
import { useAlerts } from "../components/alert/Alerts";
|
||||||
|
import { toUserFederation } from "../user-federation/routes/UserFederation";
|
||||||
|
import { useRealm } from "../context/realm-context/RealmContext";
|
||||||
|
import { GroupPickerDialog } from "../components/group/GroupPickerDialog";
|
||||||
|
import { KeycloakSpinner } from "../components/keycloak-spinner/KeycloakSpinner";
|
||||||
|
import { useHelp } from "../components/help-enabler/HelpHeader";
|
||||||
|
|
||||||
|
export const DefaultsGroupsTab = () => {
|
||||||
|
const { t } = useTranslation("realm-settings");
|
||||||
|
|
||||||
|
const [isKebabOpen, toggleKebab] = useToggle();
|
||||||
|
const [isGroupPickerOpen, toggleGroupPicker] = useToggle();
|
||||||
|
const [defaultGroups, setDefaultGroups] = useState<GroupRepresentation[]>();
|
||||||
|
const [selectedRows, setSelectedRows] = useState<GroupRepresentation[]>([]);
|
||||||
|
|
||||||
|
const [key, setKey] = useState(0);
|
||||||
|
const [load, setLoad] = useState(0);
|
||||||
|
const reload = () => setLoad(load + 1);
|
||||||
|
|
||||||
|
const adminClient = useAdminClient();
|
||||||
|
const { realm } = useRealm();
|
||||||
|
const { addAlert, addError } = useAlerts();
|
||||||
|
const { enabled } = useHelp();
|
||||||
|
|
||||||
|
useFetch(
|
||||||
|
() => adminClient.realms.getDefaultGroups({ realm }),
|
||||||
|
(groups) => {
|
||||||
|
setDefaultGroups(groups);
|
||||||
|
setKey(key + 1);
|
||||||
|
},
|
||||||
|
[load]
|
||||||
|
);
|
||||||
|
|
||||||
|
const loader = () => Promise.resolve(defaultGroups!);
|
||||||
|
|
||||||
|
const removeGroup = async () => {
|
||||||
|
try {
|
||||||
|
await Promise.all(
|
||||||
|
selectedRows.map((group) =>
|
||||||
|
adminClient.realms.removeDefaultGroup({
|
||||||
|
realm,
|
||||||
|
id: group.id!,
|
||||||
|
})
|
||||||
|
)
|
||||||
|
);
|
||||||
|
addAlert(
|
||||||
|
t("groupRemove", { count: selectedRows.length }),
|
||||||
|
AlertVariant.success
|
||||||
|
);
|
||||||
|
setSelectedRows([]);
|
||||||
|
} catch (error) {
|
||||||
|
addError("realm-settings:groupRemoveError", error);
|
||||||
|
}
|
||||||
|
reload();
|
||||||
|
};
|
||||||
|
|
||||||
|
const addGroups = async (groups: GroupRepresentation[]) => {
|
||||||
|
try {
|
||||||
|
await Promise.all(
|
||||||
|
groups.map((group) =>
|
||||||
|
adminClient.realms.addDefaultGroup({
|
||||||
|
realm,
|
||||||
|
id: group.id!,
|
||||||
|
})
|
||||||
|
)
|
||||||
|
);
|
||||||
|
addAlert(
|
||||||
|
t("defaultGroupAdded", { count: groups.length }),
|
||||||
|
AlertVariant.success
|
||||||
|
);
|
||||||
|
} catch (error) {
|
||||||
|
addError("realm-settings:defaultGroupAddedError", error);
|
||||||
|
}
|
||||||
|
reload();
|
||||||
|
};
|
||||||
|
|
||||||
|
const [toggleRemoveDialog, RemoveDialog] = useConfirmDialog({
|
||||||
|
titleKey: t("removeConfirmTitle", { count: selectedRows.length }),
|
||||||
|
messageKey: t("removeConfirm", { count: selectedRows.length }),
|
||||||
|
continueButtonLabel: "common:delete",
|
||||||
|
continueButtonVariant: ButtonVariant.danger,
|
||||||
|
onConfirm: removeGroup,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!defaultGroups) {
|
||||||
|
return <KeycloakSpinner />;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<RemoveDialog />
|
||||||
|
{isGroupPickerOpen && (
|
||||||
|
<GroupPickerDialog
|
||||||
|
type="selectMany"
|
||||||
|
text={{
|
||||||
|
title: "realm-settings:addDefaultGroups",
|
||||||
|
ok: "common:add",
|
||||||
|
}}
|
||||||
|
onConfirm={(groups) => {
|
||||||
|
addGroups(groups);
|
||||||
|
toggleGroupPicker();
|
||||||
|
}}
|
||||||
|
onClose={toggleGroupPicker}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
{enabled && (
|
||||||
|
<Popover
|
||||||
|
bodyContent={
|
||||||
|
<Trans i18nKey="realm-settings-help:defaultGroups">
|
||||||
|
{" "}
|
||||||
|
<Link to={toUserFederation({ realm })} />.
|
||||||
|
</Trans>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<TextContent
|
||||||
|
className="keycloak__section_intro__help"
|
||||||
|
style={{
|
||||||
|
paddingLeft: "var(--pf-c-page__main-section--PaddingLeft)",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Text>
|
||||||
|
<QuestionCircleIcon /> {t("whatIsDefaultGroups")}
|
||||||
|
</Text>
|
||||||
|
</TextContent>
|
||||||
|
</Popover>
|
||||||
|
)}
|
||||||
|
<KeycloakDataTable
|
||||||
|
key={key}
|
||||||
|
canSelectAll
|
||||||
|
onSelect={(rows) => setSelectedRows([...rows])}
|
||||||
|
loader={loader}
|
||||||
|
ariaLabelKey="realm-settings:defaultGroups"
|
||||||
|
searchPlaceholderKey="realm-settings:searchForGroups"
|
||||||
|
toolbarItem={
|
||||||
|
<>
|
||||||
|
<ToolbarItem>
|
||||||
|
<Button
|
||||||
|
data-testid="openCreateGroupModal"
|
||||||
|
variant="primary"
|
||||||
|
onClick={toggleGroupPicker}
|
||||||
|
>
|
||||||
|
{t("addGroups")}
|
||||||
|
</Button>
|
||||||
|
</ToolbarItem>
|
||||||
|
<ToolbarItem>
|
||||||
|
<Dropdown
|
||||||
|
toggle={
|
||||||
|
<KebabToggle
|
||||||
|
onToggle={toggleKebab}
|
||||||
|
isDisabled={selectedRows!.length === 0}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
isOpen={isKebabOpen}
|
||||||
|
isPlain
|
||||||
|
dropdownItems={[
|
||||||
|
<DropdownItem
|
||||||
|
key="action"
|
||||||
|
component="button"
|
||||||
|
onClick={() => {
|
||||||
|
toggleRemoveDialog();
|
||||||
|
toggleKebab();
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{t("common:remove")}
|
||||||
|
</DropdownItem>,
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
</ToolbarItem>
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
actions={[
|
||||||
|
{
|
||||||
|
title: t("common:remove"),
|
||||||
|
onRowClick: (group: GroupRepresentation) => {
|
||||||
|
setSelectedRows([group]);
|
||||||
|
toggleRemoveDialog();
|
||||||
|
return Promise.resolve(false);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
columns={[
|
||||||
|
{
|
||||||
|
name: "name",
|
||||||
|
displayKey: "groups:groupName",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "path",
|
||||||
|
displayKey: "groups:path",
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
emptyState={
|
||||||
|
<ListEmptyState
|
||||||
|
hasIcon
|
||||||
|
message={t("noDefaultGroups")}
|
||||||
|
instructions={
|
||||||
|
<Trans i18nKey="realm-settings:noDefaultGroupsInstructions">
|
||||||
|
{" "}
|
||||||
|
<Link to={toUserFederation({ realm })} />
|
||||||
|
Add groups...
|
||||||
|
</Trans>
|
||||||
|
}
|
||||||
|
primaryActionText={t("addGroups")}
|
||||||
|
onPrimaryAction={toggleGroupPicker}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
|
@ -7,6 +7,7 @@ import { useAdminClient, useFetch } from "../context/auth/AdminClient";
|
||||||
import { useRealm } from "../context/realm-context/RealmContext";
|
import { useRealm } from "../context/realm-context/RealmContext";
|
||||||
import { AssociatedRolesTab } from "../realm-roles/AssociatedRolesTab";
|
import { AssociatedRolesTab } from "../realm-roles/AssociatedRolesTab";
|
||||||
import { KeycloakSpinner } from "../components/keycloak-spinner/KeycloakSpinner";
|
import { KeycloakSpinner } from "../components/keycloak-spinner/KeycloakSpinner";
|
||||||
|
import { DefaultsGroupsTab } from "./DefaultGroupsTab";
|
||||||
|
|
||||||
export const UserRegistration = () => {
|
export const UserRegistration = () => {
|
||||||
const { t } = useTranslation("realm-settings");
|
const { t } = useTranslation("realm-settings");
|
||||||
|
@ -29,11 +30,11 @@ export const UserRegistration = () => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Tabs
|
<Tabs
|
||||||
key={key}
|
|
||||||
activeKey={activeTab}
|
activeKey={activeTab}
|
||||||
onSelect={(_, key) => setActiveTab(key as number)}
|
onSelect={(_, key) => setActiveTab(key as number)}
|
||||||
>
|
>
|
||||||
<Tab
|
<Tab
|
||||||
|
key={key}
|
||||||
id="roles"
|
id="roles"
|
||||||
eventKey={10}
|
eventKey={10}
|
||||||
title={<TabTitleText>{t("defaultRoles")}</TabTitleText>}
|
title={<TabTitleText>{t("defaultRoles")}</TabTitleText>}
|
||||||
|
@ -48,7 +49,7 @@ export const UserRegistration = () => {
|
||||||
eventKey={20}
|
eventKey={20}
|
||||||
title={<TabTitleText>{t("defaultGroups")}</TabTitleText>}
|
title={<TabTitleText>{t("defaultGroups")}</TabTitleText>}
|
||||||
>
|
>
|
||||||
<h1>Work in progress</h1>
|
<DefaultsGroupsTab />
|
||||||
</Tab>
|
</Tab>
|
||||||
</Tabs>
|
</Tabs>
|
||||||
);
|
);
|
||||||
|
|
|
@ -143,5 +143,7 @@ export default {
|
||||||
"The condition checks the role of the entity who tries to create/update the client to determine whether the policy is applied.",
|
"The condition checks the role of the entity who tries to create/update the client to determine whether the policy is applied.",
|
||||||
clientUpdaterSourceRolesTooltip:
|
clientUpdaterSourceRolesTooltip:
|
||||||
"The condition is checked during client registration/update requests and it evaluates to true if the entity (usually user), who is creating/updating client is member of the specified role. For reference the realm role, you can use the realm role name like 'my_realm_role' . For reference client role, you can use the client_id.role_name for example 'my_client.my_client_role' will refer to client role 'my_client_role' of client 'my_client'. ",
|
"The condition is checked during client registration/update requests and it evaluates to true if the entity (usually user), who is creating/updating client is member of the specified role. For reference the realm role, you can use the realm role name like 'my_realm_role' . For reference client role, you can use the client_id.role_name for example 'my_client.my_client_role' will refer to client role 'my_client_role' of client 'my_client'. ",
|
||||||
|
defaultGroups:
|
||||||
|
"Default groups allow you to automatically assign groups membership whenever any new user is created or imported through <1>identity brokering</1>.",
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -726,6 +726,24 @@ export default {
|
||||||
"You can edit the supported locales. If you haven't selected supported locales yet, you can only edit the English locale.",
|
"You can edit the supported locales. If you haven't selected supported locales yet, you can only edit the English locale.",
|
||||||
defaultRoles: "Default roles",
|
defaultRoles: "Default roles",
|
||||||
defaultGroups: "Default groups",
|
defaultGroups: "Default groups",
|
||||||
|
whatIsDefaultGroups: "What is the function of default groups?",
|
||||||
|
searchForGroups: "Search group",
|
||||||
|
addDefaultGroups: "Add default groups",
|
||||||
|
removeConfirmTitle_one: "Remove group?",
|
||||||
|
removeConfirmTitle_other: "Remove groups?",
|
||||||
|
removeConfirm_one: "Are you sure you want to remove this group",
|
||||||
|
removeConfirm_other: "Are you sure you want to remove these groups.",
|
||||||
|
groupRemove_one: "Group removed",
|
||||||
|
groupRemove_other: "Groups removed",
|
||||||
|
groupRemoveError: "Error removing group {error}",
|
||||||
|
defaultGroupAdded_one: "New group added to the default groups",
|
||||||
|
defaultGroupAdded_other: "Added {{count}} groups to the default groups",
|
||||||
|
defaultGroupAddedError:
|
||||||
|
"Error adding group(s) to the default group {error}",
|
||||||
|
noDefaultGroups: "No default groups",
|
||||||
|
noDefaultGroupsInstructions:
|
||||||
|
"Default groups allow you to automatically assign group membership whenever any new user is created or imported throughout <1>identity brokering</1>. Add default groups to get started",
|
||||||
|
addGroups: "Add groups",
|
||||||
securityDefences: "Security defenses",
|
securityDefences: "Security defenses",
|
||||||
headers: "Headers",
|
headers: "Headers",
|
||||||
bruteForceDetection: "Brute force detection",
|
bruteForceDetection: "Brute force detection",
|
||||||
|
|
Loading…
Reference in a new issue