From 1f674aab41721f14d3f789aebb2e83f6bee3d5b8 Mon Sep 17 00:00:00 2001 From: Negue Date: Fri, 8 May 2015 18:52:29 +0200 Subject: [PATCH 1/4] /user/anonymized - return user json without personal data --- test/api.mocha.coffee | 6 ++++ website/src/controllers/user.js | 58 +++++++++++++++++++++++++++++++++ website/src/routes/apiv2.coffee | 5 +++ 3 files changed, 69 insertions(+) diff --git a/test/api.mocha.coffee b/test/api.mocha.coffee index 2a853562cf..caf608b14c 100644 --- a/test/api.mocha.coffee +++ b/test/api.mocha.coffee @@ -259,6 +259,12 @@ describe "API", -> expect(body.err).to.be "Task not found." done() + describe "Anonymized User", -> + it "/api/v2/user/anonymized", (done) -> + request.get(baseURL + "/user/anonymized").set("Accept", "application/json").end (res) -> + expect(res.statusCode).to.be 200 + done() + ###* GROUPS ### diff --git a/website/src/controllers/user.js b/website/src/controllers/user.js index 949e4cfb7b..3956cfa540 100644 --- a/website/src/controllers/user.js +++ b/website/src/controllers/user.js @@ -215,6 +215,64 @@ api.getUser = function(req, res, next) { return res.json(200, user); }; +/** + * Get anonymized User + */ +api.getUserAnonymized = function(req, res, next) { + var user = res.locals.user.toJSON(); + user.stats.toNextLevel = shared.tnl(user.stats.lvl); + user.stats.maxHealth = 50; + user.stats.maxMP = res.locals.user._statsComputed.maxMP; + delete user.apiToken; + if (user.auth) { + delete user.auth; + } + + delete user.webhooks; + + _.forEach(user.inbox.messages, function(msg){ + msg.text = "inbox message text"; + }); + + _.forEach(user.tags, function(tag){ + tag.name = "tag"; + tag.challenge = "challenge"; + }); + + function cleanChecklist(task){ + var checklistIndex = 0; + + _.forEach(task.checklist, function(c){ + c.text = "item" + checklistIndex++; + }); + } + + _.forEach(user.habits, function(task){ + task.text = "task text"; + task.notes = "task notes"; + }); + + _.forEach(user.rewards, function(task){ + task.text = "task text"; + task.notes = "task notes"; + }); + + _.forEach(user.dailys, function(task){ + task.text = "task text"; + task.notes = "task notes"; + + cleanChecklist(task); + }); + + _.forEach(user.todos, function(task){ + task.text = "task text"; + task.notes = "task notes"; + + cleanChecklist(task); + }); + + return res.json(200, user); +}; /** * This tells us for which paths users can call `PUT /user` (or batch-update equiv, which use `User.set()` on our client). diff --git a/website/src/routes/apiv2.coffee b/website/src/routes/apiv2.coffee index f30b03cb53..b4ae4a5a1e 100644 --- a/website/src/routes/apiv2.coffee +++ b/website/src/routes/apiv2.coffee @@ -227,6 +227,11 @@ module.exports = (swagger, v2) -> description: "Get the full user object" action: user.getUser + "/user/anonymized": + spec: + description: "Get the user object without any personal data" + action: user.getUserAnonymized + "/user:PUT": spec: path: '/user' From f402e21a5c506664da3986bfb191907a4b4f321c Mon Sep 17 00:00:00 2001 From: Negue Date: Fri, 8 May 2015 19:58:54 +0200 Subject: [PATCH 2/4] delete more properties --- website/src/controllers/user.js | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/website/src/controllers/user.js b/website/src/controllers/user.js index 3956cfa540..1bcd32bd6d 100644 --- a/website/src/controllers/user.js +++ b/website/src/controllers/user.js @@ -223,12 +223,24 @@ api.getUserAnonymized = function(req, res, next) { user.stats.toNextLevel = shared.tnl(user.stats.lvl); user.stats.maxHealth = 50; user.stats.maxMP = res.locals.user._statsComputed.maxMP; + delete user.apiToken; + if (user.auth) { - delete user.auth; + delete user.auth.local; + delete user.auth.facebook; } + delete user.profile; + delete user.purchased.plan; + delete user.contributor; + delete user.invitations; + + delete user.items.special.nyeReceived; + delete user.items.special.valentineReceived; + delete user.webhooks; + delete user.achievements.challenges; _.forEach(user.inbox.messages, function(msg){ msg.text = "inbox message text"; From 2bc13ea69a7d16fc59dc7b6e2aab753aef573c00 Mon Sep 17 00:00:00 2001 From: Negue Date: Sun, 10 May 2015 21:26:55 +0200 Subject: [PATCH 3/4] delete newMessages --- website/src/controllers/user.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/website/src/controllers/user.js b/website/src/controllers/user.js index 1bcd32bd6d..eaab7279b4 100644 --- a/website/src/controllers/user.js +++ b/website/src/controllers/user.js @@ -231,6 +231,8 @@ api.getUserAnonymized = function(req, res, next) { delete user.auth.facebook; } + delete user.newMessages; + delete user.profile; delete user.purchased.plan; delete user.contributor; From 0afd56e8ad1c55eaf7a98b2b68c20cf95d98f3ce Mon Sep 17 00:00:00 2001 From: Blade Barringer Date: Sun, 24 May 2015 22:03:40 -0500 Subject: [PATCH 4/4] Refine anonymous user test --- test/api/anonymized.coffee | 55 ++++++++++++++++++++++++++++++++++---- 1 file changed, 50 insertions(+), 5 deletions(-) diff --git a/test/api/anonymized.coffee b/test/api/anonymized.coffee index ae7e5c132c..e0bbfa9a6b 100644 --- a/test/api/anonymized.coffee +++ b/test/api/anonymized.coffee @@ -2,13 +2,58 @@ app = require("../../website/src/server") -describe "Site Status", -> +describe "GET /api/v2/user/anonymized", -> + + anon = null before (done) -> - registerNewUser(done, true) - - describe "Anonymized User", -> - it "/api/v2/user/anonymized", (done) -> + # TODO: Seed user with messages, rewards, dailys, checklists, webhooks, etc + registerNewUser -> request.get(baseURL + "/user/anonymized").set("Accept", "application/json").end (res) -> expect(res.statusCode).to.be 200 + anon = res.body + expect(anon._id).to.equal user._id done() + , true + + it 'removes credentials and financial information', (done) -> + expect(anon.apiToken).to.not.exist + expect(anon.auth.local).to.not.exist + expect(anon.auth.facebook).to.not.exist + expect(anon.purchased.plan).to.not.exist + done() + + it 'removes profile information', (done) -> + expect(anon.profile).to.not.exist + expect(anon.contributor).to.not.exist + expect(anon.achievements.challenges).to.not.exist + done() + + it 'removes social information', (done) -> + expect(anon.newMessages).to.not.exist + expect(anon.invitations).to.not.exist + expect(anon.items.special.nyeReceived).to.not.exist + expect(anon.items.special.valentineReceived).to.not.exist + _(anon.inbox.messages).each (msg) -> + expect(msg).to.equal 'inbox message text' + done() + + it 'removes webhooks', (done) -> + expect(anon.webhooks).to.not.exist + done() + + it 'anonymizes task info', (done) -> + _(['habits', 'todos', 'dailys', 'rewards']).each (tasks) -> + _(anon[tasks]).each (task) -> + expect(task.text).to.equal 'task text' + expect(task.notes).to.equal 'task notes' + checklist_count = 0 + _(task.checklist).each (box) -> + box.text = 'item' + checklist_count++ + done() + + it 'anonymizes tags', (done) -> + _(anon.tags).each (tag) -> + expect(tag.name).to.equal 'tag' + expect(tag.challenge).to.equal 'challenge' + done()