Created
September 12, 2017 00:09
-
-
Save bc-jasond/95bbc98076717234ce183e12035472f3 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
We are implementing a `view` that must consume | |
some external service (which we've mocked below). The service returns | |
data that needs to be sanitized for client consumption -- in the | |
below example it includes sensitive information like SSN, email, etc.... The | |
exercises work through simple sanitizations, to slightly more complex | |
ones, before asking that the interviewee try to define a general approach | |
to solving the problem. | |
*/ | |
var _ = require('lodash'); | |
var externalService = function(projectName){ | |
// Mock; in real life we use some information | |
// about the project to, say, read from a | |
// particular URL. | |
return { | |
'project': 'Sanitization Project', | |
'users': [ | |
{ | |
'username': 'z', | |
'email': '[email protected]', | |
'ssn': '111223333', | |
'apiKeys': [ | |
{ | |
'codename': 'tugboat', | |
'code': 'la8dfh47', | |
}, | |
{ | |
'codename': 'titanic', | |
'code': 'dg810fj3', | |
}, | |
] | |
}, | |
{ | |
'username': 'bk', | |
'email': '[email protected]', | |
'ssn': '889900000', | |
'apiKeys': [], | |
} | |
], | |
}; | |
}; | |
function last4(obj, key) { | |
const ssnReplaceChars = '*****'; | |
const ssnLast4 = obj[key].substring(5); | |
obj[key] = `${ssnReplaceChars}${ssnLast4}`; | |
} | |
function strip(obj, key) { | |
delete obj[key]; | |
} | |
var sanitize = function(response){ | |
//const blacklisted = ['ssn', 'code']; | |
if (_.isObject(response)) { | |
for (let key in response.keys()) { | |
if (definition.hasOwnProperty(key)) { | |
definition[key](response, key); | |
} | |
sanitize(response[key]); | |
// value = transformations[transformation](value, key, response); | |
} | |
} | |
if (_.isArray(response)) { | |
_.map(response, sanitize); | |
} | |
return response; | |
}; | |
var view = function(projectName){ | |
response = externalService(projectName); | |
sanitize(response); | |
return response; | |
}; | |
var response = view('part 0'); | |
// Part 4: | |
// | |
// Seems like this is getting to be a common occurrence -- let's | |
// make it easier on ourselves. Any time you see key, do value. | |
var definition = { | |
ssn: 'last4', | |
email: 'strip', | |
code: 'strip' | |
}; | |
response = view('part 4'); | |
console.assert(response.users[0].ssn == '*****3333', 'last 4'); | |
console.assert(response.users[1].ssn == '*****0000', 'last 4'); | |
console.assert(!response.users[0].email, 'stripped email'); | |
console.assert(!response.users[1].email, 'stripped email'); | |
console.assert(!response.users[0].apiKeys[0].code, 'stripped first code'); | |
console.assert(!response.users[0].apiKeys[1].code, 'stripped second code'); | |
console.info('part 4 done!'); | |
// Part 4 solution | |
var transformations = { | |
'last-4': function(value){ | |
return value.replace(/^.{5}/, '*****') | |
}, | |
'domain-only': function(value){ | |
return '****@' + value.split('@')[1]; | |
}, | |
'strip': function(value, key, response){ | |
delete response[key]; | |
} | |
}; | |
var sanitize = function(response){ | |
if(_.isObject(response)){ | |
_.forEach(response, function(value, key){ | |
var transformation = definition[key]; | |
if(transformation){ | |
value = transformations[transformation](value, key, response); | |
} | |
if(!_.isUndefined(value)){ | |
response[key] = value; | |
sanitize(value); | |
} | |
}); | |
} | |
else if(_.isArray(response)){ | |
_.map(response, sanitize); | |
} | |
return; | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment