diff --git a/core/server/api/v2/index.js b/core/server/api/v2/index.js index f053ebf797..e3b0ebcc66 100644 --- a/core/server/api/v2/index.js +++ b/core/server/api/v2/index.js @@ -1 +1,5 @@ -module.exports = {}; +module.exports = { + get session() { + return require('./session'); + } +}; diff --git a/core/server/api/v2/session.js b/core/server/api/v2/session.js new file mode 100644 index 0000000000..e8e21ad8ff --- /dev/null +++ b/core/server/api/v2/session.js @@ -0,0 +1,45 @@ +const Promise = require('bluebird'); +const common = require('../../lib/common'); +const models = require('../../models'); +const auth = require('../../services/auth'); + +const session = { + read(options) { + /* + * TODO + * Don't query db for user, when new api http wrapper is in we can + * have direct access to req.user, we can also get access to some session + * inofrmation too and send it back + */ + return models.User.findOne({id: options.context.user}); + }, + add(object) { + if (!object || !object.username || !object.password) { + return Promise.reject(new common.errors.UnauthorizedError({ + message: common.i18n.t('errors.middleware.auth.accessDenied') + })); + } + + return models.User.check({ + email: object.username, + password: object.password + }).then((user) => { + return Promise.resolve((req, res, next) => { + req.user = user; + auth.session.createSession(req, res, next); + }); + }).catch((err) => { + throw new common.errors.UnauthorizedError({ + message: common.i18n.t('errors.middleware.auth.accessDenied'), + err + }); + }); + }, + delete() { + return Promise.resolve((req, res, next) => { + auth.session.destroySession(req, res, next); + }); + } +}; + +module.exports = session; diff --git a/core/test/unit/api/v2/session_spec.js b/core/test/unit/api/v2/session_spec.js new file mode 100644 index 0000000000..9840b8c08f --- /dev/null +++ b/core/test/unit/api/v2/session_spec.js @@ -0,0 +1,112 @@ +const should = require('should'); +const sinon = require('sinon'); + +const models = require('../../../../server/models'); +const {UnauthorizedError} = require('../../../../server/lib/common/errors'); + +const sessionController = require('../../../../server/api/v2/session'); +const sessionServiceMiddleware = require('../../../../server/services/auth/session/middleware'); + +describe('Session controller', function () { + let sandbox; + + before(function () { + models.init(); + sandbox = sinon.sandbox.create(); + }); + + afterEach(function () { + sandbox.restore(); + }); + + it('exports an add method', function () { + should.equal(typeof sessionController.add, 'function'); + }); + it('exports an delete method', function () { + should.equal(typeof sessionController.delete, 'function'); + }); + + describe('#add', function () { + it('throws an UnauthorizedError if the object is missing a username and password', function () { + return sessionController.add({}).then(() => { + should.fail('session.add did not throw'); + },(err) => { + should.equal(err instanceof UnauthorizedError, true); + }); + }); + + it('it checks the username and password and throws UnauthorizedError if it fails', function () { + const userCheckStub = sandbox.stub(models.User, 'check') + .rejects(new Error()); + + return sessionController.add({ + username: 'freddy@vodafone.com', + password: 'qu33nRul35' + }, {}).then(() => { + should.fail('session.add did not throw'); + },(err) => { + should.equal(err instanceof UnauthorizedError, true); + }); + }); + + it('it returns a function that sets req.user and calls createSession if the check works', function () { + const fakeReq = {}; + const fakeRes = {}; + const fakeNext = () => {}; + const fakeUser = models.User.forge({}); + sandbox.stub(models.User, 'check') + .resolves(fakeUser); + + const createSessionStub = sandbox.stub(sessionServiceMiddleware, 'createSession'); + + return sessionController.add({ + username: 'freddy@vodafone.com', + password: 'qu33nRul35' + }, {}).then((fn) => { + fn(fakeReq, fakeRes, fakeNext); + }).then(function () { + const createSessionStubCall = createSessionStub.getCall(0); + should.equal(fakeReq.user, fakeUser); + should.equal(createSessionStubCall.args[0], fakeReq); + should.equal(createSessionStubCall.args[1], fakeRes); + should.equal(createSessionStubCall.args[2], fakeNext); + }); + }); + }); + + describe('#delete', function () { + it('returns a function that calls destroySession', function () { + const fakeReq = {}; + const fakeRes = {}; + const fakeNext = () => {}; + const destroySessionStub = sandbox.stub(sessionServiceMiddleware, 'destroySession'); + + return sessionController.delete().then((fn) => { + fn(fakeReq, fakeRes, fakeNext); + }).then(function () { + const destroySessionStubCall = destroySessionStub.getCall(0); + should.equal(destroySessionStubCall.args[0], fakeReq); + should.equal(destroySessionStubCall.args[1], fakeRes); + should.equal(destroySessionStubCall.args[2], fakeNext); + }); + }); + }); + + describe('#get', function () { + it('returns the result of User.findOne', function () { + const findOneReturnVal = new Promise(() => {}); + const findOneStub = sandbox.stub(models.User, 'findOne') + .returns(findOneReturnVal); + + const result = sessionController.read({ + context: { + user: 108 + } + }); + should.equal(result, findOneReturnVal); + should.deepEqual(findOneStub.args[0][0], { + id: 108 + }); + }); + }); +});