using System.Security.Cryptography; using IdentityShroud.Core.Contracts; using IdentityShroud.Core.Helpers; using IdentityShroud.Core.Messages.Realm; using IdentityShroud.Core.Model; using Microsoft.EntityFrameworkCore; namespace IdentityShroud.Core.Services; public record RealmCreateResponse(Guid Id, string Slug, string Name); public class RealmService( Db db, IEncryptionService encryptionService) : IRealmService { public async Task FindBySlug(string slug, CancellationToken ct = default) { return await db.Realms .SingleOrDefaultAsync(r => r.Slug == slug, ct); } public async Task> Create(RealmCreateRequest request, CancellationToken ct = default) { Realm realm = new() { Id = request.Id ?? Guid.CreateVersion7(), Slug = request.Slug ?? SlugHelper.GenerateSlug(request.Name), Name = request.Name, Keys = [ CreateKey() ], }; db.Add(realm); await db.SaveChangesAsync(ct); return new RealmCreateResponse( realm.Id, realm.Slug, realm.Name); } public async Task LoadActiveKeys(Realm realm) { await db.Entry(realm).Collection(r => r.Keys) .Query() .Where(k => k.DeactivatedAt == null) .LoadAsync(); } private Key CreateKey() { using RSA rsa = RSA.Create(2048); Key key = new() { Priority = 10, }; key.SetPrivateKey(encryptionService, rsa.ExportPkcs8PrivateKey()); return key; } }