mirror of
https://github.com/grafana/grafana.git
synced 2025-01-15 19:22:34 -06:00
SSO LDAP: Add Group Mappings field (#92993)
* Add GroupMApping component * Add remove/add buttons * Implement role fields * Change value as number for org ids * Add i18n extracts * Use conditional for GrafanaAdmin switch
This commit is contained in:
parent
20f7e11987
commit
8ea374b773
@ -5,6 +5,7 @@ import { useFormContext } from 'react-hook-form';
|
||||
import { GrafanaTheme2, SelectableValue } from '@grafana/data';
|
||||
import {
|
||||
useStyles2,
|
||||
Button,
|
||||
CollapsableSection,
|
||||
Divider,
|
||||
Drawer,
|
||||
@ -25,6 +26,8 @@ import {
|
||||
import { t, Trans } from 'app/core/internationalization';
|
||||
import { LdapPayload, MapKeyCertConfigured } from 'app/types';
|
||||
|
||||
import { GroupMappingComponent } from './LdapGroupMapping';
|
||||
|
||||
interface Props {
|
||||
onClose: () => void;
|
||||
mapKeyCertConfigured: MapKeyCertConfigured;
|
||||
@ -90,6 +93,23 @@ export const LdapDrawerComponent = ({
|
||||
</Trans>
|
||||
);
|
||||
|
||||
const onAddGroupMapping = () => {
|
||||
setValue(`${serverConfig}.group_mappings`, [
|
||||
...getValues(`${serverConfig}.group_mappings`),
|
||||
{
|
||||
group_dn: '',
|
||||
org_id: 1,
|
||||
org_role: 'Viewer',
|
||||
grafana_admin: false,
|
||||
},
|
||||
]);
|
||||
};
|
||||
|
||||
const onRemoveGroupMapping = (index: number) => {
|
||||
const groupMappings = getValues(`${serverConfig}.group_mappings`);
|
||||
setValue(`${serverConfig}.group_mappings`, [...groupMappings.slice(0, index), ...groupMappings.slice(index + 1)]);
|
||||
};
|
||||
|
||||
return (
|
||||
<Drawer title={t('ldap-drawer.title', 'Advanced settings')} onClose={onClose}>
|
||||
<CollapsableSection label={t('ldap-drawer.misc-section.label', 'Misc')} isOpen={true}>
|
||||
@ -204,7 +224,13 @@ export const LdapDrawerComponent = ({
|
||||
{...register(`${serverConfig}.group_search_filter_user_attribute`)}
|
||||
/>
|
||||
</Field>
|
||||
{watch('settings.config.servers.0.group_mappings')?.map((_, i) => {
|
||||
return <GroupMappingComponent key={i} groupMappingIndex={i} onRemove={() => onRemoveGroupMapping(i)} />;
|
||||
})}
|
||||
<Divider />
|
||||
<Button className={styles.button} variant="secondary" icon="plus" onClick={() => onAddGroupMapping()}>
|
||||
<Trans i18nKey="ldap-drawer.group-mapping-section.add.button">Add group mapping</Trans>
|
||||
</Button>
|
||||
</CollapsableSection>
|
||||
<CollapsableSection
|
||||
label={t('ldap-drawer.extra-security-section.label', 'Extra security measures')}
|
||||
@ -420,5 +446,8 @@ function getStyles(theme: GrafanaTheme2) {
|
||||
sectionLabel: css({
|
||||
fontSize: theme.typography.size.lg,
|
||||
}),
|
||||
button: css({
|
||||
marginBottom: theme.spacing(4),
|
||||
}),
|
||||
};
|
||||
}
|
||||
|
74
public/app/features/admin/ldap/LdapGroupMapping.tsx
Normal file
74
public/app/features/admin/ldap/LdapGroupMapping.tsx
Normal file
@ -0,0 +1,74 @@
|
||||
import { useFormContext } from 'react-hook-form';
|
||||
|
||||
import { SelectableValue } from '@grafana/data';
|
||||
import { Box, Button, Field, Input, RadioButtonGroup, Switch } from '@grafana/ui';
|
||||
import { contextSrv } from 'app/core/core';
|
||||
import { t, Trans } from 'app/core/internationalization';
|
||||
import { LdapPayload, OrgRole } from 'app/types';
|
||||
|
||||
const roleOptions: Array<SelectableValue<string>> = Object.keys(OrgRole).map((key) => {
|
||||
return { label: key, value: key };
|
||||
});
|
||||
|
||||
interface GroupMappingProps {
|
||||
onRemove: () => void;
|
||||
groupMappingIndex: number;
|
||||
}
|
||||
|
||||
export const GroupMappingComponent = ({ groupMappingIndex, onRemove }: GroupMappingProps) => {
|
||||
const { getValues, register, setValue } = useFormContext<LdapPayload>();
|
||||
return (
|
||||
<Box borderColor="strong" borderStyle="solid" padding={2} marginBottom={2}>
|
||||
<Field
|
||||
htmlFor="group-dn"
|
||||
label={t('ldap-drawer.group-mapping.group-dn.label', 'Group DN')}
|
||||
description={t(
|
||||
'ldap-drawer.group-mapping.group-dn.description',
|
||||
'The name of the key used to extract the ID token from the returned OAuth2 token.'
|
||||
)}
|
||||
>
|
||||
<Input id="group-dn" {...register(`settings.config.servers.0.group_mappings.${groupMappingIndex}.group_dn`)} />
|
||||
</Field>
|
||||
<Field label={t('ldap-drawer.group-mapping.org-role.label', 'Org role *')}>
|
||||
<RadioButtonGroup
|
||||
id={`org-role-${groupMappingIndex}`}
|
||||
options={roleOptions}
|
||||
value={getValues(`settings.config.servers.0.group_mappings.${groupMappingIndex}.org_role`)}
|
||||
onChange={(v) => setValue(`settings.config.servers.0.group_mappings.${groupMappingIndex}.org_role`, v)}
|
||||
/>
|
||||
</Field>
|
||||
<Field
|
||||
htmlFor="org-id"
|
||||
label={t('ldap-drawer.group-mapping.org-id.label', 'Org ID')}
|
||||
description={t(
|
||||
'ldap-drawer.group-mapping.org-id.description',
|
||||
'The Grafana organization database id. Default org (ID 1) will be used if left out'
|
||||
)}
|
||||
>
|
||||
<Input
|
||||
id="org-id"
|
||||
type="number"
|
||||
{...register(`settings.config.servers.0.group_mappings.${groupMappingIndex}.org_id`, { valueAsNumber: true })}
|
||||
/>
|
||||
</Field>
|
||||
{contextSrv.isGrafanaAdmin && (
|
||||
<Field
|
||||
htmlFor="grafana-admin"
|
||||
label={t('ldap-drawer.group-mapping.grafana-admin.label', 'Grafana Admin')}
|
||||
description={t(
|
||||
'ldap-drawer.group-mapping.grafana-admin.description',
|
||||
'If enabled, all users from this group will be Grafana Admins'
|
||||
)}
|
||||
>
|
||||
<Switch
|
||||
id="grafana-admin"
|
||||
{...register(`settings.config.servers.0.group_mappings.${groupMappingIndex}.grafana_admin`)}
|
||||
/>
|
||||
</Field>
|
||||
)}
|
||||
<Button variant="secondary" fill="outline" icon="trash-alt" onClick={onRemove}>
|
||||
<Trans i18nKey="ldap-drawer.group-mapping.remove.button">Remove group mapping</Trans>
|
||||
</Button>
|
||||
</Box>
|
||||
);
|
||||
};
|
@ -1045,7 +1045,30 @@
|
||||
"use-ssl-label": "Use SSL",
|
||||
"use-ssl-tooltip": "For a complete list of supported ciphers and TLS versions, refer to: {\n <TextLink style={{ fontSize: 'inherit' }} href=\"https://go.dev/src/crypto/tls/cipher_suites.go\" external>\n https://go.dev/src/crypto/tls/cipher_suites.go\n </TextLink>}"
|
||||
},
|
||||
"group-mapping": {
|
||||
"grafana-admin": {
|
||||
"description": "If enabled, all users from this group will be Grafana Admins",
|
||||
"label": "Grafana Admin"
|
||||
},
|
||||
"group-dn": {
|
||||
"description": "The name of the key used to extract the ID token from the returned OAuth2 token.",
|
||||
"label": "Group DN"
|
||||
},
|
||||
"org-id": {
|
||||
"description": "The Grafana organization database id. Default org (ID 1) will be used if left out",
|
||||
"label": "Org ID"
|
||||
},
|
||||
"org-role": {
|
||||
"label": "Org role *"
|
||||
},
|
||||
"remove": {
|
||||
"button": "Remove group mapping"
|
||||
}
|
||||
},
|
||||
"group-mapping-section": {
|
||||
"add": {
|
||||
"button": "Add group mapping"
|
||||
},
|
||||
"description": "Map LDAP groups to Grafana org roles",
|
||||
"group-search-base-dns-description": "Separate by commas or spaces",
|
||||
"group-search-base-dns-label": "Group search base DNS",
|
||||
|
@ -1045,7 +1045,30 @@
|
||||
"use-ssl-label": "Ůşę ŜŜĿ",
|
||||
"use-ssl-tooltip": "Főř ä čőmpľęŧę ľįşŧ őƒ şūppőřŧęđ čįpĥęřş äʼnđ ŦĿŜ vęřşįőʼnş, řęƒęř ŧő: {\n <ŦęχŧĿįʼnĸ şŧyľę={{ fontSize: 'inherit' }} ĥřęƒ=\"ĥŧŧpş://ģő.đęv/şřč/čřypŧő/ŧľş/čįpĥęř_şūįŧęş.ģő\" ęχŧęřʼnäľ>\n ĥŧŧpş://ģő.đęv/şřč/čřypŧő/ŧľş/čįpĥęř_şūįŧęş.ģő\n </ŦęχŧĿįʼnĸ>}"
|
||||
},
|
||||
"group-mapping": {
|
||||
"grafana-admin": {
|
||||
"description": "Ĩƒ ęʼnäþľęđ, äľľ ūşęřş ƒřőm ŧĥįş ģřőūp ŵįľľ þę Ğřäƒäʼnä Åđmįʼnş",
|
||||
"label": "Ğřäƒäʼnä Åđmįʼn"
|
||||
},
|
||||
"group-dn": {
|
||||
"description": "Ŧĥę ʼnämę őƒ ŧĥę ĸęy ūşęđ ŧő ęχŧřäčŧ ŧĥę ĨĐ ŧőĸęʼn ƒřőm ŧĥę řęŧūřʼnęđ ØÅūŧĥ2 ŧőĸęʼn.",
|
||||
"label": "Ğřőūp ĐŃ"
|
||||
},
|
||||
"org-id": {
|
||||
"description": "Ŧĥę Ğřäƒäʼnä őřģäʼnįžäŧįőʼn đäŧäþäşę įđ. Đęƒäūľŧ őřģ (ĨĐ 1) ŵįľľ þę ūşęđ įƒ ľęƒŧ őūŧ",
|
||||
"label": "Øřģ ĨĐ"
|
||||
},
|
||||
"org-role": {
|
||||
"label": "Øřģ řőľę *"
|
||||
},
|
||||
"remove": {
|
||||
"button": "Ŗęmővę ģřőūp mäppįʼnģ"
|
||||
}
|
||||
},
|
||||
"group-mapping-section": {
|
||||
"add": {
|
||||
"button": "Åđđ ģřőūp mäppįʼnģ"
|
||||
},
|
||||
"description": "Mäp ĿĐÅP ģřőūpş ŧő Ğřäƒäʼnä őřģ řőľęş",
|
||||
"group-search-base-dns-description": "Ŝępäřäŧę þy čőmmäş őř şpäčęş",
|
||||
"group-search-base-dns-label": "Ğřőūp şęäřčĥ þäşę ĐŃŜ",
|
||||
|
Loading…
Reference in New Issue
Block a user