1 var GroupManager = library.RestStandardized.build();
  2 var AdminUtils = library.AdminUtils.build();
  3 
  4 /**
  5  * @name GroupManager_GET
  6  * @class Collects Group info
  7  * @description  GET /wf/restapi/v2/admin/groupManager: This endpoint can collect all groups info or a specific groups info given the "id" or "name"
  8  * @param [id] search for a specific group by group id
  9  * @param [name] search for a specific group by name
 10  * @param [pretty=false] format the response to be human readable?
 11  *
 12  * @example GET /wf/restapi/v2/admin/groupManager
 13  * Response:
 14  *
 15  [
 16   {
 17     "loadingDockType": 0,
 18     "hidden": false,
 19     "description": "all of the system users",
 20     "priority": 1,
 21     "editLevel": 5,
 22     "loginText": "",
 23     "viewLevel": 5,
 24     "name": "users",
 25     "id": 6,
 26     "acls": [
 27       "0_6_FDD90A54-82B2-4257-AC4B-A8BBCAC939EF",
 28       "0_6_E0AA2BEC-0557-4417-A545-F67C0F51BA27"
 29     ],
 30     "users": [
 31       1
 32     ]
 33   },
 34   {
 35     "loadingDockType": 0,
 36     "hidden": false,
 37     "description": "A group for testing",
 38     "ldapDn": "",
 39     "priority": 1,
 40     "editLevel": 5,
 41     "loginText": "",
 42     "viewLevel": 5,
 43     "name": "Testing",
 44     "id": 8,
 45     "acls": [
 46       "0_8_56AB9B61-ACEC-4039-A626-9309CE2A8C7C"
 47     ],
 48     "users": [
 49       1
 50     ]
 51   }
 52  ]
 53  * @example GET /wf/restapi/v2/admin/groupManager?name=Testing
 54  * Response:
 55  *
 56  [
 57   {
 58     "loadingDockType": 0,
 59     "hidden": false,
 60     "description": "A group for testing",
 61     "ldapDn": "",
 62     "priority": 1,
 63     "editLevel": 5,
 64     "loginText": "",
 65     "viewLevel": 5,
 66     "name": "Testing",
 67     "id": 8,
 68     "acls": [
 69       "0_8_56AB9B61-ACEC-4039-A626-9309CE2A8C7C"
 70     ],
 71     "users": [
 72       1
 73     ]
 74   }
 75  ]
 76  * @example GET /wf/restapi/v2/admin/groupManager?id=6
 77  * Response:
 78  *
 79  [
 80   {
 81     "loadingDockType": 0,
 82     "hidden": false,
 83     "description": "all of the system users",
 84     "priority": 1,
 85     "editLevel": 5,
 86     "loginText": "",
 87     "viewLevel": 5,
 88     "name": "users",
 89     "id": 6,
 90     "acls": [
 91       "0_6_FDD90A54-82B2-4257-AC4B-A8BBCAC939EF",
 92       "0_6_E0AA2BEC-0557-4417-A545-F67C0F51BA27"
 93     ],
 94     "users": [
 95       1
 96     ]
 97   }
 98  ]
 99  */
100 GroupManager.doGet = function (theRequest) {
101   if (!context.getUser().isGlobalAdmin()) {
102     return GroupManager.setStatus(
103       GroupManager.errors.e403,
104       "Global Admin User Required"
105     );
106   }
107   var aGroupObjects = [];
108   var aGroup = findGroup(theRequest);
109   if (aGroup != null) {
110     aGroupObjects.push(aGroup);
111   } else if (!Boolean(theRequest.name) && !Boolean(theRequest.id)) {
112     aGroupObjects = groupManager.getAllGroups();
113   }
114   return AdminUtils.jsArray(aGroupObjects, AdminUtils.jsGroup);
115 };
116 
117 /**
118  * @name GroupManager_POST
119  * @class Creates groups
120  * @description  POST /wf/restapi/v2/admin/groupManager: This endpoint creates new groups or fails if the group already exists
121  * @param groups An array of group objects to create. These objects should have the same structure as collected from GroupManager_GET but without the "id" property.
122  * @param [pretty=false] format the response to be human readable?
123  *
124  * @example POST /wf/restapi/v2/admin/groupManager
125  * Body form-data:
126  * groups =
127  [
128     {
129         "loadingDockType": 10000,
130         "hidden": false,
131         "description": "Group to test creating new groups",
132         "ldapDn": "",
133         "priority": 2,
134         "editLevel": 4,
135         "loginText": "this is displayed on login",
136         "viewLevel": 6,
137         "name": "New Group",
138         "users": [
139             1
140         ]
141     }
142  ]
143 
144  Response:
145  [
146     {
147         "loadingDockType": 1,
148         "hidden": false,
149         "description": "Group to test creating new groups",
150         "ldapDn": "",
151         "priority": 2,
152         "editLevel": 4,
153         "loginText": "this is displayed on login",
154         "viewLevel": 6,
155         "name": "New Group",
156         "id": 9,
157         "acls": [],
158         "users": [
159             1
160         ]
161     }
162  ]
163  */
164 GroupManager.doPost = function (theRequestData) {
165   if (!context.getUser().isGlobalAdmin()) {
166     return GroupManager.setStatus(
167       GroupManager.errors.e403,
168       "Global Admin User Required"
169     );
170   }
171   var aGroups = GroupManager.massageToArray(theRequestData.groups);
172   return AdminUtils.jsArray(aGroups, function (aGroup) {
173     //theres no need to find a group by ID here
174     //we only want to create a group if it doesn't exist already
175     if (aGroup.id != null && aGroup.id != undefined) {
176       delete aGroup.id;
177     }
178     if (!Boolean(aGroup.name)) {
179       return GroupManager.setStatus(
180         GroupManager.errors.e400,
181         "Group name not provided"
182       );
183     }
184     var anExistingGroup = findGroup(aGroup);
185     if (anExistingGroup != null) {
186       var anError = GroupManager.setStatus(
187         GroupManager.errors.e400,
188         "Group already exists"
189       );
190       anError.group = AdminUtils.jsGroup(anExistingGroup);
191       return anError;
192     }
193     try {
194       var anUpdated = createOrUpdateGroup(aGroup, null);
195       return AdminUtils.jsGroup(anUpdated);
196     } catch (anE) {
197       logger.error(anE + "\n" + anE.stack);
198       return GroupManager.setStatus(
199         GroupManager.errors.e500,
200         "Failed to create group: " + anE.message
201       );
202     }
203   });
204 };
205 
206 /**
207  * @name GroupManager_PUT
208  * @class Creates or updates groups
209  * @description  PUT /wf/restapi/v2/admin/groupManager: This endpoint creates groups or updates existing groups.
210  * @param groups An array of group objects to create. These objects should have the same structure as collected from GroupManager_GET.
211  * If you are creating a new group the "id" parameter is not required, but it is required to update an existing group.
212  * @param [pretty=false] format the response to be human readable?
213  *
214  * @example PUT /wf/restapi/v2/admin/groupManager (Creating a new group)
215  * Body form-data:
216  * groups =
217  [
218     {
219         "loadingDockType": 10000,
220         "hidden": false,
221         "description": "Group to test creating new groups",
222         "ldapDn": "",
223         "priority": 2,
224         "editLevel": 4,
225         "loginText": "this is displayed on login",
226         "viewLevel": 6,
227         "name": "New Group",
228         "users": [
229             1
230         ]
231     }
232  ]
233 
234  Response:
235  [
236     {
237         "loadingDockType": 1,
238         "hidden": false,
239         "description": "Group to test creating new groups",
240         "ldapDn": "",
241         "priority": 2,
242         "editLevel": 4,
243         "loginText": "this is displayed on login",
244         "viewLevel": 6,
245         "name": "New Group",
246         "id": 9,
247         "acls": [],
248         "users": [
249             1
250         ]
251     }
252  ]
253 
254  * @example PUT /wf/restapi/v2/admin/groupManager (Updating the group from the previous example. Updated the description, priority, editLevel, viewLevel, name and users)
255  * Body form-data:
256  * groups =
257  [
258     {
259         "loadingDockType": 1,
260         "hidden": false,
261         "description": "Group to test modifying",
262         "ldapDn": "",
263         "priority": 1,
264         "editLevel": 5,
265         "loginText": "this is displayed on login",
266         "viewLevel": 5,
267         "name": "New Group rename",
268         "id": 9,
269         "acls": [],
270         "users": [
271             2
272         ]
273     }
274  ]
275 
276  Response:
277  [
278     {
279         "loadingDockType": 1,
280         "hidden": false,
281         "description": "Group to test modifying",
282         "ldapDn": "",
283         "priority": 1,
284         "editLevel": 5,
285         "loginText": "this is displayed on login",
286         "viewLevel": 5,
287         "name": "New Group rename",
288         "id": 9,
289         "acls": [],
290         "users": [
291             2
292         ]
293     }
294  ]
295  */
296 GroupManager.doPut = function (theRequestData) {
297   if (!context.getUser().isGlobalAdmin()) {
298     return GroupManager.setStatus(
299       GroupManager.errors.e403,
300       "Global Admin User Required"
301     );
302   }
303   var aGroups = GroupManager.massageToArray(theRequestData.groups);
304   return AdminUtils.jsArray(aGroups, function (aGroup) {
305     var anExistingGroup;
306     if (!!aGroup.id) {
307       anExistingGroup = groupManager.findGroupById(aGroup.id);
308 
309       // If the user provided a group id and that id doesn't exist do nothing
310       if (anExistingGroup === null) {
311         return GroupManager.setStatus(
312           GroupManager.errors.e400,
313           "Failed to find group by id: " + aGroup.id
314         );
315       }
316     }
317 
318     try {
319       var anUpdated = createOrUpdateGroup(aGroup, anExistingGroup);
320       return AdminUtils.jsGroup(anUpdated);
321     } catch (anE) {
322       logger.error(anE + "\n" + anE.stack);
323       var anError = GroupManager.setStatus(
324         GroupManager.errors.e500,
325         (anExistingGroup == null
326           ? "Failed to create group: "
327           : "Failed to update group: ") + anE.message
328       );
329       anError.group = AdminUtils.jsGroup(anExistingGroup);
330       return anError;
331     }
332   });
333 };
334 
335 /**
336  * @name GroupManager_DELETE
337  * @class Removes groups
338  * @description  DELETE /wf/restapi/v2/admin/groupManager: Removes groups from MediaBeacon
339  * @param groups An array of group objects to remove. These objects can have the same structure as collected from GroupManager_GET, but only require "id" or "name".
340  * @param [pretty=false] format the response to be human readable?
341  *
342  * @example DELETE /wf/restapi/v2/admin/groupManager
343  * Body form-data:
344  * groups =
345  [
346     {
347         "loadingDockType": 1,
348         "hidden": false,
349         "description": "Group to test modifying",
350         "ldapDn": "",
351         "priority": 1,
352         "editLevel": 5,
353         "loginText": "this is displayed on login",
354         "viewLevel": 5,
355         "name": "New Group rename",
356         "id": 9,
357         "acls": [],
358         "users": [
359             2
360         ]
361     },
362     {
363         "name": "Delete by name"
364     },
365     {
366         "id": 11
367     }
368  ]
369  * Response:
370  [
371     {
372         "loadingDockType": 1,
373         "hidden": false,
374         "description": "Group to test modifying",
375         "ldapDn": "",
376         "priority": 1,
377         "editLevel": 5,
378         "loginText": "this is displayed on login",
379         "viewLevel": 5,
380         "name": "New Group rename",
381         "id": 9,
382         "acls": [],
383         "users": []
384     },
385     {
386         "loadingDockType": 1,
387         "hidden": false,
388         "description": "",
389         "ldapDn": "",
390         "priority": 1,
391         "editLevel": 5,
392         "loginText": "",
393         "viewLevel": 5,
394         "name": "Delete by name",
395         "id": 10,
396         "acls": [],
397         "users": []
398     },
399     {
400         "loadingDockType": 1,
401         "hidden": false,
402         "description": "",
403         "ldapDn": "",
404         "priority": 1,
405         "editLevel": 5,
406         "loginText": "",
407         "viewLevel": 5,
408         "name": "Delete by id",
409         "id": 11,
410         "acls": [],
411         "users": []
412     }
413  ]
414  */
415 GroupManager.doDelete = function (theRequestData) {
416   if (!context.getUser().isGlobalAdmin()) {
417     return GroupManager.setStatus(
418       GroupManager.errors.e403,
419       "Global Admin User Required"
420     );
421   }
422   var aGroups = GroupManager.massageToArray(theRequestData.groups);
423   return AdminUtils.jsArray(aGroups, function (aGroup) {
424     var anExistingGroup = findGroup(aGroup);
425     if (anExistingGroup == null) {
426       //group is already deleted. do nothing
427       return null;
428     }
429     try {
430       groupManager.deleteGroupById(anExistingGroup.id);
431     } catch (anE) {
432       logger.error(anE + "\n" + anE.stack);
433       var anError = GroupManager.setStatus(
434         GroupManager.errors.e500,
435         anE.message
436       );
437       anError.group = AdminUtils.jsGroup(anExistingGroup);
438       return anError;
439     }
440     return AdminUtils.jsGroup(anExistingGroup);
441   });
442 };
443 
444 GroupManager.run();
445 
446 function findGroup(theDataObject) {
447   if (theDataObject.id != undefined && theDataObject.id != null) {
448     return groupManager.findGroupById(theDataObject.id);
449   } else if (!!theDataObject.name) {
450     return groupManager.findGroupByName(theDataObject.name);
451   }
452   return null;
453 }
454 
455 /**
456  * Updates teh groups settings and users.
457  * Creates a new group if theGroup is null
458  * @param theJsGroup object from client
459  * @param theGroup the group to update or null if the group hasn't been created yet
460  * @returns {*}
461  */
462 function createOrUpdateGroup(theJsGroup, theGroup) {
463   //Create the group if its undefined
464   if (!theGroup) {
465     theGroup = groupManager.findOrCreateGroup(theJsGroup.name);
466   }
467   //Set user data
468   var aSetters = [
469     "loadingDockType",
470     "hidden",
471     "description",
472     "ldapDn",
473     "priority",
474     "editLevel",
475     "loginText",
476     "viewLevel",
477     "name",
478   ];
479   var aModified = false;
480   for (var anAttribute in theJsGroup) {
481     if (aSetters.indexOf(anAttribute) < 0) {
482       continue;
483     }
484     if (theGroup[anAttribute] !== theJsGroup[anAttribute]) {
485       theGroup[anAttribute] = theJsGroup[anAttribute];
486       aModified = true;
487     }
488   }
489   if (aModified) {
490     theGroup.updateGroup();
491   }
492   // Add/Remove users from groups
493   AdminUtils.resolveArrayDifferences(
494     theJsGroup.users,
495     AdminUtils.jsArray(theGroup.getUsers(), function (theUser) {
496       return theUser.userId;
497     }),
498     function (theUserToAdd) {
499       userManager.addToGroup(
500         userManager.findByUserId(theUserToAdd).username,
501         theGroup.name
502       );
503     },
504     function (theUserToRemove) {
505       userManager.removeFromGroup(
506         userManager.findByUserId(theUserToRemove).username,
507         theGroup.name
508       );
509     }
510   );
511   return findGroup({ id: theGroup.id });
512 }
513