Scaffolded project
This commit is contained in:
commit
17a561094a
123 changed files with 64313 additions and 0 deletions
61
Services/Auth/SingleUserSeedService.cs
Normal file
61
Services/Auth/SingleUserSeedService.cs
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.Extensions.Options;
|
||||
using WorkTracker.Configuration;
|
||||
using WorkTracker.Data;
|
||||
|
||||
namespace WorkTracker.Services.Auth;
|
||||
|
||||
public sealed class SingleUserSeedService : IHostedService
|
||||
{
|
||||
private readonly IServiceProvider serviceProvider;
|
||||
private readonly IOptions<SingleUserOptions> options;
|
||||
private readonly ILogger<SingleUserSeedService> logger;
|
||||
|
||||
public SingleUserSeedService(
|
||||
IServiceProvider serviceProvider,
|
||||
IOptions<SingleUserOptions> options,
|
||||
ILogger<SingleUserSeedService> logger)
|
||||
{
|
||||
this.serviceProvider = serviceProvider;
|
||||
this.options = options;
|
||||
this.logger = logger;
|
||||
}
|
||||
|
||||
public async Task StartAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
if (!options.Value.SeedOnStartup)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
using var scope = serviceProvider.CreateScope();
|
||||
var userManager = scope.ServiceProvider.GetRequiredService<UserManager<ApplicationUser>>();
|
||||
|
||||
var configuredEmail = options.Value.Email;
|
||||
var existingUser = await userManager.FindByEmailAsync(configuredEmail);
|
||||
|
||||
if (existingUser is not null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var user = new ApplicationUser
|
||||
{
|
||||
UserName = configuredEmail,
|
||||
Email = configuredEmail,
|
||||
EmailConfirmed = true
|
||||
};
|
||||
|
||||
var result = await userManager.CreateAsync(user, options.Value.Password);
|
||||
if (!result.Succeeded)
|
||||
{
|
||||
var errors = string.Join("; ", result.Errors.Select(x => x.Description));
|
||||
logger.LogError("Unable to seed single user account {Email}. Errors: {Errors}", configuredEmail, errors);
|
||||
return;
|
||||
}
|
||||
|
||||
logger.LogInformation("Seeded single user account {Email}", configuredEmail);
|
||||
}
|
||||
|
||||
public Task StopAsync(CancellationToken cancellationToken) => Task.CompletedTask;
|
||||
}
|
||||
6
Services/Festivities/IItalianFestivitySource.cs
Normal file
6
Services/Festivities/IItalianFestivitySource.cs
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
namespace WorkTracker.Services.Festivities;
|
||||
|
||||
public interface IItalianFestivitySource
|
||||
{
|
||||
IReadOnlyCollection<DateOnly> GetFestivities(int year);
|
||||
}
|
||||
46
Services/Festivities/ItalianFestivitySource.cs
Normal file
46
Services/Festivities/ItalianFestivitySource.cs
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
namespace WorkTracker.Services.Festivities;
|
||||
|
||||
public sealed class ItalianFestivitySource : IItalianFestivitySource
|
||||
{
|
||||
public IReadOnlyCollection<DateOnly> GetFestivities(int year)
|
||||
{
|
||||
var easterSunday = GetEasterSunday(year);
|
||||
var easterMonday = easterSunday.AddDays(1);
|
||||
|
||||
return new HashSet<DateOnly>
|
||||
{
|
||||
new(year, 1, 1),
|
||||
new(year, 1, 6),
|
||||
easterSunday,
|
||||
easterMonday,
|
||||
new(year, 4, 25),
|
||||
new(year, 5, 1),
|
||||
new(year, 6, 2),
|
||||
new(year, 8, 15),
|
||||
new(year, 11, 1),
|
||||
new(year, 12, 8),
|
||||
new(year, 12, 25),
|
||||
new(year, 12, 26)
|
||||
};
|
||||
}
|
||||
|
||||
private static DateOnly GetEasterSunday(int year)
|
||||
{
|
||||
var a = year % 19;
|
||||
var b = year / 100;
|
||||
var c = year % 100;
|
||||
var d = b / 4;
|
||||
var e = b % 4;
|
||||
var f = (b + 8) / 25;
|
||||
var g = (b - f + 1) / 3;
|
||||
var h = (19 * a + b - d - g + 15) % 30;
|
||||
var i = c / 4;
|
||||
var k = c % 4;
|
||||
var l = (32 + 2 * e + 2 * i - h - k) % 7;
|
||||
var m = (a + 11 * h + 22 * l) / 451;
|
||||
var month = (h + l - 7 * m + 114) / 31;
|
||||
var day = ((h + l - 7 * m + 114) % 31) + 1;
|
||||
|
||||
return new DateOnly(year, month, day);
|
||||
}
|
||||
}
|
||||
10
Services/Settings/IAppSettingsService.cs
Normal file
10
Services/Settings/IAppSettingsService.cs
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
using WorkTracker.Domain;
|
||||
|
||||
namespace WorkTracker.Services.Settings;
|
||||
|
||||
public interface IAppSettingsService
|
||||
{
|
||||
Task<AppSettingsDocument> GetAsync(CancellationToken cancellationToken = default);
|
||||
|
||||
Task<AppSettingsDocument> SaveAsync(AppSettingsDocument settings, CancellationToken cancellationToken = default);
|
||||
}
|
||||
44
Services/Settings/MongoAppSettingsService.cs
Normal file
44
Services/Settings/MongoAppSettingsService.cs
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
using MongoDB.Driver;
|
||||
using WorkTracker.Domain;
|
||||
|
||||
namespace WorkTracker.Services.Settings;
|
||||
|
||||
public sealed class MongoAppSettingsService : IAppSettingsService
|
||||
{
|
||||
private const string DefaultSettingsId = "global";
|
||||
private readonly IMongoCollection<AppSettingsDocument> appSettingsCollection;
|
||||
|
||||
public MongoAppSettingsService(IMongoDatabase database)
|
||||
{
|
||||
appSettingsCollection = database.GetCollection<AppSettingsDocument>("app_settings");
|
||||
}
|
||||
|
||||
public async Task<AppSettingsDocument> GetAsync(CancellationToken cancellationToken = default)
|
||||
{
|
||||
var filter = Builders<AppSettingsDocument>.Filter.Eq(x => x.Id, DefaultSettingsId);
|
||||
var settings = await appSettingsCollection.Find(filter).FirstOrDefaultAsync(cancellationToken);
|
||||
|
||||
if (settings is not null)
|
||||
{
|
||||
return settings;
|
||||
}
|
||||
|
||||
var defaults = new AppSettingsDocument();
|
||||
await appSettingsCollection.InsertOneAsync(defaults, cancellationToken: cancellationToken);
|
||||
return defaults;
|
||||
}
|
||||
|
||||
public async Task<AppSettingsDocument> SaveAsync(AppSettingsDocument settings, CancellationToken cancellationToken = default)
|
||||
{
|
||||
var existing = await GetAsync(cancellationToken);
|
||||
|
||||
settings.Id = DefaultSettingsId;
|
||||
settings.CreatedAtUtc = existing.CreatedAtUtc;
|
||||
settings.UpdatedAtUtc = DateTimeOffset.UtcNow;
|
||||
|
||||
var filter = Builders<AppSettingsDocument>.Filter.Eq(x => x.Id, DefaultSettingsId);
|
||||
await appSettingsCollection.ReplaceOneAsync(filter, settings, new ReplaceOptions { IsUpsert = true }, cancellationToken);
|
||||
|
||||
return settings;
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue