using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Text; using System.Threading.Tasks; using Fido2NetLib; using gehGassi.Core.Interfaces; using gehGassi.Domain.Users; namespace gehGassi.Core.Services { /// /// Service der die Verwaltung von Fido-Credentials realisiert /// [ExcludeFromCodeCoverage] public class FidoService : ServiceBase, IFidoService { private readonly IUserService _userService; /// /// Erstellt eine Instanz /// /// Instanz eines IUnitOfWork /// Instanz eines IUserService public FidoService(IUnitOfWork unitOfWork, IUserService userService) : base(unitOfWork) { _userService = userService; } /// /// Gibt eine gefilterte Liste von Fido-Credentials zurück /// /// Filterbegriff der in bestimmten Feldern gesucht wird /// List betroffener Fido-Credentials public IQueryable Filter(string filter) { return Repository.Query(c => c.Name.Contains(filter)); } /// /// Gibt eine gefilterte Liste von Fido-Credentials für einen Benutzer zurück /// /// Filterbegriff der in bestimmten Feldern gesucht wird /// Benutzername /// List betroffener Fido-Credentials public IQueryable Filter(string filter, string username) { return Repository.Query(c => c.Name.Contains(filter) && c.Username == username); } /// /// Erstellen eines Fido-Credentials /// /// Fido-Credential public FidoStoredCredential Create() { var item = new FidoStoredCredential { RegDate = DateTimeOffset.UtcNow }; return item; } /// /// Gibt alle Credentials für einen Benutzer zurück /// /// Benutzername /// Liste Credentials public async Task> GetCredentialsAsync(string username) { return (await Repository.FindAsync(c => c.Username == username).ConfigureAwait(false)).ToList(); } /// /// Gibt eine Liste aller Benutzer zurück die über eine CredentialId verfügen /// /// CredentialId /// Liste Fido2 User public async Task> GetUsersByCredentialIdAsync(byte[] credentialId) { var credentialIdString = Base64Url.Encode(credentialId); var credential = await Repository.SingleOrDefaultAsync(c => c.DescriptorJson.Contains(credentialIdString)); if (credential == null) return new List(); var users = await _userService.FindAsync(c => Encoding.UTF8.GetBytes(c.UserName).SequenceEqual(credential.UserId)); return users.Select(c => new Fido2User() { Name = c.UserName, Id = Encoding.UTF8.GetBytes(c.UserName) }).ToList(); } /// /// Gibt zurück ob ein Benutzer über Fido credentials verfügt /// /// Benutzername /// true wenn ja, false sonst public async Task HasFidoCredentialsAsync(string username) { return (await Repository.CountAsync(c => c.Username == username).ConfigureAwait(false)) > 0; } /// /// Gibt ein Credential zurück /// /// CredentialId /// FidoStoredCredential public async Task GetByIdAsync(byte[] id) { var credentialIdString = Base64Url.Encode(id); return await Repository.FirstOrDefaultAsync(c => c.DescriptorJson.Contains(credentialIdString)).ConfigureAwait(false); } /// /// Gibt eine Liste von Credentials anhand des userHandles zurück /// /// Userhandle /// Liste Credentials public async Task> GetCredentialsByUserHandleAsync(byte[] userHandle) { return (await Repository.FindAsync(c => c.UserHandle.SequenceEqual(userHandle)).ConfigureAwait(false)).ToList(); } /// /// Aktualisieren des Counters /// /// /// /// Task public async Task UpdateCounterAsync(byte[] credentialId, uint counter) { var credentialIdString = Base64Url.Encode(credentialId); var item = await Repository.FirstOrDefaultAsync(c => c.DescriptorJson.Contains(credentialIdString)).ConfigureAwait(false); item.SignatureCounter = counter; await CommitAsync("System"); } } }