The open and composable observability and data visualization platform. Visualize metrics, logs, and traces from multiple sources like Prometheus, Loki, Elasticsearch, InfluxDB, Postgres and many more.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 
grafana/public/app/features/auth-config/utils/data.ts

137 lines
3.8 KiB

import { SelectableValue } from '@grafana/data';
import { fieldMap, sectionFields } from '../fields';
import { FieldData, SSOProvider, SSOProviderDTO } from '../types';
import { isSelectableValue } from './guards';
export const emptySettings: SSOProviderDTO = {
allowAssignGrafanaAdmin: false,
allowSignUp: false,
allowedDomains: [],
allowedGroups: [],
allowedOrganizations: [],
apiUrl: '',
authStyle: '',
authUrl: '',
autoLogin: false,
clientAuthentication: '',
clientId: '',
clientSecret: '',
managedIdentityClientId: '',
federatedCredentialAudience: '',
emailAttributeName: '',
emailAttributePath: '',
emptyScopes: false,
enabled: false,
extra: {},
groupsAttributePath: '',
hostedDomain: '',
icon: 'shield',
name: '',
roleAttributePath: '',
roleAttributeStrict: false,
scopes: [],
signoutRedirectUrl: '',
skipOrgRoleSync: false,
teamIds: [],
teamIdsAttributePath: '',
teamsUrl: '',
tlsClientCa: '',
tlsClientCert: '',
tlsClientKey: '',
tlsSkipVerify: false,
tokenUrl: '',
type: '',
usePkce: false,
useRefreshToken: false,
};
const strToValue = (val: string | string[]): SelectableValue[] => {
if (!val?.length) {
return [];
}
if (Array.isArray(val)) {
return val.map((v) => ({ label: v, value: v }));
}
// Stored as JSON Array
if (val.startsWith('[') && val.endsWith(']')) {
return JSON.parse(val).map((v: string) => ({ label: v, value: v }));
}
return val.split(/[\s,]/).map((s) => ({ label: s, value: s }));
};
export function dataToDTO(data?: SSOProvider): SSOProviderDTO {
if (!data) {
return emptySettings;
}
const providerFields = getFieldsForProvider(data.provider);
const arrayFields = getArrayFields(fieldMap(data.provider), providerFields);
const settings = { ...data.settings };
for (const field of arrayFields) {
//@ts-expect-error
settings[field] = strToValue(settings[field]);
}
//@ts-expect-error
return settings;
}
const valuesToString = (values: Array<SelectableValue<string>>) => {
if (values.length <= 1) {
return values.map(({ value }) => value).join(',');
}
// Store as JSON array if there are multiple values
return JSON.stringify(values.map(({ value }) => value));
};
const getFieldsForProvider = (provider: string) => {
const sections = sectionFields[provider];
// include the enabled field because it is not part of the fields defined for providers
const fields = ['enabled'];
return Object.values(sections).reduce(
(result, section) => [
...result,
...section.fields.map((field) => (typeof field === 'string' ? field : field.name)),
],
fields
);
};
// Convert the DTO to the data format used by the API
export function dtoToData(dto: SSOProviderDTO, provider: string) {
let current: Partial<SSOProviderDTO> = dto;
const providerFields = getFieldsForProvider(provider);
const arrayFields = getArrayFields(fieldMap(provider), providerFields);
// filter out the fields that are not defined on the provider
const settings: Partial<SSOProviderDTO> = Object.keys(current)
.filter((key) => providerFields.includes(key))
.reduce((obj, key) => {
//@ts-expect-error
return { ...obj, [key]: current[key] };
}, {});
for (const field of arrayFields) {
const value = current[field];
if (value) {
if (isSelectableValue(value)) {
//@ts-expect-error
settings[field] = valuesToString(value);
} else if (isSelectableValue([value])) {
//@ts-expect-error
settings[field] = value.value;
}
}
}
return settings;
}
export function getArrayFields(obj: Record<string, FieldData>, providerFields: string[]): Array<keyof SSOProviderDTO> {
return Object.entries(obj)
.filter(([key, value]) => providerFields.includes(key) && value.type === 'select')
.map(([key]) => key as keyof SSOProviderDTO);
}