Skip to content

Commit

Permalink
Merge branch 'master' into ssologin
Browse files Browse the repository at this point in the history
  • Loading branch information
harshkothari410 committed Mar 28, 2017
2 parents 9d4569e + 27a0b79 commit 9d0a139
Show file tree
Hide file tree
Showing 22 changed files with 218 additions and 142 deletions.
3 changes: 3 additions & 0 deletions api/v1/controllers/authenticate.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ module.exports = {
return u.handleError(next, _err, resourceName);
}

// create token
const token = jwtUtil.createToken(req.user.name, req.user.name);
req.session.token = token;
const retObj = {
success: true,
message: 'authentication succeeded',
Expand Down
1 change: 1 addition & 0 deletions api/v1/controllers/register.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ module.exports = {

const userObj = u.responsify(user, helper, req.method);
userObj.token = tokenToReturn;
req.session.token = tokenToReturn;
u.logAPI(req, resultObj, userObj);
return res.status(httpStatus.CREATED).json(userObj);
});
Expand Down
22 changes: 17 additions & 5 deletions api/v1/helpers/verbs/doDelete.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ const redisModelSample = require('../../../../cache/models/samples');
function doDelete(req, res, next, props) {
const resultObj = { reqStartTime: new Date() }; // for logging
let delPromise;
let obj;
if (featureToggles.isFeatureEnabled(constants.featureName) &&
props.modelName === 'Sample') {
const sampleName = req.swagger.params.key.value.toLowerCase();
Expand All @@ -42,11 +43,22 @@ function doDelete(req, res, next, props) {
)
.then((o) => u.isWritable(req, o,
featureToggles.isFeatureEnabled('enforceWritePermission')))
.then((o) => o.destroy());
.then((o) => {
/*
* An empty array is returned when destroy is called on an instance
* of a model that has hard delete turned on. We still want to return
* the deleted instance in all the cases. So, before the instance
* is destroyed it is saved and for models with hard deleted turned on
* this saved instance is returned
*/
obj = o;
return o.destroy();
});
}

delPromise
.then((o) => {
const retVal = o === undefined || o.length === 0 ? obj : o;
resultObj.dbTime = new Date() - resultObj.reqStartTime;
const assocNames = [];

Expand All @@ -62,14 +74,14 @@ function doDelete(req, res, next, props) {

// publish the delete event to the redis channel
if (props.publishEvents) {
publisher.publishSample(o, props.associatedModels.subject,
publisher.publishSample(retVal, props.associatedModels.subject,
event.sample.del);
}

// when a resource is deleted, delete all its associations too
u.deleteAllAssociations(o, assocNames);
u.logAPI(req, resultObj, o);
return res.status(httpStatus.OK).json(u.responsify(o, props, req.method));
u.deleteAllAssociations(retVal, assocNames);
u.logAPI(req, resultObj, retVal);
return res.status(httpStatus.OK).json(u.responsify(retVal, props, req.method));
})
.catch((err) => u.handleError(next, err, props.modelName));
}
Expand Down
43 changes: 11 additions & 32 deletions db/model/sample.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,9 @@ const u = require('../helpers/sampleUtils');
const common = require('../helpers/common');
const ResourceNotFoundError = require('../dbErrors').ResourceNotFoundError;
const UpdateDeleteForbidden = require('../dbErrors').UpdateDeleteForbidden;
const eventName = {
add: 'refocus.internal.realtime.sample.add',
upd: 'refocus.internal.realtime.sample.update',
del: 'refocus.internal.realtime.sample.remove',
};
const messageCodeLen = 5;
const assoc = {};
const EMPTY_STRING = '';
const NO = 0;
const maxSampleNameLength = constants.fieldlen.longish +
constants.fieldlen.normalName + 1; // eslint-disable-line no-magic-numbers

Expand All @@ -36,11 +30,6 @@ module.exports = function sample(seq, dataTypes) {
primaryKey: true,
defaultValue: dataTypes.UUIDV4,
},
isDeleted: {
type: dataTypes.BIGINT,
defaultValue: 0,
allowNull: false,
},
messageBody: {
type: dataTypes.STRING(constants.fieldlen.longish),
},
Expand Down Expand Up @@ -107,7 +96,6 @@ module.exports = function sample(seq, dataTypes) {
name: 'subjectId',
allowNull: false,
},
onDelete: 'CASCADE',
hooks: true,
});
Sample.addScope('defaultScope', {
Expand Down Expand Up @@ -206,18 +194,18 @@ module.exports = function sample(seq, dataTypes) {
where: {
subjectId: subjasp.subject.id,
aspectId: subjasp.aspect.id,
isDeleted: NO,
},
});
})
.then((o) => {
if (o === null) {
return Sample.create(toUpsert);
}

// set value changed to true, during updates to avoid timeouts
// Adding this to the before update hook does
// give the needed effect; so adding it here!!!.
/*
* set value changed to true during updates to avoid timeouts.
* Adding this to the before update hook does
* give the needed effect; so adding it here!!!.
*/
o.changed('value', true);
return o.update(toUpsert);
})
Expand Down Expand Up @@ -321,17 +309,6 @@ module.exports = function sample(seq, dataTypes) {
);
}, // hooks.beforeCreate

/**
* Update isDeleted.
*
* @param {Sample} inst - The Sample instance being deleted
* @returns {Promise} which resolves undefined or rejects if an error
* was encountered trying to update the instance's isDeleted field
*/
beforeDestroy(inst /* , opts */) {
return common.setIsDeleted(seq.Promise, inst);
}, // hooks.beforeDestroy

/**
* Update status if value changed, loading the aspect (asynchronously)
* if the instance doesn't already include its associated aspect.
Expand Down Expand Up @@ -370,11 +347,14 @@ module.exports = function sample(seq, dataTypes) {

}, // hooks
indexes: [
{ unique: true, fields: ['aspectId', 'subjectId', 'isDeleted'] },
{
name: 'SampleStatusDeletedAt',
name: 'AspectIdSubjectId',
unique: true,
fields: ['aspectId', 'subjectId'],
},
{
name: 'SampleStatus',
fields: [
'deletedAt',
'status',
],
},
Expand Down Expand Up @@ -416,7 +396,6 @@ module.exports = function sample(seq, dataTypes) {
}
}, // setStatusChangedAt
}, // instanceMethods
paranoid: true,
});
return Sample;

Expand Down
36 changes: 36 additions & 0 deletions migrations/20170323033552-hardDeleteSamples.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/**
* Copyright (c) 2017, salesforce.com, inc.
* All rights reserved.
* Licensed under the BSD 3-Clause license.
* For full license text, see LICENSE.txt file in the repo root or
* https://opensource.org/licenses/BSD-3-Clause
*/
'use strict';

module.exports = {
up(qi /* , Sequelize */) {
/*
Add altering commands here.
Return a promise to correctly handle asynchronicity.
Example:
return qi.createTable('users', { id: Sequelize.INTEGER });
*/
return qi.sequelize.transaction(() =>
qi.sequelize.query('Delete from "Samples" where "deletedAt" is ' +
' not null', {
type: qi.sequelize.QueryTypes.DELETE,
}));
},

down(qi /* , Sequelize */) { // NO-op
/*
Add reverting commands here.
Return a promise to correctly handle asynchronicity.
Example:
return qi.dropTable('users');
*/

},
};
52 changes: 52 additions & 0 deletions migrations/20170323202239-sampleSchemaForHardDelete.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/**
* Copyright (c) 2017, salesforce.com, inc.
* All rights reserved.
* Licensed under the BSD 3-Clause license.
* For full license text, see LICENSE.txt file in the repo root or
* https://opensource.org/licenses/BSD-3-Clause
*/
'use strict';
const TBL = 'Samples';
module.exports = {
up(qi, Sequelize) {
/*
Add altering commands here.
Return a promise to correctly handle asynchronicity.
Example:
return qi.createTable('users', { id: Sequelize.INTEGER });
*/
return qi.sequelize.transaction(() => qi.removeColumn(TBL, 'isDeleted'))
.then(() => qi.removeColumn(TBL, 'deletedAt'))
.then(() => qi.removeIndex(TBL, 'samples_aspect_id_subject_id_is_deleted'))
.then(() => qi.removeIndex(TBL, 'SampleStatusDeletedAt'))
.then(() => qi.addIndex(TBL, ['status'],
{ indexName: 'SampleStatus' }))
.then(() => qi.addIndex(TBL, ['aspectId', 'subjectId'],
{ indexName: 'AspectIdSubjectId' }));
},

down(qi, Sequelize) {
// /*
// Add reverting commands here.
// Return a promise to correctly handle asynchronicity.

// Example:
// return qi.dropTable('users');
// */
return qi.sequelize.transaction(() => qi.addColumn(TBL, 'isDeleted', {
type: Sequelize.DATE,
allowNull: true,
}))
.then(() => qi.addColumn(TBL, 'deletedAt', {
type: Sequelize.DATE,
allowNull: true,
}))
.then(() => qi.addIndex(TBL, ['aspectId', 'subjectId', 'isDeleted'],
{ unique: true, indexName: 'samples_aspect_id_subject_id_is_deleted' }))
.then(() => qi.addIndex(TBL, ['status', 'deletedAt'],
{ indexName: 'SampleStatusDeletedAt' }))
.then(() => qi.removeIndex(TBL, 'SampleStatus'))
.then(() => qi.removeIndex(TBL, 'AspectIdSubjectId'));
},
};
4 changes: 2 additions & 2 deletions tests/api/v1/aspects/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,10 @@ module.exports = {
subjectToCreate,

forceDelete(done) {
tu.forceDelete(tu.db.Aspect, testStartTime)
tu.forceDelete(tu.db.Sample, testStartTime)
.then(() => tu.forceDelete(tu.db.Tag, testStartTime))
.then(() => tu.forceDelete(tu.db.Subject, testStartTime))
.then(() => tu.forceDelete(tu.db.Sample, testStartTime))
.then(() => tu.forceDelete(tu.db.Aspect, testStartTime))
.then(() => done())
.catch(done);
},
Expand Down
38 changes: 0 additions & 38 deletions tests/api/v1/authenticate/authenticateUser.js
Original file line number Diff line number Diff line change
Expand Up @@ -160,41 +160,3 @@ describe('api: authenticate sso user', () => {
});
});
});

describe('loadView: /authenticate route', () => {
let tokenVal;

before((done) => {
api.post(registerPath)
.send(u.fakeUserCredentials)
.end((err, res) => {
if (err) {
done(err);
}

tokenVal = res.body.token;
done();
});
});

after(u.forceDelete);

it('/authenticate returns token', (done) => {
api
.post('/authenticate')
.type('form')
.send({
username: u.fakeUserCredentials.username,
password: u.fakeUserCredentials.password,
})
.end((error, res) => {
if (error) {
done(error);
} else {
expect(res.body).to.have.property('token')
.and.not.equal(undefined);
done();
}
});
});
});
6 changes: 4 additions & 2 deletions tests/api/v1/subjects/getHierarchyAspectAndTagsFilters.js
Original file line number Diff line number Diff line change
Expand Up @@ -379,8 +379,10 @@ describe(`api: GET ${path}:`, () => {

expect(res.body).to.not.equal(null);
expect(res.body.samples).to.have.length(2);
expect(res.body.samples[1]).to.have.deep
.property('aspect.name', 'temperature');
const aspectNames = [];
aspectNames.push(res.body.samples[0].aspect.name);
aspectNames.push(res.body.samples[1].aspect.name);
expect(aspectNames).to.include.members(['humidity','temperature']);
expect(res.body.children).to.have.length(1);
expect(res.body.children[0].samples).to.have.length(1);
expect(res.body.children[0].children).to.have.length(0);
Expand Down
3 changes: 2 additions & 1 deletion tests/db/model/aspect/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@ module.exports = {
},

forceDelete(done) {
tu.forceDelete(tu.db.Aspect, testStartTime)
tu.forceDelete(tu.db.Sample, testStartTime)
.then(() => tu.forceDelete(tu.db.Aspect, testStartTime))
.then(() => tu.forceDelete(tu.db.Tag, testStartTime))
.then(() => tu.forceDelete(tu.db.Subject, testStartTime))
.then(() => tu.forceDelete(tu.db.User, testStartTime))
Expand Down

0 comments on commit 9d0a139

Please sign in to comment.