IdentityShroud/IdentityShroud.Core/Services/ClientService.cs

65 lines
1.8 KiB
C#
Raw Normal View History

using System.Security.Cryptography;
using IdentityShroud.Core.Contracts;
using IdentityShroud.Core.Model;
using Microsoft.EntityFrameworkCore;
namespace IdentityShroud.Core.Services;
public class ClientService(
Db db,
IDataEncryptionService cryptor,
IClock clock) : IClientService
{
public async Task<Result<Client>> Create(Guid realmId, ClientCreateRequest request, CancellationToken ct = default)
{
Client client = new()
{
RealmId = realmId,
ClientId = request.ClientId,
Name = request.Name,
Description = request.Description,
SignatureAlgorithm = request.SignatureAlgorithm,
AllowClientCredentialsFlow = request.AllowClientCredentialsFlow ?? false,
CreatedAt = clock.UtcNow(),
};
if (client.AllowClientCredentialsFlow)
{
client.Secrets.Add(CreateSecret());
}
await db.AddAsync(client, ct);
await db.SaveChangesAsync(ct);
return client;
}
public async Task<Client?> GetByClientId(
Guid realmId,
string clientId,
CancellationToken ct = default)
{
return await db.Clients.FirstOrDefaultAsync(c => c.ClientId == clientId && c.RealmId == realmId, ct);
}
public async Task<Client?> FindById(
Guid realmId,
int id,
CancellationToken ct = default)
{
return await db.Clients.FirstOrDefaultAsync(c => c.Id == id && c.RealmId == realmId, ct);
}
private ClientSecret CreateSecret()
{
Span<byte> secret = stackalloc byte[24];
RandomNumberGenerator.Fill(secret);
return new ClientSecret()
{
CreatedAt = clock.UtcNow(),
Secret = cryptor.Encrypt(secret.ToArray()),
};
}
}