Added group sync to group mapper (#3943)

This commit is contained in:
Erik Jan de Wit 2022-12-06 10:57:21 -05:00 committed by GitHub
parent ad2dc6f89c
commit 3ac040dc34
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 48 additions and 8 deletions

View file

@ -10,6 +10,10 @@
"addLdapWizardTitle": "Add LDAP user federation provider", "addLdapWizardTitle": "Add LDAP user federation provider",
"syncChangedUsers": "Sync changed users", "syncChangedUsers": "Sync changed users",
"syncAllUsers": "Sync all users", "syncAllUsers": "Sync all users",
"syncLDAPGroupsToKeycloak": "Sync LDAP groups to Keycloak",
"syncKeycloakGroupsToLDAP": "Sync Keycloak groups to LDAP",
"syncLDAPGroupsSuccessful": "Data successfully synced {{result}}",
"syncLDAPGroupsError": "Data could not be synced due {{error}}",
"unlinkUsers": "Unlink users", "unlinkUsers": "Unlink users",
"removeImported": "Remove imported", "removeImported": "Remove imported",
"deleteProvider": "Delete provider", "deleteProvider": "Delete provider",

View file

@ -32,6 +32,7 @@ import { KeycloakSpinner } from "../../../components/keycloak-spinner/KeycloakSp
import { KeycloakTextInput } from "../../../components/keycloak-text-input/KeycloakTextInput"; import { KeycloakTextInput } from "../../../components/keycloak-text-input/KeycloakTextInput";
import { toUserFederationLdap } from "../../routes/UserFederationLdap"; import { toUserFederationLdap } from "../../routes/UserFederationLdap";
import { useConfirmDialog } from "../../../components/confirm-dialog/ConfirmDialog"; import { useConfirmDialog } from "../../../components/confirm-dialog/ConfirmDialog";
import { DirectionType } from "libs/keycloak-admin-client/lib/resources/userStorageProvider";
export default function LdapMapperDetails() { export default function LdapMapperDetails() {
const form = useForm<ComponentRepresentation>(); const form = useForm<ComponentRepresentation>();
@ -46,6 +47,8 @@ export default function LdapMapperDetails() {
const { addAlert, addError } = useAlerts(); const { addAlert, addError } = useAlerts();
const [isMapperDropdownOpen, setIsMapperDropdownOpen] = useState(false); const [isMapperDropdownOpen, setIsMapperDropdownOpen] = useState(false);
const [key, setKey] = useState(0);
const refresh = () => setKey(key + 1);
useFetch( useFetch(
async () => { async () => {
@ -118,6 +121,24 @@ export default function LdapMapperDetails() {
} }
}; };
const sync = async (direction: DirectionType) => {
try {
const result = await adminClient.userStorageProvider.mappersSync({
parentId: mapping?.parentId || "",
id: mapperId,
direction,
});
addAlert(
t("syncLDAPGroupsSuccessful", {
result: result.status,
})
);
} catch (error) {
addError("user-federation:syncLDAPGroupsError", error);
}
refresh();
};
const [toggleDeleteDialog, DeleteConfirm] = useConfirmDialog({ const [toggleDeleteDialog, DeleteConfirm] = useConfirmDialog({
titleKey: "common:deleteMappingTitle", titleKey: "common:deleteMappingTitle",
messageKey: "common:deleteMappingConfirm", messageKey: "common:deleteMappingConfirm",
@ -141,16 +162,17 @@ export default function LdapMapperDetails() {
name: "providerId", name: "providerId",
}); });
const isNew = mapperId === "new";
if (!components) { if (!components) {
return <KeycloakSpinner />; return <KeycloakSpinner />;
} }
const isNew = mapperId === "new";
const mapper = components.find((c) => c.id === mapperType);
return ( return (
<> <>
<DeleteConfirm /> <DeleteConfirm />
<ViewHeader <ViewHeader
key={key}
titleKey={mapping ? mapping.name! : t("common:createNewMapper")} titleKey={mapping ? mapping.name! : t("common:createNewMapper")}
dropdownItems={ dropdownItems={
isNew isNew
@ -159,6 +181,24 @@ export default function LdapMapperDetails() {
<DropdownItem key="delete" onClick={toggleDeleteDialog}> <DropdownItem key="delete" onClick={toggleDeleteDialog}>
{t("common:delete")} {t("common:delete")}
</DropdownItem>, </DropdownItem>,
mapper?.metadata.fedToKeycloakSyncSupported && (
<DropdownItem
key="fedSync"
onClick={() => sync("fedToKeycloak")}
>
{t("syncLDAPGroupsToKeycloak")}
</DropdownItem>
),
mapper?.metadata.keycloakToFedSyncSupported && (
<DropdownItem
key="ldapSync"
onClick={() => {
sync("keycloakToFed");
}}
>
{t("syncKeycloakGroupsToLDAP")}
</DropdownItem>
),
] ]
} }
/> />
@ -284,11 +324,7 @@ export default function LdapMapperDetails() {
)} )}
<FormProvider {...form}> <FormProvider {...form}>
{!!mapperType && ( {!!mapperType && (
<DynamicComponents <DynamicComponents properties={mapper?.properties!} />
properties={
components.find((c) => c.id === mapperType)?.properties!
}
/>
)} )}
</FormProvider> </FormProvider>
</FormAccess> </FormAccess>

View file

@ -3,7 +3,7 @@ import type SynchronizationResultRepresentation from "../defs/synchronizationRes
import Resource from "./resource.js"; import Resource from "./resource.js";
type ActionType = "triggerFullSync" | "triggerChangedUsersSync"; type ActionType = "triggerFullSync" | "triggerChangedUsersSync";
type DirectionType = "fedToKeycloak" | "keycloakToFed"; export type DirectionType = "fedToKeycloak" | "keycloakToFed";
type NameResponse = { type NameResponse = {
id: string; id: string;
name: string; name: string;