|
@@ -1,379 +0,0 @@
|
|
|
-using InABox.Clients;
|
|
|
-using InABox.Core;
|
|
|
-using InABox.IPC.Shared;
|
|
|
-using System;
|
|
|
-using System.Collections;
|
|
|
-using System.Collections.Concurrent;
|
|
|
-using System.Collections.Generic;
|
|
|
-using System.Linq;
|
|
|
-using System.Runtime.CompilerServices;
|
|
|
-using System.Text;
|
|
|
-using System.Threading.Tasks;
|
|
|
-
|
|
|
-namespace InABox.Client.IPC
|
|
|
-{
|
|
|
- internal static class LocalCache
|
|
|
- {
|
|
|
- public static string Password { get; set; }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- public class PipeIPCClient<TEntity> : BaseClient<TEntity> where TEntity : Entity, new()
|
|
|
- {
|
|
|
- private IPCClient Client;
|
|
|
-
|
|
|
- public PipeIPCClient(string pipeName)
|
|
|
- {
|
|
|
- Client = IPCClientFactory.GetClient(pipeName);
|
|
|
- Timeout = TimeSpan.FromSeconds(300);
|
|
|
- }
|
|
|
-
|
|
|
- private static string[]? _types;
|
|
|
- public override string[] SupportedTypes()
|
|
|
- {
|
|
|
- _types ??= CoreUtils.Entities
|
|
|
- .Where(x => x.GetInterfaces().Contains(typeof(IPersistent)))
|
|
|
- .Select(x => x.EntityName().Replace(".", "_"))
|
|
|
- .ToArray();
|
|
|
- return _types;
|
|
|
- }
|
|
|
-
|
|
|
- public override DatabaseInfo Info()
|
|
|
- {
|
|
|
- try
|
|
|
- {
|
|
|
- var request = new InfoRequest();
|
|
|
- PrepareRequest(request, false);
|
|
|
- var response = Send(PipeRequest.Info(request)).GetResponse<InfoResponse>();
|
|
|
- return response.Info;
|
|
|
- }
|
|
|
- catch (Exception)
|
|
|
- {
|
|
|
- return new DatabaseInfo();
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- private void PrepareRequest(Request request, bool doCredentials = true)
|
|
|
- {
|
|
|
- if(request is not ValidateRequest && Client.Disconnected)
|
|
|
- {
|
|
|
- ClientFactory.Validate(ClientFactory.UserID, LocalCache.Password);
|
|
|
- }
|
|
|
-
|
|
|
- if (doCredentials)
|
|
|
- {
|
|
|
- request.Credentials.Platform = ClientFactory.Platform;
|
|
|
- request.Credentials.Version = ClientFactory.Version;
|
|
|
- request.Credentials.Session = ClientFactory.SessionID;
|
|
|
- }
|
|
|
-
|
|
|
- Request.BeforeRequest?.Invoke(request);
|
|
|
- }
|
|
|
-
|
|
|
- private PipeRequest Send(PipeRequest request, int? timeout = null)
|
|
|
- {
|
|
|
- return Client.Send(request, timeout ?? Convert.ToInt32(Timeout.TotalMilliseconds));
|
|
|
- }
|
|
|
-
|
|
|
- protected override bool DoCheck2FA(string code, Guid? session)
|
|
|
- {
|
|
|
- var request = new Check2FARequest(code);
|
|
|
-
|
|
|
- PrepareRequest(request);
|
|
|
-
|
|
|
- var response = Send(PipeRequest.Check2FA(request)).GetResponse<Check2FAResponse>();
|
|
|
- if (response != null)
|
|
|
- {
|
|
|
- return response.Status switch
|
|
|
- {
|
|
|
- StatusCode.OK => response.Valid,
|
|
|
- StatusCode.Unauthenticated => false,
|
|
|
- _ => throw new IPCException(response.Messages),
|
|
|
- };
|
|
|
- }
|
|
|
-
|
|
|
- return false;
|
|
|
- }
|
|
|
-
|
|
|
- protected override bool DoPing()
|
|
|
- {
|
|
|
- try
|
|
|
- {
|
|
|
- var request = new PingRequest();
|
|
|
-
|
|
|
- PrepareRequest(request);
|
|
|
-
|
|
|
- var response = Send(PipeRequest.Ping(request), 10_000).GetResponse<PingResponse>();
|
|
|
- if (response != null)
|
|
|
- {
|
|
|
- return response.Status switch
|
|
|
- {
|
|
|
- StatusCode.Error or StatusCode.BadServer or StatusCode.Incomplete => throw new IPCException(response.Messages),
|
|
|
- _ => true
|
|
|
- };
|
|
|
- }
|
|
|
- }
|
|
|
- catch (Exception) { }
|
|
|
-
|
|
|
- return false;
|
|
|
- }
|
|
|
-
|
|
|
- protected override void DoDelete(TEntity entity, string auditnote)
|
|
|
- {
|
|
|
- var request = new DeleteRequest<TEntity>(entity, auditnote);
|
|
|
- PrepareRequest(request);
|
|
|
-
|
|
|
- var response = Send(PipeRequest.Delete(request)).GetResponse<DeleteResponse<TEntity>>();
|
|
|
- switch (response.Status)
|
|
|
- {
|
|
|
- case StatusCode.OK:
|
|
|
- break;
|
|
|
- case StatusCode.Unauthenticated:
|
|
|
- throw new IPCException("Client not authenticated");
|
|
|
- default:
|
|
|
- throw new IPCException(response.Messages);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- protected override void DoDelete(IList<TEntity> entities, string auditnote)
|
|
|
- {
|
|
|
- var items = entities.ToArray();
|
|
|
- var request = new MultiDeleteRequest<TEntity>(items, auditnote);
|
|
|
- PrepareRequest(request);
|
|
|
-
|
|
|
- var response = Send(PipeRequest.MultiDelete(request)).GetResponse<MultiDeleteResponse<TEntity>>();
|
|
|
- switch (response.Status)
|
|
|
- {
|
|
|
- case StatusCode.OK:
|
|
|
- break;
|
|
|
- case StatusCode.Unauthenticated:
|
|
|
- throw new IPCException("Client not authenticated");
|
|
|
- default:
|
|
|
- throw new IPCException(response.Messages);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- protected override TEntity[] DoLoad(Filter<TEntity>? filter = null, SortOrder<TEntity>? sort = null)
|
|
|
- {
|
|
|
- var request = new QueryRequest<TEntity>(filter, null, sort);
|
|
|
- PrepareRequest(request);
|
|
|
-
|
|
|
- var result = new List<TEntity>();
|
|
|
- var response = Send(PipeRequest.Query(request)).GetResponse<QueryResponse<TEntity>>();
|
|
|
- if (response.Items != null)
|
|
|
- foreach (var row in response.Items.Rows)
|
|
|
- result.Add(row.ToObject<TEntity>());
|
|
|
- return result.ToArray();
|
|
|
- }
|
|
|
-
|
|
|
- protected override CoreTable DoQuery(Filter<TEntity>? filter, Columns<TEntity>? columns, SortOrder<TEntity>? sort = null)
|
|
|
- {
|
|
|
- var request = new QueryRequest<TEntity>(filter, columns, sort);
|
|
|
- PrepareRequest(request);
|
|
|
-
|
|
|
- var response = Send(PipeRequest.Query(request)).GetResponse<QueryResponse<TEntity>>();
|
|
|
-
|
|
|
- if (response != null)
|
|
|
- {
|
|
|
- return response.Status switch
|
|
|
- {
|
|
|
- StatusCode.OK => response.Items,
|
|
|
- StatusCode.Unauthenticated => throw new IPCException("Client not authenticated", StatusCode.Unauthenticated),
|
|
|
- _ => throw new IPCException(response.Messages),
|
|
|
- };
|
|
|
- }
|
|
|
-
|
|
|
- return null;
|
|
|
- }
|
|
|
-
|
|
|
- protected override Dictionary<string, CoreTable> DoQueryMultiple(Dictionary<string, IQueryDef> queries)
|
|
|
- {
|
|
|
- var request = new MultiQueryRequest();
|
|
|
- foreach (var item in queries)
|
|
|
- {
|
|
|
- request.AddQuery(item.Key, item.Value);
|
|
|
- }
|
|
|
- PrepareRequest(request);
|
|
|
-
|
|
|
- var response = Send(PipeRequest.QueryMultiple(request)).GetResponse<MultiQueryResponse>();
|
|
|
- if (response != null)
|
|
|
- {
|
|
|
- return response.Status switch
|
|
|
- {
|
|
|
- StatusCode.OK => response.Tables,
|
|
|
- StatusCode.Unauthenticated => throw new IPCException("Client not authenticated"),
|
|
|
- _ => throw new IPCException(response.Messages),
|
|
|
- };
|
|
|
- }
|
|
|
-
|
|
|
- return null;
|
|
|
- }
|
|
|
-
|
|
|
- protected override void DoSave(TEntity entity, string auditnote)
|
|
|
- {
|
|
|
- var request = new SaveRequest<TEntity>(entity, auditnote)
|
|
|
- {
|
|
|
- ReturnOnlyChanged = true
|
|
|
- };
|
|
|
- PrepareRequest(request);
|
|
|
-
|
|
|
- var response = Send(PipeRequest.Save(request)).GetResponse<SaveResponse<TEntity>>();
|
|
|
- switch (response.Status)
|
|
|
- {
|
|
|
- case StatusCode.OK:
|
|
|
- /*var props = CoreUtils.PropertyList(typeof(TEntity), x => true, true);
|
|
|
- entity.SetObserving(false);
|
|
|
- foreach (var prop in props.Keys)
|
|
|
- {
|
|
|
- var value = CoreUtils.GetPropertyValue(response.Item, prop);
|
|
|
- CoreUtils.SetPropertyValue(entity, prop, value);
|
|
|
- }
|
|
|
-
|
|
|
- entity.CommitChanges();
|
|
|
- entity.SetObserving(true);*/
|
|
|
-
|
|
|
- entity.SetObserving(false);
|
|
|
- foreach (var (key, value) in response.ChangedValues)
|
|
|
- {
|
|
|
- if (CoreUtils.TryGetProperty<TEntity>(key, out var property))
|
|
|
- {
|
|
|
- CoreUtils.SetPropertyValue(entity, key, CoreUtils.ChangeType(value, property.PropertyType));
|
|
|
- }
|
|
|
- }
|
|
|
- entity.CommitChanges();
|
|
|
- entity.SetObserving(true);
|
|
|
-
|
|
|
- break;
|
|
|
- case StatusCode.Unauthenticated:
|
|
|
- throw new IPCException("Client not authenticated");
|
|
|
- default:
|
|
|
- throw new IPCException(response.Messages);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- protected override void DoSave(IEnumerable<TEntity> entities, string auditnote)
|
|
|
- {
|
|
|
- var items = entities.ToArray();
|
|
|
- var request = new MultiSaveRequest<TEntity>(items, auditnote)
|
|
|
- {
|
|
|
- ReturnOnlyChanged = true
|
|
|
- };
|
|
|
- PrepareRequest(request);
|
|
|
-
|
|
|
- var response = Send(PipeRequest.MultiSave(request)).GetResponse<MultiSaveResponse<TEntity>>();
|
|
|
- switch (response.Status)
|
|
|
- {
|
|
|
- case StatusCode.OK:
|
|
|
- /*var props = CoreUtils.PropertyList(typeof(TEntity), x => true, true);
|
|
|
- for (var i = 0; i < items.Length; i++)
|
|
|
- {
|
|
|
- items[i].SetObserving(false);
|
|
|
- foreach (var prop in props.Keys)
|
|
|
- {
|
|
|
- var value = CoreUtils.GetPropertyValue(response.Items[i], prop);
|
|
|
- CoreUtils.SetPropertyValue(items[i], prop, value);
|
|
|
- }
|
|
|
-
|
|
|
- //CoreUtils.DeepClone<TEntity>(response.Items[i], items[i]);
|
|
|
- items[i].CommitChanges();
|
|
|
- items[i].SetObserving(true);
|
|
|
- }*/
|
|
|
- for (int i = 0; i < items.Length; ++i)
|
|
|
- {
|
|
|
- var entity = items[i];
|
|
|
- var changedValues = response.ChangedValues[i];
|
|
|
-
|
|
|
- entity.SetObserving(false);
|
|
|
- foreach (var (key, value) in changedValues)
|
|
|
- {
|
|
|
- if (CoreUtils.TryGetProperty<TEntity>(key, out var property))
|
|
|
- {
|
|
|
- CoreUtils.SetPropertyValue(entity, key, CoreUtils.ChangeType(value, property.PropertyType));
|
|
|
- }
|
|
|
- }
|
|
|
- entity.CommitChanges();
|
|
|
- entity.SetObserving(true);
|
|
|
- }
|
|
|
- break;
|
|
|
- case StatusCode.Unauthenticated:
|
|
|
- throw new IPCException("Client not authenticated");
|
|
|
- default:
|
|
|
- throw new IPCException(response.Messages);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- protected override ValidationData DoValidate(Guid session)
|
|
|
- {
|
|
|
- return Validate(
|
|
|
- null, null, false, session);
|
|
|
- }
|
|
|
-
|
|
|
- protected override ValidationData DoValidate(string pin, Guid session)
|
|
|
- {
|
|
|
- return Validate(
|
|
|
- null, pin, true, session);
|
|
|
- }
|
|
|
-
|
|
|
- protected override ValidationData DoValidate(string userid, string password, Guid session)
|
|
|
- {
|
|
|
- return Validate(
|
|
|
- userid, password, false, session);
|
|
|
- }
|
|
|
-
|
|
|
- private ValidationData Validate(string? userid, string? password, bool usePin, Guid session = default)
|
|
|
- {
|
|
|
- var ticks = DateTime.Now.ToUniversalTime().Ticks.ToString();
|
|
|
- var request = new ValidateRequest { UsePIN = usePin };
|
|
|
-
|
|
|
- if (usePin)
|
|
|
- {
|
|
|
- request.UserID = Encryption.Encrypt(ticks, "wCq9rryEJEuHIifYrxRjxg", true);
|
|
|
- request.Password = Encryption.Encrypt(ticks, "7mhvLnqMwkCAzN+zNGlyyg", true);
|
|
|
- request.PIN = password;
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- request.UserID = userid;
|
|
|
- request.Password = password;
|
|
|
- }
|
|
|
- request.Credentials.Platform = ClientFactory.Platform;
|
|
|
- request.Credentials.Version = ClientFactory.Version;
|
|
|
- PrepareRequest(request, false);
|
|
|
- if(session != Guid.Empty)
|
|
|
- {
|
|
|
- request.Credentials.Session = session;
|
|
|
- }
|
|
|
-
|
|
|
- var response = Send(PipeRequest.Validate(request), 10000).GetResponse<ValidateResponse>();
|
|
|
- if (response != null)
|
|
|
- if (response.Status.Equals(StatusCode.OK))
|
|
|
- {
|
|
|
- LocalCache.Password = password;
|
|
|
- return new ValidationData(
|
|
|
- response.ValidationResult,
|
|
|
- response.UserID,
|
|
|
- response.UserGuid,
|
|
|
- response.SecurityID,
|
|
|
- response.Session,
|
|
|
- response.Recipient2FA,
|
|
|
- response.PasswordExpiration
|
|
|
- );
|
|
|
- }
|
|
|
- else if (response.Status == StatusCode.BadServer)
|
|
|
- {
|
|
|
- throw new IPCException(response.Messages);
|
|
|
- }
|
|
|
-
|
|
|
- return new ValidationData(
|
|
|
- ValidationResult.INVALID,
|
|
|
- "",
|
|
|
- Guid.Empty,
|
|
|
- Guid.Empty,
|
|
|
- Guid.Empty,
|
|
|
- null,
|
|
|
- DateTime.MinValue
|
|
|
- );
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-}
|