Implement the `GDPR` requirements in websites & template projects
Implementing the policies and features required by the GDPR (General Data Protection Regulation) is required. The GDPR is described here: https://gdpr.eu/what-is-gdpr/
I’d like to highlight an issue regarding two essential GDPR-related features that are currently missing in BitPlatform: the ability to delete and retrieve personal information.
These features are critical for GDPR compliance and should ideally be included directly in BitPlatform. Microsoft already provides this functionality in their default WebApp templates, so integrating it here should be a relatively quick fix.
@Kyemate We've delete account feature, is there something missing?
Sorry, my bad. Another feature that is required by gdpr is is the right to see what data an organization have on you(Article 15). So a feature where you could download the data in a json format or something could be good to have.
Here is the implementation in the default blazor template with accounts.
manageGroup.MapPost("/DownloadPersonalData", async (
HttpContext context,
[FromServices] UserManager<ApplicationUser> userManager,
[FromServices] AuthenticationStateProvider authenticationStateProvider) =>
{
var user = await userManager.GetUserAsync(context.User);
if (user is null)
{
return Results.NotFound($"Unable to load user with ID '{userManager.GetUserId(context.User)}'.");
}
var userId = await userManager.GetUserIdAsync(user);
downloadLogger.LogInformation("User with ID '{UserId}' asked for their personal data.", userId);
// Only include personal data for download
var personalData = new Dictionary<string, string>();
var personalDataProps = typeof(ApplicationUser).GetProperties().Where(
prop => Attribute.IsDefined(prop, typeof(PersonalDataAttribute)));
foreach (var p in personalDataProps)
{
personalData.Add(p.Name, p.GetValue(user)?.ToString() ?? "null");
}
var logins = await userManager.GetLoginsAsync(user);
foreach (var l in logins)
{
personalData.Add($"{l.LoginProvider} external login provider key", l.ProviderKey);
}
personalData.Add("Authenticator Key", (await userManager.GetAuthenticatorKeyAsync(user))!);
var fileBytes = JsonSerializer.SerializeToUtf8Bytes(personalData);
context.Response.Headers.TryAdd("Content-Disposition", "attachment; filename=PersonalData.json");
return TypedResults.File(fileBytes, contentType: "application/json", fileDownloadName: "PersonalData.json");
});
We could write such a thing