added azure related 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                 if (!context.params.provider) {\r
28                         return Promise.resolve(context);\r
29                 }\r
30                 \r
31                 switch(context.method){\r
32                         case 'get':\r
33                                 context.params.query._id = new ObjectID(context.id);\r
34 \r
35                                 let result = await context.app.services[context.app.get('base-path') + 'groups'].find(context.params);\r
36                                 if(result.data && result.data.length > 0){\r
37                                         context.result = result.data[0];\r
38                                 }else if(result.length > 0){\r
39                                         context.result = result[0];\r
40                                 }else{\r
41                                         context.result = [];\r
42                                 }\r
43                                 break;\r
44                         case 'find':\r
45                                 if(typeof context.params.user._id === 'string'){\r
46                                         context.params.user._id = new ObjectID(context.params.user._id);\r
47                                 }\r
48 \r
49                                 if(!context.params.user.permissions.includes('admin')){\r
50                                         context.params.query['members.userId'] = context.params.user._id;\r
51                                 }\r
52 \r
53                                 let lookup = context.params.query.lookup;\r
54                                 delete context.params.query.lookup;\r
55 \r
56                                 // If graphLookup is supplied in the query params as true, lookup all parents and children\r
57                                 if(lookup == 'up' || lookup == 'both'){\r
58                                         context.result = await new Promise((resolve, reject) => {\r
59                                                 context.app.services[context.app.get('base-path') + 'groups'].Model.aggregate([\r
60                                                         {\r
61                                                                 $match: context.params.query\r
62                                                         }\r
63                                                 ]).then(async res => {\r
64                                                         if(res.length){\r
65                                                                 for(let i = 0; i < res.length; i++){\r
66                                                                         res[i]['parentGroups'] = await getParentGroups(context.app.services[context.app.get('base-path') + 'groups'].Model, res[i]);\r
67                                                                 }\r
68                                                         }\r
69                                                         resolve(res);\r
70                                                 }).catch(err => {\r
71                                                         throw new errors.GeneralError(err);\r
72                                                 })\r
73                                         });\r
74                                 }\r
75                                 \r
76                                 //if user is an admin in one of ther groups, find children groups\r
77                                 if(lookup == 'down' || lookup == 'both'){\r
78                                         //this will be set if lookup already occured\r
79                                         if(context.result){\r
80                                                 for(let i = 0; i < context.result.length; i++){\r
81                                                         //only find children if they are admins\r
82                                                         if(checkGroupForPermission(context.result[i], context.params.user, 'management')){\r
83                                                                 let children = await getChildGroups(context.app.services[context.app.get('base-path') + 'groups'].Model, context.result[i]);\r
84                                                                 context.result[i]['childGroups'] = children;\r
85                                                         }\r
86                                                 }\r
87                                         }else{\r
88                                                 context.result = await new Promise(async (resolve, reject) => {\r
89                                                         context.app.services[context.app.get('base-path') + 'groups'].find(context.params).then(async res => {\r
90                                                                 let results;\r
91                                                                 if(res.total){\r
92                                                                         results = res.data;\r
93                                                                 }else{\r
94                                                                         results = res;\r
95                                                                 }\r
96                                                                 for(let i = 0; i < results.length; i++){\r
97                                                                         if(checkGroupForPermission(results[i], context.params.user, 'management')){\r
98                                                                                 results[i]['childGroups'] = await getChildGroups(context.app.services[context.app.get('base-path') + 'groups'].Model, results[i]);\r
99                                                                         }\r
100                                                                 }\r
101                                                                 resolve(results);\r
102                                                         }).catch(err => {\r
103                                                                 throw new errors.GeneralError(err);\r
104                                                         })\r
105                                                 });\r
106                                         }\r
107                                 }\r
108 \r
109                                 break;\r
110 \r
111                         case 'create':\r
112                                 break;\r
113 \r
114                         case 'update':\r
115                         case 'patch':\r
116                         case 'remove':\r
117                                 break;\r
118 \r
119                         default:\r
120                                 break;\r
121 \r
122 \r
123                 }\r
124 \r
125                 return context;\r
126         };\r
127 };\r
128 \r
129 getParentGroups = async function(model, group){\r
130         return new Promise(async (resolve, reject) => {\r
131                 let parentGroups = [];\r
132                 if(group.parentGroupId){\r
133                         model.aggregate([\r
134                                 {\r
135                                         $match: {\r
136                                                 '_id': group.parentGroupId\r
137                                         }\r
138                                 }\r
139                         ]).then(async res => {\r
140                                 if(res[0] && res[0].parentGroupId){\r
141                                         parentGroups.unshift(res[0]);\r
142                                         let parents = await getParentGroups(model, res[0]);\r
143                                         parents.forEach(e => {\r
144                                                 parentGroups.unshift(e);\r
145                                         });\r
146                                 }\r
147                                 resolve(parentGroups);\r
148                         }).catch(err => {\r
149                                 reject(err);\r
150                         })\r
151                 }else{\r
152                         resolve();\r
153                 }\r
154         });\r
155         \r
156 }\r
157 \r
158 getChildGroups = async function(model, group){\r
159         return new Promise(async (resolve, reject) => {\r
160                 let childGroups = [];\r
161                 model.aggregate([\r
162                         {\r
163                                 $match: {\r
164                                         'parentGroupId': group._id\r
165                                 }\r
166                         }\r
167                 ]).then(async res => {\r
168                         if(res.length > 0){\r
169                                 for(let i = 0; i < res.length; i++){\r
170                                         childGroups.push(res[i]);\r
171                                         let childern = await getChildGroups(model, res[i]);\r
172                                         childern.forEach((elem, val) => {\r
173                                                 childGroups.push(elem);\r
174                                         });\r
175                                 }\r
176                         }\r
177                         resolve(childGroups);\r
178                 }).catch(err => {\r
179                         reject(err);\r
180                 })\r
181 \r
182         })\r
183 }\r
184 \r
185 checkGroupForPermission = function(group, user, permission){\r
186         let result = false;\r
187         group.members.forEach((member, val) => {\r
188                 if(member.userId.toString() == user._id.toString()){\r
189                         group.roles.forEach((e,v) => {\r
190                                 if(e.permissions.includes(permission)){\r
191                                         if(member.roles.includes(e.roleName)){\r
192                                                 result = true;\r
193                                                 return;\r
194                                         }\r
195                                 }\r
196                         });\r
197                         return;\r
198                 }\r
199         })\r
200         return result;\r
201 }\r
202 \r
203 module.exports.afterGroups = function(){\r
204         return async context => {\r
205 \r
206         }\r
207 }\r
208 \r
209 module.exports.userFilter = function (){\r
210         return async context => {\r
211                 \r
212                 if(context.params.query){\r
213                         context.params.query._id = context.params.user._id;\r
214                 }\r
215                 if(context.id && context.id != context.params.user._id){\r
216                         throw new errors.Forbidden();\r
217                 }\r
218                 if(context.data){\r
219                         if(context.data._id && context.data._id != context.params.user._id){\r
220                                 throw new errors.Forbidden();\r
221                         }\r
222                         //should not be able to edit their groups\r
223                         delete context.data.groups;\r
224                         //should not be able to edit their permissions\r
225                         delete context.data.permissions;\r
226                         \r
227                         delete context.data.createdAt;\r
228                         delete context.data.updatedAt;\r
229                         delete context.data.enabled;\r
230                 }\r
231         }\r
232 }\r
233 \r
234 module.exports.getGroupFilter = function (options = { key: 'groupId' }) {\r
235         return async hook => {\r
236                 if(!hook.params.query){\r
237                         hook.params.query = {};\r
238                 }\r
239                 \r
240                 hook.params.query._id = hook.id;\r
241                 delete hook.id;\r
242                 \r
243                 return hook.service.find(hook.params)\r
244                         .then(result => {\r
245                                 if (result.data) {\r
246                                         hook.result = result.data[0];\r
247                                 } else {\r
248                                         hook.result = result;\r
249                                 }\r
250                                 return hook;\r
251                         });\r
252         };\r
253 };\r