diff --git a/src/Proteos.Encryption.EntityFrameworkCore/Interceptors/DecryptingMaterializationInterceptor.cs b/src/Proteos.Encryption.EntityFrameworkCore/Interceptors/DecryptingMaterializationInterceptor.cs index 0702fd4..c96c3d7 100644 --- a/src/Proteos.Encryption.EntityFrameworkCore/Interceptors/DecryptingMaterializationInterceptor.cs +++ b/src/Proteos.Encryption.EntityFrameworkCore/Interceptors/DecryptingMaterializationInterceptor.cs @@ -14,7 +14,7 @@ namespace Proteos.Encryption.EntityFrameworkCore; /// Decryption happens before the change-tracking snapshot is taken, so the decrypted values become /// the entity's original values and a freshly loaded entity is not seen as modified. /// -public sealed class DecryptingMaterializationInterceptor : IMaterializationInterceptor +internal sealed class DecryptingMaterializationInterceptor : IMaterializationInterceptor { private readonly ITenantResolver _tenantResolver; private readonly AesGcmValueEncryptionService _encryptionService; diff --git a/src/Proteos.Encryption.EntityFrameworkCore/Interceptors/EncryptingSaveChangesInterceptor.cs b/src/Proteos.Encryption.EntityFrameworkCore/Interceptors/EncryptingSaveChangesInterceptor.cs index c75590b..7fe760e 100644 --- a/src/Proteos.Encryption.EntityFrameworkCore/Interceptors/EncryptingSaveChangesInterceptor.cs +++ b/src/Proteos.Encryption.EntityFrameworkCore/Interceptors/EncryptingSaveChangesInterceptor.cs @@ -15,7 +15,7 @@ namespace Proteos.Encryption.EntityFrameworkCore; /// later. Encryption happens only for added entities and for the actually-modified properties of /// modified entities, so calling SaveChanges twice never produces ciphertext of ciphertext. /// -public sealed class EncryptingSaveChangesInterceptor : SaveChangesInterceptor +internal sealed class EncryptingSaveChangesInterceptor : SaveChangesInterceptor { private readonly ITenantResolver _tenantResolver; private readonly AesGcmValueEncryptionService _encryptionService; diff --git a/src/Proteos.Encryption.EntityFrameworkCore/Metadata/BlindIndexNormalizerResolver.cs b/src/Proteos.Encryption.EntityFrameworkCore/Metadata/BlindIndexNormalizerResolver.cs index f15a5da..c78f1be 100644 --- a/src/Proteos.Encryption.EntityFrameworkCore/Metadata/BlindIndexNormalizerResolver.cs +++ b/src/Proteos.Encryption.EntityFrameworkCore/Metadata/BlindIndexNormalizerResolver.cs @@ -3,10 +3,10 @@ namespace Proteos.Encryption.EntityFrameworkCore; /// -/// Maps a to the concrete crypto-core normalizer. This is -/// the stable bridge the later EF Core integration will use; it performs no EF runtime work. +/// Maps a to the concrete crypto-core normalizer. Internal +/// helper used by the EF integration; not part of the public API. /// -public static class BlindIndexNormalizerResolver +internal static class BlindIndexNormalizerResolver { public static IBlindIndexNormalizer Resolve(BlindIndexNormalizerKind kind) => kind switch { diff --git a/src/Proteos.Encryption.EntityFrameworkCore/Migration/EncryptionMigrationPlanner.cs b/src/Proteos.Encryption.EntityFrameworkCore/Migration/EncryptionMigrationPlanner.cs index 00b7c9d..8c68e80 100644 --- a/src/Proteos.Encryption.EntityFrameworkCore/Migration/EncryptionMigrationPlanner.cs +++ b/src/Proteos.Encryption.EntityFrameworkCore/Migration/EncryptionMigrationPlanner.cs @@ -8,7 +8,7 @@ namespace Proteos.Encryption.EntityFrameworkCore; /// stored envelope (Base64 for a string property, raw bytes for a byte[] property), reads /// Header.KeyId and compares it with the tenant's current key id — no decryption, no plaintext. /// -public sealed class EncryptionMigrationPlanner : IEncryptionMigrationPlanner +internal sealed class EncryptionMigrationPlanner : IEncryptionMigrationPlanner { private readonly ICiphertextEnvelopeCodec _codec; private readonly IKeyMaterialProvider _keyProvider; diff --git a/src/Proteos.Encryption.EntityFrameworkCore/Migration/EncryptionMigrationService.cs b/src/Proteos.Encryption.EntityFrameworkCore/Migration/EncryptionMigrationService.cs index 10a07cb..644f2cc 100644 --- a/src/Proteos.Encryption.EntityFrameworkCore/Migration/EncryptionMigrationService.cs +++ b/src/Proteos.Encryption.EntityFrameworkCore/Migration/EncryptionMigrationService.cs @@ -12,7 +12,7 @@ namespace Proteos.Encryption.EntityFrameworkCore; /// both steps are done. It reuses the same encryption and blind index services the interceptors use, /// so a migrated value is indistinguishable from a freshly written one. /// -public sealed class EncryptionMigrationService : IEncryptionMigrationService +internal sealed class EncryptionMigrationService : IEncryptionMigrationService { private readonly AesGcmValueEncryptionService _encryptionService; private readonly IBlindIndexProvider _blindIndexProvider; diff --git a/src/Proteos.Encryption.EntityFrameworkCore/Proteos.Encryption.EntityFrameworkCore.csproj b/src/Proteos.Encryption.EntityFrameworkCore/Proteos.Encryption.EntityFrameworkCore.csproj index feaeb29..98c78de 100644 --- a/src/Proteos.Encryption.EntityFrameworkCore/Proteos.Encryption.EntityFrameworkCore.csproj +++ b/src/Proteos.Encryption.EntityFrameworkCore/Proteos.Encryption.EntityFrameworkCore.csproj @@ -39,4 +39,8 @@ + + + + diff --git a/src/Proteos.Encryption.EntityFrameworkCore/PublicAPI.Shipped.txt b/src/Proteos.Encryption.EntityFrameworkCore/PublicAPI.Shipped.txt index fec7da5..351fabb 100644 --- a/src/Proteos.Encryption.EntityFrameworkCore/PublicAPI.Shipped.txt +++ b/src/Proteos.Encryption.EntityFrameworkCore/PublicAPI.Shipped.txt @@ -7,8 +7,6 @@ Microsoft.EntityFrameworkCore.ProteosEncryptionModelBuilderExtensions Microsoft.EntityFrameworkCore.ProteosEncryptionPropertyBuilderExtensions Microsoft.EntityFrameworkCore.ProteosEncryptionQueryableExtensions Microsoft.Extensions.DependencyInjection.ProteosEncryptionServiceCollectionExtensions -override Proteos.Encryption.EntityFrameworkCore.EncryptingSaveChangesInterceptor.SavingChanges(Microsoft.EntityFrameworkCore.Diagnostics.DbContextEventData! eventData, Microsoft.EntityFrameworkCore.Diagnostics.InterceptionResult result) -> Microsoft.EntityFrameworkCore.Diagnostics.InterceptionResult -override Proteos.Encryption.EntityFrameworkCore.EncryptingSaveChangesInterceptor.SavingChangesAsync(Microsoft.EntityFrameworkCore.Diagnostics.DbContextEventData! eventData, Microsoft.EntityFrameworkCore.Diagnostics.InterceptionResult result, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.ValueTask> override Proteos.Encryption.EntityFrameworkCore.EncryptionAuditReport.ToString() -> string! override Proteos.Encryption.EntityFrameworkCore.ReEncryptResumeToken.Equals(object? obj) -> bool override Proteos.Encryption.EntityFrameworkCore.ReEncryptResumeToken.GetHashCode() -> int @@ -20,10 +18,6 @@ Proteos.Encryption.EntityFrameworkCore.AlreadyEncryptedValueException.PropertyNa Proteos.Encryption.EntityFrameworkCore.BlindIndexNormalizerKind Proteos.Encryption.EntityFrameworkCore.BlindIndexNormalizerKind.Default = 0 -> Proteos.Encryption.EntityFrameworkCore.BlindIndexNormalizerKind Proteos.Encryption.EntityFrameworkCore.BlindIndexNormalizerKind.Email = 1 -> Proteos.Encryption.EntityFrameworkCore.BlindIndexNormalizerKind -Proteos.Encryption.EntityFrameworkCore.BlindIndexNormalizerResolver -Proteos.Encryption.EntityFrameworkCore.DecryptingMaterializationInterceptor -Proteos.Encryption.EntityFrameworkCore.DecryptingMaterializationInterceptor.DecryptingMaterializationInterceptor(Proteos.Encryption.EntityFrameworkCore.ITenantResolver! tenantResolver, Proteos.Encryption.Core.AesGcmValueEncryptionService! encryptionService, System.IServiceProvider! serviceProvider) -> void -Proteos.Encryption.EntityFrameworkCore.DecryptingMaterializationInterceptor.InitializedInstance(Microsoft.EntityFrameworkCore.Diagnostics.MaterializationInterceptionData materializationData, object! instance) -> object! Proteos.Encryption.EntityFrameworkCore.EncryptedAttribute Proteos.Encryption.EntityFrameworkCore.EncryptedAttribute.EncryptedAttribute() -> void Proteos.Encryption.EntityFrameworkCore.EncryptedAttribute.EncryptedAttribute(string! name) -> void @@ -85,8 +79,6 @@ Proteos.Encryption.EntityFrameworkCore.EncryptedSearchableAttribute.IndexPropert Proteos.Encryption.EntityFrameworkCore.EncryptedSearchableAttribute.IndexProperty.set -> void Proteos.Encryption.EntityFrameworkCore.EncryptedSearchableAttribute.Normalizer.get -> Proteos.Encryption.EntityFrameworkCore.BlindIndexNormalizerKind Proteos.Encryption.EntityFrameworkCore.EncryptedSearchableAttribute.Normalizer.set -> void -Proteos.Encryption.EntityFrameworkCore.EncryptingSaveChangesInterceptor -Proteos.Encryption.EntityFrameworkCore.EncryptingSaveChangesInterceptor.EncryptingSaveChangesInterceptor(Proteos.Encryption.EntityFrameworkCore.ITenantResolver! tenantResolver, Proteos.Encryption.Core.AesGcmValueEncryptionService! encryptionService, Proteos.Encryption.Abstractions.IBlindIndexProvider! blindIndexProvider, Proteos.Encryption.Core.ICiphertextEnvelopeCodec! codec, System.IServiceProvider! serviceProvider) -> void Proteos.Encryption.EntityFrameworkCore.EncryptionAuditEntry Proteos.Encryption.EntityFrameworkCore.EncryptionAuditEntry.Classification.get -> Proteos.Encryption.EntityFrameworkCore.EncryptionClassification Proteos.Encryption.EntityFrameworkCore.EncryptionAuditEntry.Classification.init -> void @@ -109,14 +101,6 @@ Proteos.Encryption.EntityFrameworkCore.EncryptionClassification.Encrypted = 0 -> Proteos.Encryption.EntityFrameworkCore.EncryptionClassification.EncryptedSearchable = 1 -> Proteos.Encryption.EntityFrameworkCore.EncryptionClassification Proteos.Encryption.EntityFrameworkCore.EncryptionClassification.Plaintext = 2 -> Proteos.Encryption.EntityFrameworkCore.EncryptionClassification Proteos.Encryption.EntityFrameworkCore.EncryptionClassification.Unclassified = 3 -> Proteos.Encryption.EntityFrameworkCore.EncryptionClassification -Proteos.Encryption.EntityFrameworkCore.EncryptionMigrationPlanner -Proteos.Encryption.EntityFrameworkCore.EncryptionMigrationPlanner.CreatePlan(Proteos.Encryption.EntityFrameworkCore.EncryptedEntityMetadata! metadata, System.Collections.Generic.IReadOnlyDictionary! storedValues, Proteos.Encryption.Abstractions.TenantId! tenant) -> Proteos.Encryption.EntityFrameworkCore.EncryptedEntityMigrationPlan! -Proteos.Encryption.EntityFrameworkCore.EncryptionMigrationPlanner.EncryptionMigrationPlanner(Proteos.Encryption.Core.ICiphertextEnvelopeCodec! codec, Proteos.Encryption.Core.IKeyMaterialProvider! keyProvider) -> void -Proteos.Encryption.EntityFrameworkCore.EncryptionMigrationPlanner.NeedsReEncryption(System.Type! propertyType, object? storedValue, Proteos.Encryption.Abstractions.KeyId! currentKeyId) -> bool -Proteos.Encryption.EntityFrameworkCore.EncryptionMigrationPlanner.ReadStoredKeyId(System.Type! propertyType, object? storedValue) -> Proteos.Encryption.Abstractions.KeyId? -Proteos.Encryption.EntityFrameworkCore.EncryptionMigrationService -Proteos.Encryption.EntityFrameworkCore.EncryptionMigrationService.EncryptionMigrationService(Proteos.Encryption.Core.AesGcmValueEncryptionService! encryptionService, Proteos.Encryption.Abstractions.IBlindIndexProvider! blindIndexProvider) -> void -Proteos.Encryption.EntityFrameworkCore.EncryptionMigrationService.ReEncrypt(Proteos.Encryption.EntityFrameworkCore.EncryptedPropertyDescriptor! descriptor, object! storedValue, Proteos.Encryption.Abstractions.TenantId! tenant) -> Proteos.Encryption.EntityFrameworkCore.MigratedEncryptedProperty! Proteos.Encryption.EntityFrameworkCore.IEncryptionMigrationPlanner Proteos.Encryption.EntityFrameworkCore.IEncryptionMigrationPlanner.CreatePlan(Proteos.Encryption.EntityFrameworkCore.EncryptedEntityMetadata! metadata, System.Collections.Generic.IReadOnlyDictionary! storedValues, Proteos.Encryption.Abstractions.TenantId! tenant) -> Proteos.Encryption.EntityFrameworkCore.EncryptedEntityMigrationPlan! Proteos.Encryption.EntityFrameworkCore.IEncryptionMigrationPlanner.NeedsReEncryption(System.Type! propertyType, object? storedValue, Proteos.Encryption.Abstractions.KeyId! currentKeyId) -> bool @@ -186,7 +170,6 @@ static Microsoft.EntityFrameworkCore.ProteosEncryptionQueryableExtensions.WhereE static Microsoft.EntityFrameworkCore.ProteosEncryptionQueryableExtensions.WhereEncryptedEquals(this System.Linq.IQueryable! source, Microsoft.EntityFrameworkCore.DbContext! dbContext, System.Linq.Expressions.Expression!>! propertySelector, string? value) -> System.Linq.IQueryable! static Microsoft.EntityFrameworkCore.ProteosEncryptionQueryableExtensions.WhereEncryptedIn(this System.Linq.IQueryable! source, Microsoft.EntityFrameworkCore.DbContext! dbContext, System.Linq.Expressions.Expression!>! propertySelector, System.Collections.Generic.IEnumerable! values) -> System.Linq.IQueryable! static Microsoft.Extensions.DependencyInjection.ProteosEncryptionServiceCollectionExtensions.AddProteosEncryption(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services, System.Action! configure) -> Microsoft.Extensions.DependencyInjection.IServiceCollection! -static Proteos.Encryption.EntityFrameworkCore.BlindIndexNormalizerResolver.Resolve(Proteos.Encryption.EntityFrameworkCore.BlindIndexNormalizerKind kind) -> Proteos.Encryption.Core.IBlindIndexNormalizer! static Proteos.Encryption.EntityFrameworkCore.EncryptedEntityMetadataScanner.Scan(System.Type! entityType) -> Proteos.Encryption.EntityFrameworkCore.EncryptedEntityMetadata! static Proteos.Encryption.EntityFrameworkCore.EncryptionAuditReport.Create(Microsoft.EntityFrameworkCore.Metadata.IReadOnlyModel! model) -> Proteos.Encryption.EntityFrameworkCore.EncryptionAuditReport! static Proteos.Encryption.EntityFrameworkCore.ReEncryptBatchOptions.Default.get -> Proteos.Encryption.EntityFrameworkCore.ReEncryptBatchOptions! diff --git a/tests/Proteos.Encryption.AwsKms.Tests/AwsKmsKeyProviderTests.cs b/tests/Proteos.Encryption.AwsKms.Tests/AwsKmsKeyProviderTests.cs index bc53e57..2de086a 100644 --- a/tests/Proteos.Encryption.AwsKms.Tests/AwsKmsKeyProviderTests.cs +++ b/tests/Proteos.Encryption.AwsKms.Tests/AwsKmsKeyProviderTests.cs @@ -144,7 +144,7 @@ public void AddProteosAwsKms_InvalidKeyId_Throws() [Theory] [InlineData(typeof(AesGcmValueEncryptionService))] // Proteos.Encryption.Core - [InlineData(typeof(EncryptingSaveChangesInterceptor))] // Proteos.Encryption.EntityFrameworkCore + [InlineData(typeof(EncryptedAttribute))] // Proteos.Encryption.EntityFrameworkCore [InlineData(typeof(AzureKeyVaultKeyProvider))] // Proteos.Encryption.AzureKeyVault public void CoreEfAndAzure_DoNotReferenceAws(Type typeFromAssembly) { diff --git a/tests/Proteos.Encryption.AzureKeyVault.Tests/AzureKeyVaultKeyProviderTests.cs b/tests/Proteos.Encryption.AzureKeyVault.Tests/AzureKeyVaultKeyProviderTests.cs index d0f84a6..063a761 100644 --- a/tests/Proteos.Encryption.AzureKeyVault.Tests/AzureKeyVaultKeyProviderTests.cs +++ b/tests/Proteos.Encryption.AzureKeyVault.Tests/AzureKeyVaultKeyProviderTests.cs @@ -153,7 +153,7 @@ public void AddProteosAzureKeyVault_InvalidKeyIdentifier_Throws() [Theory] [InlineData(typeof(AesGcmValueEncryptionService))] // Proteos.Encryption.Core - [InlineData(typeof(EncryptingSaveChangesInterceptor))] // Proteos.Encryption.EntityFrameworkCore + [InlineData(typeof(EncryptedAttribute))] // Proteos.Encryption.EntityFrameworkCore public void CoreAndEf_DoNotReferenceAzure(Type typeFromAssembly) { var referenced = typeFromAssembly.Assembly.GetReferencedAssemblies();