Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

first set of adjustments for new audit-logging plugin #557

Draft
wants to merge 2 commits into
base: gdpr
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 20 additions & 15 deletions gdpr/db/AuditLogStore.cds
Original file line number Diff line number Diff line change
@@ -1,23 +1,28 @@
using { managed, cuid, sap.common.CodeList } from '@sap/cds/common';
using {
managed,
cuid,
sap.common.CodeList
} from '@sap/cds/common';

namespace sap.capire.auditLog;

entity AuditLogStore : cuid {

Action : String enum{DataAccess; DataModification};
Action : String enum {
DataAccess;
DataModification
};

User : String;
Timestamp : Timestamp;
Tenant : String;
Channel : String;
User : String;
Timestamp : Timestamp;
Tenant : String;
Channel : String;
DataSubjectType : String; // Bussiness Partner
DataSubjectRole : String; // Customer // Employee // ...
DataSubjectID : LargeString; // key value pair as JSON
ObjectType : String; // like SalesOrder
ObjectKey : LargeString; // key value pair as JSON

DataSubjectType : String; // Bussiness Partner
DataSubjectRole : String; // Customer // Employee // ...
DataSubjectID : LargeString; // key value pair as JSON
ObjectType : String; // like SalesOrder
ObjectKey : LargeString; // key value pair as JSON

Blob : LargeString; // Payload: DataModification or Data Access as BLOB

}
Blob : LargeString; // Payload: DataModification or Data Access as BLOB

}
72 changes: 22 additions & 50 deletions gdpr/db/data-privacy.cds
Original file line number Diff line number Diff line change
Expand Up @@ -2,65 +2,37 @@
using {sap.capire.bookshop} from './schema';

// annotations for Data Privacy
annotate bookshop.Customers with @PersonalData : {
DataSubjectRole : 'Customer',
EntitySemantics : 'DataSubject'
}
{
ID @PersonalData.FieldSemantics : 'DataSubjectID';
email @PersonalData.IsPotentiallyPersonal;
firstName @PersonalData.IsPotentiallyPersonal;
lastName @PersonalData.IsPotentiallyPersonal;
// creditCardNo @PersonalData.IsPotentiallySensitive;
dateOfBirth @PersonalData.IsPotentiallyPersonal;
annotate bookshop.Customers with @PersonalData: {
DataSubjectRole: 'Customer',
EntitySemantics: 'DataSubject'
} {
ID @PersonalData.FieldSemantics : 'DataSubjectID';
email @PersonalData.IsPotentiallyPersonal;
firstName @PersonalData.IsPotentiallyPersonal;
lastName @PersonalData.IsPotentiallyPersonal;
dateOfBirth @PersonalData.IsPotentiallyPersonal;
}

annotate bookshop.CustomerBillingData with @PersonalData : {
DataSubjectRole : 'Customer',
EntitySemantics : 'DataSubjectDetails'
}
{
annotate bookshop.BillingData with @PersonalData: {
DataSubjectRole: 'Customer',
EntitySemantics: 'DataSubjectDetails'
} {
customer @PersonalData.FieldSemantics : 'DataSubjectID';
creditCardNo @PersonalData.IsPotentiallySensitive;
}

annotate bookshop.CustomerPostalAddress with @PersonalData : {
DataSubjectRole : 'Customer',
EntitySemantics : 'DataSubjectDetails'
}
{
Customer @PersonalData.FieldSemantics : 'DataSubjectID';
annotate bookshop.Addresses with @PersonalData: {
DataSubjectRole: 'Customer',
EntitySemantics: 'DataSubjectDetails'
} {
customer @PersonalData.FieldSemantics : 'DataSubjectID';
street @PersonalData.IsPotentiallyPersonal;
town @PersonalData.IsPotentiallyPersonal;
country @PersonalData.IsPotentiallyPersonal;
}

annotate bookshop.Orders with @PersonalData.EntitySemantics : 'Other'
{
ID @PersonalData.FieldSemantics : 'ContractRelatedID';
Customer @PersonalData.FieldSemantics : 'DataSubjectID';
annotate bookshop.Orders with @PersonalData.EntitySemantics: 'Other' {
ID @PersonalData.FieldSemantics : 'ContractRelatedID';
customer @PersonalData.FieldSemantics : 'DataSubjectID';
personalComment @PersonalData.IsPotentiallyPersonal;
}

// annotations for Audit Log
annotate bookshop.Customers with @AuditLog.Operation : {
Read : true,
Insert : true,
Update : true,
Delete : true
};

// annotations for Audit Log
annotate bookshop.CustomerPostalAddress with @AuditLog.Operation : {
Read : true,
Insert : true,
Update : true,
Delete : true
};

// annotations for Audit Log
annotate bookshop.Orders with @AuditLog.Operation : {
Read : true,
Insert : true,
Update : true,
Delete : true
};
46 changes: 25 additions & 21 deletions gdpr/db/schema.cds
Original file line number Diff line number Diff line change
@@ -1,37 +1,41 @@
// Proxy for importing schema from bookshop sample
using { sap.capire.bookshop.Books } from '../../bookshop/db/schema';
using { sap.capire.orders.Orders } from '../../orders/db/schema';
using { sap.capire.orders.OrderItems } from '../../orders/db/schema';
using { Country, managed, cuid } from '@sap/cds/common';
using {sap.capire.bookshop.Books} from '../../bookshop/db/schema';
using {sap.capire.orders.Orders} from '../../orders/db/schema';
using {sap.capire.orders.OrderItems} from '../../orders/db/schema';
using {
Country,
managed,
cuid
} from '@sap/cds/common';

namespace sap.capire.bookshop;

extend Orders with {
Customer : Association to Customers;
extend Orders with {
customer : Association to Customers;
personalComment : String;
}
}

entity Customers : cuid, managed {
email : String;
firstName : String;
lastName : String;
// creditCardNo : String;
dateOfBirth : Date;
billingData : Composition of one CustomerBillingData on billingData.Customer = $self;
postalAddress : Composition of one CustomerPostalAddress on postalAddress.Customer = $self;
email : String;
firstName : String;
lastName : String;
dateOfBirth : Date;
billingData : Composition of BillingData
on billingData.customer = $self;
addresses : Composition of Addresses
on addresses.customer = $self;
}

entity CustomerPostalAddress : cuid, managed {
Customer : Association to one Customers;
entity Addresses : cuid, managed {
customer : Association to one Customers;
street : String(128);
town : String(128);
country : Country;
country : Country;
someOtherField : String(128);
};


entity CustomerBillingData : cuid, managed {
Customer : Association to one Customers;
creditCardNo : String;
entity BillingData : cuid, managed {
customer : Association to one Customers;
creditCardNo : String;
};

171 changes: 49 additions & 122 deletions gdpr/srv/customAuditLog.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
const cds = require('@sap/cds')

// FIXME: no longer works like this with new audit logging plugin
module.exports = class MyAuditLogService extends cds.AuditLogService {
async init() {

// console.log('My Audit Log');
// call AuditLogService's init
await super.init()
Expand All @@ -12,132 +12,59 @@ module.exports = class MyAuditLogService extends cds.AuditLogService {

// register custom handlers
this.on('dataAccessLog', async req => {

const logs = [];

const action = 'DataAccess';
const user = req.user.id;
const timestamp = req.timestamp;
const tenant = req.tenant;
const channel = req.channel;

req.data.accesses.forEach( dataAccess => {
logs.push({
Action: action,
User: user,
Timestamp: timestamp,
Tenant: tenant,
Channel: channel,
DataSubjectType: dataAccess.dataSubject.type,
DataSubjectRole: dataAccess.dataSubject.role,
DataSubjectID: JSON.stringify(dataAccess.dataSubject.id),
ObjectType: dataAccess.dataObject.type,
ObjectKey: JSON.stringify(dataAccess.dataObject.id),
Blob: JSON.stringify(dataAccess)
}) }
)


await INSERT.into(AuditLogStore).entries(logs)
}
)
const logs = []

const action = 'DataAccess'
const user = req.user.id
const timestamp = req.timestamp
const tenant = req.tenant
const channel = req.channel

req.data.accesses.forEach(dataAccess => {
logs.push({
Action: action,
User: user,
Timestamp: timestamp,
Tenant: tenant,
Channel: channel,
DataSubjectType: dataAccess.data_subject.type,
DataSubjectRole: dataAccess.data_subject.role,
DataSubjectID: JSON.stringify(dataAccess.data_subject.id),
ObjectType: dataAccess.object.type,
ObjectKey: JSON.stringify(dataAccess.object.id),
Blob: JSON.stringify(dataAccess)
})
})

await INSERT.into(AuditLogStore).entries(logs)
})

this.on('dataModificationLog', async req => {
const mods = []

const mods = [];

const action = 'DataModification';
const user = req.user.id;
const timestamp = req.timestamp;
const tenant = req.tenant;
const channel = req.channel;
const action = 'DataModification'
const user = req.user.id
const timestamp = req.timestamp
const tenant = req.tenant
const channel = req.channel

req.data.modifications.forEach( dataModification => {
req.data.modifications.forEach(dataModification => {
mods.push({
Action: action,
User: user,
Timestamp: timestamp,
Tenant: tenant,
Channel: channel,
DataSubjectType: dataModification.dataSubject.type,
DataSubjectRole: dataModification.dataSubject.role,
DataSubjectID: JSON.stringify(dataModification.dataSubject.id),
ObjectType: dataModification.dataObject.type,
ObjectKey: JSON.stringify(dataModification.dataObject.id),
Blob: JSON.stringify(dataModification)
}) }
)


Action: action,
User: user,
Timestamp: timestamp,
Tenant: tenant,
Channel: channel,
DataSubjectType: dataModification.data_subject.type,
DataSubjectRole: dataModification.data_subject.role,
DataSubjectID: JSON.stringify(dataModification.data_subject.id),
ObjectType: dataModification.object.type,
ObjectKey: JSON.stringify(dataModification.object.id),
Blob: JSON.stringify(dataModification)
})
})

await INSERT.into(AuditLogStore).entries(mods)
}
)
}







}

/*
service AuditLogService {

// SEC-254: Log read access to sensitive personal data
event dataAccessLog {
accesses : array of Access;
};

// SEC-265: Log changes to personal data
event dataModificationLog : {
c : array of DataModification;
};
}
*/


/*
define type KeyValuePair {
keyName : String;
value : String;
};

define type DataObject {
type : String;
id : array of KeyValuePair;
};

define type DataSubject {
type : String;
id : array of KeyValuePair;
role : String;
};

define type Attribute {
name : String;
};


define type Access {
dataObject : DataObject;
dataSubject : DataSubject;
attributes : array of Attribute;
attachments : array of Attachment;
};

define type ChangedAttribute {
name : String;
oldValue : String;
newValue : String;
};

define type DataModification {
dataObject : DataObject;
dataSubject : DataSubject;
action : String @assert.range enum { Create; Update; Delete; };
attributes : array of ChangedAttribute;
})
}
}
*/
Loading