8000 make group select required when specific group is selected by edewit · Pull Request #38768 · keycloak/keycloak · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

make group select required when specific group is selected #38768

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Apr 11, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ export const Role = () => {
<AddRoleMappingModal
id="role"
type="roles"
title={t("assignRole")}
=> {
field.onChange([
...(field.value || []),
Expand All @@ -77,7 +78,6 @@ export const Role = () => {
=> {
setOpen(false);
}}
isLDAPmapper
/>
)}
<Button
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,6 @@ import useLocaleSort from "../../utils/useLocaleSort";
import { ResourcesKey, Row, ServiceRole } from "./RoleMapping";
import { getAvailableRoles } from "./queries";
import { getAvailableClientRoles } from "./resource";
import { PermissionsConfigurationTabsParams } from "../../permissions-configuration/routes/PermissionsConfigurationTabs";
import { useParams } from "react-router-dom";

type AddRoleMappingModalProps = {
id: string;
Expand All @@ -34,7 +32,8 @@ type AddRoleMappingModalProps = {
isRadio?: boolean;
onAssign: (rows: Row[]) => void;
onClose: () => void;
isLDAPmapper?: boolean;
title?: string;
actionLabel?: string;
};

type FilterType = "roles" | "clients";
Expand All @@ -52,9 +51,11 @@ export const AddRoleMappingModal = ({
id,
name,
type,
isLDAPmapper,
isRadio,
onAssign,
onClose,
title,
actionLabel,
}: AddRoleMappingModalProps) => {
const { adminClient } = useAdminClient();

Expand All @@ -71,7 +72,6 @@ export const AddRoleMappingModal = ({

const localeSort = useLocaleSort();
const compareRow = ({ role: { name } }: Row) => name?.toUpperCase();
const { tab } = useParams<PermissionsConfigurationTabsParams>();

const loader = async (
first?: number,
Expand Down Expand Up @@ -123,13 +123,7 @@ export const AddRoleMappingModal = ({
return (
<Modal
variant={ModalVariant.large}
title={
tab !== "evaluation"
? isLDAPmapper
? t("assignRole")
: t("assignRolesTo", { client: name })
: t("selectRole")
}
title={title || t("assignRolesTo", { client: name })}
isOpen
>
actions={[
Expand All @@ -143,7 +137,7 @@ export const AddRoleMappingModal = ({
onClose();
}}
>
{tab !== "evaluation" ? t("assign") : t("select")}
{actionLabel || t("assign")}
</Button>,
<Button
data-testid="cancel"
Expand All @@ -157,13 +151,7 @@ export const AddRoleMappingModal = ({
>
<KeycloakDataTable
key={key}
=> {
if (tab === "evaluation") {
setSelectedRows(rows.length > 0 ? [rows[0]] : []);
} else {
setSelectedRows([...rows]);
}
}}
=> setSelectedRows([...rows])}
searchPlaceholderKey="searchByRoleName"
isPaginated={!(filterType === "roles" && type !== "roles")}
searchTypeComponent={
Expand Down Expand Up @@ -202,7 +190,7 @@ export const AddRoleMappingModal = ({
)
}
canSelectAll
isRadio={tab === "evaluation"}
isRadio={isRadio}
loader={filterType === "roles" ? loader : clientRolesLoader}
ariaLabelKey="associatedRolesText"
columns={[
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,7 @@ const PermissionEvaluateContent = ({ client }: Props) => {
defaultValue={[]}
variant="typeahead"
isRequired
isRadio
/>
)}
<SelectControl
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,14 +69,11 @@ export const GroupSelect = ({
name={name!}
control={control}
defaultValue={defaultValue}
rules={
isRequired
? {
validate: (value?: GroupRepresentation[]) =>
value && value.length > 0,
}
: undefined
}
rules={{
validate: (value?: string[]) => {
return isRequired && value && value.length > 0;
},
}}
render={({ field }) => (
<>
{open && (
Expand Down Expand Up @@ -147,7 +144,7 @@ export const GroupSelect = ({
</Tbody>
</Table>
)}
{errors.groups && <FormErrorText message={t("requiredGroups")} />}
{errors[name!] && <FormErrorText message={t("requiredGroups")} />}
</FormGroup>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ export const ResourceType = ({
})}
defaultValue={[]}
variant="typeaheadMulti"
isRequired={withEnforceAccessTo}< 2E18 /td>
/>
)}
</>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,13 @@ import {
} from "@keycloak/keycloak-ui-shared";
import { AddRoleMappingModal } from "../../components/role-mapping/AddRoleMappingModal";
import { Row, ServiceRole } from "../../components/role-mapping/RoleMapping";
import { PermissionsConfigurationTabsParams } from "../routes/PermissionsConfigurationTabs";
import { useParams } from "react-router-dom";

type RoleSelectorProps = {
name: string;
isRadio?: boolean;
};

export const RoleSelect = ({ name }: RoleSelectorProps) => {
export const RoleSelect = ({ name, isRadio = false }: RoleSelectorProps) => {
const { adminClient } = useAdminClient();
const { t } = useTranslation();
const {
Expand All @@ -30,7 +29,6 @@ export const RoleSelect = ({ name }: RoleSelectorProps) => {
const values = getValues(name) || [];
const [isModalOpen, setIsModalOpen] = useState(false);
const [selectedRoles, setSelectedRoles] = useState<Row[]>([]);
const { tab } = useParams<PermissionsConfigurationTabsParams>();

useFetch(
async () => {
Expand All @@ -55,12 +53,10 @@ export const RoleSelect = ({ name }: RoleSelectorProps) => {

return (
<FormGroup
label={tab !== "evaluation" ? t("roles") : t("role")}
label={isRadio ? t("role") : t("roles")}
labelIcon={
<HelpItem
helpText={
tab !== "evaluation" ? t("policyRolesHelp") : t("selectRole")
}
helpText={isRadio ? t("selectRole") : t("policyRolesHelp")}
fieldLabelId="roles"
/>
}
Expand All @@ -71,27 +67,29 @@ export const RoleSelect = ({ name }: RoleSelectorProps) => {
<AddRoleMappingModal
id="role"
type="roles"
title={t("selectRole")}
actionLabel={t("select")}
isRadio={isRadio}
=> {
setValue(name, [
...values,
...(!isRadio ? values : []),
...rows
.filter((row) => row.role.id !== undefined)
.map((row) => row.role.id!),
]);

setSelectedRoles([...selectedRoles, ...rows]);
setSelectedRoles(isRadio ? rows : [...selectedRoles, ...rows]);
setIsModalOpen(false);
}}
=> setIsModalOpen(false)}
isLDAPmapper
/>
)}
<Button
data-testid="select-role-button"
variant="secondary"
=> setIsModalOpen(true)}
>
{tab !== "evaluation" ? t("addRoles") : t("selectRole")}
{isRadio ? t("selectRole") : t("addRoles")}
</Button>
{selectedRoles.length > 0 && (
<Table variant="compact">
Expand Down
4 changes: 3 additions & 1 deletion js/apps/admin-ui/test/permissions/main.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
clickCreatePermission,
clickCreatePolicySaveButton,
clickSearchButton,
deletePermission,
fillPermissionForm,
goToEvaluation,
goToPermissions,
Expand Down Expand Up @@ -76,6 +77,7 @@ test.describe("Permissions section tests", () => {

await goToPermissions(page);
await assertRowExists(page, "test-permission");
await deletePermission(page, "test-permission");
await goToPolicies(page);
await assertRowExists(page, "test-policy");
});
Expand All @@ -95,7 +97,7 @@ test.describe("Permissions section tests", () => {
await fillPolicyForm(
page,
{
name: "test-policy",
name: "test-policy2",
description: "test-description",
type: "User",
user: "test-user",
Expand Down
7 changes: 7 additions & 0 deletions js/apps/admin-ui/test/permissions/main.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import PolicyRepresentation from "@keycloak/keycloak-admin-client/lib/defs/policyRepresentation";
import { Page } from "@playwright/test";
import { selectItem } from "../utils/form";
import { confirmModal } from "../utils/modal";
import { clickRowKebabItem } from "../utils/table";

type PermissionForm = PolicyRepresentation & {
enforcementMode?: "allResources" | "specificResources";
Expand Down Expand Up @@ -68,3 +70,8 @@ export async function openSearchPanel(page: Page) {
export async function clickSearchButton(page: Page) {
await page.getByTestId("search-btn").click();
}

export async function deletePermission(page: Page, name: string) {
await clickRowKebabItem(page, name, "Delete");
await confirmModal(page);
}
Loading
0