--- /dev/null
+/* 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