Compare commits

...

6 Commits

Author SHA1 Message Date
Johannes Vogel
08a3157f1d use new kinds for audit log 2022-03-18 09:30:42 +01:00
sjvans
c9ecef4e21 Merge branch 'main' into audit-logging 2022-02-08 13:48:35 +01:00
sjvans
46f1be4395 cleanup 2022-02-08 13:47:32 +01:00
sjvans
b932637400 Update manifest.json 2022-02-08 13:45:36 +01:00
sjvans
3c6d49b88e in development, write audit logs to custom sink 2022-02-08 13:41:30 +01:00
sjvans
6928ae907a initial 2022-02-03 17:57:35 +01:00
25 changed files with 871 additions and 1 deletions

28
gdpr/.cdsrc.json Normal file
View File

@@ -0,0 +1,28 @@
{
"build": {
"target": "gen",
"tasks": [{
"for": "hana",
"src": "db",
"options": {
"model": [
"db",
"srv",
"app"
]
}
},
{
"for": "node-cf",
"src": "srv",
"options": {
"model": [
"db",
"srv",
"app"
]
}
}
]
}
}

1
gdpr/.env Normal file
View File

@@ -0,0 +1 @@
PORT = 4007

4
gdpr/.etc/deploy.sh Normal file
View File

@@ -0,0 +1,4 @@
npm run build
cf create-service-push
cf bind-service gdpr-srv gdpr-pdm -c .pdm/pdm-binding-config.json
cf restage gdpr-srv

7
gdpr/.etc/undeploy.sh Normal file
View File

@@ -0,0 +1,7 @@
cf delete gdpr-srv -f
cf delete gdpr-db-deployer -f
cf delete-service gdpr-pdm -f
cf delete-service gdpr-auditlog -f
cf delete-service gdpr-uaa -f
cf delete-service gdpr-hdi -f
cf delete-service gdpr-logs -f

View File

@@ -0,0 +1,16 @@
{
"fullyQualifiedApplicationName": "capire-gdpr",
"fullyQualifiedModuleName": "gdpr-srv",
"applicationTitle": "Capire GDPR Sample App",
"applicationTitleKey": "Capire GDPR Sample App",
"applicationURL": "https://capire-gdpr-srv.cfapps.eu10.hana.ondemand.com",
"endPoints": [{
"type": "odatav4",
"serviceName": "PDMService",
"serviceURI": "/pdm",
"serviceTitle": "Capire GDPR Sample App PDM Service",
"serviceTitleKey": "Capire GDPR Sample App PDM Service",
"hasGdprV4Annotations": true,
"cacheControl": "no-cache"
}]
}

View File

@@ -0,0 +1,8 @@
{
"xs-security": {
"xsappname": "capire-gdpr",
"authorities": ["$ACCEPT_GRANTED_AUTHORITIES"]
},
"fullyQualifiedApplicationName": "capire-gdpr",
"appConsentServiceEnabled": true
}

317
gdpr/app/fiori.cds Normal file
View File

@@ -0,0 +1,317 @@
////////////////////////////////////////////////////////////////////////////
//
// Note: this is designed for the GDPRService being co-located with
// orders. It does not work if GDPRService is run as a separate
// process, and is not intended to do so.
//
////////////////////////////////////////////////////////////////////////////
using {GDPRService} from '../srv/gdpr-service';
annotate cds.UUID with @Core.Computed;
/*
* Orders
*/
@odata.draft.enabled
annotate GDPRService.Orders with @(UI : {
SelectionFields : [
createdAt,
createdBy
],
LineItem : [
{
Value : OrderNo,
Label : 'Order number'
},
{
Value : customer.firstName,
Label : 'First Name'
},
{
Value : customer.lastName,
Label : 'Last Name'
}
],
HeaderInfo : {
TypeName : 'Order',
TypeNamePlural : 'Orders',
Title : {
Value : OrderNo,
Label : 'Order number'
}
},
Identification : [
{
Value : createdBy,
Label : 'Created by'
},
{
Value : createdAt,
Label : 'Created at'
}
],
HeaderFacets : [
{
$Type : 'UI.ReferenceFacet',
Label : '{i18n>Created}',
Target : '@UI.FieldGroup#Created'
},
{
$Type : 'UI.ReferenceFacet',
Label : '{i18n>Modified}',
Target : '@UI.FieldGroup#Modified'
},
],
Facets : [
{
$Type : 'UI.ReferenceFacet',
Label : '{i18n>Details}',
Target : '@UI.FieldGroup#Details'
},
{
$Type : 'UI.ReferenceFacet',
Label : '{i18n>OrderItems}',
Target : 'Items/@UI.LineItem'
},
],
FieldGroup #Details : {Data : [
{
Value : customer_ID,
Label : 'Customer'
},
{
Value : customer.firstName,
Label : 'First Name'
},
{
Value : customer.lastName,
Label : 'Last Name'
},
{
Value : currency_code,
Label : 'Currency'
}
]},
FieldGroup #Created : {Data : [
{
Value : createdBy,
Label : 'Created by'
},
{
Value : createdAt,
Label : 'Created at'
}
]},
FieldGroup #Modified : {Data : [
{
Value : modifiedBy,
Label : 'Modified by'
},
{
Value : modifiedAt,
Label : 'Modified at'
}
]},
}, ) {
createdAt @UI.HiddenFilter : false;
createdBy @UI.HiddenFilter : false;
customer @ValueList.entity : 'Customers';
};
/*
* TODO: Order Items are not really maintainable in Fiori preview app
*/
annotate GDPRService.Orders.Items with @(UI : {
LineItem : [
{
Value : product_ID,
Label : 'Product ID'
},
{
Value : title,
Label : 'Product Name'
},
{
Value : price,
Label : 'Price'
},
{
Value : quantity,
Label : 'Quantity'
},
],
Identification : [
{
Value : product_ID,
Label : 'Product ID'
},
{
Value : title,
Label : 'Product Name'
},
{
Value : quantity,
Label : 'Quantity'
},
{
Value : price,
Label : 'Price'
},
],
Facets : [{
$Type : 'UI.ReferenceFacet',
Label : 'Order Items',
Target : '@UI.Identification'
}, ],
}, ) {
ID @Core.Computed @UI.Hidden : true;
title @Core.Computed;
price @Core.Computed;
quantity @(Common.FieldControl : #Mandatory);
};
/*
* Customers
*/
@odata.draft.enabled
annotate GDPRService.Customers with @(UI : {
SelectionFields : [
firstName,
lastName
],
LineItem : [
{
Value : firstName,
Label : 'First Name'
},
{
Value : lastName,
Label : 'Last Name'
},
{
Value : dateOfBirth,
Label : 'Date of Birth'
}
],
HeaderInfo : {
TypeName : 'Customer',
TypeNamePlural : 'Customers',
Title : {
Value : lastName,
Label : 'Last Name'
},
Description : {
Value : firstName,
Label : 'First Name'
}
},
Identification : [
{
Value : createdBy,
Label : 'Created by'
},
{
Value : createdAt,
Label : 'Created at'
}
],
HeaderFacets : [
{
$Type : 'UI.ReferenceFacet',
Label : '{i18n>Created}',
Target : '@UI.FieldGroup#Created'
},
{
$Type : 'UI.ReferenceFacet',
Label : '{i18n>Modified}',
Target : '@UI.FieldGroup#Modified'
},
],
Facets : [
{
$Type : 'UI.ReferenceFacet',
Label : '{i18n>Details}',
Target : '@UI.FieldGroup#Details'
},
{
$Type : 'UI.ReferenceFacet',
Label : '{i18n>Addresses}',
Target : 'addresses/@UI.LineItem'
},
],
FieldGroup #Details : {Data : [
{
Value : dateOfBirth,
Label : 'Date of Birth'
},
{
Value : email,
Label : 'E-Mail'
},
{
Value : creditCardNo,
Label : 'Credit Card Number'
}
]},
FieldGroup #Created : {Data : [
{
Value : createdBy,
Label : 'Created by'
},
{
Value : createdAt,
Label : 'Created at'
}
]},
FieldGroup #Modified : {Data : [
{
Value : modifiedBy,
Label : 'Modified by'
},
{
Value : modifiedAt,
Label : 'Modified at'
}
]},
}, ) {
createdAt @UI.HiddenFilter : false;
createdBy @UI.HiddenFilter : false;
};
annotate GDPRService.CustomerPostalAddresses with @(UI : {
LineItem : [
{
Value : town,
Label : 'Town'
},
{
Value : street,
Label : 'Street'
},
{
Value : country.name,
Label : 'Country'
}
],
Identification : [
{
Value : town,
Label : 'Town'
},
{
Value : street,
Label : 'Street'
},
{
Value : country_code,
Label : 'Country Code'
}
],
Facets : [{
$Type : 'UI.ReferenceFacet',
Label : 'Customer Postal Address',
Target : '@UI.Identification'
}, ],
}, );

56
gdpr/db/data-privacy.cds Normal file
View File

@@ -0,0 +1,56 @@
using {sap.capire.orders} from '@capire/orders';
using {sap.capire.gdpr} from './schema';
/*
* annotations for Data Privacy (Personal Data Manager and Audit Logging)
*/
annotate gdpr.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 gdpr.CustomerPostalAddresses with @PersonalData : {
DataSubjectRole : 'Customer',
EntitySemantics : 'DataSubjectDetails'
}{
customer @PersonalData.FieldSemantics : 'DataSubjectID';
street @PersonalData.IsPotentiallyPersonal;
town @PersonalData.IsPotentiallyPersonal;
country @PersonalData.IsPotentiallyPersonal;
}
/*
* TODO: Personal Data Manager doesn't know EntitySemantics: 'Other' and FieldSemantics: 'ContractRelatedID'
* see: https://help.sap.com/viewer/620a3ea6aaf64610accdd05cca9e3de2/Cloud/en-US/5a55fae1eb7c496c92c56071186d76b3.html
*/
annotate orders.Orders with @PersonalData : {
DataSubjectRole : 'Customer',
EntitySemantics : 'LegalGround'
}{
ID @PersonalData.FieldSemantics : 'LegalGroundID';
customer @PersonalData.FieldSemantics : 'DataSubjectID';
}
/*
* additional annotations for Audit Logging
*/
annotate gdpr.Customers with @AuditLog.Operation : {
Read : true,
Insert : true,
Update : true,
Delete : true
};
annotate gdpr.CustomerPostalAddresses with @AuditLog.Operation : {
Read : true,
Insert : true,
Update : true,
Delete : true
};

View File

@@ -0,0 +1,3 @@
ID;modifiedAt;createdAt;createdBy;modifiedBy;customer_ID;street;town;country_code
1e2f2640-6866-4dcf-8f4d-3027aa831cad;2019-04-04;2019-01-31;admin@business.com;admin@business.com;8e2f2640-6866-4dcf-8f4d-3027aa831cad;Hauptstrasse 11;Berlin;DE
24e718c9-ff99-47f1-8ca3-950c850777d4;2019-04-04;2019-01-30;admin@business.com;admin@business.com;74e718c9-ff99-47f1-8ca3-950c850777d4;Main Street 22;London;GB
Internal Server Error - Bruno's Gitea
500 Internal Server Error

Gitea Version: 1.24.4