If you haven't heard about GDPR by now, you have probably either been living without an internet connection or haven't checked your email in the past few weeks. Otherwise, you probably have already received at least 100 privacy-related emails (just like we did) before and after May 25th 2018.
Like most of the companies and products that in some way collect, process and store personal data, we at Sitefinity Insight have been busy during the last couple of months implementing GDPR-related features. Note that those features by themselves will not make your business as a whole GDPR compliant - that compliance involves a company-wide, cross-department efforts and changes.
In this post, we’ll look at the GDPR-related tools we delivered in Sitefinity Insight to make your road to GDPR compliance easier.
Our focus is to deliver adequate workflows that provide access to the data collected and reported to Sitefinity Insight, so the owners of that data can both get it as well as remove that data altogether. These are the so called “right of access” and “right to erasure (or right to be forgotten),” which GDPR grants to all data subjects (for an exact definition of all these terms, see here). Note that we already have an explicit functionality to modify any of the reported data about a contact (the more recently reported values simply override the older ones) aligned with the GDPR’s “right to rectification”.
So, the “right to be forgotten” is implemented through the ability to delete all of the data of a subject that had been reported to Sitefinity Insight, while the data export covers the “right of access.” Both functionalities have been implemented across our API, .NET SDK and web application, and work by providing the tracking Id of the subject whose data you want to be deleted/exported.
We have introduced two different approaches for consuming those new capabilities – a manual approach, where you need to delete/export data from your Sitefinity Insight data center; and an integrated approach accommodated by our .NET SDK to be used in automated workflows.
Let’s take a look at how each of those work.
Figure 1 Data cleanup tab in the Administration section
Both delete and export functionalities follow a similar workflow. First you need to provide the tracking ID (check this article to see how to obtain it) with which you have reported the subject whose data you want to delete or export (Figure 2). Next, all of the subjects that have been reported with that ID across different data sources will be shown (Figure 3).
Figure 2 Initial Delete screen, on which you need to provide the tracking ID of the contact whose data you wish to delete. The screen for the export request is identical except for the header and button captions.
Figure 3 Contact selection for the delete request. The screen for the export request is identical except for the header and button captions.
After you select the contacts whose data you wish to delete/export, just click on the button and the delete/export request will be created and taken care of. Note that the delete functionality will ask you to confirm your action, along with explaining its consequences (Figure 4).
Figure 4 Delete request confirmation
After you have created your delete/export request, you can track its status on the history page (see Figure 5 below). Note that once the export request is completed, you can download the data from that screen as well (for more information about the history screen, please take a look at this article).
Figure 5 Export/Delete requests history/status screen
The latest version of our .NET SDK introduces two new clients, which you can use to create and monitor delete/export requests. The code snippet below shows the basic usage of the clients.
// Fill in your credentials and data center api key
var accessToken =
new
AccessToken(
"username"
,
"password"
);
string
dataCenterApiKey =
"data-center-api-key"
;
// Set the contact for which you wish to delete/export data
var contactForWhichToDeleteOrExportData =
new
List<SubjectId>()
{
new
SubjectId(
"data-source-name-here"
,
"tracking-id-of-the-contact-for-which-to-export-data"
)
};
// Create the export data client
IContactExportRequestClient contactExportClient =
new
ContactExportRequestClient(accessToken, dataCenterApiKey);
// This is how you create a new report for exporting data
ContactExportRequest newlyCreatedExportRequest = await contactExportClient.CreateExportRequest(contactForWhichToDeleteOrExportData);
// You can get all of the export requests in the data center
var allExportRequests = contactExportClient.GetAllExportRequests(
new
LoadOptions());
// Or you can get a specific request by knowing its id
ContactExportRequest existingExportRequestObtainedById = await contactExportClient.GetExportRequestById(newlyCreatedExportRequest.Id);
// If the status of the export request is DataPrepared, you can proceed and download the exported data
if
(existingExportRequestObtainedById.Status == ContactExportRequestStatus.DataPrepared)
{
// Note that the report is zipped
Stream exportedDataZipStream = await contactExportClient.DownloadExportedData(existingExportRequestObtainedById.Id);
string
zipFileDownloadLocation = Path.Combine(Directory.GetCurrentDirectory(),
"report.zip"
);
using
(var zipFileStream = File.Create(zipFileDownloadLocation))
{
exportedDataZipStream.CopyTo(zipFileStream);
}
// The exported data is in json format
string
extractedReportFileLocation = Path.Combine(Directory.GetCurrentDirectory(),
"exportedData.json"
);
ZipFile.ExtractToDirectory(zipFileDownloadLocation, extractedReportFileLocation);
using
(var exportedDataStreamReader =
new
StreamReader(extractedReportFileLocation))
{
using
(var exportedDataJsonReader =
new
JsonTextReader(exportedDataStreamReader))
{
ExportFileData exportedData =
new
JsonSerializer().Deserialize<ExportFileData>(exportedDataJsonReader);
}
}
}
// This is how you create a delete data client
IContactDeleteRequestClient contactDeleteClient =
new
ContactDeleteRequestClient(accessToken, dataCenterApiKey);
// And this is how you can create a new data delete request
ContactDeleteRequest newlyCreatedDeleteRequest = await contactDeleteClient.CreateDeleteRequest(contactForWhichToDeleteOrExportData);
// You can get all of the delete requests in the data center
var allDeleteRequests = contactDeleteClient.GetAll(
new
LoadOptions());
// Or a specific one if you know its id
ContactDeleteRequest existingDeleteRequestObtainedById = await contactDeleteClient.GetById(newlyCreatedDeleteRequest.Id);
// You can consider the data to have been deleted when the status of the request is Done
if
(existingDeleteRequestObtainedById.Status == ContactDeleteRequestStatus.Done)
{
Console.WriteLine(
"The data has been successfully deleted"
);
}
In addition, the latest version of our JS SDK, which is used to enable the easier collection of data client-side, has also been updated to include an on/off data collection parameter (called enableTracking). This should be used to reflect whether the data subject has accepted or rejected the data collection consent you are now required to provide to him/her before you start collecting any data.
// Set the enableTracking parameter to TRUE, if the client has ACCEPTED the data collection consent.
var
decClient =
new
sfDataIntell.Client({
apiKey:
'[api-key-here]'
,
source:
'[data-source-name-here]'
,
enableTracking:
true
});
// Set the enableTracking parameter to FALSE, if the client has REJECTED the data collection consent. The JS SDK will NOT report ANY data now.
var
decClient =
new
sfDataIntell.Client({
apiKey:
'[api-key-here]'
,
source:
'[data-source-name-here]'
,
enableTracking:
false
});
Code Snippet 2 Using the new enableTracking parameter
We have also reviewed our policies and procedures to make sure we take into consideration all of the recommendations and requirements of the GDPR framework.
You can find additional information about the GDPR-related features on the Manage personal data section of our Sitefinity Insight Documentation portal.
As always, we are open to feedback and suggestions, so if you have any, please do not hesitate to let us know below in the comments.
View all posts from The Progress Team on the Progress blog. Connect with us about all things application development and deployment, data integration and digital business.
Let our experts teach you how to use Sitefinity's best-in-class features to deliver compelling digital experiences.
Learn MoreSubscribe to get all the news, info and tutorials you need to build better business apps and sites