141 lines
5.5 KiB
C#

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
{
/// <summary>
/// Service der die Verwaltung von Fido-Credentials realisiert
/// </summary>
[ExcludeFromCodeCoverage]
public class FidoService : ServiceBase<FidoStoredCredential>, IFidoService
{
private readonly IUserService _userService;
/// <summary>
/// Erstellt eine Instanz
/// </summary>
/// <param name="unitOfWork">Instanz eines IUnitOfWork</param>
/// <param name="userService">Instanz eines IUserService</param>
public FidoService(IUnitOfWork unitOfWork, IUserService userService) : base(unitOfWork)
{
_userService = userService;
}
/// <summary>
/// Gibt eine gefilterte Liste von Fido-Credentials zurück
/// </summary>
/// <param name="filter">Filterbegriff der in bestimmten Feldern gesucht wird</param>
/// <returns>List betroffener Fido-Credentials</returns>
public IQueryable<FidoStoredCredential> Filter(string filter)
{
return Repository.Query(c => c.Name.Contains(filter));
}
/// <summary>
/// Gibt eine gefilterte Liste von Fido-Credentials für einen Benutzer zurück
/// </summary>
/// <param name="filter">Filterbegriff der in bestimmten Feldern gesucht wird</param>
/// <param name="username">Benutzername</param>
/// <returns>List betroffener Fido-Credentials</returns>
public IQueryable<FidoStoredCredential> Filter(string filter, string username)
{
return Repository.Query(c => c.Name.Contains(filter) && c.Username == username);
}
/// <summary>
/// Erstellen eines Fido-Credentials
/// </summary>
/// <returns>Fido-Credential</returns>
public FidoStoredCredential Create()
{
var item = new FidoStoredCredential
{
RegDate = DateTimeOffset.UtcNow
};
return item;
}
/// <summary>
/// Gibt alle Credentials für einen Benutzer zurück
/// </summary>
/// <param name="username">Benutzername</param>
/// <returns>Liste Credentials</returns>
public async Task<List<FidoStoredCredential>> GetCredentialsAsync(string username)
{
return (await Repository.FindAsync(c => c.Username == username).ConfigureAwait(false)).ToList();
}
/// <summary>
/// Gibt eine Liste aller Benutzer zurück die über eine CredentialId verfügen
/// </summary>
/// <param name="credentialId">CredentialId</param>
/// <returns>Liste Fido2 User</returns>
public async Task<List<Fido2User>> GetUsersByCredentialIdAsync(byte[] credentialId)
{
var credentialIdString = Base64Url.Encode(credentialId);
var credential = await Repository.SingleOrDefaultAsync(c => c.DescriptorJson.Contains(credentialIdString));
if (credential == null)
return new List<Fido2User>();
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();
}
/// <summary>
/// Gibt zurück ob ein Benutzer über Fido credentials verfügt
/// </summary>
/// <param name="username">Benutzername</param>
/// <returns>true wenn ja, false sonst</returns>
public async Task<bool> HasFidoCredentialsAsync(string username)
{
return (await Repository.CountAsync(c => c.Username == username).ConfigureAwait(false)) > 0;
}
/// <summary>
/// Gibt ein Credential zurück
/// </summary>
/// <param name="id">CredentialId</param>
/// <returns>FidoStoredCredential</returns>
public async Task<FidoStoredCredential> GetByIdAsync(byte[] id)
{
var credentialIdString = Base64Url.Encode(id);
return await Repository.FirstOrDefaultAsync(c => c.DescriptorJson.Contains(credentialIdString)).ConfigureAwait(false);
}
/// <summary>
/// Gibt eine Liste von Credentials anhand des userHandles zurück
/// </summary>
/// <param name="userHandle">Userhandle</param>
/// <returns>Liste Credentials</returns>
public async Task<List<FidoStoredCredential>> GetCredentialsByUserHandleAsync(byte[] userHandle)
{
return (await Repository.FindAsync(c => c.UserHandle.SequenceEqual(userHandle)).ConfigureAwait(false)).ToList();
}
/// <summary>
/// Aktualisieren des Counters
/// </summary>
/// <param name="credentialId"></param>
/// <param name="counter"></param>
/// <returns>Task</returns>
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");
}
}
}