Skip to content

Commit d3c950f

Browse files
committed
Add API functions for request types and request forms to export/import/delete them
1 parent dd685d8 commit d3c950f

54 files changed

Lines changed: 38775 additions & 1 deletion

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 368 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,368 @@
1+
import util from 'util';
2+
3+
import { State } from '../../../shared/State';
4+
import { getApiSearchAll } from '../../../utils/ExportImportUtils';
5+
import { getHostOnlyUrl } from '../../../utils/ForgeRockUtils';
6+
import { Metadata } from '../../ApiTypes';
7+
import { generateGovernanceApi } from '../../BaseApi';
8+
9+
const requestFormsEndpointURLTemplate = '%s/iga/governance/requestForms';
10+
const requestFormURLTemplate = requestFormsEndpointURLTemplate + '/%s';
11+
const requestFormAssignmentsEndpointURLTemplate =
12+
'%s/iga/governance/requestFormAssignments';
13+
const assignRequestFormAssignmentsEndpointURLTemplate =
14+
requestFormAssignmentsEndpointURLTemplate + '?_action=assign';
15+
const unassignRequestFormAssignmentsEndpointURLTemplate =
16+
requestFormAssignmentsEndpointURLTemplate + '?_action=unassign';
17+
18+
export type RequestFormType = 'lcmRequest' | 'request' | 'applicationRequest';
19+
export type RequestFormOperationType = 'create' | 'update' | 'delete';
20+
export type Field =
21+
| TextField
22+
| TextAreaField
23+
| CheckboxField
24+
| SelectField
25+
| MultiSelectField
26+
| DateField
27+
| FormTextField
28+
| SectionField;
29+
export type FieldType =
30+
| 'string'
31+
| 'textarea'
32+
| 'checkbox'
33+
| 'select'
34+
| 'multiselect'
35+
| 'date'
36+
| 'section'
37+
| 'formText';
38+
export type SelectFieldObjectType =
39+
| 'entitlement'
40+
| 'application'
41+
| 'organization'
42+
| 'role'
43+
| 'user';
44+
45+
export interface RequestFormEvent {
46+
type?: 'script';
47+
script?: string | string[];
48+
}
49+
50+
export interface FieldRow {
51+
id: string;
52+
fields: Field[];
53+
}
54+
55+
export interface RequestFormField {
56+
id: string;
57+
type: FieldType;
58+
customSlot: 'formText' | false;
59+
validation: {
60+
required?: boolean;
61+
regex?: {
62+
pattern?: string;
63+
message?: string;
64+
};
65+
};
66+
layout: {
67+
columns: number;
68+
offset: number;
69+
};
70+
}
71+
72+
export interface CustomFormField extends RequestFormField {
73+
model: string;
74+
label: string;
75+
description?: string;
76+
readOnly: boolean;
77+
onChangeEvent: RequestFormEvent;
78+
}
79+
80+
export interface TextField extends CustomFormField {
81+
defaultValue: string;
82+
}
83+
84+
export interface TextAreaField extends TextField {} // Same as TextField
85+
86+
export interface CheckboxField extends CustomFormField {
87+
defaultValue: boolean;
88+
}
89+
90+
export interface SelectField extends CustomFormField {
91+
options:
92+
| {
93+
object: SelectFieldObjectType;
94+
queryFilter?: string;
95+
}
96+
| {
97+
value: string;
98+
label: string;
99+
selectedByDefault?: boolean;
100+
}[];
101+
}
102+
103+
export interface MultiSelectField extends SelectField {} // Same as SelectField
104+
105+
export interface DateField extends CustomFormField {} // Same as CustomFormField
106+
107+
export interface FormTextField extends RequestFormField {
108+
formText: string;
109+
}
110+
111+
export interface SectionField extends RequestFormField {
112+
model: string;
113+
header: string;
114+
footer: string;
115+
fields: FieldRow[];
116+
}
117+
118+
export interface RequestFormForm {
119+
fields?: FieldRow[];
120+
events?: {
121+
onLoad?: RequestFormEvent;
122+
};
123+
}
124+
125+
export interface RequestFormSkeleton {
126+
name: string;
127+
type: RequestFormType;
128+
id: string;
129+
description: string;
130+
categories: {
131+
applicationType: string | null;
132+
objectType: string | null;
133+
operation: RequestFormOperationType;
134+
lcmType?: string | null;
135+
requestType?: string;
136+
};
137+
form: RequestFormForm;
138+
_rev?: number;
139+
metadata?: Metadata;
140+
// This is a field we use when exporting to include any references to configuration that depends on the request form (such as workflows, request types, or applications)
141+
assignments?: RequestFormAssignment[];
142+
}
143+
144+
export interface RequestFormAssignment {
145+
formId: string;
146+
/**
147+
* objectId looks different depending on the request form type, but uses data from the categories if it's the first assignment:
148+
*
149+
* Applications: application/<applicationType>/<objectType>/<operation>
150+
* LCM: lcm/<lcmType>/<operation>
151+
* Custom Request: requestType/<requestType>
152+
*/
153+
objectId: string;
154+
metadata?: Metadata;
155+
}
156+
157+
/**
158+
* Get request form
159+
* @param {string} formId The request form id
160+
* @returns {Promise<RequestFormSkeleton>} A promise that resolves to a request form object
161+
*/
162+
export async function getRequestForm({
163+
formId,
164+
state,
165+
}: {
166+
formId: string;
167+
state: State;
168+
}): Promise<RequestFormSkeleton> {
169+
const urlString = util.format(
170+
requestFormURLTemplate,
171+
getHostOnlyUrl(state.getHost()),
172+
formId
173+
);
174+
const { data } = await generateGovernanceApi({
175+
resource: {},
176+
state,
177+
}).get(urlString, {
178+
withCredentials: true,
179+
});
180+
return data;
181+
}
182+
183+
/**
184+
* Query request forms
185+
* @param {string} queryFilter The query filter to query with. Default: 'true'
186+
* @returns {Promise<RequestFormSkeleton[]>} A promise that resolves to an array of request form objects
187+
*/
188+
export async function queryRequestForms({
189+
queryFilter = 'true',
190+
state,
191+
}: {
192+
queryFilter?: string;
193+
state: State;
194+
}): Promise<RequestFormSkeleton[]> {
195+
const urlString = util.format(
196+
requestFormsEndpointURLTemplate,
197+
getHostOnlyUrl(state.getHost())
198+
);
199+
return await getApiSearchAll<RequestFormSkeleton>({
200+
url: urlString,
201+
queryFilter,
202+
state,
203+
});
204+
}
205+
206+
/**
207+
* Get request form assignments. If no id(s) are provided, it will return all existing form assignments.
208+
* @param {string} formId The optional request form id. If specified, gets assignments for the specified form.
209+
* @param {string} workflowId The optional workflow id. If specified, gets assignments for the specified workflow.
210+
* @param {string} applicationId The optional application id. If specified, gets assignments for the specified application.
211+
* @returns {Promise<RequestFormAssignment[]>} A promise that resolves to an array of request form assignment objects
212+
*/
213+
export async function getRequestFormAssignments({
214+
formId,
215+
workflowId,
216+
applicationId,
217+
state,
218+
}: {
219+
formId?: string;
220+
workflowId?: string;
221+
applicationId?: string;
222+
state: State;
223+
}): Promise<RequestFormAssignment[]> {
224+
const urlString = util.format(
225+
requestFormAssignmentsEndpointURLTemplate,
226+
getHostOnlyUrl(state.getHost())
227+
);
228+
const expressions = [];
229+
if (formId) {
230+
expressions.push(`formId eq "${formId}"`);
231+
}
232+
if (workflowId) {
233+
expressions.push(`objectId sw "workflow/${workflowId}"`);
234+
}
235+
if (applicationId) {
236+
expressions.push(`objectId sw "application/${applicationId}"`);
237+
}
238+
return await getApiSearchAll<RequestFormAssignment>({
239+
url: urlString,
240+
queryFilter: expressions.length ? expressions.join(' and ') : 'true',
241+
state,
242+
});
243+
}
244+
245+
/**
246+
* Put request form
247+
* @param {string} formId The request form id
248+
* @param {RequestFormSkeleton} formData The request form data
249+
* @returns {Promise<RequestFormSkeleton>} A promise that resolves to a request form object
250+
*/
251+
export async function putRequestForm({
252+
formId,
253+
formData,
254+
state,
255+
}: {
256+
formId: string;
257+
formData: RequestFormSkeleton;
258+
state: State;
259+
}): Promise<RequestFormSkeleton> {
260+
const urlString = util.format(
261+
requestFormURLTemplate,
262+
getHostOnlyUrl(state.getHost()),
263+
formId
264+
);
265+
const { data } = await generateGovernanceApi({
266+
resource: {},
267+
state,
268+
}).put(urlString, formData, {
269+
withCredentials: true,
270+
});
271+
return data;
272+
}
273+
274+
/**
275+
* Assign request form to an object
276+
* @param {string} formId The request form id
277+
* @param {string} objectId The object id
278+
* @returns {Promise<RequestFormAssignment>} A promise that resolves to a request form assignment object
279+
*/
280+
export async function assignRequestForm({
281+
formId,
282+
objectId,
283+
state,
284+
}: {
285+
formId: string;
286+
objectId: string;
287+
state: State;
288+
}): Promise<RequestFormAssignment> {
289+
const urlString = util.format(
290+
assignRequestFormAssignmentsEndpointURLTemplate,
291+
getHostOnlyUrl(state.getHost())
292+
);
293+
const { data } = await generateGovernanceApi({
294+
resource: {},
295+
state,
296+
}).post(
297+
urlString,
298+
{
299+
formId,
300+
objectId,
301+
},
302+
{
303+
withCredentials: true,
304+
}
305+
);
306+
return data;
307+
}
308+
309+
/**
310+
* Unassign request form from an object
311+
* @param {string} formId The request form id
312+
* @param {string} objectId The object id
313+
* @returns {Promise<RequestFormAssignment>} A promise that resolves to a request form assignment object
314+
*/
315+
export async function unassignRequestForm({
316+
formId,
317+
objectId,
318+
state,
319+
}: {
320+
formId: string;
321+
objectId: string;
322+
state: State;
323+
}): Promise<RequestFormAssignment> {
324+
const urlString = util.format(
325+
unassignRequestFormAssignmentsEndpointURLTemplate,
326+
getHostOnlyUrl(state.getHost())
327+
);
328+
const { data } = await generateGovernanceApi({
329+
resource: {},
330+
state,
331+
}).post(
332+
urlString,
333+
{
334+
formId,
335+
objectId,
336+
},
337+
{
338+
withCredentials: true,
339+
}
340+
);
341+
return data;
342+
}
343+
344+
/**
345+
* Delete request form
346+
* @param {string} formId The request form id
347+
* @returns {Promise<RequestFormSkeleton>} A promise that resolves to a request form object
348+
*/
349+
export async function deleteRequestForm({
350+
formId,
351+
state,
352+
}: {
353+
formId: string;
354+
state: State;
355+
}): Promise<RequestFormSkeleton> {
356+
const urlString = util.format(
357+
requestFormURLTemplate,
358+
getHostOnlyUrl(state.getHost()),
359+
formId
360+
);
361+
const { data } = await generateGovernanceApi({
362+
resource: {},
363+
state,
364+
}).delete(urlString, {
365+
withCredentials: true,
366+
});
367+
return data;
368+
}

0 commit comments

Comments
 (0)