Compare commits
16 Commits
feat/clien
...
d013d3edfa
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d013d3edfa | ||
|
|
f267fe955b | ||
|
|
644283cf8f | ||
|
|
82aa8d1143 | ||
|
|
7459f05748 | ||
|
|
36f75d003a | ||
|
|
76ce64691a | ||
|
|
7c03282066 | ||
|
|
7ae95b729f | ||
|
|
9ee8a51664 | ||
|
|
b1d1a898b8 | ||
|
|
4ed3e79565 | ||
|
|
8d9de4502e | ||
|
|
7dd91c73c4 | ||
|
|
65c64a3f9a | ||
|
|
1d600aa453 |
@@ -7,7 +7,7 @@ namespace DigitalData.Core.API
|
||||
[ApiController]
|
||||
[Route("api/[controller]")]
|
||||
public class BasicCRUDControllerBase<TCRUDService, TDto, TEntity, TId> : CRUDControllerBase<TCRUDService, TDto, TDto, TDto, TEntity, TId>
|
||||
where TCRUDService : ICRUDService<TDto, TDto, TDto, TEntity, TId>
|
||||
where TCRUDService : ICRUDService<TDto, TDto, TEntity, TId>
|
||||
where TDto : class, IUnique<TId>
|
||||
where TEntity : class, IUnique<TId>
|
||||
{
|
||||
|
||||
@@ -11,13 +11,12 @@ namespace DigitalData.Core.API
|
||||
/// <typeparam name="TCRUDService">The derived CRUD service type implementing ICRUDService<TCreateDto, TReadDto, TUpdateDto, TEntity, TId>.</typeparam>
|
||||
/// <typeparam name="TCreateDto">The Data Transfer Object type for create operations.</typeparam>
|
||||
/// <typeparam name="TReadDto">The Data Transfer Object type for read operations.</typeparam>
|
||||
/// <typeparam name="TUpdateDto">The Data Transfer Object type for update operations.</typeparam>
|
||||
/// <typeparam name="TEntity">The entity type CRUD operations will be performed on.</typeparam>
|
||||
/// <typeparam name="TId">The type of the entity's identifier.</typeparam>
|
||||
[ApiController]
|
||||
[Route("api/[controller]")]
|
||||
public class CRUDControllerBase<TCRUDService, TCreateDto, TReadDto, TUpdateDto, TEntity, TId> : ControllerBase
|
||||
where TCRUDService : ICRUDService<TCreateDto, TReadDto, TUpdateDto, TEntity, TId>
|
||||
where TCRUDService : ICRUDService<TCreateDto, TReadDto, TEntity, TId>
|
||||
where TCreateDto : class
|
||||
where TReadDto : class
|
||||
where TUpdateDto : class, IUnique<TId>
|
||||
|
||||
@@ -12,13 +12,12 @@ namespace DigitalData.Core.API
|
||||
/// <typeparam name="TCRUDService">The derived CRUD service type implementing ICRUDService<TCreateDto, TReadDto, TUpdateDto, TEntity, TId>.</typeparam>
|
||||
/// <typeparam name="TCreateDto">The Data Transfer Object type for create operations.</typeparam>
|
||||
/// <typeparam name="TReadDto">The Data Transfer Object type for read operations.</typeparam>
|
||||
/// <typeparam name="TUpdateDto">The Data Transfer Object type for update operations.</typeparam>
|
||||
/// <typeparam name="TEntity">The entity type CRUD operations will be performed on.</typeparam>
|
||||
/// <typeparam name="TId">The type of the entity's identifier.</typeparam>
|
||||
[ApiController]
|
||||
[Route("api/[controller]")]
|
||||
public class CRUDControllerBaseWithErrorHandling<TCRUDService, TCreateDto, TReadDto, TUpdateDto, TEntity, TId> : ControllerBase
|
||||
where TCRUDService : ICRUDService<TCreateDto, TReadDto, TUpdateDto, TEntity, TId>
|
||||
where TCRUDService : ICRUDService<TCreateDto, TReadDto, TEntity, TId>
|
||||
where TCreateDto : class
|
||||
where TReadDto : class
|
||||
where TUpdateDto : class, IUnique<TId>
|
||||
|
||||
@@ -19,7 +19,7 @@ namespace DigitalData.Core.API
|
||||
/// <param name="index">The key in the ViewData dictionary where the value will be stored.</param>
|
||||
/// <param name="value">The value to be stored in the ViewData dictionary.</param>
|
||||
/// <returns>The same ViewResult object with updated ViewData, allowing for additional chained operations.</returns>
|
||||
public static ViewResult WithData(this ViewResult viewResult, string index, object value)
|
||||
public static ViewResult WithData(this ViewResult viewResult, string index, object? value)
|
||||
{
|
||||
viewResult.ViewData[index] = value;
|
||||
return viewResult;
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
<OutputType>Library</OutputType>
|
||||
<Description>This package provides a comprehensive set of API controllers and related utilities for the DigitalData.Core library. It includes generic CRUD controllers, localization extensions, middleware for security policies, and application model conventions.</Description>
|
||||
<PackageId>DigitalData.Core.API</PackageId>
|
||||
<Version>2.0.0.0</Version>
|
||||
<Version>2.1.1</Version>
|
||||
<Authors>Digital Data GmbH</Authors>
|
||||
<Company>Digital Data GmbH</Company>
|
||||
<Product>DigitalData.Core.API</Product>
|
||||
@@ -16,6 +16,8 @@
|
||||
<RepositoryUrl>http://git.dd:3000/AppStd/WebCoreModules.git</RepositoryUrl>
|
||||
<PackageTags>digital data core api</PackageTags>
|
||||
<PackageIcon>core_icon.png</PackageIcon>
|
||||
<AssemblyVersion>2.1.1</AssemblyVersion>
|
||||
<FileVersion>2.1.1</FileVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -15,7 +15,7 @@ namespace DigitalData.Core.Abstractions.Application
|
||||
/// This interface is useful for entities that do not require different DTOs for different operations,
|
||||
/// allowing for a more concise and maintainable codebase when implementing services for such entities.
|
||||
/// </remarks>
|
||||
public interface IBasicCRUDService<TDto, TEntity, TId> : ICRUDService<TDto, TDto, TDto, TEntity, TId>
|
||||
public interface IBasicCRUDService<TDto, TEntity, TId> : ICRUDService<TDto, TDto, TEntity, TId>
|
||||
where TDto : class, IUnique<TId> where TEntity : class, IUnique<TId>
|
||||
{
|
||||
}
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
|
||||
namespace DigitalData.Core.Abstractions.Application
|
||||
{
|
||||
public interface ICRUDService<TCreateDto, TReadDto, TUpdateDto, TEntity, TId> : IReadService<TReadDto, TEntity, TId>
|
||||
where TCreateDto : class where TReadDto : class where TUpdateDto : IUnique<TId> where TEntity : class, IUnique<TId>
|
||||
public interface ICRUDService<TCreateDto, TReadDto, TEntity, TId> : IReadService<TReadDto, TEntity, TId>
|
||||
where TCreateDto : class where TReadDto : class where TEntity : class, IUnique<TId>
|
||||
{
|
||||
/// <summary>
|
||||
/// Asynchronously creates a new entity based on the provided <paramref name="createDto"/> and returns the identifier of the created entity wrapped in a <see cref="DataResult{TId}"/>.
|
||||
@@ -20,6 +20,6 @@ namespace DigitalData.Core.Abstractions.Application
|
||||
/// </summary>
|
||||
/// <param name="updateDto">The updateDTO with updated values for the entity.</param>
|
||||
/// <returns>An Result indicating the outcome of the update operation, with an appropriate message.</returns>
|
||||
Task<Result> UpdateAsync(TUpdateDto updateDto);
|
||||
Task<Result> UpdateAsync<TUpdateDto>(TUpdateDto updateDto) where TUpdateDto : IUnique<TId>;
|
||||
}
|
||||
}
|
||||
@@ -17,9 +17,9 @@
|
||||
<RepositoryUrl>http://git.dd:3000/AppStd/WebCoreModules.git</RepositoryUrl>
|
||||
<PackAsTool>False</PackAsTool>
|
||||
<PackageIcon>core_icon.png</PackageIcon>
|
||||
<Version>2.2.1</Version>
|
||||
<AssemblyVersion>2.2.1</AssemblyVersion>
|
||||
<FileVersion>2.2.1</FileVersion>
|
||||
<Version>3.0.0</Version>
|
||||
<AssemblyVersion>3.0.0</AssemblyVersion>
|
||||
<FileVersion>3.0.0</FileVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
namespace DigitalData.Core.Abstractions.Security
|
||||
{
|
||||
public interface IAsymCryptService<TParams> : IRSAFactory<TParams>
|
||||
public interface IAsymCryptService : IRSAFactory
|
||||
{
|
||||
public IEnumerable<IRSADecryptor> Decryptors { get; }
|
||||
|
||||
public IEnumerable<IRSAEncryptor> Encryptors { get; }
|
||||
}
|
||||
|
||||
public interface IAsymCryptService<TParams> : IAsymCryptService, IRSAFactory<TParams> { }
|
||||
}
|
||||
@@ -7,11 +7,7 @@ namespace DigitalData.Core.Abstractions.Security
|
||||
public string Pem { get; init; }
|
||||
|
||||
public RSAEncryptionPadding Padding { get; init; }
|
||||
|
||||
public string? Directory { get; set; }
|
||||
|
||||
public string? FileName { get; set; }
|
||||
|
||||
|
||||
public string Issuer { get; init; }
|
||||
|
||||
public string Audience { get; init; }
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
namespace DigitalData.Core.Abstractions.Security
|
||||
{
|
||||
public interface IRSAFactory<TParams>
|
||||
public interface IRSAFactory
|
||||
{
|
||||
string CreateRSAPrivateKeyPem(int? keySizeInBits = null);
|
||||
|
||||
@@ -13,4 +13,6 @@ namespace DigitalData.Core.Abstractions.Security
|
||||
HashAlgorithmName? hashAlgorithmName = null,
|
||||
int? iterationCount = null);
|
||||
}
|
||||
|
||||
public interface IRSAFactory<TParams> : IRSAFactory { }
|
||||
}
|
||||
@@ -19,7 +19,7 @@ namespace DigitalData.Core.Application
|
||||
/// and a culture-specific translation service for any necessary text translations, ensuring a versatile and internationalized approach to CRUD operations.
|
||||
/// </remarks>
|
||||
public class BasicCRUDService<TCRUDRepository, TDto, TEntity, TId> :
|
||||
CRUDService<TCRUDRepository, TDto, TDto, TDto, TEntity, TId>, IBasicCRUDService<TDto, TEntity, TId>
|
||||
CRUDService<TCRUDRepository, TDto, TDto, TEntity, TId>, IBasicCRUDService<TDto, TEntity, TId>
|
||||
where TCRUDRepository : ICRUDRepository<TEntity, TId> where TDto : class, IUnique<TId> where TEntity : class, IUnique<TId>
|
||||
{
|
||||
/// <summary>
|
||||
|
||||
@@ -12,11 +12,10 @@ namespace DigitalData.Core.Application
|
||||
/// </summary>
|
||||
/// <typeparam name="TCreateDto">The DTO type for create operations.</typeparam>
|
||||
/// <typeparam name="TReadDto">The DTO type for read operations.</typeparam>
|
||||
/// <typeparam name="TUpdateDto">The DTO type for update operations.</typeparam>
|
||||
/// <typeparam name="TEntity">The entity type.</typeparam>
|
||||
/// <typeparam name="TId">The type of the identifier for the entity.</typeparam>
|
||||
public class CRUDService<TCRUDRepository, TCreateDto, TReadDto, TUpdateDto, TEntity, TId> : ReadService<TCRUDRepository, TReadDto, TEntity, TId>, ICRUDService<TCreateDto, TReadDto, TUpdateDto, TEntity, TId>
|
||||
where TCRUDRepository : ICRUDRepository<TEntity, TId> where TCreateDto : class where TReadDto : class where TUpdateDto : IUnique<TId> where TEntity : class, IUnique<TId>
|
||||
public class CRUDService<TCRUDRepository, TCreateDto, TReadDto, TEntity, TId> : ReadService<TCRUDRepository, TReadDto, TEntity, TId>, ICRUDService<TCreateDto, TReadDto, TEntity, TId>
|
||||
where TCRUDRepository : ICRUDRepository<TEntity, TId> where TCreateDto : class where TReadDto : class where TEntity : class, IUnique<TId>
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
@@ -45,7 +44,7 @@ namespace DigitalData.Core.Application
|
||||
/// </summary>
|
||||
/// <param name="updateDto">The DTO to update an entity from.</param>
|
||||
/// <returns>A service message indicating success or failure.</returns>
|
||||
public virtual async Task<Result> UpdateAsync(TUpdateDto updateDto)
|
||||
public virtual async Task<Result> UpdateAsync<TUpdateDto>(TUpdateDto updateDto) where TUpdateDto : IUnique<TId>
|
||||
{
|
||||
var currentEntitiy = await _repository.ReadByIdAsync(updateDto.Id);
|
||||
|
||||
|
||||
@@ -40,7 +40,6 @@ namespace DigitalData.Core.Application
|
||||
/// <typeparam name="TCRUDRepository">The repository type that provides CRUD operations for entities of type TEntity.</typeparam>
|
||||
/// <typeparam name="TCreateDto">The DTO type used for create operations.</typeparam>
|
||||
/// <typeparam name="TReadDto">The DTO type used for read operations.</typeparam>
|
||||
/// <typeparam name="TUpdateDto">The DTO type used for update operations.</typeparam>
|
||||
/// <typeparam name="TEntity">The entity type corresponding to the DTOs.</typeparam>
|
||||
/// <typeparam name="TId">The type of the entity's identifier.</typeparam>
|
||||
/// <typeparam name="TProfile">The AutoMapper profile type for configuring mappings between the DTOs and the entity.</typeparam>
|
||||
@@ -48,9 +47,9 @@ namespace DigitalData.Core.Application
|
||||
/// <param name="configureService">An optional action to configure additional services for the CRUD service.</param>
|
||||
/// <returns>The original <see cref="IServiceCollection"/> instance, allowing further configuration.</returns>
|
||||
public static IServiceCollection AddCleanCRUDService<TCRUDRepository, TCreateDto, TReadDto, TUpdateDto, TEntity, TId, TProfile>(this IServiceCollection services, Action<IServiceCollection>? configureService = null)
|
||||
where TCRUDRepository : ICRUDRepository<TEntity, TId> where TCreateDto : class where TReadDto : class where TUpdateDto : class, IUnique<TId> where TEntity : class, IUnique<TId> where TProfile : Profile
|
||||
where TCRUDRepository : ICRUDRepository<TEntity, TId> where TCreateDto : class where TReadDto : class, IUnique<TId> where TEntity : class, IUnique<TId> where TProfile : Profile
|
||||
{
|
||||
services.AddScoped<ICRUDService<TCreateDto, TReadDto, TUpdateDto, TEntity, TId>, CRUDService<TCRUDRepository, TCreateDto, TReadDto, TUpdateDto, TEntity, TId>>();
|
||||
services.AddScoped<ICRUDService<TCreateDto, TReadDto, TEntity, TId>, CRUDService<TCRUDRepository, TCreateDto, TReadDto, TEntity, TId>>();
|
||||
configureService?.Invoke(services);
|
||||
|
||||
services.AddAutoMapper(typeof(TProfile).Assembly);
|
||||
|
||||
@@ -14,7 +14,9 @@
|
||||
<PackageIcon>core_icon.png</PackageIcon>
|
||||
<RepositoryUrl>http://git.dd:3000/AppStd/WebCoreModules.git</RepositoryUrl>
|
||||
<PackageTags>digital data core application clean architecture</PackageTags>
|
||||
<Version>2.0.0.0</Version>
|
||||
<Version>3.0.1</Version>
|
||||
<AssemblyVersion>3.0.1</AssemblyVersion>
|
||||
<FileVersion>3.0.1</FileVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -10,8 +10,6 @@ namespace DigitalData.Core.Security
|
||||
{
|
||||
public IEnumerable<IRSADecryptor> Decryptors => _params.Decryptors;
|
||||
|
||||
public IEnumerable<IRSAEncryptor> Encryptors => _params.Encryptors;
|
||||
|
||||
public AsymCryptService(IOptions<TAsymCryptParams> options, ILogger<AsymCryptService<TAsymCryptParams>>? logger = null) : base(options)
|
||||
{
|
||||
logger?.LogInformation("Core.Secrets version: {Version}, Created on: {CreationDate}.", Secrets.Version, Secrets.CreationDate.ToString("dd.MM.yyyy"));
|
||||
|
||||
@@ -1,55 +1,53 @@
|
||||
using DigitalData.Core.Abstractions.Security;
|
||||
using DigitalData.Core.Security.Cryptographer;
|
||||
|
||||
namespace DigitalData.Core.Security.Config
|
||||
{
|
||||
public class AsymCryptParams : RSAFactoryParams
|
||||
{
|
||||
public string Directory { get; init; } = string.Empty;
|
||||
public string PemDirectory { get; init; } = string.Empty;
|
||||
|
||||
public string Separator { get; init; } = "_-_";
|
||||
|
||||
public IEnumerable<RSADecryptor> Decryptors { get; init; } = new List<RSADecryptor>();
|
||||
|
||||
/// <summary>
|
||||
/// 0: Issuer - 1: Audience - 2: Type tag - 3: Version
|
||||
/// 0: Issuer - 1: Audience - 2: Secret version (if is encrypted)
|
||||
/// </summary>
|
||||
public string FileNameFormat { get; init; } = "{0}_-_{1}_-_{2}_-_{3}.pem";
|
||||
private string CreateFileName(params object[] objs) => string.Join(Separator, objs);
|
||||
|
||||
public string EncryptorTag { get; init; } = "public";
|
||||
|
||||
public string DecryptorTag { get; init; } = "private";
|
||||
|
||||
public string EncryptedDecryptorTag { get; init; } = "enc-private";
|
||||
|
||||
public IEnumerable<IRSADecryptor> Decryptors { get; init; } = new List<IRSADecryptor>();
|
||||
|
||||
public IEnumerable<IRSAEncryptor> Encryptors { get; init; } = new List<IRSAEncryptor>();
|
||||
|
||||
private string TypeTagOf(IRSACryptographer crypt)
|
||||
{
|
||||
if (crypt is IRSAEncryptor)
|
||||
return EncryptorTag;
|
||||
else if (crypt is IRSADecryptor decryptor)
|
||||
return decryptor.Encrypt ? EncryptedDecryptorTag : DecryptorTag;
|
||||
else
|
||||
throw new InvalidOperationException(
|
||||
"Unknown cryptographer type. The crypt parameter must be either IRSAEncryptor or IRSADecryptor.");
|
||||
}
|
||||
private string CreatePem(bool isEncrypted) => isEncrypted
|
||||
? Instance.RSAFactory.CreateEncryptedPrivateKeyPem(keySizeInBits: KeySizeInBits, password: Secrets.PBE_PASSWORD,
|
||||
pbeEncryptionAlgorithm: PbeEncryptionAlgorithm, hashAlgorithmName: PbeHashAlgorithmName, iterationCount: PbeIterationCount)
|
||||
: Instance.RSAFactory.CreateRSAPrivateKeyPem(keySizeInBits: KeySizeInBits);
|
||||
|
||||
public override void OnDeserialized()
|
||||
{
|
||||
base.OnDeserialized();
|
||||
|
||||
var cryptographers = Encryptors.Cast<IRSACryptographer>().Concat(Decryptors.Cast<IRSACryptographer>());
|
||||
// Create root folder if it does not exist
|
||||
if (!Directory.Exists(PemDirectory))
|
||||
Directory.CreateDirectory(PemDirectory);
|
||||
|
||||
foreach (var crypt in cryptographers)
|
||||
foreach (var crypt in Decryptors)
|
||||
{
|
||||
// set default path
|
||||
if (crypt.Pem is null)
|
||||
if (crypt.IsPemNull)
|
||||
{
|
||||
crypt.Directory ??= Directory;
|
||||
crypt.FileName ??= string.Format(
|
||||
FileNameFormat,
|
||||
crypt.Issuer,
|
||||
crypt.Audience,
|
||||
TypeTagOf(crypt),
|
||||
Secrets.Version);
|
||||
var file_name_params = new List<object> { crypt.Issuer, crypt.Audience };
|
||||
if (crypt.Encrypt)
|
||||
file_name_params.Add(Secrets.Version);
|
||||
|
||||
var file_name = CreateFileName(file_name_params);
|
||||
var path = Path.Combine(PemDirectory, file_name);
|
||||
|
||||
if (File.Exists(path))
|
||||
crypt.SetPem(File.ReadAllText(path));
|
||||
else
|
||||
{
|
||||
var pem = CreatePem(crypt.Encrypt);
|
||||
crypt.SetPem(File.ReadAllText(pem));
|
||||
Task.Run(async () => await File.WriteAllTextAsync(path: path, pem));
|
||||
}
|
||||
}
|
||||
|
||||
crypt.Init();
|
||||
|
||||
@@ -10,16 +10,14 @@ namespace DigitalData.Core.Security.Cryptographer
|
||||
public string Pem
|
||||
{
|
||||
get => _pem
|
||||
?? throw new InvalidOperationException($"Pem is not initialized. Please ensure that the PEM is set or properly loaded from the file. Issuer: {Issuer}, Audience: {Audience}.");
|
||||
?? throw PemIsNullException;
|
||||
init => _pem = value;
|
||||
}
|
||||
|
||||
public string? PemPath => FileName is null ? null : Path.Combine(Directory ?? string.Empty, FileName);
|
||||
|
||||
public string? Directory { get; set; }
|
||||
|
||||
public string? FileName { get; set; }
|
||||
|
||||
internal bool IsPemNull => _pem is null;
|
||||
|
||||
private InvalidOperationException PemIsNullException => new($"Pem is not initialized. Please ensure that the PEM is set or properly loaded from the file. Issuer: {Issuer}, Audience: {Audience}.");
|
||||
|
||||
public RSAEncryptionPadding Padding { get; init; } = RSAEncryptionPadding.OaepSHA256;
|
||||
|
||||
protected virtual RSA RSA { get; } = RSA.Create();
|
||||
@@ -29,25 +27,13 @@ namespace DigitalData.Core.Security.Cryptographer
|
||||
public string Audience { get; init; } = string.Empty;
|
||||
|
||||
internal RSACryptographer() { }
|
||||
|
||||
public virtual void UnableToInitPemEvent() => throw new InvalidOperationException(
|
||||
$"Pem is not initialized and pem file is null. Issuer is {Issuer} and audience {Audience}.");
|
||||
|
||||
public virtual void FileNotFoundEvent() => throw new FileNotFoundException(
|
||||
$"Pem is not initialized and pem file is not found in {PemPath}. Issuer is {Issuer} and audience {Audience}.");
|
||||
internal void SetPem(string pem) => _pem = pem;
|
||||
|
||||
// TODO: make file read asynchronous, consider multiple routing
|
||||
public virtual void Init()
|
||||
{
|
||||
if(_pem is null)
|
||||
{
|
||||
if(PemPath is null)
|
||||
UnableToInitPemEvent();
|
||||
if (File.Exists(PemPath))
|
||||
_pem = File.ReadAllText(PemPath);
|
||||
else
|
||||
FileNotFoundEvent();
|
||||
}
|
||||
if (_pem is null)
|
||||
throw PemIsNullException;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,4 @@
|
||||
using DigitalData.Core.Abstractions.Security;
|
||||
using DigitalData.Core.Security.Config;
|
||||
using DigitalData.Core.Security.Extensions;
|
||||
using System.Security.Cryptography;
|
||||
|
||||
@@ -34,22 +33,5 @@ namespace DigitalData.Core.Security.Cryptographer
|
||||
else
|
||||
RSA.ImportFromPem(Pem);
|
||||
}
|
||||
|
||||
public override void FileNotFoundEvent()
|
||||
{
|
||||
var new_decryptor = new RSADecryptor()
|
||||
{
|
||||
Pem = RSAFactory<RSAFactoryParams>.Static.CreateRSAPrivateKeyPem(),
|
||||
Encrypt = Encrypt
|
||||
};
|
||||
|
||||
_pem = new_decryptor.Pem;
|
||||
|
||||
if (PemPath is not null)
|
||||
Task.Run(async () =>
|
||||
{
|
||||
await File.WriteAllTextAsync(_pem, PemPath);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,4 @@
|
||||
using DigitalData.Core.Abstractions.Security;
|
||||
using DigitalData.Core.Security.Config;
|
||||
using DigitalData.Core.Security.Extensions;
|
||||
|
||||
namespace DigitalData.Core.Security.Cryptographer
|
||||
@@ -17,21 +16,5 @@ namespace DigitalData.Core.Security.Cryptographer
|
||||
base.Init();
|
||||
RSA.ImportFromPem(base.Pem);
|
||||
}
|
||||
|
||||
public override void FileNotFoundEvent()
|
||||
{
|
||||
var new_decryptor = new RSADecryptor()
|
||||
{
|
||||
Pem = RSAFactory<RSAFactoryParams>.Static.CreateRSAPrivateKeyPem()
|
||||
};
|
||||
|
||||
_pem = new_decryptor.Encryptor.Pem;
|
||||
|
||||
if (PemPath is not null)
|
||||
Task.Run(async () =>
|
||||
{
|
||||
await File.WriteAllTextAsync(_pem, PemPath);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,10 +7,6 @@ namespace DigitalData.Core.Security.Cryptographer
|
||||
{
|
||||
public class RSAFactory<TRSAFactoryParams> : IRSAFactory<TRSAFactoryParams> where TRSAFactoryParams : RSAFactoryParams
|
||||
{
|
||||
private static readonly Lazy<RSAFactory<RSAFactoryParams>> LazyInstance = new(() => new(Options.Create<RSAFactoryParams>(new())));
|
||||
|
||||
public static RSAFactory<RSAFactoryParams> Static => LazyInstance.Value;
|
||||
|
||||
protected readonly TRSAFactoryParams _params;
|
||||
|
||||
public RSAFactory(IOptions<TRSAFactoryParams> options) => _params = options.Value;
|
||||
|
||||
@@ -3,7 +3,6 @@ using DigitalData.Core.Security.Config;
|
||||
using DigitalData.Core.Security.Cryptographer;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.DependencyInjection.Extensions;
|
||||
using Microsoft.Extensions.Options;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
@@ -21,35 +20,85 @@ namespace DigitalData.Core.Security
|
||||
options.Converters.Add(new JsonStringEnumConverter());
|
||||
return options;
|
||||
}
|
||||
|
||||
private static IServiceCollection AddAsymCryptService<TAsymCryptParams>(this IServiceCollection services, bool setAsDefault = false) where TAsymCryptParams : AsymCryptParams
|
||||
=> setAsDefault
|
||||
? services.AddScoped<IAsymCryptService, AsymCryptService<TAsymCryptParams>>()
|
||||
: services.AddScoped<IAsymCryptService<TAsymCryptParams>, AsymCryptService<TAsymCryptParams>>();
|
||||
|
||||
private static IServiceCollection AddAsymCryptService<TAsymCryptParams>(this IServiceCollection services)
|
||||
/// <summary>
|
||||
/// Registers a custom asym crypt service with specified parameters from the given configuration section.
|
||||
/// </summary>
|
||||
/// <typeparam name="TAsymCryptParams"></typeparam>
|
||||
/// <param name="services"></param>
|
||||
/// <param name="section"></param>
|
||||
/// <param name="setAsDefault">If true, the factory is registered as the default <see cref="IRSAFactory"/>. Otherwise, it is registered as <see cref="IRSAFactory{TRSAFactoryParams}"/>.</param>
|
||||
/// <returns></returns>
|
||||
public static IServiceCollection AddAsymCryptService<TAsymCryptParams>(this IServiceCollection services, IConfigurationSection section, bool setAsDefault = false)
|
||||
where TAsymCryptParams : AsymCryptParams
|
||||
{
|
||||
services.TryAddScoped<IAsymCryptService<TAsymCryptParams>, AsymCryptService<TAsymCryptParams>>();
|
||||
return services;
|
||||
}
|
||||
=> services.Configure<TAsymCryptParams>(section).AddAsymCryptService<TAsymCryptParams>(setAsDefault: setAsDefault);
|
||||
|
||||
public static IServiceCollection AddAsymCryptService<TAsymCryptParams>(this IServiceCollection services, IConfigurationSection section)
|
||||
/// <summary>
|
||||
/// Registers an asym crypt service with the specified parameters from the given instance. Optionally, sets it as the default factory.
|
||||
/// </summary>
|
||||
/// <typeparam name="TAsymCryptParams"></typeparam>
|
||||
/// <param name="services"></param>
|
||||
/// <param name="param"></param>
|
||||
/// <param name="setAsDefault">If true, the factory is registered as the default <see cref="IRSAFactory"/>. Otherwise, it is registered as <see cref="IRSAFactory{TRSAFactoryParams}"/>.</param>
|
||||
/// <returns></returns>
|
||||
public static IServiceCollection AddAsymCryptService<TAsymCryptParams>(this IServiceCollection services, TAsymCryptParams param, bool setAsDefault = false)
|
||||
where TAsymCryptParams : AsymCryptParams
|
||||
=> services.Configure<TAsymCryptParams>(section).AddAsymCryptService<TAsymCryptParams>();
|
||||
=> services.AddSingleton(Options.Create(param)).AddAsymCryptService<TAsymCryptParams>(setAsDefault: setAsDefault);
|
||||
|
||||
public static IServiceCollection AddAsymCryptService<TAsymCryptParams>(this IServiceCollection services, TAsymCryptParams param)
|
||||
where TAsymCryptParams : AsymCryptParams
|
||||
=> services.AddSingleton(Options.Create(param)).AddAsymCryptService<TAsymCryptParams>();
|
||||
/// <summary>
|
||||
/// Registers default asym crypt service with the specified parameters from the given instance.
|
||||
/// </summary>
|
||||
/// <param name="services"></param>
|
||||
/// <param name="param"></param>
|
||||
/// <returns></returns>
|
||||
public static IServiceCollection AddAsymCryptService(this IServiceCollection services, AsymCryptParams param) => services.AddAsymCryptService(param: param, setAsDefault: true);
|
||||
|
||||
private static IServiceCollection AddRSAFactory<TRSAFactoryParams>(this IServiceCollection services)
|
||||
/// <summary>
|
||||
/// Registers default RSA Factory instance with default params
|
||||
/// </summary>
|
||||
/// <param name="services"></param>
|
||||
/// <param name="factoryParams"></param>
|
||||
/// <returns>The updated <see cref="IServiceCollection"/> with the RSA Factory registered.</returns>
|
||||
public static IServiceCollection AddRSAFactory(this IServiceCollection services, RSAFactoryParams? factoryParams = null)
|
||||
=> services.AddScoped<IRSAFactory>(_ => new RSAFactory<RSAFactoryParams>(Options.Create(factoryParams ?? new())));
|
||||
|
||||
/// <summary>
|
||||
/// Registers a custom RSA Factory with specified parameters from the given configuration section.
|
||||
/// </summary>
|
||||
/// <typeparam name="TRSAFactoryParams"></typeparam>
|
||||
/// <param name="services"></param>
|
||||
/// <param name="section"></param>
|
||||
/// <param name="setAsDefault">If true, the factory is registered as the default <see cref="IRSAFactory"/>. Otherwise, it is registered as <see cref="IRSAFactory{TRSAFactoryParams}"/>.</param>
|
||||
/// <returns>The updated <see cref="IServiceCollection"/> with the RSA Factory registered.</returns>
|
||||
public static IServiceCollection AddRSAFactory<TRSAFactoryParams>(this IServiceCollection services, IConfigurationSection section, bool setAsDefault = false)
|
||||
where TRSAFactoryParams : RSAFactoryParams
|
||||
{
|
||||
services.TryAddScoped<IRSAFactory<TRSAFactoryParams>, RSAFactory<TRSAFactoryParams>>();
|
||||
return services;
|
||||
services.Configure<TRSAFactoryParams>(section);
|
||||
return setAsDefault
|
||||
? services.AddSingleton<IRSAFactory, RSAFactory<TRSAFactoryParams>>()
|
||||
: services.AddSingleton<IRSAFactory<TRSAFactoryParams>, RSAFactory<TRSAFactoryParams>>();
|
||||
}
|
||||
|
||||
public static IServiceCollection AddRSAFactory<TRSAFactoryParams>(this IServiceCollection services, IConfigurationSection section)
|
||||
/// <summary>
|
||||
/// Registers an RSA Factory with the specified parameters from the given instance. Optionally, sets it as the default factory.
|
||||
/// </summary>
|
||||
/// <typeparam name="TRSAFactoryParams">The type of the RSA factory parameters.</typeparam>
|
||||
/// <param name="services"></param>
|
||||
/// <param name="rsaParams"></param>
|
||||
/// <param name="setAsDefault">If true, the factory is registered as the default <see cref="IRSAFactory"/>. Otherwise, it is registered as <see cref="IRSAFactory{TRSAFactoryParams}"/>.</param>
|
||||
/// <returns>The updated <see cref="IServiceCollection"/> with the RSA Factory registered.</returns>
|
||||
public static IServiceCollection AddRSAFactory<TRSAFactoryParams>(this IServiceCollection services, TRSAFactoryParams rsaParams, bool setAsDefault = false)
|
||||
where TRSAFactoryParams : RSAFactoryParams
|
||||
=> services.Configure<TRSAFactoryParams>(section).AddRSAFactory<TRSAFactoryParams>();
|
||||
|
||||
public static IServiceCollection AddRSAFactory<TRSAFactoryParams>(this IServiceCollection services, TRSAFactoryParams param)
|
||||
where TRSAFactoryParams : RSAFactoryParams
|
||||
=> services.AddSingleton(Options.Create(param)).AddRSAFactory<TRSAFactoryParams>();
|
||||
{
|
||||
services.AddSingleton(Options.Create(rsaParams));
|
||||
return setAsDefault
|
||||
? services.AddSingleton<IRSAFactory, RSAFactory<TRSAFactoryParams>>()
|
||||
: services.AddSingleton<IRSAFactory<TRSAFactoryParams>, RSAFactory<TRSAFactoryParams>>();
|
||||
}
|
||||
}
|
||||
}
|
||||
14
DigitalData.Core.Security/Instance.cs
Normal file
14
DigitalData.Core.Security/Instance.cs
Normal file
@@ -0,0 +1,14 @@
|
||||
using DigitalData.Core.Abstractions.Security;
|
||||
using DigitalData.Core.Security.Config;
|
||||
using DigitalData.Core.Security.Cryptographer;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
namespace DigitalData.Core.Security
|
||||
{
|
||||
public static class Instance
|
||||
{
|
||||
private static readonly Lazy<RSAFactory<RSAFactoryParams>> LazyInstance = new(() => new(Options.Create<RSAFactoryParams>(new())));
|
||||
|
||||
public static IRSAFactory RSAFactory => LazyInstance.Value;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user