Skip to content

Commit d56e73c

Browse files
mariayordsjvans
andauthored
Fix: skip logging for keys marked as personal data (#119)
Fixes: https://github.tools.sap/cap/issues/issues/16783 --------- Co-authored-by: sjvans <30337871+sjvans@users.noreply.github.com> Co-authored-by: D050513 <sebastian.van.syckel@sap.com>
1 parent 9e2b920 commit d56e73c

File tree

5 files changed

+81
-57
lines changed

5 files changed

+81
-57
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file.
44
This project adheres to [Semantic Versioning](http://semver.org/).
55
The format is based on [Keep a Changelog](http://keepachangelog.com/).
66

7+
## Version 0.8.2 - tbd
8+
9+
### Fixed
10+
11+
- Erroneous modification log for non-updated key properties
12+
713
## Version 0.8.1 - 2024-09-13
814

915
### Fixed

lib/modification.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -88,19 +88,19 @@ const addDiffToCtx = async function (req) {
8888
}
8989
addDiffToCtx._initial = true
9090

91-
const _getOldAndNew = (action, row, key) => {
91+
const _getOldAndNew = (action, row, key, entity) => {
9292
let oldValue = action === 'Create' ? null : row._old && row._old[key]
93-
if (oldValue === undefined) oldValue = null
93+
if (oldValue === undefined) oldValue = action === 'Update' && key in entity.keys ? row[key] : null
9494
else if (Array.isArray(oldValue)) oldValue = JSON.stringify(oldValue)
9595
let newValue = action === 'Delete' ? null : row[key]
9696
if (newValue === undefined) newValue = null
9797
else if (Array.isArray(newValue)) newValue = JSON.stringify(newValue)
9898
return { oldValue, newValue }
9999
}
100100

101-
const _addAttribute = (log, action, row, key) => {
101+
const _addAttribute = (log, action, row, key, entity) => {
102102
if (!log.attributes.find(ele => ele.name === key)) {
103-
const { oldValue, newValue } = _getOldAndNew(action, row, key)
103+
const { oldValue, newValue } = _getOldAndNew(action, row, key, entity)
104104
if (oldValue !== newValue) {
105105
const attr = { name: key }
106106
if (action !== 'Create') attr.old = oldValue
@@ -139,7 +139,7 @@ const _processorFnModification = (modificationLogs, model, req, beforeWrite) =>
139139
} else if (category === 'DataSubjectID') {
140140
addDataSubject(modificationLog, row, key, entity)
141141
} else if (category === 'IsPotentiallyPersonal' || category === 'IsPotentiallySensitive') {
142-
_addAttribute(modificationLog, action, row, key)
142+
_addAttribute(modificationLog, action, row, key, entity)
143143
// do not log the value of a sensitive attribute
144144
if (element['@PersonalData.IsPotentiallySensitive']) _maskAttribute(modificationLog.attributes, key)
145145
}

test/personal-data/crud.test.js

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -678,6 +678,35 @@ describe('personal data audit logging in CRUD', () => {
678678
})
679679
})
680680

681+
test('update entity with key as personal data', async () => {
682+
const idMain = 'daac72b5-5b4a-4831-b559-d0e68baa3b22'
683+
const idSub = 'f6407ee1-3af5-423a-9b18-83a004306524'
684+
const DATA_SUBJECT_M = {
685+
type: 'CRUD_1.MainEntities',
686+
role: 'MainEntity',
687+
id: { ID: idMain }
688+
}
689+
const responseMain = await POST(
690+
'/crud-1/MainEntities',
691+
{ ID: idMain, subEntities: [{ ID: idSub, name: 'myName' }] },
692+
{ auth: ALICE }
693+
)
694+
expect(responseMain).toMatchObject({ status: 201 })
695+
696+
const response = await PATCH(`/crud-1/SubEntities(${idSub})`, { name: 'newName' }, { auth: ALICE })
697+
698+
expect(response).toMatchObject({ status: 200 })
699+
expect(_logs).toContainMatchObject({
700+
user: 'alice',
701+
object: {
702+
type: 'CRUD_1.SubEntities',
703+
id: { ID: idSub }
704+
},
705+
data_subject: DATA_SUBJECT_M,
706+
attributes: [{ name: 'name', old: 'myName', new: 'newName' }]
707+
})
708+
})
709+
681710
test('update Pages with integers', async () => {
682711
const page = {
683712
sensitive: 999,

test/personal-data/srv/crud-service.cds

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ service CRUD_1 {
1515
entity StatusChange as projection on db.StatusChange;
1616
entity LastOne as projection on db.LastOne;
1717
entity Notes as projection on db.Notes;
18+
entity MainEntities as projection on db.MainEntities;
19+
entity SubEntities as projection on db.SubEntities;
1820

1921
entity AddressAttachment as
2022
projection on db.AddressAttachment {
@@ -95,6 +97,12 @@ service CRUD_1 {
9597
notes @PersonalData.IsPotentiallySensitive @PersonalData.IsPotentiallyPersonal;
9698
skills @PersonalData.IsPotentiallyPersonal;
9799
}
100+
101+
annotate SubEntities with @PersonalData : {EntitySemantics: 'DataSubjectDetails'} {
102+
mainEntity @PersonalData.FieldSemantics: 'DataSubjectID';
103+
ID @PersonalData.IsPotentiallyPersonal;
104+
name @PersonalData.IsPotentiallyPersonal;
105+
}
98106
}
99107

100108
@path : '/crud-2'
@@ -132,7 +140,7 @@ service CRUD_2 {
132140
@requires: 'admin'
133141
service CRUD_3 {
134142

135-
entity R1 as
143+
entity R1 as
136144
projection on db.RBase {
137145
key ID as r1_ID,
138146
emailAddress as r1_emailAddress,
@@ -146,7 +154,7 @@ service CRUD_3 {
146154
DataSubjectRole: 'Renamed Customer'
147155
};
148156

149-
entity R2 as
157+
entity R2 as
150158
projection on R1 {
151159
key r1_ID as r2_ID,
152160
r1_emailAddress as r2_emailAddress,
@@ -160,23 +168,23 @@ service CRUD_3 {
160168
DataSubjectRole: 'Twice Renamed Customer'
161169
};
162170

163-
entity C as
171+
entity C as
164172
projection on CRUD_1.Customers {
165173
key ID as c_id,
166174
emailAddress as c_emailAddress,
167175
addresses as c_addresses
168176
};
169177

170178

171-
entity CPA as
179+
entity CPA as
172180
projection on CRUD_1.CustomerPostalAddress {
173181
key ID as cpa_id,
174182
town as cpa_town,
175183
customer as cpa_customer,
176184
attachments as cpa_attachments
177185
};
178186

179-
entity AA as
187+
entity AA as
180188
projection on CRUD_1.AddressAttachment {
181189
key ID as aa_id,
182190
todo as aa_todo,
@@ -188,9 +196,9 @@ service CRUD_3 {
188196
@requires: 'admin'
189197
service CRUD_4 {
190198

191-
entity RenamedMainEntities as projection on db.MainEntities;
199+
entity RenamedMainEntities as projection on db.MainEntities;
192200

193-
entity RenamedSubEntities as
201+
entity RenamedSubEntities as
194202
projection on db.SubEntities {
195203
key ID as renamedID,
196204
name,
@@ -203,8 +211,8 @@ service CRUD_4 {
203211
@requires: 'admin'
204212
service CRUD_5 {
205213

206-
entity A as projection on db.A;
207-
entity B as projection on db.B;
208-
entity C as projection on db.C;
214+
entity A as projection on db.A;
215+
entity B as projection on db.B;
216+
entity C as projection on db.C;
209217

210218
}

test/personal-data/srv/fiori-service.cds

Lines changed: 23 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -20,33 +20,27 @@ service Fiori_1 {
2020
entity LastOne as projection on db.LastOne;
2121
entity Notes as projection on db.Notes;
2222

23-
entity AddressAttachment as projection on db.AddressAttachment {
24-
*,
25-
address.customer as customer
26-
}
23+
entity AddressAttachment as
24+
projection on db.AddressAttachment {
25+
*,
26+
address.customer as customer
27+
}
2728

28-
annotate Orders with @PersonalData: {
29-
EntitySemantics: 'Other'
30-
} {
29+
annotate Orders with @PersonalData: {EntitySemantics: 'Other'} {
3130
misc @PersonalData.IsPotentiallySensitive;
3231
}
3332

34-
annotate OrderHeader with @PersonalData: {
35-
EntitySemantics: 'Other'
36-
} {
33+
annotate OrderHeader with @PersonalData: {EntitySemantics: 'Other'} {
3734
description @PersonalData.IsPotentiallySensitive;
3835
}
3936

40-
annotate OrderHeader.sensitiveData with @PersonalData: {
41-
EntitySemantics: 'Other'
42-
} {
37+
annotate OrderHeader.sensitiveData with @PersonalData: {EntitySemantics: 'Other'} {
4338
note @PersonalData.IsPotentiallySensitive;
4439
}
4540

46-
annotate Pages with @PersonalData : {
47-
EntitySemantics: 'DataSubject'
48-
// no DataSubjectRole for testing purposes
49-
} {
41+
annotate Pages with @PersonalData : {EntitySemantics: 'DataSubject'
42+
// no DataSubjectRole for testing purposes
43+
} {
5044
ID @PersonalData.FieldSemantics: 'DataSubjectID';
5145
sensitive @PersonalData.IsPotentiallySensitive;
5246
personal @PersonalData.IsPotentiallyPersonal;
@@ -63,45 +57,33 @@ service Fiori_1 {
6357
creditCardNo @PersonalData.IsPotentiallySensitive;
6458
}
6559

66-
annotate CustomerPostalAddress with @PersonalData: {
67-
EntitySemantics: 'DataSubjectDetails'
68-
} {
60+
annotate CustomerPostalAddress with @PersonalData: {EntitySemantics: 'DataSubjectDetails'} {
6961
customer @PersonalData.FieldSemantics : 'DataSubjectID';
7062
street @PersonalData.IsPotentiallySensitive;
7163
town @PersonalData.IsPotentiallyPersonal;
7264
}
7365

74-
annotate CustomerStatus with @PersonalData: {
75-
EntitySemantics: 'DataSubjectDetails'
76-
} {
66+
annotate CustomerStatus with @PersonalData: {EntitySemantics: 'DataSubjectDetails'} {
7767
description @PersonalData.IsPotentiallySensitive;
7868
todo @PersonalData.IsPotentiallyPersonal;
7969
}
8070

81-
annotate StatusChange with @PersonalData: {
82-
EntitySemantics: 'DataSubjectDetails'
83-
} {
71+
annotate StatusChange with @PersonalData: {EntitySemantics: 'DataSubjectDetails'} {
8472
description @PersonalData.IsPotentiallySensitive;
8573
secondKey @PersonalData.IsPotentiallyPersonal;
8674
}
8775

88-
annotate LastOne with @PersonalData: {
89-
EntitySemantics: 'DataSubjectDetails'
90-
} {
76+
annotate LastOne with @PersonalData: {EntitySemantics: 'DataSubjectDetails'} {
9177
lastOneField @PersonalData.IsPotentiallySensitive;
9278
}
9379

94-
annotate AddressAttachment with @PersonalData: {
95-
EntitySemantics: 'DataSubjectDetails'
96-
} {
80+
annotate AddressAttachment with @PersonalData: {EntitySemantics: 'DataSubjectDetails'} {
9781
customer @PersonalData.FieldSemantics : 'DataSubjectID';
9882
description @PersonalData.IsPotentiallySensitive;
9983
todo @PersonalData.IsPotentiallyPersonal;
10084
}
10185

102-
annotate Notes with @PersonalData: {
103-
EntitySemantics: 'Other'
104-
} {
86+
annotate Notes with @PersonalData: {EntitySemantics: 'Other'} {
10587
note @PersonalData.IsPotentiallySensitive;
10688
dummyArray @PersonalData.IsPotentiallyPersonal;
10789
}
@@ -115,14 +97,13 @@ service Fiori_2 {
11597

11698
entity CustomerPostalAddress as projection on db.CustomerPostalAddress;
11799

118-
entity AddressAttachment as projection on db.AddressAttachment {
119-
*,
120-
address.customer as customer
121-
}
100+
entity AddressAttachment as
101+
projection on db.AddressAttachment {
102+
*,
103+
address.customer as customer
104+
}
122105

123-
annotate Customers with @PersonalData : {
124-
EntitySemantics: 'Other'
125-
} {
106+
annotate Customers with @PersonalData : {EntitySemantics: 'Other'} {
126107
addresses @PersonalData.FieldSemantics: 'DataSubjectID';
127108
}
128109

0 commit comments

Comments
 (0)