From 3c6d49b88e335c0f78bc24f712c653dda67880a2 Mon Sep 17 00:00:00 2001 From: sjvans Date: Tue, 8 Feb 2022 13:41:30 +0100 Subject: [PATCH] in development, write audit logs to custom sink --- gdpr/.cdsrc.json | 6 ++++-- gdpr/db/data-privacy.cds | 2 +- gdpr/db/schema.cds | 1 + gdpr/package.json | 5 ++++- gdpr/readme.md | 1 + gdpr/srv/auth.js | 15 ++++++++------- gdpr/srv/server.js | 26 ++++++++++++++++++++++++++ 7 files changed, 45 insertions(+), 11 deletions(-) create mode 100644 gdpr/srv/server.js diff --git a/gdpr/.cdsrc.json b/gdpr/.cdsrc.json index 513273ea..bdc1b712 100644 --- a/gdpr/.cdsrc.json +++ b/gdpr/.cdsrc.json @@ -7,7 +7,8 @@ "options": { "model": [ "db", - "srv" + "srv", + "app" ] } }, @@ -17,7 +18,8 @@ "options": { "model": [ "db", - "srv" + "srv", + "app" ] } } diff --git a/gdpr/db/data-privacy.cds b/gdpr/db/data-privacy.cds index 03fd8e5f..d6cc056d 100644 --- a/gdpr/db/data-privacy.cds +++ b/gdpr/db/data-privacy.cds @@ -9,7 +9,7 @@ annotate gdpr.Customers with @PersonalData : { EntitySemantics : 'DataSubject' }{ ID @PersonalData.FieldSemantics : 'DataSubjectID'; - emailAddress @PersonalData.IsPotentiallyPersonal; + email @PersonalData.IsPotentiallyPersonal; firstName @PersonalData.IsPotentiallyPersonal; lastName @PersonalData.IsPotentiallyPersonal; creditCardNo @PersonalData.IsPotentiallySensitive; diff --git a/gdpr/db/schema.cds b/gdpr/db/schema.cds index 033f838a..6a4d80d8 100644 --- a/gdpr/db/schema.cds +++ b/gdpr/db/schema.cds @@ -25,5 +25,6 @@ entity CustomerPostalAddresses : cuid, managed { customer : Association to Customers; street : String(128); town : String(128); + @assert.integrity : false country : Country; }; diff --git a/gdpr/package.json b/gdpr/package.json index 3615611b..aa99e72e 100644 --- a/gdpr/package.json +++ b/gdpr/package.json @@ -36,7 +36,10 @@ }, "features": { "audit_personal_data": true, - "fiori_preview": true + "fiori_preview": true, + "[production]": { + "kibana_formatter": true + } }, "hana": { "deploy-format": "hdbtable" diff --git a/gdpr/readme.md b/gdpr/readme.md index 0a18125b..22c0eb8e 100644 --- a/gdpr/readme.md +++ b/gdpr/readme.md @@ -32,3 +32,4 @@ create roles for Audit Log Viewer Service and Personal Data Manager, and assign - clarify annotation `EntitySemantics`, which differs between audit logging (`Other`) and personal data manager (`LegalGround`) - annotations for order items Fiori preview app + `Products` has `@cds.persistence.skip:'always'` +- how to reuse intial data from `common`? diff --git a/gdpr/srv/auth.js b/gdpr/srv/auth.js index caa17447..7ca86d8a 100644 --- a/gdpr/srv/auth.js +++ b/gdpr/srv/auth.js @@ -1,9 +1,5 @@ /* * workaround to avoid approuter et al. setup - * - * DO NOT USE FOR PRODUCTION! - * - no token validation - * - no xsappname check */ const jwt = require('jsonwebtoken') @@ -12,7 +8,13 @@ const tenant = process.env.VCAP_SERVICES : 'anonymous' module.exports = (req, res, next) => { - // decode JWT coming from Personal Data Manager + /* + * decode JWT coming from Personal Data Manager + * + * DO NOT USE FOR PRODUCTION! + * - no token validation + * - no xsappname check + */ const bearer = req.headers.authorization && req.headers.authorization.split('Bearer ')[1] if (bearer) { const { client_id: id, zid: tenant, scope: roles } = jwt.decode(bearer) @@ -31,8 +33,7 @@ module.exports = (req, res, next) => { req.user = { id, tenant, - // is: role => role !== 'PersonalDataManagerUser' - is: role => true + is: role => role !== 'PersonalDataManagerUser' } return next() } diff --git a/gdpr/srv/server.js b/gdpr/srv/server.js new file mode 100644 index 00000000..99378311 --- /dev/null +++ b/gdpr/srv/server.js @@ -0,0 +1,26 @@ +const cds = require('@sap/cds') + +/* + * in development, write audit logs to custom sink (i.e., to console in this example) + */ +cds.on('served', async () => { + if (process.env.NODE_ENV === 'production') return + + const auditLogService = await cds.connect.to('audit-log') + // use prepend to get called before the generic implementation + auditLogService.prepend(function() { + const LOG = cds.log('my custom audit logging impl') + // triggered when reading sensitive personal data + this.on('dataAccessLog', function(req) { + const { accesses } = req.data + for (const access of accesses) LOG.info(access) + }) + // triggered when modifying personal data + this.on('dataModificationLog', function(req) { + const { modifications } = req.data + for (const modification of modifications) LOG.info(modification) + }) + }) +}) + +module.exports = cds.server