Skip to content

Commit ecc8ef1

Browse files
CopilotSmilefoundernhathoang989
authored
Implement comprehensive HIPAA and GDPR compliance framework for MixCore CMS (#790)
* Initial plan * Phase 1: Implement foundational HIPAA/GDPR compliance entities and services Co-authored-by: Smilefounder <3785721+Smilefounder@users.noreply.github.com> * Phase 2: Implement DSR services, retention management, field encryption, and compliance APIs Co-authored-by: Smilefounder <3785721+Smilefounder@users.noreply.github.com> * Final Phase: Add break-glass access, DPIA workflow, and comprehensive implementation summary Co-authored-by: Smilefounder <3785721+Smilefounder@users.noreply.github.com> * Complete missing TODO items: Add BreakGlassService, DpiaService implementations and missing entity configurations Co-authored-by: Smilefounder <3785721+Smilefounder@users.noreply.github.com> * Add Decimal type and refactor database constants - Introduced a new `Decimal` database constant with mappings for various databases. - Updated `SqliteDatabaseConstants` to change `Date` type to `date`, `Guid` to `text`, and `Decimal` to `decimal(18,2)`. - Refactored `AuditLogConfiguration` for table name changes and added compliance indexes. - Enhanced `BreakGlassAccess` and `BreakGlassAudit` classes to utilize nullable properties. - Initialized string properties in `ConsentEvent`, `DataFieldMetadata`, and `DataProtectionImpactAssessment` with `string.Empty`. - Improved service classes to handle nullable properties and refined database operations. - Updated interfaces to return nullable types where applicable. - Added new properties and methods for better functionality and maintainability. - Updated project references in `mix.library.csproj` to include new compliance entities. - Refactored `EncryptedStringConverter` for basic encryption and decryption. - Enhanced user data export handling in `DsrService` for better serialization. - Added comments and documentation for clarity and maintainability. * Remove template files and add GDPR migration support Updated `mixcore.csproj` to exclude all files in the `wwwroot\mixcontent\templates\**` directory from compilation and resources. Added new migration files for MySQL, PostgreSQL, SQL Server, and SQLite to implement GDPR-related properties in the `AuditLog` entity, including `CorrelationId`, `PhiAccessFlag`, `SessionId`, `TenantId`, and `UserAgent`. Updated `MySqlAuditLogDbContextModelSnapshot.cs` to reflect these changes. Additionally, revised `Readme.md` to provide clearer instructions for adding migrations and updating the database. --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: Smilefounder <3785721+Smilefounder@users.noreply.github.com> Co-authored-by: Nhật Hoàng <nhathoang989@gmail.com>
1 parent 57db512 commit ecc8ef1

File tree

71 files changed

+5846
-130
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

71 files changed

+5846
-130
lines changed

src/applications/mixcore/mixcore.csproj

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,13 @@
1818
<NoWarn>$(NoWarn);1591</NoWarn>
1919
</PropertyGroup>
2020

21+
<ItemGroup>
22+
<Compile Remove="wwwroot\mixcontent\templates\**" />
23+
<Content Remove="wwwroot\mixcontent\templates\**" />
24+
<EmbeddedResource Remove="wwwroot\mixcontent\templates\**" />
25+
<None Remove="wwwroot\mixcontent\templates\**" />
26+
</ItemGroup>
27+
2128
<ItemGroup>
2229
<ProjectReference Include="..\..\modules\mix.common\mix.common.csproj" />
2330
<ProjectReference Include="..\..\modules\mix.grpc\mix.grpc.csproj" />

src/platform/mix.database/Base/IDatabaseConstants.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ public interface IDatabaseConstants
1111
public string Date { get; }
1212
public string Guid { get; }
1313
public string Integer { get; }
14+
public string Decimal { get; }
1415
public string Long { get; }
1516
public string String { get; }
1617
public string NString { get; }

src/platform/mix.database/Base/_CassandraDatabaseConstants.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ public class CassandraDatabaseConstants : IDatabaseConstants
2020

2121
string IDatabaseConstants.Integer => "int";
2222

23+
string IDatabaseConstants.Decimal => "decimal";
24+
2325
string IDatabaseConstants.Long => "BigInt";
2426

2527
string IDatabaseConstants.String => "varchar";

src/platform/mix.database/Base/_MySqlDatabaseConstants.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ public class MySqlDatabaseConstants : IDatabaseConstants
2121

2222
string IDatabaseConstants.Integer => "int";
2323

24+
string IDatabaseConstants.Decimal => "decimal";
25+
2426
string IDatabaseConstants.Long => "BigInt";
2527

2628
string IDatabaseConstants.String => "varchar";

src/platform/mix.database/Base/_PostgresSqlDatabaseConstants.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ public class PostgresDatabaseConstants : IDatabaseConstants
2020

2121
string IDatabaseConstants.Integer => "int";
2222

23+
string IDatabaseConstants.Decimal => "decimal";
24+
2325
string IDatabaseConstants.Long => "BigInt";
2426

2527
string IDatabaseConstants.String => "varchar";

src/platform/mix.database/Base/_SqlServerDatabaseConstants.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ public class SqlServerDatabaseConstants : IDatabaseConstants
2020

2121
string IDatabaseConstants.Integer => "int";
2222

23+
string IDatabaseConstants.Decimal => "decimal";
24+
2325
string IDatabaseConstants.Long => "BigInt";
2426

2527
string IDatabaseConstants.String => "varchar";

src/platform/mix.database/Base/_SqliteDatabaseConstants.cs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,27 +14,29 @@ public class SqliteDatabaseConstants : IDatabaseConstants
1414

1515
string IDatabaseConstants.DateTime => "datetime";
1616

17-
string IDatabaseConstants.Date => "datetime";
17+
string IDatabaseConstants.Date => "date";
1818

19-
string IDatabaseConstants.Guid => "uniqueidentifier";
19+
string IDatabaseConstants.Guid => "text";
2020

2121
string IDatabaseConstants.Integer => "integer";
2222

23-
string IDatabaseConstants.Long => "BigInt";
23+
string IDatabaseConstants.Decimal => "decimal(18,2)";
24+
25+
string IDatabaseConstants.Long => "bigint";
2426

2527
string IDatabaseConstants.String => "varchar";
2628

2729
string IDatabaseConstants.NString => "varchar";
2830

2931
string IDatabaseConstants.Text => "text";
3032

31-
string IDatabaseConstants.GenerateUUID => "newid()";
33+
string IDatabaseConstants.GenerateUUID => "hex(randomblob(16))";
3234

3335
string IDatabaseConstants.Time => "time";
3436

35-
string IDatabaseConstants.Now => "(DATETIME('now'))";
37+
string IDatabaseConstants.Now => "datetime('now')";
3638

37-
string IDatabaseConstants.Boolean => "INTEGER";
39+
string IDatabaseConstants.Boolean => "integer";
3840

3941
string IDatabaseConstants.BacktickOpen => "[";
4042

src/platform/mix.database/Entities/AuditLog/AuditLog.cs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using Newtonsoft.Json.Linq;
2+
using System.ComponentModel.DataAnnotations;
23

34
namespace Mix.Database.Entities.AuditLog
45
{
@@ -14,5 +15,19 @@ public class AuditLog: EntityBase<Guid>
1415
public JObject Body { get; set; }
1516
public JObject Response { get; set; }
1617
public JObject Exception { get; set; }
18+
19+
// HIPAA/GDPR Compliance Enhancement Fields
20+
[MaxLength(100)]
21+
public string CorrelationId { get; set; }
22+
23+
public int? TenantId { get; set; }
24+
25+
public bool PhiAccessFlag { get; set; }
26+
27+
[MaxLength(500)]
28+
public string UserAgent { get; set; }
29+
30+
[MaxLength(100)]
31+
public string SessionId { get; set; }
1732
}
1833
}

src/platform/mix.database/Entities/AuditLog/EntityConfigurations/AuditLogConfiguration.cs

Lines changed: 35 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
1-
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
2-
using Mix.Database.Entities.Account;
3-
using Mix.Database.EntityConfigurations;
4-
using Newtonsoft.Json.Linq;
1+
using Microsoft.EntityFrameworkCore;
2+
using Microsoft.EntityFrameworkCore.Metadata.Builders;
3+
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
54
using Mix.Database.EntityConfigurations.Base;
6-
using Microsoft.Extensions.DependencyModel.Resolution;
75
using Mix.Database.Services.MixGlobalSettings;
6+
using Newtonsoft.Json.Linq;
7+
88
namespace Mix.Database.Entities.AuditLog.EntityConfigurations
99
{
1010
internal class AuditLogConfiguration : EntityBaseConfiguration<AuditLog, Guid>
11-
1211
{
1312
public AuditLogConfiguration(DatabaseService databaseService) : base(databaseService)
1413
{
@@ -17,7 +16,8 @@ public AuditLogConfiguration(DatabaseService databaseService) : base(databaseSer
1716
public override void Configure(EntityTypeBuilder<AuditLog> builder)
1817
{
1918
base.Configure(builder);
20-
builder.ToTable(MixDbTableNames.AUDIT_LOG);
19+
builder.ToTable("mix_audit_log");
20+
2121
builder.Property(e => e.Success)
2222
.HasColumnName("success")
2323
.HasColumnType(Config.Boolean);
@@ -30,10 +30,6 @@ public override void Configure(EntityTypeBuilder<AuditLog> builder)
3030
.HasColumnName("response_time")
3131
.HasColumnType(Config.Integer);
3232

33-
builder.Property(e => e.Success)
34-
.HasColumnName("success")
35-
.HasColumnType(Config.Boolean);
36-
3733
builder.Property(e => e.RequestIp)
3834
.HasColumnName("request_ip")
3935
.HasColumnType($"{Config.String}{Config.SmallLength}");
@@ -73,6 +69,34 @@ public override void Configure(EntityTypeBuilder<AuditLog> builder)
7369
.IsRequired(false)
7470
.HasColumnName("exception")
7571
.HasColumnType(Config.Text);
72+
73+
// HIPAA/GDPR Compliance Enhancement Fields
74+
builder.Property(e => e.CorrelationId)
75+
.HasColumnName("correlation_id")
76+
.HasColumnType($"{Config.String}{Config.MediumLength}");
77+
78+
builder.Property(e => e.TenantId)
79+
.HasColumnName("tenant_id")
80+
.HasColumnType(Config.Integer);
81+
82+
builder.Property(e => e.PhiAccessFlag)
83+
.HasColumnName("phi_access_flag")
84+
.HasColumnType(Config.Boolean);
85+
86+
builder.Property(e => e.UserAgent)
87+
.HasColumnName("user_agent")
88+
.HasColumnType($"{Config.String}{Config.MaxLength}");
89+
90+
builder.Property(e => e.SessionId)
91+
.HasColumnName("session_id")
92+
.HasColumnType($"{Config.String}{Config.MediumLength}");
93+
94+
// Indexes for compliance queries
95+
builder.HasIndex(e => new { e.TenantId, e.PhiAccessFlag })
96+
.HasDatabaseName("IX_AuditLog_Tenant_PHI");
97+
98+
builder.HasIndex(e => e.CorrelationId)
99+
.HasDatabaseName("IX_AuditLog_CorrelationId");
76100
}
77101
}
78102
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
using Mix.Database.Entities.Base;
2+
using System;
3+
using System.Collections.Generic;
4+
using System.ComponentModel.DataAnnotations;
5+
6+
namespace Mix.Database.Entities.Compliance
7+
{
8+
public class BreakGlassAccess : TenantEntityBase<int>
9+
{
10+
[Required]
11+
public Guid UserId { get; set; }
12+
13+
[Required]
14+
[MaxLength(100)]
15+
public string AccessReason { get; set; } = string.Empty;
16+
17+
[Required]
18+
[MaxLength(500)]
19+
public string Justification { get; set; } = string.Empty;
20+
21+
[Required]
22+
[MaxLength(100)]
23+
public string ApprovedBy { get; set; } = string.Empty;
24+
25+
public DateTime AccessStartTime { get; set; }
26+
public DateTime AccessEndTime { get; set; }
27+
public DateTime? ActualEndTime { get; set; }
28+
29+
[Required]
30+
public BreakGlassStatus Status { get; set; }
31+
32+
[MaxLength(45)]
33+
public string? IpAddress { get; set; }
34+
35+
[MaxLength(500)]
36+
public string? UserAgent { get; set; }
37+
38+
public virtual ICollection<BreakGlassAudit>? AuditTrail { get; set; }
39+
}
40+
41+
public enum BreakGlassStatus
42+
{
43+
Requested = 1,
44+
Approved = 2,
45+
Active = 3,
46+
Expired = 4,
47+
Revoked = 5
48+
}
49+
}

0 commit comments

Comments
 (0)