|
|
|
|
using System.Collections.Immutable;
|
|
|
|
|
using Connected;
|
|
|
|
|
using Connected.Entities;
|
|
|
|
|
using Connected.Entities.Storage;
|
|
|
|
|
using Connected.Notifications.Events;
|
|
|
|
|
using Connected.Security.Cryptography;
|
|
|
|
|
using Connected.Security.Identity;
|
|
|
|
|
using Connected.ServiceModel;
|
|
|
|
|
using Connected.Services;
|
|
|
|
|
|
|
|
|
|
namespace Common.Security.Identity;
|
|
|
|
|
|
|
|
|
|
internal sealed class QueryUsers : ServiceFunction<IDto, ImmutableList<IUser>?>
|
|
|
|
|
{
|
|
|
|
|
public QueryUsers(IUserCache cache)
|
|
|
|
|
{
|
|
|
|
|
Cache = cache;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private IUserCache Cache { get; }
|
|
|
|
|
protected override async Task<ImmutableList<IUser>?> OnInvoke()
|
|
|
|
|
{
|
|
|
|
|
return await (from dc in Cache select dc).AsEntities<IUser>();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
internal sealed class SelectUser : ServiceFunction<PrimaryKeyArgs<int>, IUser?>
|
|
|
|
|
{
|
|
|
|
|
public SelectUser(IUserCache cache)
|
|
|
|
|
{
|
|
|
|
|
Cache = cache;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private IUserCache Cache { get; }
|
|
|
|
|
protected override async Task<IUser?> OnInvoke()
|
|
|
|
|
{
|
|
|
|
|
return await (from dc in Cache
|
|
|
|
|
where dc.Id == Arguments.Id
|
|
|
|
|
select dc).AsEntity();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Resolves user by a specified criteria string
|
|
|
|
|
/// </summary>
|
|
|
|
|
internal sealed class ResolveUser : ServiceFunction<UserResolveArgs, IUser?>
|
|
|
|
|
{
|
|
|
|
|
public ResolveUser(IUserCache cache)
|
|
|
|
|
{
|
|
|
|
|
Cache = cache;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private IUserCache Cache { get; }
|
|
|
|
|
protected override async Task<IUser?> OnInvoke()
|
|
|
|
|
{
|
|
|
|
|
/*
|
|
|
|
|
* First, try to resolve by login name
|
|
|
|
|
*/
|
|
|
|
|
if (await (from dc in Cache where string.Equals(dc.LoginName, Arguments.Criteria, StringComparison.OrdinalIgnoreCase) select dc).AsEntity() is IUser user)
|
|
|
|
|
return user;
|
|
|
|
|
/*
|
|
|
|
|
* Next, try by authentication token
|
|
|
|
|
*/
|
|
|
|
|
if (Guid.TryParse(Arguments.Criteria, out Guid authenticationToken))
|
|
|
|
|
{
|
|
|
|
|
if (await (from dc in Cache where dc.AuthenticationToken == authenticationToken select dc).AsEntity() is IUser authUser)
|
|
|
|
|
return authUser;
|
|
|
|
|
}
|
|
|
|
|
/*
|
|
|
|
|
* Next, try by email
|
|
|
|
|
*/
|
|
|
|
|
if (Arguments.Criteria?.Contains('@') == true)
|
|
|
|
|
{
|
|
|
|
|
if (await (from dc in Cache where string.Equals(dc.Email, Arguments.Criteria, StringComparison.OrdinalIgnoreCase) select dc).AsEntity() is IUser emailUser)
|
|
|
|
|
return emailUser;
|
|
|
|
|
}
|
|
|
|
|
/*
|
|
|
|
|
* Now by id
|
|
|
|
|
*/
|
|
|
|
|
if (int.TryParse(Arguments.Criteria, out int id))
|
|
|
|
|
{
|
|
|
|
|
if (await (from dc in Cache where dc.Id == id select dc).AsEntity() is IUser idUser)
|
|
|
|
|
return idUser;
|
|
|
|
|
}
|
|
|
|
|
/*
|
|
|
|
|
* Doesn't exist.
|
|
|
|
|
*/
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
internal sealed class LookupUsers : ServiceFunction<PrimaryKeyListArgs<int>, ImmutableList<IUser>?>
|
|
|
|
|
{
|
|
|
|
|
public LookupUsers(IUserCache cache)
|
|
|
|
|
{
|
|
|
|
|
Cache = cache;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private IUserCache Cache { get; }
|
|
|
|
|
protected override async Task<ImmutableList<IUser>?> OnInvoke()
|
|
|
|
|
{
|
|
|
|
|
if (Arguments.IdList is null)
|
|
|
|
|
return default;
|
|
|
|
|
|
|
|
|
|
return await (from dc in Cache
|
|
|
|
|
where Arguments.IdList.Contains(dc.Id)
|
|
|
|
|
select dc).AsEntities<IUser>();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
internal sealed class InsertUser : ServiceFunction<UserInsertArgs, int>
|
|
|
|
|
{
|
|
|
|
|
public InsertUser(IUserService userService, IUserCache cache, IStorageProvider storage, IEventService events)
|
|
|
|
|
{
|
|
|
|
|
UserService = userService;
|
|
|
|
|
Cache = cache;
|
|
|
|
|
Storage = storage;
|
|
|
|
|
Events = events;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private IUserCache Cache { get; }
|
|
|
|
|
private IStorageProvider Storage { get; }
|
|
|
|
|
private IEventService Events { get; }
|
|
|
|
|
private IUserService UserService { get; }
|
|
|
|
|
|
|
|
|
|
protected override async Task<int> OnInvoke()
|
|
|
|
|
{
|
|
|
|
|
if (Arguments.AsEntity<User>(State.New) is not User entity)
|
|
|
|
|
throw EntityExceptions.EntityCastException(Arguments.GetType(), typeof(User));
|
|
|
|
|
|
|
|
|
|
var result = await Storage.Open<User>().Update(entity);
|
|
|
|
|
|
|
|
|
|
return result.Id;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected override async Task OnCommitted()
|
|
|
|
|
{
|
|
|
|
|
await Cache.Refresh(Result);
|
|
|
|
|
await Events.Enqueue(this, UserService, ServiceEvents.Inserted, Result);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
internal sealed class DeleteUser : ServiceAction<PrimaryKeyArgs<int>>
|
|
|
|
|
{
|
|
|
|
|
public DeleteUser(IUserService userService, IStorageProvider storage, IUserCache cache, IEventService events)
|
|
|
|
|
{
|
|
|
|
|
UserService = userService;
|
|
|
|
|
Storage = storage;
|
|
|
|
|
Cache = cache;
|
|
|
|
|
Events = events;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private IUserService UserService { get; }
|
|
|
|
|
private IStorageProvider Storage { get; }
|
|
|
|
|
private IUserCache Cache { get; }
|
|
|
|
|
private IEventService Events { get; }
|
|
|
|
|
|
|
|
|
|
protected override async Task OnInvoke()
|
|
|
|
|
{
|
|
|
|
|
await Storage.Open<User>().Update(new User { Id = Arguments.Id, State = State.Deleted });
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected override async Task OnCommitted()
|
|
|
|
|
{
|
|
|
|
|
await Cache.Remove(Arguments.Id);
|
|
|
|
|
await Events.Enqueue(this, UserService, ServiceEvents.Deleted, Arguments.Id);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
internal sealed class UpdateUser : ServiceAction<UserUpdateArgs>
|
|
|
|
|
{
|
|
|
|
|
public UpdateUser(IUserService userService, IUserCache cache, IStorageProvider storage, IEventService events)
|
|
|
|
|
{
|
|
|
|
|
UserService = userService;
|
|
|
|
|
Cache = cache;
|
|
|
|
|
Storage = storage;
|
|
|
|
|
Events = events;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private IUserService UserService { get; }
|
|
|
|
|
private IUserCache Cache { get; }
|
|
|
|
|
private IStorageProvider Storage { get; }
|
|
|
|
|
private IEventService Events { get; }
|
|
|
|
|
|
|
|
|
|
protected override async Task OnInvoke()
|
|
|
|
|
{
|
|
|
|
|
await Storage.Open<User>().Update(await Load(), Arguments, async () =>
|
|
|
|
|
{
|
|
|
|
|
await Cache.Refresh(Arguments.Id);
|
|
|
|
|
|
|
|
|
|
return await Load();
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private async Task<User?> Load() => await (from dc in Cache where dc.Id == Arguments.Id select dc).AsEntity();
|
|
|
|
|
|
|
|
|
|
protected override async Task OnCommitted()
|
|
|
|
|
{
|
|
|
|
|
await Cache.Refresh(Arguments.Id);
|
|
|
|
|
await Events.Enqueue(this, UserService, ServiceEvents.Updated, Arguments.Id);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
internal sealed class UserUpdatePassword : ServiceAction<UserPasswordArgs>
|
|
|
|
|
{
|
|
|
|
|
public UserUpdatePassword(IUserService userService, ICryptographyService cryptographyService, IStorageProvider storage, IUserCache cache, IEventService events)
|
|
|
|
|
{
|
|
|
|
|
UserService = userService;
|
|
|
|
|
CryptographyService = cryptographyService;
|
|
|
|
|
Storage = storage;
|
|
|
|
|
Cache = cache;
|
|
|
|
|
Events = events;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private IUserService UserService { get; }
|
|
|
|
|
private ICryptographyService CryptographyService { get; }
|
|
|
|
|
private IStorageProvider Storage { get; }
|
|
|
|
|
public IUserCache Cache { get; }
|
|
|
|
|
public IEventService Events { get; }
|
|
|
|
|
|
|
|
|
|
protected override async Task OnInvoke()
|
|
|
|
|
{
|
|
|
|
|
await Storage.Open<User>().Update(await Load(), Arguments, async () =>
|
|
|
|
|
{
|
|
|
|
|
await Cache.Refresh(Arguments.Id);
|
|
|
|
|
|
|
|
|
|
return await Load();
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private async Task<User?> Load() => await (from dc in Cache where dc.Id == Arguments.Id select dc).AsEntity();
|
|
|
|
|
|
|
|
|
|
protected override async Task OnCommitted()
|
|
|
|
|
{
|
|
|
|
|
await Cache.Refresh(Arguments.Id);
|
|
|
|
|
await Events.Enqueue(this, UserService, ServiceEvents.Updated, Arguments.Id);
|
|
|
|
|
}
|
|
|
|
|
}
|