added svcapi ui and camunda code
[it/otf.git] / otf-frontend / server / src / feathers / hooks / filters.js
diff --git a/otf-frontend/server/src/feathers/hooks/filters.js b/otf-frontend/server/src/feathers/hooks/filters.js
new file mode 100644 (file)
index 0000000..d81cd3f
--- /dev/null
@@ -0,0 +1,225 @@
+/*  Copyright (c) 2019 AT&T Intellectual Property.                             #\r
+#                                                                              #\r
+#   Licensed under the Apache License, Version 2.0 (the "License");            #\r
+#   you may not use this file except in compliance with the License.           #\r
+#   You may obtain a copy of the License at                                    #\r
+#                                                                              #\r
+#       http://www.apache.org/licenses/LICENSE-2.0                             #\r
+#                                                                              #\r
+#   Unless required by applicable law or agreed to in writing, software        #\r
+#   distributed under the License is distributed on an "AS IS" BASIS,          #\r
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   #\r
+#   See the License for the specific language governing permissions and        #\r
+#   limitations under the License.                                             #\r
+##############################################################################*/\r
+\r
+\r
+// Use this hook to manipulate incoming or outgoing data.\r
+// For more information on hooks see: http://docs.feathersjs.com/api/hooks.html\r
+const { iff, disallow } = require('feathers-hooks-common');\r
+const errors = require('@feathersjs/errors');\r
+const { ObjectID } = require('mongodb');\r
+//const getEntity = async (context) => await new Promise((resolve, reject) => context.app.services[context.path].get(context.id || context.data._id, context.params).then(r => {resolve(r)}).catch(e => {reject(e)}));\r
+\r
+module.exports.groupFilter = function (options = null) {\r
+       return async context => {\r
+\r
+               \r
+               switch(context.method){\r
+                       case 'get':\r
+                               context.params.query._id = new ObjectID(context.id);\r
+\r
+                               let result = await context.app.services[context.app.get('base-path') + 'groups'].find(context.params);\r
+                               if(result.data && result.data.length > 0){\r
+                                       context.result = result.data[0];\r
+                               }else if(result.length > 0){\r
+                                       context.result = result[0];\r
+                               }else{\r
+                                       context.result = [];\r
+                               }\r
+                               break;\r
+                       case 'find':\r
+                               if(typeof context.params.user._id === 'string'){\r
+                                       context.params.user._id = new ObjectID(context.params.user._id);\r
+                               }\r
+\r
+                               if(!context.params.user.permissions.includes('admin')){\r
+                                       context.params.query['members.userId'] = context.params.user._id;\r
+                               }\r
+\r
+                               let lookup = context.params.query.lookup;\r
+                               delete context.params.query.lookup;\r
+\r
+                               // If graphLookup is supplied in the query params as true, lookup all parents and children\r
+                               if(lookup == 'up' || lookup == 'both'){\r
+                                       context.result = await new Promise((resolve, reject) => {\r
+                                               context.app.services[context.app.get('base-path') + 'groups'].Model.aggregate([\r
+                                                       {\r
+                                                               $match: context.params.query\r
+                                                       },\r
+                                                       {\r
+                                                               $graphLookup: {\r
+                                                                       from: "groups",\r
+                                                                       startWith: "$parentGroupId",\r
+                                                                       connectFromField: "parentGroupId",\r
+                                                                       connectToField: "_id",\r
+                                                                       as: "parentGroups"\r
+                                                               }\r
+                                                       }\r
+                                               ]).then(res => {\r
+                                                       resolve(res);\r
+                                               }).catch(err => {\r
+                                                       throw new errors.GeneralError(err);\r
+                                               })\r
+                                       });\r
+                               }\r
+                               \r
+                               //if user is an admin in one of ther groups, find children groups\r
+                               if(lookup == 'down' || lookup == 'both'){\r
+                                       //this will be set if lookup already occured\r
+                                       if(context.result){\r
+                                               for(let i = 0; i < context.result.length; i++){\r
+                                                       //only find children if they are admins\r
+                                                       if(checkGroupForPermission(context.result[i], context.params.user, 'management')){\r
+                                                               let children = await getChildGroups(context.app.services[context.app.get('base-path') + 'groups'].Model, context.result[i]);\r
+                                                               context.result[i]['childGroups'] = children;\r
+                                                       }\r
+                                               }\r
+                                       }else{\r
+                                               context.result = await new Promise(async (resolve, reject) => {\r
+                                                       context.app.services[context.app.get('base-path') + 'groups'].find(context.params).then(async res => {\r
+                                                               let results;\r
+                                                               if(res.total){\r
+                                                                       results = res.data;\r
+                                                               }else{\r
+                                                                       results = res;\r
+                                                               }\r
+                                                               for(let i = 0; i < results.length; i++){\r
+                                                                       if(checkGroupForPermission(results[i], context.params.user, 'management')){\r
+                                                                               results[i]['childGroups'] = await getChildGroups(context.app.services[context.app.get('base-path') + 'groups'].Model, results[i]);\r
+                                                                       }\r
+                                                               }\r
+                                                               resolve(results);\r
+                                                       }).catch(err => {\r
+                                                               throw new errors.GeneralError(err);\r
+                                                       })\r
+                                               });\r
+                                       }\r
+                               }\r
+\r
+                               break;\r
+\r
+                       case 'create':\r
+                               break;\r
+\r
+                       case 'update':\r
+                       case 'patch':\r
+                       case 'remove':\r
+                               break;\r
+\r
+                       default:\r
+                               break;\r
+\r
+\r
+               }\r
+\r
+               return context;\r
+       };\r
+};\r
+\r
+getChildGroups = async function(model, group){\r
+       return new Promise(async (resolve, reject) => {\r
+               let childGroups = [];\r
+               model.aggregate([\r
+                       {\r
+                               $match: {\r
+                                       'parentGroupId': group._id\r
+                               }\r
+                       }\r
+               ]).then(async res => {\r
+                       if(res.length > 0){\r
+                               for(let i = 0; i < res.length; i++){\r
+                                       childGroups.push(res[i]);\r
+                                       let childern = await getChildGroups(model, res[i]);\r
+                                       childern.forEach((elem, val) => {\r
+                                               childGroups.push(elem);\r
+                                       });\r
+                               }\r
+                       }\r
+                       resolve(childGroups);\r
+               }).catch(err => {\r
+                       reject(err);\r
+               })\r
+\r
+       })\r
+}\r
+\r
+checkGroupForPermission = function(group, user, permission){\r
+       let result = false;\r
+       group.members.forEach((member, val) => {\r
+               if(member.userId.toString() == user._id.toString()){\r
+                       group.roles.forEach((e,v) => {\r
+                               if(e.permissions.includes(permission)){\r
+                                       if(member.roles.includes(e.roleName)){\r
+                                               result = true;\r
+                                               return;\r
+                                       }\r
+                               }\r
+                       });\r
+                       return;\r
+               }\r
+       })\r
+       return result;\r
+}\r
+\r
+module.exports.afterGroups = function(){\r
+       return async context => {\r
+\r
+       }\r
+}\r
+\r
+module.exports.userFilter = function (){\r
+       return async context => {\r
+               \r
+               if(context.params.query){\r
+                       context.params.query._id = context.params.user._id;\r
+               }\r
+               if(context.id && context.id != context.params.user._id){\r
+                       throw new errors.Forbidden();\r
+               }\r
+               if(context.data){\r
+                       if(context.data._id && context.data._id != context.params.user._id){\r
+                               throw new errors.Forbidden();\r
+                       }\r
+                       //should not be able to edit their groups\r
+                       delete context.data.groups;\r
+                       //should not be able to edit their permissions\r
+                       delete context.data.permissions;\r
+                       \r
+                       delete context.data.createdAt;\r
+                       delete context.data.updatedAt;\r
+                       delete context.data.enabled;\r
+               }\r
+       }\r
+}\r
+\r
+module.exports.getGroupFilter = function (options = { key: 'groupId' }) {\r
+       return async hook => {\r
+               if(!hook.params.query){\r
+                       hook.params.query = {};\r
+               }\r
+               \r
+               hook.params.query._id = hook.id;\r
+               delete hook.id;\r
+               \r
+               return hook.service.find(hook.params)\r
+                       .then(result => {\r
+                               if (result.data) {\r
+                                       hook.result = result.data[0];\r
+                               } else {\r
+                                       hook.result = result;\r
+                               }\r
+                               return hook;\r
+                       });\r
+       };\r
+};\r