diff --git a/Directory.Packages.props b/Directory.Packages.props index 0f31e32..806b335 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -8,6 +8,7 @@ + diff --git a/src/AppServices/AppServices.csproj b/src/AppServices/AppServices.csproj index abb3a5a..7813edf 100644 --- a/src/AppServices/AppServices.csproj +++ b/src/AppServices/AppServices.csproj @@ -11,6 +11,7 @@ + @@ -22,7 +23,6 @@ - diff --git a/src/AppServices/Notifications/NotificationService.cs b/src/AppServices/Notifications/NotificationService.cs index 3c99644..e204d44 100644 --- a/src/AppServices/Notifications/NotificationService.cs +++ b/src/AppServices/Notifications/NotificationService.cs @@ -1,5 +1,5 @@ using GaEpd.EmailService; -using GaEpd.EmailService.Repository; +using GaEpd.EmailService.EmailLogRepository; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Hosting; using MyApp.AppServices.ErrorLogging; @@ -39,7 +39,7 @@ public async Task SendNotificationAsync(Template template, s Message message; try { - message = Message.Create(subject, recipientEmail, settings.DefaultSender, textBody, htmlBody); + message = Message.Create(subject, recipientEmail, textBody, htmlBody); } catch (Exception e) { @@ -47,7 +47,7 @@ public async Task SendNotificationAsync(Template template, s return NotificationResult.FailureResult($"{FailurePrefix} An error occurred when generating the email."); } - if (settings.SaveEmail) await repository.InsertAsync(EmailLog.Create(message), token).ConfigureAwait(false); + if (settings.EnableEmailLog) await repository.InsertAsync(message, token).ConfigureAwait(false); if (settings is { EnableEmail: false, EnableEmailAuditing: false }) { @@ -56,7 +56,7 @@ public async Task SendNotificationAsync(Template template, s try { - await emailService.SendEmailAsync(message, settings, token).ConfigureAwait(false); + _ = emailService.SendEmailAsync(message, token).ConfigureAwait(false); } catch (Exception e) { diff --git a/src/AppServices/RegisterServices/AutoMapperProfiles.cs b/src/AppServices/RegisterServices/AutoMapperProfiles.cs index a14fa6a..14c9142 100644 --- a/src/AppServices/RegisterServices/AutoMapperProfiles.cs +++ b/src/AppServices/RegisterServices/AutoMapperProfiles.cs @@ -5,9 +5,7 @@ namespace MyApp.AppServices.RegisterServices; public static class AutoMapperProfiles { - public static void AddAutoMapperProfiles(this IServiceCollection services) - { - // Add AutoMapper profiles + // Add AutoMapper profiles + public static IServiceCollection AddAutoMapperProfiles(this IServiceCollection services) => services.AddAutoMapper(expression => expression.AddProfile()); - } } diff --git a/src/AppServices/RegisterServices/RegisterAppServices.cs b/src/AppServices/RegisterServices/RegisterAppServices.cs index d4fbd0e..2ce28d3 100644 --- a/src/AppServices/RegisterServices/RegisterAppServices.cs +++ b/src/AppServices/RegisterServices/RegisterAppServices.cs @@ -14,7 +14,7 @@ namespace MyApp.AppServices.RegisterServices; public static class RegisterAppServices { - public static void AddAppServices(this IServiceCollection services) + public static IServiceCollection AddAppServices(this IServiceCollection services) { // Work Entries services.AddScoped(); @@ -27,8 +27,7 @@ public static void AddAppServices(this IServiceCollection services) services.AddScoped(); services.AddScoped(); - // Email - services.AddTransient(); + // Notifications services.AddScoped(); // Offices @@ -37,5 +36,7 @@ public static void AddAppServices(this IServiceCollection services) // Data Export services.AddScoped(); + + return services; } } diff --git a/src/AppServices/RegisterServices/Validators.cs b/src/AppServices/RegisterServices/Validators.cs index c75bd03..4732837 100644 --- a/src/AppServices/RegisterServices/Validators.cs +++ b/src/AppServices/RegisterServices/Validators.cs @@ -6,6 +6,6 @@ namespace MyApp.AppServices.RegisterServices; public static class Validators { // Add all validators - public static void AddValidators(this IServiceCollection services) => + public static IServiceCollection AddValidators(this IServiceCollection services) => services.AddValidatorsFromAssemblyContaining(typeof(Validators)); } diff --git a/src/EfRepository/DbContext/AppDbContext.cs b/src/EfRepository/DbContext/AppDbContext.cs index 7cc33f1..f05b445 100644 --- a/src/EfRepository/DbContext/AppDbContext.cs +++ b/src/EfRepository/DbContext/AppDbContext.cs @@ -1,4 +1,4 @@ -using GaEpd.EmailService.Repository; +using GaEpd.EmailService.EmailLogRepository; using Microsoft.AspNetCore.Identity.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; using MyApp.Domain.Entities.EntryActions; diff --git a/src/EfRepository/Repositories/EmailLogRepository.cs b/src/EfRepository/Repositories/EmailLogRepository.cs index da9334b..10fe66c 100644 --- a/src/EfRepository/Repositories/EmailLogRepository.cs +++ b/src/EfRepository/Repositories/EmailLogRepository.cs @@ -1,12 +1,19 @@ -using GaEpd.EmailService.Repository; +using GaEpd.EmailService; +using GaEpd.EmailService.EmailLogRepository; +using Microsoft.Extensions.Configuration; using MyApp.EfRepository.DbContext; namespace MyApp.EfRepository.Repositories; -public sealed class EmailLogRepository(AppDbContext dbContext) : IEmailLogRepository +public sealed class EmailLogRepository(AppDbContext dbContext, IConfiguration configuration) : IEmailLogRepository { - public async Task InsertAsync(EmailLog emailLog, CancellationToken token = default) + public async Task InsertAsync(Message message, CancellationToken token = default) { + var settings = new EmailServiceSettings(); + configuration.GetSection(nameof(EmailServiceSettings)).Bind(settings); + if (!settings.EnableEmailLog) return; + + var emailLog = EmailLog.Create(message); await dbContext.EmailLogs.AddAsync(emailLog, token).ConfigureAwait(false); await dbContext.SaveChangesAsync(token).ConfigureAwait(false); } diff --git a/src/EmailService/EmailService.cs b/src/EmailService/EmailService.cs deleted file mode 100644 index e269fb5..0000000 --- a/src/EmailService/EmailService.cs +++ /dev/null @@ -1,65 +0,0 @@ -using GaEpd.EmailService.Utilities; -using MailKit.Net.Smtp; -using MailKit.Security; -using MimeKit; - -namespace GaEpd.EmailService; - -public class EmailService : IEmailService -{ - public async Task SendEmailAsync(Message message, EmailServiceSettings settings, CancellationToken token = default) - { - if (settings is { EnableEmail: false, EnableEmailAuditing: false }) return; - - var emailMessage = new MimeMessage(); - emailMessage.From.Add(new MailboxAddress(string.Empty, message.Sender)); - emailMessage.Cc.AddRange(message.CopyRecipients.Select(address => new MailboxAddress(string.Empty, address))); - emailMessage.Subject = message.Subject; - - if (settings.EnableEmail && message.Recipients.Count > 0) - { - emailMessage.To.AddRange(message.Recipients.Select(address => new MailboxAddress(string.Empty, address))); - - var builder = new BodyBuilder - { - TextBody = message.TextBody, - HtmlBody = message.HtmlBody - }; - emailMessage.Body = builder.ToMessageBody(); - - await SendEmailMessageAsync(emailMessage, settings, token).ConfigureAwait(false); - } - - if (settings is { EnableEmailAuditing: true, AuditEmailRecipients.Count: > 0 }) - { - emailMessage.Cc.Clear(); - emailMessage.To.Clear(); - emailMessage.To.AddRange(settings.AuditEmailRecipients - .Select(address => new MailboxAddress(string.Empty, address))); - - const string auditText = "This is a copy of the original email for auditing purposes. Original recipient: "; - var auditBuilder = new BodyBuilder - { - TextBody = string.Concat(auditText, message.Recipients.ConcatWithSeparator(", "), Environment.NewLine, - Environment.NewLine, message.TextBody), - HtmlBody = string.Concat($"{auditText}{message.Recipients.ConcatWithSeparator(", ")}

", - message.HtmlBody) - }; - emailMessage.Body = auditBuilder.ToMessageBody(); - - await SendEmailMessageAsync(emailMessage, settings, token).ConfigureAwait(false); - } - } - - private static async Task SendEmailMessageAsync(MimeMessage emailMessage, EmailServiceSettings settings, - CancellationToken token) - { - if (!Enum.TryParse(settings.SecureSocketOption, out SecureSocketOptions secureSocketOption)) - secureSocketOption = SecureSocketOptions.Auto; - using var client = new SmtpClient(); - await client.ConnectAsync(settings.SmtpHost, settings.SmtpPort, secureSocketOption, token) - .ConfigureAwait(false); - await client.SendAsync(emailMessage, token).ConfigureAwait(false); - await client.DisconnectAsync(true, token).ConfigureAwait(false); - } -} diff --git a/src/EmailService/EmailService.csproj b/src/EmailService/EmailService.csproj deleted file mode 100644 index d09bc66..0000000 --- a/src/EmailService/EmailService.csproj +++ /dev/null @@ -1,16 +0,0 @@ - - - - net9.0 - enable - enable - GaEpd.EmailService - - - - - - - - - diff --git a/src/EmailService/EmailService.csproj.DotSettings b/src/EmailService/EmailService.csproj.DotSettings deleted file mode 100644 index 89316e4..0000000 --- a/src/EmailService/EmailService.csproj.DotSettings +++ /dev/null @@ -1,2 +0,0 @@ - - Library \ No newline at end of file diff --git a/src/EmailService/EmailServiceSettings.cs b/src/EmailService/EmailServiceSettings.cs deleted file mode 100644 index d4b2533..0000000 --- a/src/EmailService/EmailServiceSettings.cs +++ /dev/null @@ -1,13 +0,0 @@ -namespace GaEpd.EmailService; - -public class EmailServiceSettings -{ - public bool EnableEmail { get; init; } - public bool SaveEmail { get; init; } - public string SmtpHost { get; init; } = null!; - public int SmtpPort { get; init; } - public string DefaultSender { get; init; } = null!; - public string SecureSocketOption { get; init; } = null!; - public bool EnableEmailAuditing { get; init; } - public List AuditEmailRecipients { get; init; } = null!; -} diff --git a/src/EmailService/IEmailService.cs b/src/EmailService/IEmailService.cs deleted file mode 100644 index e96a1ac..0000000 --- a/src/EmailService/IEmailService.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace GaEpd.EmailService; - -public interface IEmailService -{ - Task SendEmailAsync(Message message, EmailServiceSettings settings, CancellationToken token = default); -} diff --git a/src/EmailService/Message.cs b/src/EmailService/Message.cs deleted file mode 100644 index 3b9e6b9..0000000 --- a/src/EmailService/Message.cs +++ /dev/null @@ -1,44 +0,0 @@ -namespace GaEpd.EmailService; - -public record Message -{ - public string Sender { get; private set; } = string.Empty; - public string Subject { get; private set; } = string.Empty; - public List Recipients { get; } = []; - public List CopyRecipients { get; } = []; - public string? TextBody { get; private set; } - public string? HtmlBody { get; private set; } - - public static Message Create(string subject, string recipient, string sender, string? textBody, string? htmlBody, - IEnumerable? copyRecipients = null) => - Create(subject, [recipient], sender, textBody, htmlBody, copyRecipients); - - public static Message Create(string subject, ICollection recipients, string sender, string? textBody, - string? htmlBody, IEnumerable? copyRecipients = null) - { - if(string.IsNullOrWhiteSpace(subject)) - throw new ArgumentException("A subject must be provided.", nameof(subject)); - - if (recipients.Count == 0) - throw new ArgumentException("At least one recipient must be specified.", nameof(recipients)); - - if (recipients.Any(string.IsNullOrEmpty)) - throw new ArgumentException("Recipient cannot be null, empty, or white space.", nameof(recipients)); - - if (string.IsNullOrEmpty(htmlBody) && string.IsNullOrEmpty(textBody)) - throw new ArgumentException("Either a plaintext or HTML body must be provided.", nameof(htmlBody)); - - var message = new Message - { - Sender = sender, - Subject = subject, - TextBody = textBody, - HtmlBody = htmlBody, - }; - - message.Recipients.AddRange(recipients); - if (copyRecipients != null) message.CopyRecipients.AddRange(copyRecipients); - - return message; - } -} diff --git a/src/EmailService/Properties/AssemblyInfo.cs b/src/EmailService/Properties/AssemblyInfo.cs deleted file mode 100644 index 948f7d1..0000000 --- a/src/EmailService/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,3 +0,0 @@ -using System.Runtime.CompilerServices; - -[assembly: InternalsVisibleTo("EmailServiceTests")] diff --git a/src/EmailService/Repository/EmailLog.cs b/src/EmailService/Repository/EmailLog.cs deleted file mode 100644 index 1e27152..0000000 --- a/src/EmailService/Repository/EmailLog.cs +++ /dev/null @@ -1,42 +0,0 @@ -using GaEpd.EmailService.Utilities; -using System.ComponentModel.DataAnnotations; - -namespace GaEpd.EmailService.Repository; - -public record EmailLog -{ - [Key] - public required Guid Id { get; init; } - - public DateTimeOffset? CreatedAt { get; init; } - - [StringLength(200)] - public required string Sender { get; init; } - - [StringLength(200)] - public required string Subject { get; init; } - - [StringLength(2000)] - public required string Recipients { get; init; } - - [StringLength(2000)] - public string? CopyRecipients { get; init; } - - [StringLength(15_000)] - public string? TextBody { get; init; } - - [StringLength(20_000)] - public string? HtmlBody { get; init; } - - public static EmailLog Create(Message message) => new() - { - Id = Guid.NewGuid(), - Sender = message.Sender.Truncate(200), - Subject = message.Subject.Truncate(200), - Recipients = message.Recipients.ConcatWithSeparator(",").Truncate(2000), - CopyRecipients = message.CopyRecipients.ConcatWithSeparator(",").Truncate(2000), - TextBody = message.TextBody.Truncate(15_000), - HtmlBody = message.HtmlBody.Truncate(20_000), - CreatedAt = DateTimeOffset.Now, - }; -} diff --git a/src/EmailService/Repository/IEmailLogRepository.cs b/src/EmailService/Repository/IEmailLogRepository.cs deleted file mode 100644 index 5953609..0000000 --- a/src/EmailService/Repository/IEmailLogRepository.cs +++ /dev/null @@ -1,12 +0,0 @@ -namespace GaEpd.EmailService.Repository; - -public interface IEmailLogRepository : IDisposable, IAsyncDisposable -{ - /// - /// Inserts a new . - /// - /// The Email Log to insert. - /// - /// - Task InsertAsync(EmailLog emailLog, CancellationToken token = default); -} diff --git a/src/EmailService/Utilities/StringExtensions.cs b/src/EmailService/Utilities/StringExtensions.cs deleted file mode 100644 index 4d6ae1a..0000000 --- a/src/EmailService/Utilities/StringExtensions.cs +++ /dev/null @@ -1,21 +0,0 @@ -using System.Diagnostics.CodeAnalysis; - -namespace GaEpd.EmailService.Utilities; - -internal static class StringExtensions -{ - public static string ConcatWithSeparator(this IEnumerable items, string separator = " ") => - string.Join(separator, items.Where(s => !string.IsNullOrEmpty(s))); - - [return: NotNullIfNotNull(nameof(value))] - public static string? Truncate(this string? value, int maxLength, string suffix = "…") - { - if (maxLength < 0) throw new ArgumentException("maxLength must not be negative.", nameof(maxLength)); - if (value is null) return null; - if (string.IsNullOrEmpty(value) || maxLength == 0) return string.Empty; - if (value.Length <= maxLength) return value; - return maxLength < suffix.Length - ? value[..maxLength] - : $"{value[..(maxLength - suffix.Length)]}{suffix}"; - } -} diff --git a/src/LocalRepository/Repositories/LocalEmailLogRepository.cs b/src/LocalRepository/Repositories/LocalEmailLogRepository.cs index 77d6945..10e61bc 100644 --- a/src/LocalRepository/Repositories/LocalEmailLogRepository.cs +++ b/src/LocalRepository/Repositories/LocalEmailLogRepository.cs @@ -1,10 +1,11 @@ -using GaEpd.EmailService.Repository; +using GaEpd.EmailService; +using GaEpd.EmailService.EmailLogRepository; namespace MyApp.LocalRepository.Repositories; public sealed class LocalEmailLogRepository : IEmailLogRepository { - public Task InsertAsync(EmailLog emailLog, CancellationToken token = default) => Task.CompletedTask; + public Task InsertAsync(Message message, CancellationToken token = default) => Task.CompletedTask; public void Dispose() { diff --git a/src/WebApp/Platform/AppConfiguration/DataPersistence.cs b/src/WebApp/Platform/AppConfiguration/DataPersistence.cs index b1e8eed..717ea95 100644 --- a/src/WebApp/Platform/AppConfiguration/DataPersistence.cs +++ b/src/WebApp/Platform/AppConfiguration/DataPersistence.cs @@ -1,4 +1,4 @@ -using GaEpd.EmailService.Repository; +using GaEpd.EmailService.EmailLogRepository; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Diagnostics; using MyApp.Domain.Entities.EntryActions; @@ -15,20 +15,22 @@ namespace MyApp.WebApp.Platform.AppConfiguration; public static class DataPersistence { - public static void AddDataPersistence(this IServiceCollection services, ConfigurationManager configuration, + public static IServiceCollection AddDataPersistence(this IServiceCollection services, + ConfigurationManager configuration, IWebHostEnvironment environment) { // When configured, use in-memory data; otherwise use a SQL Server database. if (AppSettings.DevSettings.UseInMemoryData) { // Use in-memory data for all repositories. - services.AddSingleton(); - services.AddSingleton(); - services.AddSingleton(); - services.AddSingleton(); - services.AddSingleton(); + services + .AddSingleton() + .AddSingleton() + .AddSingleton() + .AddSingleton() + .AddSingleton(); - return; + return services; } // When in-memory data is disabled, use a database connection. @@ -47,7 +49,7 @@ public static void AddDataPersistence(this IServiceCollection services, Configur dbBuilder .UseSqlServer(connectionString, sqlServerOpts => sqlServerOpts.EnableRetryOnFailure()) .ConfigureWarnings(builder => builder.Throw(RelationalEventId.MultipleCollectionIncludeWarning)); - + if (environment.IsDevelopment()) dbBuilder.EnableSensitiveDataLogging(); }); @@ -57,10 +59,13 @@ public static void AddDataPersistence(this IServiceCollection services, Configur } // Repositories - services.AddScoped(); - services.AddScoped(); - services.AddScoped(); - services.AddScoped(); - services.AddScoped(); + services + .AddScoped() + .AddScoped() + .AddScoped() + .AddScoped() + .AddScoped(); + + return services; } } diff --git a/src/WebApp/Program.cs b/src/WebApp/Program.cs index 2612545..bc8813a 100644 --- a/src/WebApp/Program.cs +++ b/src/WebApp/Program.cs @@ -1,3 +1,4 @@ +using GaEpd.EmailService.Utilities; using GaEpd.FileService; using Microsoft.AspNetCore.DataProtection; using Microsoft.OpenApi.Models; @@ -43,7 +44,8 @@ // https://gaepdit.github.io/web-apps/use-https.html#how-to-enable-hsts if (!isDevelopment) { - builder.Services.AddHsts(options => options.MaxAge = TimeSpan.FromMinutes(300)) + builder.Services + .AddHsts(options => options.MaxAge = TimeSpan.FromMinutes(300)) .AddHttpsRedirection(options => { options.HttpsPort = 443; @@ -52,32 +54,38 @@ } // Configure application monitoring. -builder.Services.AddTransient(); -builder.Services.AddSingleton(provider => -{ - var client = new RaygunClient(provider.GetService()!, provider.GetService()!); - client.SendingMessage += (_, eventArgs) => eventArgs.Message.Details.Tags.Add(builder.Environment.EnvironmentName); - return client; -}); -builder.Services.AddRaygun(opts => -{ - opts.ApiKey = AppSettings.RaygunSettings.ApiKey; - opts.ApplicationVersion = Assembly.GetEntryAssembly()?.GetName().Version?.ToString(3); - opts.ExcludeErrorsFromLocal = AppSettings.RaygunSettings.ExcludeErrorsFromLocal; - opts.IgnoreFormFieldNames = ["*Password"]; - opts.EnvironmentVariables.Add("ASPNETCORE_*"); -}); -builder.Services.AddRaygunUserProvider(); -builder.Services.AddHttpContextAccessor(); // needed by RaygunScriptPartial +builder.Services + .AddTransient() + .AddSingleton(provider => + { + var client = new RaygunClient(provider.GetService()!, + provider.GetService()!); + client.SendingMessage += (_, eventArgs) => + eventArgs.Message.Details.Tags.Add(builder.Environment.EnvironmentName); + return client; + }) + .AddRaygun(opts => + { + opts.ApiKey = AppSettings.RaygunSettings.ApiKey; + opts.ApplicationVersion = Assembly.GetEntryAssembly()?.GetName().Version?.ToString(3); + opts.ExcludeErrorsFromLocal = AppSettings.RaygunSettings.ExcludeErrorsFromLocal; + opts.IgnoreFormFieldNames = ["*Password"]; + opts.EnvironmentVariables.Add("ASPNETCORE_*"); + }) + .AddRaygunUserProvider() + .AddHttpContextAccessor(); // needed by RaygunScriptPartial // Add app services. -builder.Services.AddAutoMapperProfiles(); -builder.Services.AddAppServices(); -builder.Services.AddValidators(); +builder.Services + .AddAutoMapperProfiles() + .AddAppServices() + .AddEmailService() + .AddValidators(); // Add data stores. -builder.Services.AddDataPersistence(builder.Configuration, builder.Environment); -builder.Services.AddFileServices(builder.Configuration); +builder.Services + .AddDataPersistence(builder.Configuration, builder.Environment) + .AddFileServices(builder.Configuration); // Initialize database. builder.Services.AddHostedService(); @@ -117,14 +125,14 @@ // Configure security HTTP headers if (!app.Environment.IsDevelopment() || AppSettings.DevSettings.UseSecurityHeadersInDev) { - app.UseHsts(); - app.UseSecurityHeaders(policyCollection => policyCollection.AddSecurityHeaderPolicies()); + app.UseHsts().UseSecurityHeaders(policyCollection => policyCollection.AddSecurityHeaderPolicies()); } if (!string.IsNullOrEmpty(AppSettings.RaygunSettings.ApiKey)) app.UseRaygun(); // Configure the application pipeline. -app.UseStatusCodePagesWithReExecute("/Error/{0}") +app + .UseStatusCodePagesWithReExecute("/Error/{0}") .UseHttpsRedirection() .UseWebOptimizer() .UseStaticFiles() @@ -133,7 +141,8 @@ .UseAuthorization(); // Configure API documentation. -app.UseSwagger(options => { options.RouteTemplate = "api-docs/{documentName}/openapi.json"; }) +app + .UseSwagger(options => { options.RouteTemplate = "api-docs/{documentName}/openapi.json"; }) .UseSwaggerUI(options => { options.SwaggerEndpoint($"{apiVersion}/openapi.json", $"{apiTitle} {apiVersion}"); diff --git a/src/WebApp/appsettings.json b/src/WebApp/appsettings.json index 0ef1bac..586f472 100644 --- a/src/WebApp/appsettings.json +++ b/src/WebApp/appsettings.json @@ -40,15 +40,16 @@ }, "EmailServiceSettings": { "EnableEmail": false, - "SaveEmail": true, "SmtpHost": "localhost", "SmtpPort": 25, - "DefaultSender": "App.Emailer@email.invalid", + "DefaultSenderName": "EPD-IT", + "DefaultSenderEmail": "App.Emailer@email.invalid", "SecureSocketOption": "None", "EnableEmailAuditing": false, "AuditEmailRecipients": [ "Audit.Recipient@email.invalid" - ] + ], + "EnableEmailLog": true }, "DevSettings": { "UseDevSettings": true, diff --git a/template-app.sln b/template-app.sln index a3605ea..52f8eed 100644 --- a/template-app.sln +++ b/template-app.sln @@ -27,8 +27,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LocalRepositoryTests", "tes EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WebAppTests", "tests\WebAppTests\WebAppTests.csproj", "{0C0DFDC9-DB51-4C14-91F8-30E9FC66E32C}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EmailService", "src\EmailService\EmailService.csproj", "{1D7EE75A-3FA5-4BC7-B11D-4E6EABA19BC9}" -EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -82,10 +80,6 @@ Global {0C0DFDC9-DB51-4C14-91F8-30E9FC66E32C}.Debug|Any CPU.Build.0 = Debug|Any CPU {0C0DFDC9-DB51-4C14-91F8-30E9FC66E32C}.Release|Any CPU.ActiveCfg = Release|Any CPU {0C0DFDC9-DB51-4C14-91F8-30E9FC66E32C}.Release|Any CPU.Build.0 = Release|Any CPU - {1D7EE75A-3FA5-4BC7-B11D-4E6EABA19BC9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {1D7EE75A-3FA5-4BC7-B11D-4E6EABA19BC9}.Debug|Any CPU.Build.0 = Debug|Any CPU - {1D7EE75A-3FA5-4BC7-B11D-4E6EABA19BC9}.Release|Any CPU.ActiveCfg = Release|Any CPU - {1D7EE75A-3FA5-4BC7-B11D-4E6EABA19BC9}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(NestedProjects) = preSolution {13FAE9CA-FE4A-447E-8957-037E5DAD845B} = {DB76F5B0-EC9D-4144-91AA-46D5679152A3} diff --git a/tests/AppServicesTests/Permissions/AuthorizationServiceBuilder.cs b/tests/AppServicesTests/Permissions/AuthorizationServiceBuilder.cs index 332f44e..b68ed37 100644 --- a/tests/AppServicesTests/Permissions/AuthorizationServiceBuilder.cs +++ b/tests/AppServicesTests/Permissions/AuthorizationServiceBuilder.cs @@ -8,8 +8,7 @@ public static class AuthorizationServiceBuilder public static IAuthorizationService BuildAuthorizationService(Action setupServices) { var services = new ServiceCollection(); - services.AddAuthorization(); - services.AddLogging(); + services.AddAuthorization().AddLogging(); setupServices.Invoke(services); return services.BuildServiceProvider().GetRequiredService(); } diff --git a/tests/AppServicesTests/Permissions/PolicyTests/ActiveUserPolicy.cs b/tests/AppServicesTests/Permissions/PolicyTests/ActiveUserPolicy.cs index 4af8605..90d3abb 100644 --- a/tests/AppServicesTests/Permissions/PolicyTests/ActiveUserPolicy.cs +++ b/tests/AppServicesTests/Permissions/PolicyTests/ActiveUserPolicy.cs @@ -13,8 +13,7 @@ public class ActiveUserPolicy [SetUp] public void SetUp() => _authorization = AuthorizationServiceBuilder.BuildAuthorizationService(collection => - collection.AddAuthorizationBuilder() - .AddPolicy(nameof(Policies.ActiveUser), Policies.ActiveUser)); + collection.AddAuthorizationBuilder().AddPolicy(nameof(Policies.ActiveUser), Policies.ActiveUser)); [Test] public async Task WhenActiveAndAuthenticated_Succeeds()