added svcapi ui and camunda code
[it/otf.git] / otf-frontend / server / src / feathers / hooks / filters.js
1 /*  Copyright (c) 2019 AT&T Intellectual Property.                             #\r
2 #                                                                              #\r
3 #   Licensed under the Apache License, Version 2.0 (the "License");            #\r
4 #   you may not use this file except in compliance with the License.           #\r
5 #   You may obtain a copy of the License at                                    #\r
6 #                                                                              #\r
7 #       http://www.apache.org/licenses/LICENSE-2.0                             #\r
8 #                                                                              #\r
9 #   Unless required by applicable law or agreed to in writing, software        #\r
10 #   distributed under the License is distributed on an "AS IS" BASIS,          #\r
11 #   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   #\r
12 #   See the License for the specific language governing permissions and        #\r
13 #   limitations under the License.                                             #\r
14 ##############################################################################*/\r
15 \r
16 \r
17 // Use this hook to manipulate incoming or outgoing data.\r
18 // For more information on hooks see: http://docs.feathersjs.com/api/hooks.html\r
19 const { iff, disallow } = require('feathers-hooks-common');\r
20 const errors = require('@feathersjs/errors');\r
21 const { ObjectID } = require('mongodb');\r
22 //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
23 \r
24 module.exports.groupFilter = function (options = null) {\r
25         return async context => {\r
26 \r
27                 \r
28                 switch(context.method){\r
29                         case 'get':\r
30                                 context.params.query._id = new ObjectID(context.id);\r
31 \r
32                                 let result = await context.app.services[context.app.get('base-path') + 'groups'].find(context.params);\r
33                                 if(result.data && result.data.length > 0){\r
34                                         context.result = result.data[0];\r
35                                 }else if(result.length > 0){\r
36                                         context.result = result[0];\r
37                                 }else{\r
38                                         context.result = [];\r
39                                 }\r
40                                 break;\r
41                         case 'find':\r
42                                 if(typeof context.params.user._id === 'string'){\r
43                                         context.params.user._id = new ObjectID(context.params.user._id);\r
44                                 }\r
45 \r
46                                 if(!context.params.user.permissions.includes('admin')){\r
47                                         context.params.query['members.userId'] = context.params.user._id;\r
48                                 }\r
49 \r
50                                 let lookup = context.params.query.lookup;\r
51                                 delete context.params.query.lookup;\r
52 \r
53                                 // If graphLookup is supplied in the query params as true, lookup all parents and children\r
54                                 if(lookup == 'up' || lookup == 'both'){\r
55                                         context.result = await new Promise((resolve, reject) => {\r
56                                                 context.app.services[context.app.get('base-path') + 'groups'].Model.aggregate([\r
57                                                         {\r
58                                                                 $match: context.params.query\r
59                                                         },\r
60                                                         {\r
61                                                                 $graphLookup: {\r
62                                                                         from: "groups",\r
63                                                                         startWith: "$parentGroupId",\r
64                                                                         connectFromField: "parentGroupId",\r
65                                                                         connectToField: "_id",\r
66                                                                         as: "parentGroups"\r
67                                                                 }\r
68                                                         }\r
69                                                 ]).then(res => {\r
70                                                         resolve(res);\r
71                                                 }).catch(err => {\r
72                                                         throw new errors.GeneralError(err);\r
73                                                 })\r
74                                         });\r
75                                 }\r
76                                 \r
77                                 //if user is an admin in one of ther groups, find children groups\r
78                                 if(lookup == 'down' || lookup == 'both'){\r
79                                         //this will be set if lookup already occured\r
80                                         if(context.result){\r
81                                                 for(let i = 0; i < context.result.length; i++){\r
82                                                         //only find children if they are admins\r
83                                                         if(checkGroupForPermission(context.result[i], context.params.user, 'management')){\r
84                                                                 let children = await getChildGroups(context.app.services[context.app.get('base-path') + 'groups'].Model, context.result[i]);\r
85                                                                 context.result[i]['childGroups'] = children;\r
86                                                         }\r
87                                                 }\r
88                                         }else{\r
89                                                 context.result = await new Promise(async (resolve, reject) => {\r
90                                                         context.app.services[context.app.get('base-path') + 'groups'].find(context.params).then(async res => {\r
91                                                                 let results;\r
92                                                                 if(res.total){\r
93                                                                         results = res.data;\r
94                                                                 }else{\r
95                                                                         results = res;\r
96                                                                 }\r
97                                                                 for(let i = 0; i < results.length; i++){\r
98                                                                         if(checkGroupForPermission(results[i], context.params.user, 'management')){\r
99                                                                                 results[i]['childGroups'] = await getChildGroups(context.app.services[context.app.get('base-path') + 'groups'].Model, results[i]);\r
100                                                                         }\r
101                                                                 }\r
102                                                                 resolve(results);\r
103                                                         }).catch(err => {\r
104                                                                 throw new errors.GeneralError(err);\r
105                                                         })\r
106                                                 });\r
107                                         }\r
108                                 }\r
109 \r
110                                 break;\r
111 \r
112                         case 'create':\r
113                                 break;\r
114 \r
115                         case 'update':\r
116                         case 'patch':\r
117                         case 'remove':\r
118                                 break;\r
119 \r
120                         default:\r
121                                 break;\r
122 \r
123 \r
124                 }\r
125 \r
126                 return context;\r
127         };\r
128 };\r
129 \r
130 getChildGroups = async function(model, group){\r
131         return new Promise(async (resolve, reject) => {\r
132                 let childGroups = [];\r
133                 model.aggregate([\r
134                         {\r
135                                 $match: {\r
136                                         'parentGroupId': group._id\r
137                                 }\r
138                         }\r
139                 ]).then(async res => {\r
140                         if(res.length > 0){\r
141                                 for(let i = 0; i < res.length; i++){\r
142                                         childGroups.push(res[i]);\r
143                                         let childern = await getChildGroups(model, res[i]);\r
144                                         childern.forEach((elem, val) => {\r
145                                                 childGroups.push(elem);\r
146                                         });\r
147                                 }\r
148                         }\r
149                         resolve(childGroups);\r
150                 }).catch(err => {\r
151                         reject(err);\r
152                 })\r
153 \r
154         })\r
155 }\r
156 \r
157 checkGroupForPermission = function(group, user, permission){\r
158         let result = false;\r
159         group.members.forEach((member, val) => {\r
160                 if(member.userId.toString() == user._id.toString()){\r
161                         group.roles.forEach((e,v) => {\r
162                                 if(e.permissions.includes(permission)){\r
163                                         if(member.roles.includes(e.roleName)){\r
164                                                 result = true;\r
165                                                 return;\r
166                                         }\r
167                                 }\r
168                         });\r
169                         return;\r
170                 }\r
171         })\r
172         return result;\r
173 }\r
174 \r
175 module.exports.afterGroups = function(){\r
176         return async context => {\r
177 \r
178         }\r
179 }\r
180 \r
181 module.exports.userFilter = function (){\r
182         return async context => {\r
183                 \r
184                 if(context.params.query){\r
185                         context.params.query._id = context.params.user._id;\r
186                 }\r
187                 if(context.id && context.id != context.params.user._id){\r
188                         throw new errors.Forbidden();\r
189                 }\r
190                 if(context.data){\r
191                         if(context.data._id && context.data._id != context.params.user._id){\r
192                                 throw new errors.Forbidden();\r
193                         }\r
194                         //should not be able to edit their groups\r
195                         delete context.data.groups;\r
196                         //should not be able to edit their permissions\r
197                         delete context.data.permissions;\r
198                         \r
199                         delete context.data.createdAt;\r
200                         delete context.data.updatedAt;\r
201                         delete context.data.enabled;\r
202                 }\r
203         }\r
204 }\r
205 \r
206 module.exports.getGroupFilter = function (options = { key: 'groupId' }) {\r
207         return async hook => {\r
208                 if(!hook.params.query){\r
209                         hook.params.query = {};\r
210                 }\r
211                 \r
212                 hook.params.query._id = hook.id;\r
213                 delete hook.id;\r
214                 \r
215                 return hook.service.find(hook.params)\r
216                         .then(result => {\r
217                                 if (result.data) {\r
218                                         hook.result = result.data[0];\r
219                                 } else {\r
220                                         hook.result = result;\r
221                                 }\r
222                                 return hook;\r
223                         });\r
224         };\r
225 };\r