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");
}
}
}