65 lines
No EOL
1.8 KiB
C#
65 lines
No EOL
1.8 KiB
C#
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()),
|
|
};
|
|
|
|
}
|
|
} |