From ecf5648e8b0e7431d76b8e3e1e30180214c00e66 Mon Sep 17 00:00:00 2001 From: Ace Nassri Date: Tue, 1 Aug 2017 16:54:13 -0700 Subject: [PATCH 1/2] Add DLP image redaction sample --- dlp/redact.js | 60 ++++++++++++++++++ dlp/system-test/redact.test.js | 38 ++++++++++- .../redact-multiple-types.correct.png | Bin 0 -> 5338 bytes .../resources/redact-single-type.correct.png | Bin 0 -> 7039 bytes 4 files changed, 95 insertions(+), 3 deletions(-) create mode 100644 dlp/system-test/resources/redact-multiple-types.correct.png create mode 100644 dlp/system-test/resources/redact-single-type.correct.png diff --git a/dlp/redact.js b/dlp/redact.js index ec1c03ddf2..73f2ee3f9a 100644 --- a/dlp/redact.js +++ b/dlp/redact.js @@ -64,6 +64,59 @@ function redactString (string, replaceString, minLikelihood, infoTypes) { // [END redact_string] } +function redactImage (filepath, minLikelihood, infoTypes, outputPath) { + // [START redact_image] + // Imports required Node.js libraries + const mime = require('mime'); + const fs = require('fs'); + + // Imports the Google Cloud Data Loss Prevention library + const DLP = require('@google-cloud/dlp'); + + // Instantiates a client + const dlp = DLP(); + + // The path to a local file to inspect. Can be a JPG or PNG image file. + // const fileName = 'path/to/image.png'; + + // The minimum likelihood required before redacting a match + // const minLikelihood = LIKELIHOOD_UNSPECIFIED; + + // The infoTypes of information to redact + // const infoTypes = ['EMAIL_ADDRESS', 'PHONE_NUMBER']; + + // The local path to save the resulting image to. + // const outputPath = 'result.png'; + + const fileItems = [{ + type: mime.lookup(filepath) || 'application/octet-stream', + data: Buffer.from(fs.readFileSync(filepath)).toString('base64') + }]; + + const imageRedactionConfigs = infoTypes.map((infoType) => { + return { infoType: infoType }; + }); + + const request = { + inspectConfig: { + minLikelihood: minLikelihood + }, + imageRedactionConfigs: imageRedactionConfigs, + items: fileItems + }; + + dlp.redactContent(request) + .then((response) => { + const image = response[0].items[0].data; + fs.writeFileSync(outputPath, image); + console.log(`Saved image redaction results to path: ${outputPath}`); + }) + .catch((err) => { + console.log(`Error in redactImage: ${err.message || err}`); + }); + // [END redact_image] +} + const cli = require(`yargs`) .demand(1) .command( @@ -72,6 +125,12 @@ const cli = require(`yargs`) {}, (opts) => redactString(opts.string, opts.replaceString, opts.minLikelihood, opts.infoTypes) ) + .command( + `image `, + `Redact sensitive data from an image using the Data Loss Prevention API.`, + {}, + (opts) => redactImage(opts.filepath, opts.minLikelihood, opts.infoTypes, opts.outputPath) + ) .option('m', { alias: 'minLikelihood', default: 'LIKELIHOOD_UNSPECIFIED', @@ -96,6 +155,7 @@ const cli = require(`yargs`) }) }) .example(`node $0 string "My name is Gary" "REDACTED" -t US_MALE_NAME`) + .example(`node $0 image resources/test.png redaction_result.png -t US_MALE_NAME`) .wrap(120) .recommendCommands() .epilogue(`For more information, see https://cloud.google.com/dlp/docs. Optional flags are explained at https://cloud.google.com/dlp/docs/reference/rest/v2beta1/content/inspect#InspectConfig`); diff --git a/dlp/system-test/redact.test.js b/dlp/system-test/redact.test.js index 1b053c6307..139bc7432e 100644 --- a/dlp/system-test/redact.test.js +++ b/dlp/system-test/redact.test.js @@ -17,20 +17,24 @@ const path = require('path'); const test = require('ava'); +const fs = require('fs'); const tools = require('@google-cloud/nodejs-repo-tools'); const cmd = 'node redact'; const cwd = path.join(__dirname, `..`); +const testImage = 'resources/test.png'; +const testResourcePath = 'system-test/resources'; + test.before(tools.checkCredentials); // redact_string -test(`should redact sensitive data from a string`, async (t) => { +test(`should redact multiple sensitive data types from a string`, async (t) => { const output = await tools.runAsync(`${cmd} string "I am Gary and my phone number is (123) 456-7890." REDACTED -t US_MALE_NAME PHONE_NUMBER`, cwd); t.is(output, 'I am REDACTED and my phone number is REDACTED.'); }); -test(`should ignore unspecified type names when redacting from a string`, async (t) => { +test(`should redact a single sensitive data type from a string`, async (t) => { const output = await tools.runAsync(`${cmd} string "I am Gary and my phone number is (123) 456-7890." REDACTED -t PHONE_NUMBER`, cwd); t.is(output, 'I am Gary and my phone number is REDACTED.'); }); @@ -40,6 +44,34 @@ test(`should report string redaction handling errors`, async (t) => { t.regex(output, /Error in redactString/); }); +// redact_image +test(`should redact a single sensitive data type from an image`, async (t) => { + const testName = `redact-multiple-types`; + const output = await tools.runAsync(`${cmd} image ${testImage} ${testName}.result.png -t PHONE_NUMBER EMAIL_ADDRESS`, cwd); + + t.true(output.includes(`Saved image redaction results to path: ${testName}.result.png`)); + + const correct = fs.readFileSync(`${testResourcePath}/${testName}.correct.png`); + const result = fs.readFileSync(`${testName}.result.png`); + t.deepEqual(correct, result); +}); + +test(`should redact multiple sensitive data types from an image`, async (t) => { + const testName = `redact-single-type`; + const output = await tools.runAsync(`${cmd} image ${testImage} ${testName}.result.png -t PHONE_NUMBER`, cwd); + + t.true(output.includes(`Saved image redaction results to path: ${testName}.result.png`)); + + const correct = fs.readFileSync(`${testResourcePath}/${testName}.correct.png`); + const result = fs.readFileSync(`${testName}.result.png`); + t.deepEqual(correct, result); +}); + +test(`should report image redaction handling errors`, async (t) => { + const output = await tools.runAsync(`${cmd} image ${testImage} nonexistent.result.png -t BAD_TYPE`, cwd); + t.regex(output, /Error in redactImage/); +}); + // CLI options test(`should have a minLikelihood option`, async (t) => { const promiseA = tools.runAsync(`${cmd} string "My phone number is (123) 456-7890." REDACTED -t PHONE_NUMBER -m VERY_LIKELY`, cwd); @@ -50,4 +82,4 @@ test(`should have a minLikelihood option`, async (t) => { const outputB = await promiseB; t.is(outputB, 'My phone number is REDACTED.'); -}); +}); \ No newline at end of file diff --git a/dlp/system-test/resources/redact-multiple-types.correct.png b/dlp/system-test/resources/redact-multiple-types.correct.png new file mode 100644 index 0000000000000000000000000000000000000000..952b768f3a057776b77a5cef4732c323c5e49548 GIT binary patch literal 5338 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 literal 0 HcmV?d00001 From e1c56b3b354597e024e772ba76a59fe3d3046881 Mon Sep 17 00:00:00 2001 From: Ace Nassri Date: Wed, 2 Aug 2017 12:33:17 -0700 Subject: [PATCH 2/2] Fix lint --- dlp/system-test/redact.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dlp/system-test/redact.test.js b/dlp/system-test/redact.test.js index 139bc7432e..13c60e2cb3 100644 --- a/dlp/system-test/redact.test.js +++ b/dlp/system-test/redact.test.js @@ -82,4 +82,4 @@ test(`should have a minLikelihood option`, async (t) => { const outputB = await promiseB; t.is(outputB, 'My phone number is REDACTED.'); -}); \ No newline at end of file +});