Skip to content

Commit

Permalink
completed user controller
Browse files Browse the repository at this point in the history
  • Loading branch information
iolufemi committed Aug 13, 2017
1 parent d614784 commit f514ab1
Show file tree
Hide file tree
Showing 7 changed files with 243 additions and 65 deletions.
34 changes: 18 additions & 16 deletions TODO.md
Original file line number Diff line number Diff line change
@@ -1,22 +1,24 @@
### TODOs
| Filename | line # | TODO
|:------|:------:|:------
| gulpfile.js | 146 | Add gulp-banner to add GNU GPL nitice on every js file.
| gulpfile.js | 146 | Add gulp-banner to add GNU GPL notice on every js file.
| controllers/Initialize.js | 18 | Test initialize controller
| controllers/Users.js | 9 | Test buildProjection function
| controllers/Users.js | 112 | Test limiting
| controllers/Users.js | 113 | Test that response contains count of total record for the query
| controllers/Users.js | 114 | Test that the last document Id in the return array of documents is in the response
| controllers/Users.js | 115 | Test that sorting works
| controllers/Users.js | 116 | Test that projection works
| controllers/Users.js | 117 | Test that populating works
| controllers/Users.js | 118 | Test that date range works
| controllers/Users.js | 216 | Finish users controller
| controllers/Users.js | 217 | Finish users route
| controllers/Users.js | 218 | Test that any deleted data is backed up
| routes/index.js | 213 | Implement API Generator
| controllers/Users.js | 13 | Test buildProjection function
| controllers/Users.js | 116 | Test limiting
| controllers/Users.js | 117 | Test that response contains count of total record for the query
| controllers/Users.js | 118 | Test that the last document Id in the return array of documents is in the response
| controllers/Users.js | 119 | Test that sorting works
| controllers/Users.js | 120 | Test that projection works
| controllers/Users.js | 121 | Test that populating works
| controllers/Users.js | 122 | Test that date range works
| controllers/Users.js | 295 | Test users controller
| controllers/Users.js | 296 | Finish users route
| controllers/Users.js | 297 | Test that any deleted data is backed up
| routes/index.js | 214 | Implement API Generator
| routes/initialize.js | 10 | Test initialize route
| services/encryption/index.js | 40 | Generate checksum here
| services/queue/clock.js | 11 | work on a clock functionality so kue can support scheduled jobs
| services/queue/jobs.js | 75 | Add webhook Job here
| services/queue/workers.js | 18 | Add Webhook worker here
| services/encryption/index.js | 40 | Generate checksum here
| services/queue/jobs.js | 80 | Test saveToTrash job
| services/queue/jobs.js | 93 | Test Webhook Event
| services/queue/jobs.js | 137 | Test Secure Webhooks
| services/queue/jobs.js | 144 | Test Unsecure Webhooks
105 changes: 92 additions & 13 deletions controllers/Users.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
"use strict";

var Users = require('../models').Users;
var Trash = require('../models').Trash;
var q = require('q');
var queue = require('../services/queue');

var service = 'Users';

var UsersController = {};

Expand Down Expand Up @@ -190,29 +194,104 @@ UsersController.count = function(req,res,next){
});
};

UsersController.delete = function(query){
UsersController.delete = function(req,res,next){
var query = req.query;
// Find match
// Push match to a queue for back up
// Delete matches
return Users.deleteMany(query);
Users.find(query)
.then(function(resp){
var num = resp.length;
var last = num - 1;
for(var n in resp){
if(typeof resp === 'object'){
// Backup data in Trash
var backupData = {};
backupData.service = service;
backupData.data = resp[n];
backupData.owner = req.userId;
backupData.deletedBy = req.userId;
backupData.client = req.appId;
backupData.developer = req.developer;

queue.create('saveToTrash', backupData)
.save();
if(n === last){
return resp;
}
}else{
if(n === last){
return resp;
}
}
}
})
.then(function(resp){
// Delete matches
return Users.deleteMany(query);
})
.then(function(resp){
res.ok(resp);
})
.catch(function(err){
next(err);
});
};

UsersController.deleteOne = function(id){
UsersController.deleteOne = function(req,res,next){
var id = req.query.id;
// Find match
// Push match to a queue for back up
// Delete matches
return Users.findByIdAndRemove(id);
Users.findById(id)
.then(function(resp){
// Backup data in Trash
var backupData = {};
backupData.service = service;
backupData.data = resp;
backupData.owner = req.userId;
backupData.deletedBy = req.userId;
backupData.client = req.appId;
backupData.developer = req.developer;

queue.create('saveToTrash', backupData)
.save();
return [resp];
})
.then(function(resp){
// Delete match
return Users.findByIdAndRemove(id);
})
.then(function(resp){
res.ok(resp);
})
.catch(function(err){
next(err);
});
};

UsersController.restore = function(query){
UsersController.restore = function(req,res,next){
var id = req.query.id;
// Find data by ID from trash
// Restore to DB
// Delete from trash
return Users.count(query);
Trash.findById(id)
.then(function(resp){
if(resp.service === service){
// Restore to DB
return Users.create(resp.data);
}else{
throw new Error('This data does not belong to this service');
}
})
.then(function(resp){
// Delete from trash
return [Trash.findByIdAndRemove(id), resp];
})
.spread(function(trash, resp){
res.ok(resp);
})
.catch(function(err){
next(err);
});
};

module.exports = UsersController;

// Todo: Finish users controller
// Todo: Test users controller
// Todo: Finish users route
// ToDo: Test that any deleted data is backed up
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@
"q": "^1.4.1",
"randomstring": "^1.1.5",
"redis": "^2.7.1",
"request": "^2.81.0",
"request-promise": "^4.2.1",
"util": "^0.10.3",
"winston": "^2.3.1",
"winston-bugsnag": "^2.1.0"
Expand Down
1 change: 1 addition & 0 deletions routes/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ router._enforceUserIdAndAppId = function(req,res,next){
}else{
req.userId = userId;
req.appId = appId;
req.developer = developer;
req.body.client = appId;
req.body.owner = userId;
req.body.createdBy = userId;
Expand Down
150 changes: 119 additions & 31 deletions services/queue/jobs.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
var models = require('../../models');
var _ = require('lodash');
var log = require('../logger');
var encryption = require('../encryption');
var crypto = require('crypto');
var request = require('request-promise');
var q = require('q');

var jobs = {};

Expand Down Expand Up @@ -37,41 +41,125 @@ jobs.updateRequestLog = function(response, done){
// Creates search tags for all db records
jobs.createSearchTags = function(data, done){
log.info('Creating search index for: ', data._id);
var model = data.model;
var update = data.update ? true : false;
if(data.update){
delete data.update;
}
delete data.model;
var ourDoc = data;
var split = [];
delete ourDoc._id;
delete ourDoc.createdAt;
delete ourDoc.updatedAt;
delete ourDoc.tags;
for(var n in ourDoc){
if(typeof ourDoc[n] === 'string'){
split.push(ourDoc[n].split(' '));
var model = data.model;
var update = data.update ? true : false;
if(data.update){
delete data.update;
}
delete data.model;
var ourDoc = data;
var split = [];
delete ourDoc._id;
delete ourDoc.createdAt;
delete ourDoc.updatedAt;
delete ourDoc.tags;
for(var n in ourDoc){
if(typeof ourDoc[n] === 'string'){
split.push(ourDoc[n].split(' '));
}
}
}

var task;
if(update){
task = models[model].update(data,{ $set: { updatedAt: new Date()}, $addToSet: {tags: {$each: split}} });
}else{
task = models[model].update(data,{ $set: { tags: split} });
}
var task;
if(update){
task = models[model].update(data,{ $set: { updatedAt: new Date()}, $addToSet: {tags: {$each: split}} });
}else{
task = models[model].update(data,{ $set: { tags: split} });
}

task
.then(function(res){
return done(false, res);
})
.catch(function(err){
log.error(err);
return done(new Error(err.message));
});
task
.then(function(res){
return done(false, res);
})
.catch(function(err){
log.error(err);
return done(new Error(err.message));
});
};

// Todo: Add webhook Job here
// Backup Data to Trash
// ToDo: Test saveToTrash job
jobs.saveToTrash = function(data, done){
log.info('Saving '+data._id+' to Trash...');
models.Trash.create(data)
.then(function(res){
done(false, res);
})
.catch(function(err){
done(new Error(err.message));
});
};

// Send Webhook Event
// ToDo: Test Webhook Event
jobs.sendWebhook = function(data, done){
log.info('Sending Webhook to '+data.url+' (Secure mode: '+ data.secure+') with data => '+data.data);
var hookData = {};
// Expected data
// {
// url: 'http://string.com',
// secure: true, // true or false
// data: {
// someData: 'this',
// someOtherData: 'and this'
// }
// }
//
// Data Sent to Hook Url
// {
// secure: true, // true or false
// truth: 'a45de562fc65428ac537f', // checksum (Optional)
// x-tag: 'gjsdgjadgjdabchyriadndbmnqoeequcmbsdbmdbshjchd', // Encryption Key (Optional)
// data: 'Encryted data if secure is true or data object if secure is false'
// }
var hookPromise;
if(data.secure){
hookData.secure = data.secure;
// Convert the Object to String
var stringData = JSON.stringify(data.data);

// Generate Checksum
var checksum = crypto.createHash('sha512')
.update(stringData)
.digest('hex');
hookData.truth = checksum;
// Encrypt Data
var key;
hookPromise = encryption.generateKey()
.then(function(resp){
key = resp;
hookData['x-tag'] = key;
return encryption.encrypt(stringData, key);
})
.then(function(resp){
hookData.data = resp;
return hookData;
});
// ToDo: Test Secure Webhooks
}else{
hookPromise = q.fcall(function(){
hookData.secure = false;
hookData.data = data.data;
return hookData;
});
// ToDo: Test Unsecure Webhooks
}

hookPromise
.then(function(resp){
var options = {
method: 'POST',
uri: data.url,
body: resp,
json: true // Automatically parses the JSON string in the response
};
return request(options);
})
.then(function(resp){
done(false, resp);
})
.catch(function(err){
done(new Error(err.message));
});
};

module.exports = jobs;
14 changes: 10 additions & 4 deletions services/queue/workers.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,24 @@
var queue = require('./');
var jobs = require('./jobs');

queue.process('searchIndex',2, function(job, done){
queue.process('searchIndex', 2, function(job, done){
jobs.createSearchTags(job.data, done);
});

queue.process('logRequest',2, function(job, done){
queue.process('logRequest', 2, function(job, done){
jobs.createRequestLog(job.data, done);
});

queue.process('logResponse',2, function(job, done){
queue.process('logResponse', 2, function(job, done){
jobs.updateRequestLog(job.data, done);
});

// ToDo: Add Webhook worker here
queue.process('saveToTrash', 2, function(job, done){
jobs.saveToTrash(job.data, done);
});

queue.process('sendWebhook', 2, function(job,done){
jobs.sendWebhook(job.data, done);
});

module.exports = queue;
2 changes: 1 addition & 1 deletion test/services/queue.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ describe('#Queue service', function(){
it('should load processes', function() {
var process = require('../../services/queue/workers');
// We have configured queue to create 2 workers per job making a total of 6 workers for 3 jobs that we currently have
process.workers.length.should.equal(6);
process.workers.length.should.equal(10);
});


Expand Down

0 comments on commit f514ab1

Please sign in to comment.