diff --git a/src/routes/index.js b/src/routes/index.js index f2f7bdc67..296cb8ba2 100644 --- a/src/routes/index.js +++ b/src/routes/index.js @@ -19,5 +19,6 @@ exports = module.exports = { settings: require('./settings.js'), support: require('./support.js'), tasks: require('./tasks.js'), + tokens: require('./tokens.js'), users: require('./users.js') }; diff --git a/src/routes/tokens.js b/src/routes/tokens.js new file mode 100644 index 000000000..1d3b22f3f --- /dev/null +++ b/src/routes/tokens.js @@ -0,0 +1,73 @@ +'use strict'; + +exports = module.exports = { + verifyOwnership: verifyOwnership, + getAll: getAll, + get: get, + add: add, + del: del +}; + +var assert = require('assert'), + BoxError = require('../boxerror.js'), + HttpError = require('connect-lastmile').HttpError, + HttpSuccess = require('connect-lastmile').HttpSuccess, + tokens = require('../tokens.js'); + +function verifyOwnership(req, res, next) { + assert.strictEqual(typeof req.user, 'object'); + assert.strictEqual(typeof req.params.id, 'string'); + + tokens.get(req.params.id, function (error, result) { + if (error) return next(BoxError.toHttpError(error)); + + if (result.identifier !== req.user.id) return next(new HttpError(403, 'User is not owner')); + + req.token = result; + + next(); + }); +} + +function getAll(req, res, next) { + assert.strictEqual(typeof req.user, 'object'); + + tokens.getAllByUserId(req.user.id, function (error, result) { + if (error) return next(BoxError.toHttpError(error)); + + next(new HttpSuccess(200, { tokens: result })); + }); +} + +function get(req, res, next) { + assert.strictEqual(typeof req.user, 'object'); + assert.strictEqual(typeof req.token, 'object'); + + next(new HttpSuccess(200, req.token)); +} + +function add(req, res, next) { + assert.strictEqual(typeof req.user, 'object'); + assert.strictEqual(typeof req.body, 'object'); + + if (typeof req.body.name !== 'string') return next(new HttpError(400, 'name must be string')); + + const expiration = 100 * 365 * 24 * 60 * 60 * 1000; // forever - 100 years TODO maybe we should allow 0 or -1 to make that explicit + + tokens.add(tokens.ID_SDK, req.user.id, expiration, { name: req.body.name }, function (error, result) { + if (error) return next(BoxError.toHttpError(error)); + + next(new HttpSuccess(201, result)); + }); +} + +function del(req, res, next) { + assert.strictEqual(typeof req.user, 'object'); + assert.strictEqual(typeof req.token, 'object'); + + tokens.del(req.token.id, function (error) { + if (error) return next(BoxError.toHttpError(error)); + + next(new HttpSuccess(204, {})); + }); +} diff --git a/src/server.js b/src/server.js index b30f21571..b5324320d 100644 --- a/src/server.js +++ b/src/server.js @@ -157,6 +157,12 @@ function initializeExpressSync() { router.get ('/api/v1/app_passwords/:id', token, authorizeUser, routes.appPasswords.get); router.del ('/api/v1/app_passwords/:id', token, authorizeUser, routes.appPasswords.del); + // access tokens + router.get ('/api/v1/tokens', token, authorizeUser, routes.tokens.getAll); + router.post('/api/v1/tokens', token, authorizeUser, routes.tokens.add); + router.get ('/api/v1/tokens/:id', token, authorizeUser, routes.tokens.verifyOwnership, routes.tokens.get); + router.del ('/api/v1/tokens/:id', token, authorizeUser, routes.tokens.verifyOwnership, routes.tokens.del); + // user routes router.get ('/api/v1/users', token, authorizeUser, routes.users.list); router.post('/api/v1/users', token, authorizeAdmin, routes.users.create); diff --git a/src/tokens.js b/src/tokens.js index a51b05e2c..15071792b 100644 --- a/src/tokens.js +++ b/src/tokens.js @@ -2,6 +2,9 @@ exports = module.exports = { add: add, + get: get, + del: del, + getAllByUserId: getAllByUserId, // token client ids. we categorize them so we can have different restrictions based on the client ID_WEBADMIN: 'cid-webadmin', // dashboard oauth @@ -56,3 +59,36 @@ function add(clientId, userId, expiresAt, options, callback) { }); }); } + +function get(id, callback) { + assert.strictEqual(typeof id, 'string'); + assert.strictEqual(typeof callback, 'function'); + + tokendb.get(id, function (error, result) { + if (error) return callback(error); + + callback(null, result); + }); +} + +function del(id, callback) { + assert.strictEqual(typeof id, 'string'); + assert.strictEqual(typeof callback, 'function'); + + tokendb.del(id, function (error, result) { + if (error) return callback(error); + + callback(null, result); + }); +} + +function getAllByUserId(userId, callback) { + assert.strictEqual(typeof userId, 'string'); + assert.strictEqual(typeof callback, 'function'); + + tokendb.getByIdentifier(userId, function (error, result) { + if (error) return callback(error); + + callback(null, result); + }); +}