diff --git a/src/eventlog.js b/src/eventlog.js index 2adb3a23e..353401520 100644 --- a/src/eventlog.js +++ b/src/eventlog.js @@ -6,6 +6,7 @@ exports = module.exports = { add: add, get: get, getAllPaged: getAllPaged, + getByQueryPaged: getByQueryPaged, // keep in sync with webadmin index.js filter ACTION_ACTIVATE: 'cloudron.activate', @@ -97,3 +98,17 @@ function getAllPaged(page, perPage, callback) { callback(null, boxes); }); } + +function getByQueryPaged(action, search, page, perPage, callback) { + assert(typeof action === 'string' || action === null); + assert(typeof search === 'string' || search === null); + assert.strictEqual(typeof page, 'number'); + assert.strictEqual(typeof perPage, 'number'); + assert.strictEqual(typeof callback, 'function'); + + eventlogdb.getByQueryPaged(action, search, page, perPage, function (error, boxes) { + if (error) return callback(new EventLogError(EventLogError.INTERNAL_ERROR, error)); + + callback(null, boxes); + }); +} diff --git a/src/eventlogdb.js b/src/eventlogdb.js index 8fd3eab1f..8008b93e2 100644 --- a/src/eventlogdb.js +++ b/src/eventlogdb.js @@ -3,6 +3,7 @@ exports = module.exports = { get: get, getAllPaged: getAllPaged, + getByQueryPaged: getByQueryPaged, add: add, count: count, @@ -12,6 +13,7 @@ exports = module.exports = { var assert = require('assert'), database = require('./database.js'), DatabaseError = require('./databaseerror'), + mysql = require('mysql'), safe = require('safetydance'); var EVENTLOGS_FIELDS = [ 'id', 'action', 'source', 'data', 'creationTime' ].join(','); @@ -49,6 +51,39 @@ function getAllPaged(page, perPage, callback) { }); } +function getByQueryPaged(action, search, page, perPage, callback) { + assert(typeof action === 'string' || action === null); + assert(typeof search === 'string' || search === null); + assert.strictEqual(typeof page, 'number'); + assert.strictEqual(typeof perPage, 'number'); + assert.strictEqual(typeof callback, 'function'); + + var data = []; + var query = 'SELECT ' + EVENTLOGS_FIELDS + ' FROM eventlog'; + + if (action || search) query += ' WHERE'; + if (search) query += ' data LIKE ' + mysql.escape('%' + search + '%'); + if (action && search) query += ' AND '; + + if (action) { + query += ' action=?'; + data.push(action); + } + + query += ' ORDER BY creationTime DESC LIMIT ?,?'; + + data.push((page-1)*perPage); + data.push(perPage); + + database.query(query, data, function (error, results) { + if (error) return callback(new DatabaseError(DatabaseError.INTERNAL_ERROR, error)); + + results.forEach(postProcess); + + callback(null, results); + }); +} + function add(id, action, source, data, callback) { assert.strictEqual(typeof id, 'string'); assert.strictEqual(typeof action, 'string'); diff --git a/src/routes/eventlog.js b/src/routes/eventlog.js index a9ca3c5ba..a1e8d413f 100644 --- a/src/routes/eventlog.js +++ b/src/routes/eventlog.js @@ -15,9 +15,20 @@ function get(req, res, next) { var perPage = typeof req.query.per_page !== 'undefined'? parseInt(req.query.per_page) : 25; if (!perPage || perPage < 0) return next(new HttpError(400, 'per_page query param has to be a postive number')); - eventlog.getAllPaged(page, perPage, function (error, result) { - if (error) return next(new HttpError(500, error)); + if (req.query.action && typeof req.query.action !== 'string') return next(new HttpError(400, 'action must be a string')); + if (req.query.search && typeof req.query.search !== 'string') return next(new HttpError(400, 'search must be a string')); - next(new HttpSuccess(200, { eventlogs: result })); - }); + if (req.query.action || req.query.search) { + eventlog.getByQueryPaged(req.query.action || null, req.query.search || null, page, perPage, function (error, result) { + if (error) return next(new HttpError(500, error)); + + next(new HttpSuccess(200, { eventlogs: result })); + }); + } else { + eventlog.getAllPaged(page, perPage, function (error, result) { + if (error) return next(new HttpError(500, error)); + + next(new HttpSuccess(200, { eventlogs: result })); + }); + } } diff --git a/src/routes/test/eventlog-test.js b/src/routes/test/eventlog-test.js index 078132323..10f1402c4 100644 --- a/src/routes/test/eventlog-test.js +++ b/src/routes/test/eventlog-test.js @@ -115,5 +115,38 @@ describe('Eventlog API', function () { done(); }); }); + + it('succeeds with action', function (done) { + superagent.get(SERVER_URL + '/api/v1/eventlog') + .query({ access_token: token, page: 1, per_page: 10, action: 'cloudron.activate' }) + .end(function (error, result) { + expect(result.statusCode).to.equal(200); + expect(result.body.eventlogs.length).to.equal(1); + + done(); + }); + }); + + it('succeeds with search', function (done) { + superagent.get(SERVER_URL + '/api/v1/eventlog') + .query({ access_token: token, page: 1, per_page: 10, search: EMAIL }) + .end(function (error, result) { + expect(result.statusCode).to.equal(200); + expect(result.body.eventlogs.length).to.equal(1); + + done(); + }); + }); + + it('succeeds with search', function (done) { + superagent.get(SERVER_URL + '/api/v1/eventlog') + .query({ access_token: token, page: 1, per_page: 10, search: EMAIL, action: 'cloudron.activate' }) + .end(function (error, result) { + expect(result.statusCode).to.equal(200); + expect(result.body.eventlogs.length).to.equal(0); + + done(); + }); + }); }); });