Skip to content

Commit f514ab1

Browse files
committed
completed user controller
1 parent d614784 commit f514ab1

File tree

7 files changed

+243
-65
lines changed

7 files changed

+243
-65
lines changed

TODO.md

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,24 @@
11
### TODOs
22
| Filename | line # | TODO
33
|:------|:------:|:------
4-
| gulpfile.js | 146 | Add gulp-banner to add GNU GPL nitice on every js file.
4+
| gulpfile.js | 146 | Add gulp-banner to add GNU GPL notice on every js file.
55
| controllers/Initialize.js | 18 | Test initialize controller
6-
| controllers/Users.js | 9 | Test buildProjection function
7-
| controllers/Users.js | 112 | Test limiting
8-
| controllers/Users.js | 113 | Test that response contains count of total record for the query
9-
| controllers/Users.js | 114 | Test that the last document Id in the return array of documents is in the response
10-
| controllers/Users.js | 115 | Test that sorting works
11-
| controllers/Users.js | 116 | Test that projection works
12-
| controllers/Users.js | 117 | Test that populating works
13-
| controllers/Users.js | 118 | Test that date range works
14-
| controllers/Users.js | 216 | Finish users controller
15-
| controllers/Users.js | 217 | Finish users route
16-
| controllers/Users.js | 218 | Test that any deleted data is backed up
17-
| routes/index.js | 213 | Implement API Generator
6+
| controllers/Users.js | 13 | Test buildProjection function
7+
| controllers/Users.js | 116 | Test limiting
8+
| controllers/Users.js | 117 | Test that response contains count of total record for the query
9+
| controllers/Users.js | 118 | Test that the last document Id in the return array of documents is in the response
10+
| controllers/Users.js | 119 | Test that sorting works
11+
| controllers/Users.js | 120 | Test that projection works
12+
| controllers/Users.js | 121 | Test that populating works
13+
| controllers/Users.js | 122 | Test that date range works
14+
| controllers/Users.js | 295 | Test users controller
15+
| controllers/Users.js | 296 | Finish users route
16+
| controllers/Users.js | 297 | Test that any deleted data is backed up
17+
| routes/index.js | 214 | Implement API Generator
1818
| routes/initialize.js | 10 | Test initialize route
19+
| services/encryption/index.js | 40 | Generate checksum here
1920
| services/queue/clock.js | 11 | work on a clock functionality so kue can support scheduled jobs
20-
| services/queue/jobs.js | 75 | Add webhook Job here
21-
| services/queue/workers.js | 18 | Add Webhook worker here
22-
| services/encryption/index.js | 40 | Generate checksum here
21+
| services/queue/jobs.js | 80 | Test saveToTrash job
22+
| services/queue/jobs.js | 93 | Test Webhook Event
23+
| services/queue/jobs.js | 137 | Test Secure Webhooks
24+
| services/queue/jobs.js | 144 | Test Unsecure Webhooks

controllers/Users.js

Lines changed: 92 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
"use strict";
22

33
var Users = require('../models').Users;
4+
var Trash = require('../models').Trash;
45
var q = require('q');
6+
var queue = require('../services/queue');
7+
8+
var service = 'Users';
59

610
var UsersController = {};
711

@@ -190,29 +194,104 @@ UsersController.count = function(req,res,next){
190194
});
191195
};
192196

193-
UsersController.delete = function(query){
197+
UsersController.delete = function(req,res,next){
198+
var query = req.query;
194199
// Find match
195-
// Push match to a queue for back up
196-
// Delete matches
197-
return Users.deleteMany(query);
200+
Users.find(query)
201+
.then(function(resp){
202+
var num = resp.length;
203+
var last = num - 1;
204+
for(var n in resp){
205+
if(typeof resp === 'object'){
206+
// Backup data in Trash
207+
var backupData = {};
208+
backupData.service = service;
209+
backupData.data = resp[n];
210+
backupData.owner = req.userId;
211+
backupData.deletedBy = req.userId;
212+
backupData.client = req.appId;
213+
backupData.developer = req.developer;
214+
215+
queue.create('saveToTrash', backupData)
216+
.save();
217+
if(n === last){
218+
return resp;
219+
}
220+
}else{
221+
if(n === last){
222+
return resp;
223+
}
224+
}
225+
}
226+
})
227+
.then(function(resp){
228+
// Delete matches
229+
return Users.deleteMany(query);
230+
})
231+
.then(function(resp){
232+
res.ok(resp);
233+
})
234+
.catch(function(err){
235+
next(err);
236+
});
198237
};
199238

200-
UsersController.deleteOne = function(id){
239+
UsersController.deleteOne = function(req,res,next){
240+
var id = req.query.id;
201241
// Find match
202-
// Push match to a queue for back up
203-
// Delete matches
204-
return Users.findByIdAndRemove(id);
242+
Users.findById(id)
243+
.then(function(resp){
244+
// Backup data in Trash
245+
var backupData = {};
246+
backupData.service = service;
247+
backupData.data = resp;
248+
backupData.owner = req.userId;
249+
backupData.deletedBy = req.userId;
250+
backupData.client = req.appId;
251+
backupData.developer = req.developer;
252+
253+
queue.create('saveToTrash', backupData)
254+
.save();
255+
return [resp];
256+
})
257+
.then(function(resp){
258+
// Delete match
259+
return Users.findByIdAndRemove(id);
260+
})
261+
.then(function(resp){
262+
res.ok(resp);
263+
})
264+
.catch(function(err){
265+
next(err);
266+
});
205267
};
206268

207-
UsersController.restore = function(query){
269+
UsersController.restore = function(req,res,next){
270+
var id = req.query.id;
208271
// Find data by ID from trash
209-
// Restore to DB
210-
// Delete from trash
211-
return Users.count(query);
272+
Trash.findById(id)
273+
.then(function(resp){
274+
if(resp.service === service){
275+
// Restore to DB
276+
return Users.create(resp.data);
277+
}else{
278+
throw new Error('This data does not belong to this service');
279+
}
280+
})
281+
.then(function(resp){
282+
// Delete from trash
283+
return [Trash.findByIdAndRemove(id), resp];
284+
})
285+
.spread(function(trash, resp){
286+
res.ok(resp);
287+
})
288+
.catch(function(err){
289+
next(err);
290+
});
212291
};
213292

214293
module.exports = UsersController;
215294

216-
// Todo: Finish users controller
295+
// Todo: Test users controller
217296
// Todo: Finish users route
218297
// ToDo: Test that any deleted data is backed up

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,8 @@
7272
"q": "^1.4.1",
7373
"randomstring": "^1.1.5",
7474
"redis": "^2.7.1",
75+
"request": "^2.81.0",
76+
"request-promise": "^4.2.1",
7577
"util": "^0.10.3",
7678
"winston": "^2.3.1",
7779
"winston-bugsnag": "^2.1.0"

routes/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ router._enforceUserIdAndAppId = function(req,res,next){
6161
}else{
6262
req.userId = userId;
6363
req.appId = appId;
64+
req.developer = developer;
6465
req.body.client = appId;
6566
req.body.owner = userId;
6667
req.body.createdBy = userId;

services/queue/jobs.js

Lines changed: 119 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@
33
var models = require('../../models');
44
var _ = require('lodash');
55
var log = require('../logger');
6+
var encryption = require('../encryption');
7+
var crypto = require('crypto');
8+
var request = require('request-promise');
9+
var q = require('q');
610

711
var jobs = {};
812

@@ -37,41 +41,125 @@ jobs.updateRequestLog = function(response, done){
3741
// Creates search tags for all db records
3842
jobs.createSearchTags = function(data, done){
3943
log.info('Creating search index for: ', data._id);
40-
var model = data.model;
41-
var update = data.update ? true : false;
42-
if(data.update){
43-
delete data.update;
44-
}
45-
delete data.model;
46-
var ourDoc = data;
47-
var split = [];
48-
delete ourDoc._id;
49-
delete ourDoc.createdAt;
50-
delete ourDoc.updatedAt;
51-
delete ourDoc.tags;
52-
for(var n in ourDoc){
53-
if(typeof ourDoc[n] === 'string'){
54-
split.push(ourDoc[n].split(' '));
44+
var model = data.model;
45+
var update = data.update ? true : false;
46+
if(data.update){
47+
delete data.update;
48+
}
49+
delete data.model;
50+
var ourDoc = data;
51+
var split = [];
52+
delete ourDoc._id;
53+
delete ourDoc.createdAt;
54+
delete ourDoc.updatedAt;
55+
delete ourDoc.tags;
56+
for(var n in ourDoc){
57+
if(typeof ourDoc[n] === 'string'){
58+
split.push(ourDoc[n].split(' '));
59+
}
5560
}
56-
}
5761

58-
var task;
59-
if(update){
60-
task = models[model].update(data,{ $set: { updatedAt: new Date()}, $addToSet: {tags: {$each: split}} });
61-
}else{
62-
task = models[model].update(data,{ $set: { tags: split} });
63-
}
62+
var task;
63+
if(update){
64+
task = models[model].update(data,{ $set: { updatedAt: new Date()}, $addToSet: {tags: {$each: split}} });
65+
}else{
66+
task = models[model].update(data,{ $set: { tags: split} });
67+
}
6468

65-
task
66-
.then(function(res){
67-
return done(false, res);
68-
})
69-
.catch(function(err){
70-
log.error(err);
71-
return done(new Error(err.message));
72-
});
69+
task
70+
.then(function(res){
71+
return done(false, res);
72+
})
73+
.catch(function(err){
74+
log.error(err);
75+
return done(new Error(err.message));
76+
});
7377
};
7478

75-
// Todo: Add webhook Job here
79+
// Backup Data to Trash
80+
// ToDo: Test saveToTrash job
81+
jobs.saveToTrash = function(data, done){
82+
log.info('Saving '+data._id+' to Trash...');
83+
models.Trash.create(data)
84+
.then(function(res){
85+
done(false, res);
86+
})
87+
.catch(function(err){
88+
done(new Error(err.message));
89+
});
90+
};
91+
92+
// Send Webhook Event
93+
// ToDo: Test Webhook Event
94+
jobs.sendWebhook = function(data, done){
95+
log.info('Sending Webhook to '+data.url+' (Secure mode: '+ data.secure+') with data => '+data.data);
96+
var hookData = {};
97+
// Expected data
98+
// {
99+
// url: 'http://string.com',
100+
// secure: true, // true or false
101+
// data: {
102+
// someData: 'this',
103+
// someOtherData: 'and this'
104+
// }
105+
// }
106+
//
107+
// Data Sent to Hook Url
108+
// {
109+
// secure: true, // true or false
110+
// truth: 'a45de562fc65428ac537f', // checksum (Optional)
111+
// x-tag: 'gjsdgjadgjdabchyriadndbmnqoeequcmbsdbmdbshjchd', // Encryption Key (Optional)
112+
// data: 'Encryted data if secure is true or data object if secure is false'
113+
// }
114+
var hookPromise;
115+
if(data.secure){
116+
hookData.secure = data.secure;
117+
// Convert the Object to String
118+
var stringData = JSON.stringify(data.data);
119+
120+
// Generate Checksum
121+
var checksum = crypto.createHash('sha512')
122+
.update(stringData)
123+
.digest('hex');
124+
hookData.truth = checksum;
125+
// Encrypt Data
126+
var key;
127+
hookPromise = encryption.generateKey()
128+
.then(function(resp){
129+
key = resp;
130+
hookData['x-tag'] = key;
131+
return encryption.encrypt(stringData, key);
132+
})
133+
.then(function(resp){
134+
hookData.data = resp;
135+
return hookData;
136+
});
137+
// ToDo: Test Secure Webhooks
138+
}else{
139+
hookPromise = q.fcall(function(){
140+
hookData.secure = false;
141+
hookData.data = data.data;
142+
return hookData;
143+
});
144+
// ToDo: Test Unsecure Webhooks
145+
}
146+
147+
hookPromise
148+
.then(function(resp){
149+
var options = {
150+
method: 'POST',
151+
uri: data.url,
152+
body: resp,
153+
json: true // Automatically parses the JSON string in the response
154+
};
155+
return request(options);
156+
})
157+
.then(function(resp){
158+
done(false, resp);
159+
})
160+
.catch(function(err){
161+
done(new Error(err.message));
162+
});
163+
};
76164

77165
module.exports = jobs;

services/queue/workers.js

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,24 @@
33
var queue = require('./');
44
var jobs = require('./jobs');
55

6-
queue.process('searchIndex',2, function(job, done){
6+
queue.process('searchIndex', 2, function(job, done){
77
jobs.createSearchTags(job.data, done);
88
});
99

10-
queue.process('logRequest',2, function(job, done){
10+
queue.process('logRequest', 2, function(job, done){
1111
jobs.createRequestLog(job.data, done);
1212
});
1313

14-
queue.process('logResponse',2, function(job, done){
14+
queue.process('logResponse', 2, function(job, done){
1515
jobs.updateRequestLog(job.data, done);
1616
});
1717

18-
// ToDo: Add Webhook worker here
18+
queue.process('saveToTrash', 2, function(job, done){
19+
jobs.saveToTrash(job.data, done);
20+
});
21+
22+
queue.process('sendWebhook', 2, function(job,done){
23+
jobs.sendWebhook(job.data, done);
24+
});
1925

2026
module.exports = queue;

test/services/queue.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ describe('#Queue service', function(){
4747
it('should load processes', function() {
4848
var process = require('../../services/queue/workers');
4949
// We have configured queue to create 2 workers per job making a total of 6 workers for 3 jobs that we currently have
50-
process.workers.length.should.equal(6);
50+
process.workers.length.should.equal(10);
5151
});
5252

5353

0 commit comments

Comments
 (0)