Initial commit

This commit is contained in:
2026-06-02 10:51:14 +02:00
committed by kawa
commit d19092c84e
182 changed files with 13757 additions and 0 deletions
@@ -0,0 +1,96 @@
using System.Text;
using System.Text.Json;
using SharepointToolbox.Web.Core.Models;
namespace SharepointToolbox.Web.Infrastructure.Persistence;
public class UserRepository
{
private readonly string _filePath;
private readonly SemaphoreSlim _writeLock = new(1, 1);
private static readonly JsonSerializerOptions _opts = new()
{
WriteIndented = true,
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
PropertyNameCaseInsensitive = true
};
public UserRepository(string filePath) { _filePath = filePath; }
public async Task<IReadOnlyList<AppUser>> LoadAsync()
{
if (!File.Exists(_filePath)) return Array.Empty<AppUser>();
var json = await File.ReadAllTextAsync(_filePath, Encoding.UTF8);
var root = JsonSerializer.Deserialize<UsersRoot>(json, _opts);
return (IReadOnlyList<AppUser>?)root?.Users ?? Array.Empty<AppUser>();
}
public async Task<AppUser?> FindByEmailAsync(string email)
{
var users = await LoadAsync();
return users.FirstOrDefault(u => u.Email.Equals(email, StringComparison.OrdinalIgnoreCase));
}
public async Task SaveAsync(IReadOnlyList<AppUser> users)
{
await _writeLock.WaitAsync();
try
{
var root = new UsersRoot { Users = users.ToList() };
var json = JsonSerializer.Serialize(root, _opts);
var tmpPath = _filePath + ".tmp";
var dir = Path.GetDirectoryName(_filePath);
if (!string.IsNullOrEmpty(dir)) Directory.CreateDirectory(dir);
await File.WriteAllTextAsync(tmpPath, json, Encoding.UTF8);
File.Move(tmpPath, _filePath, overwrite: true);
}
finally { _writeLock.Release(); }
}
public async Task UpsertAsync(AppUser user)
{
await _writeLock.WaitAsync();
try
{
var users = (await LoadInternal()).ToList();
var idx = users.FindIndex(u => u.Id == user.Id);
if (idx >= 0) users[idx] = user;
else users.Add(user);
await SaveInternal(users);
}
finally { _writeLock.Release(); }
}
public async Task DeleteAsync(string userId)
{
await _writeLock.WaitAsync();
try
{
var users = (await LoadInternal()).ToList();
users.RemoveAll(u => u.Id == userId);
await SaveInternal(users);
}
finally { _writeLock.Release(); }
}
private async Task<IReadOnlyList<AppUser>> LoadInternal()
{
if (!File.Exists(_filePath)) return Array.Empty<AppUser>();
var json = await File.ReadAllTextAsync(_filePath, Encoding.UTF8);
var root = JsonSerializer.Deserialize<UsersRoot>(json, _opts);
return (IReadOnlyList<AppUser>?)root?.Users ?? Array.Empty<AppUser>();
}
private async Task SaveInternal(List<AppUser> users)
{
var root = new UsersRoot { Users = users };
var json = JsonSerializer.Serialize(root, _opts);
var tmpPath = _filePath + ".tmp";
var dir = Path.GetDirectoryName(_filePath);
if (!string.IsNullOrEmpty(dir)) Directory.CreateDirectory(dir);
await File.WriteAllTextAsync(tmpPath, json, Encoding.UTF8);
File.Move(tmpPath, _filePath, overwrite: true);
}
private sealed class UsersRoot { public List<AppUser> Users { get; set; } = new(); }
}