From 0154cfcc99d4bbf060586e760d34408f97c4f9dc Mon Sep 17 00:00:00 2001 From: Dion Date: Sun, 13 Oct 2024 10:26:18 +0200 Subject: [PATCH] code format && add comments --- .../DataProtection/SqlXmlRepository.cs | 167 ++++++++++-------- 1 file changed, 90 insertions(+), 77 deletions(-) diff --git a/starsky/starsky.foundation.database/DataProtection/SqlXmlRepository.cs b/starsky/starsky.foundation.database/DataProtection/SqlXmlRepository.cs index 95a5232265..8590784986 100644 --- a/starsky/starsky.foundation.database/DataProtection/SqlXmlRepository.cs +++ b/starsky/starsky.foundation.database/DataProtection/SqlXmlRepository.cs @@ -3,9 +3,11 @@ using System.Linq; using System.Xml.Linq; using Microsoft.AspNetCore.DataProtection.Repositories; +using Microsoft.Data.Sqlite; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Storage; using Microsoft.Extensions.DependencyInjection; +using MySqlConnector; using starsky.foundation.database.Data; using starsky.foundation.database.Models; using starsky.foundation.database.Query; @@ -13,106 +15,117 @@ using starsky.foundation.platform.Helpers; using starsky.foundation.platform.Interfaces; -namespace starsky.foundation.database.DataProtection +namespace starsky.foundation.database.DataProtection; + +/// +/// @see: +/// https://nicolas.guelpa.me/blog/2017/01/11/dotnet-core-data-protection-keys-repository.html +/// @see: +/// https://docs.microsoft.com/en-us/aspnet/core/security/data-protection/introduction?view=aspnetcore-5.0 +/// @see: +/// https://medium.com/@_kbremner/storing-asp-net-core-data-protection-keys-in-the-database-f284d13897b8 +/// @see: https://docs.microsoft.com/en-us/aspnet/core/host-and-deploy/web-farm +/// +[Service(typeof(IXmlRepository), InjectionLifetime = InjectionLifetime.Scoped)] +public class SqlXmlRepository : IXmlRepository { - [Service(typeof(IXmlRepository), InjectionLifetime = InjectionLifetime.Scoped)] - public class SqlXmlRepository : IXmlRepository + private readonly ApplicationDbContext _dbContext; + private readonly IWebLogger _logger; + private readonly IServiceScopeFactory _scopeFactory; + + public SqlXmlRepository(ApplicationDbContext dbContext, IServiceScopeFactory scopeFactory, + IWebLogger logger) { - private readonly ApplicationDbContext _dbContext; - private readonly IServiceScopeFactory _scopeFactory; - private readonly IWebLogger _logger; + _dbContext = dbContext; + _scopeFactory = scopeFactory; + _logger = logger; + } - public SqlXmlRepository(ApplicationDbContext dbContext, IServiceScopeFactory scopeFactory, IWebLogger logger) + public IReadOnlyCollection GetAllElements() + { + try { - _dbContext = dbContext; - _scopeFactory = scopeFactory; - _logger = logger; - } + var result = _dbContext.DataProtectionKeys + .Where(p => p.Xml != null).AsEnumerable() + .Select(x => XElement.Parse(x.Xml!)).ToList(); - public IReadOnlyCollection GetAllElements() + return result; + } + catch ( Exception exception ) { - try + if ( exception is not RetryLimitExceededException && + exception is not MySqlException && + exception is not SqliteException ) { - var result = _dbContext.DataProtectionKeys - .Where(p => p.Xml != null).AsEnumerable() - .Select(x => XElement.Parse(x.Xml!)).ToList(); - - return result; + throw; } - catch ( Exception exception ) - { - if ( exception is not RetryLimitExceededException && - exception is not MySqlConnector.MySqlException && - exception is not Microsoft.Data.Sqlite.SqliteException ) - { - throw; - } - - // MySqlConnector.MySqlException (0x80004005): Table 'starsky.DataProtectionKeys' doesn't exist - // or Microsoft.Data.Sqlite.SqliteException (0x80004005): SQLite Error 1: 'no such table: DataProtectionKeys - if ( !exception.Message.Contains("0x80004005") && - !exception.Message.Contains( - "no such table: DataProtectionKeys") ) - { - return new List(); - } - _logger.LogInformation("run migration: dotnet ef database update"); - _dbContext.Database.Migrate(); + // MySqlConnector.MySqlException (0x80004005): Table 'starsky.DataProtectionKeys' doesn't exist + // or Microsoft.Data.Sqlite.SqliteException (0x80004005): SQLite Error 1: 'no such table: DataProtectionKeys + if ( !exception.Message.Contains("0x80004005") && + !exception.Message.Contains( + "no such table: DataProtectionKeys") ) + { return new List(); } + + _logger.LogInformation("run migration: dotnet ef database update"); + _dbContext.Database.Migrate(); + return new List(); } + } - /// - /// This function crashes usually on the first run - /// - /// Xml element - /// name of item - public void StoreElement(XElement element, string friendlyName) + /// + /// This function crashes usually on the first run + /// + /// Xml element + /// name of item + public void StoreElement(XElement element, string friendlyName) + { + bool LocalDefault(ApplicationDbContext ctx) { - bool LocalDefault(ApplicationDbContext ctx) + ctx.DataProtectionKeys.Add(new DataProtectionKey { - ctx.DataProtectionKeys.Add(new DataProtectionKey - { - Xml = element.ToString(SaveOptions.DisableFormatting), - FriendlyName = friendlyName - }); - ctx.SaveChanges(); - return true; - } + Xml = element.ToString(SaveOptions.DisableFormatting), + FriendlyName = friendlyName + }); + ctx.SaveChanges(); + return true; + } + + bool LocalDefaultQuery() + { + var context = new InjectServiceScope(_scopeFactory).Context(); + return LocalDefault(context); + } - bool LocalDefaultQuery() + try + { + LocalDefault(_dbContext); + } + catch ( Exception exception ) + { + if ( exception is not DbUpdateException && + exception is not RetryLimitExceededException && + exception is not MySqlException && + exception is not SqliteException ) { - var context = new InjectServiceScope(_scopeFactory).Context(); - return LocalDefault(context); + throw; } + var retryInterval = _dbContext.GetType().FullName?.Contains("test") == true + ? TimeSpan.FromSeconds(0) + : TimeSpan.FromSeconds(5); + try { - LocalDefault(_dbContext); + RetryHelper.Do( + LocalDefaultQuery, retryInterval, 2); } - catch ( Exception exception ) + catch ( AggregateException aggregateException ) { - if ( exception is not DbUpdateException && - exception is not RetryLimitExceededException && - exception is not MySqlConnector.MySqlException && - exception is not Microsoft.Data.Sqlite.SqliteException ) - { - throw; - } - - var retryInterval = _dbContext.GetType().FullName?.Contains("test") == true ? - TimeSpan.FromSeconds(0) : TimeSpan.FromSeconds(5); - - try - { - RetryHelper.Do( - LocalDefaultQuery, retryInterval, 2); - } - catch ( AggregateException aggregateException ) - { - _logger.LogError(aggregateException, "[SqlXmlRepository] catch-ed AggregateException"); - } + _logger.LogError(aggregateException, + "[SqlXmlRepository] catch-ed AggregateException"); } } }