Browse Source

Fixed server code for IPC

Kenric Nugteren 2 years ago
parent
commit
8e8d4d3a34

+ 0 - 2
InABox.Server/IPC/IPCServer.cs

@@ -4,8 +4,6 @@ using H.Pipes.Args;
 using InABox.API;
 using InABox.Clients;
 using InABox.Core;
-using InABox.Server.WebSocket;
-using Piping;
 using System.Collections.Concurrent;
 using System.IO.Pipes;
 using System.Reflection;

+ 0 - 372
InABox.Server/IPC/PipeIPCServer.cs

@@ -1,372 +0,0 @@
-using H.Formatters;
-using H.Pipes;
-using H.Pipes.AccessControl;
-using H.Pipes.Args;
-using InABox.API;
-using InABox.Clients;
-using InABox.Core;
-using InABox.IPC.Shared;
-using InABox.Server.WebSocket;
-using System;
-using System.Collections.Concurrent;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.IO.Pipes;
-using System.Linq;
-using System.Reflection;
-using System.Security.Principal;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace Piping
-{
-    using PipeResponse = PipeRequest;
-
-    delegate void PipePollEvent(PipeNotifyState.Session session);
-
-    class PipeNotifyState
-    {
-        public class Session
-        {
-            public PipeConnection<PipeResponse?> Connection { get; }
-
-            public Guid SessionID { get; }
-
-            public Platform Platform { get; }
-
-            public Session(PipeConnection<PipeResponse?> connection, Guid sessionID, Platform platform)
-            {
-                Connection = connection;
-                SessionID = sessionID;
-                Platform = platform;
-            }
-        }
-
-        public ConcurrentDictionary<Guid, Session> SessionMap = new();
-
-        public event PipePollEvent? OnPoll;
-
-        public void Poll(Session session)
-        {
-            OnPoll?.Invoke(session);
-        }
-    }
-
-    class PipeIPCNotifier : Notifier
-    {
-        PipeNotifyState NotifyState { get; set; }
-
-        public PipeIPCNotifier(PipeNotifyState notifyState)
-        {
-            NotifyState = notifyState;
-            NotifyState.OnPoll += NotifyState_OnPoll;
-        }
-
-        private void NotifyState_OnPoll(PipeNotifyState.Session session)
-        {
-            Notify.Poll(session.SessionID);
-        }
-
-        protected override IEnumerable<Guid> GetSessions(Platform platform)
-        {
-            return NotifyState.SessionMap.Where(x => x.Value.Platform == platform).Select(x => x.Key);
-        }
-
-        protected override IEnumerable<Guid> GetUserSessions(Guid userID)
-        {
-            return CredentialsCache.GetUserSessions(userID);
-        }
-
-        protected override void NotifyAll<TNotification>(TNotification notification)
-        {
-            foreach(var session in NotifyState.SessionMap.Values)
-            {
-                session.Connection.WriteAsync(PipeRequest.Notification(notification)).ContinueWith(task =>
-                {
-                    if(task.Exception != null)
-                    {
-                        Logger.Send(LogType.Error, "", $"Error in notification: {CoreUtils.FormatException(task.Exception)}");
-                    }
-                });
-            }
-        }
-
-        protected override void NotifySession<TNotification>(Guid sessionID, TNotification notification)
-        {
-            if(NotifyState.SessionMap.TryGetValue(sessionID, out var session))
-            {
-                session.Connection.WriteAsync(PipeRequest.Notification(notification)).ContinueWith(task =>
-                {
-                    if (task.Exception != null)
-                    {
-                        Logger.Send(LogType.Error, "", $"Error in notification: {CoreUtils.FormatException(task.Exception)}");
-                    }
-                });
-            }
-        }
-
-        protected override void NotifySession(Guid sessionID, Type TNotification, BaseObject notification)
-        {
-            if (NotifyState.SessionMap.TryGetValue(sessionID, out var session))
-            {
-                session.Connection.WriteAsync(PipeRequest.Notification(TNotification, notification)).ContinueWith(task =>
-                {
-                    if (task.Exception != null)
-                    {
-                        Logger.Send(LogType.Error, "", $"Error in notification: {CoreUtils.FormatException(task.Exception)}");
-                    }
-                });
-            }
-        }
-    }
-
-    public class PipeIPCServer : IDisposable
-    {
-        PipeServer<PipeRequest> Server;
-
-        PipeNotifyState NotifyState = new();
-
-        public PipeIPCServer(string name)
-        {
-            Server = new PipeServer<PipeRequest>(name);
-
-            Notify.AddNotifier(new PipeIPCNotifier(NotifyState));
-
-            var pipeSecurity = new PipeSecurity();
-            pipeSecurity.AddAccessRule(new PipeAccessRule(new SecurityIdentifier(WellKnownSidType.LocalSid, null), PipeAccessRights.ReadWrite, System.Security.AccessControl.AccessControlType.Allow));
-            pipeSecurity.AddAccessRule(new PipeAccessRule(new SecurityIdentifier(WellKnownSidType.LocalServiceSid, null), PipeAccessRights.ReadWrite, System.Security.AccessControl.AccessControlType.Allow));
-            pipeSecurity.AddAccessRule(new PipeAccessRule(new SecurityIdentifier(WellKnownSidType.LocalSystemSid, null), PipeAccessRights.ReadWrite, System.Security.AccessControl.AccessControlType.Allow));
-
-            Server.SetPipeSecurity(pipeSecurity);
-
-            Server.ClientConnected += Server_ClientConnected;
-            Server.ClientDisconnected += Server_ClientDisconnected;
-            Server.MessageReceived += Server_MessageReceived;
-            Server.ExceptionOccurred += Server_ExceptionOccurred;
-        }
-
-        private void Server_ExceptionOccurred(object? sender, H.Pipes.Args.ExceptionEventArgs e)
-        {
-            Logger.Send(LogType.Error, "", $"Exception Occurred: {e.Exception.Message}");
-        }
-
-        public void Start()
-        {
-            Server.StartAsync().Wait();
-        }
-
-        private static List<Type>? _persistentRemotable;
-
-        private static Type? GetEntity(string entityName)
-        {
-            _persistentRemotable ??= CoreUtils.TypeList(
-                e => e.IsSubclassOf(typeof(Entity)) &&
-                     e.GetInterfaces().Contains(typeof(IRemotable)) &&
-                     e.GetInterfaces().Contains(typeof(IPersistent))).ToList();
-            return _persistentRemotable.FirstOrDefault(x => x.Name == entityName);
-        }
-
-        private static Type? GetResponseType(Method method, string? entityName)
-        {
-            if(entityName != null)
-            {
-                var entityType = GetEntity(entityName);
-                if(entityType != null)
-                {
-                    var response = method switch
-                    {
-                        Method.Query => typeof(QueryResponse<>).MakeGenericType(entityType),
-                        Method.Delete => typeof(DeleteResponse<>).MakeGenericType(entityType),
-                        Method.MultiDelete => typeof(MultiDeleteResponse<>).MakeGenericType(entityType),
-                        Method.Save => typeof(SaveResponse<>).MakeGenericType(entityType),
-                        Method.MultiSave => typeof(MultiSaveResponse<>).MakeGenericType(entityType),
-                        _ => null
-                    };
-                    if (response != null) return response;
-                }
-            }
-            return method switch
-            {
-                Method.QueryMultiple => typeof(MultiQueryResponse),
-                Method.Validate => typeof(ValidateResponse),
-                Method.Check2FA => typeof(Check2FAResponse),
-                _ => null
-            };
-        }
-
-        private class RequestData
-        {
-            public ConnectionMessageEventArgs<PipeRequest?> e { get; }
-
-            public RequestData(ConnectionMessageEventArgs<PipeResponse?> e)
-            {
-                this.e = e;
-            }
-        }
-
-        private PipeResponse QueryMultiple(PipeRequest request, RequestData data)
-        {
-            var response = RestService.QueryMultiple(request.GetRequest<MultiQueryRequest>(), true);
-            return request.Respond(response);
-        }
-
-        private PipeResponse Validate(PipeRequest request, RequestData data)
-        {
-            var validateRequest = request.GetRequest<ValidateRequest>();
-            var response = RestService.Validate(validateRequest);
-
-            if(response.Session != Guid.Empty)
-            {
-                var newSession = new PipeNotifyState.Session(data.e.Connection, response.Session, validateRequest.Credentials.Platform);
-                NotifyState.SessionMap[response.Session] = newSession;
-                NotifyState.Poll(newSession);
-            }
-
-            return request.Respond(response);
-        }
-
-        private PipeResponse Ping(PipeRequest request, RequestData data) => request.Respond(new PingResponse().Status(StatusCode.OK));
-
-        private PipeResponse Info(PipeRequest request, RequestData data)
-        {
-            var response = RestService.Info(request.GetRequest<InfoRequest>());
-            return request.Respond(response);
-        }
-        
-        private PipeResponse Check2FA(PipeRequest request, RequestData data)
-        {
-            var response = RestService.Check2FA(request.GetRequest<Check2FARequest>());
-            return request.Respond(response);
-        }
-
-        private PipeResponse Query<T>(PipeRequest request, RequestData data) where T : Entity, new()
-        {
-            var response = RestService<T>.List(request.GetRequest<QueryRequest<T>>());
-            return request.Respond(response);
-        }
-
-        private PipeResponse Save<T>(PipeRequest request, RequestData data) where T : Entity, new()
-        {
-            var response = RestService<T>.Save(request.GetRequest<SaveRequest<T>>());
-            return request.Respond(response);
-        }
-        private PipeResponse MultiSave<T>(PipeRequest request, RequestData data) where T : Entity, new()
-        {
-            var response = RestService<T>.MultiSave(request.GetRequest<MultiSaveRequest<T>>());
-            return request.Respond(response);
-        }
-
-        private PipeResponse Delete<T>(PipeRequest request, RequestData data) where T : Entity, new()
-        {
-            var response = RestService<T>.Delete(request.GetRequest<DeleteRequest<T>>());
-            return request.Respond(response);
-        }
-        private PipeResponse MultiDelete<T>(PipeRequest request, RequestData data) where T : Entity, new()
-        {
-            var response = RestService<T>.MultiDelete(request.GetRequest<MultiDeleteRequest<T>>());
-            return request.Respond(response);
-        }
-
-        private static readonly MethodInfo QueryMethod = GetMethod(nameof(Query));
-        private static readonly MethodInfo SaveMethod = GetMethod(nameof(Save));
-        private static readonly MethodInfo MultiSaveMethod = GetMethod(nameof(MultiSave));
-        private static readonly MethodInfo DeleteMethod = GetMethod(nameof(Delete));
-        private static readonly MethodInfo MultiDeleteMethod = GetMethod(nameof(MultiDelete));
-        private static readonly MethodInfo QueryMultipleMethod = GetMethod(nameof(QueryMultiple));
-        private static readonly MethodInfo ValidateMethod = GetMethod(nameof(Validate));
-        private static readonly MethodInfo Check2FAMethod = GetMethod(nameof(Check2FA));
-        private static readonly MethodInfo PingMethod = GetMethod(nameof(Ping));
-        private static readonly MethodInfo InfoMethod = GetMethod(nameof(Info));
-
-        private static MethodInfo GetMethod(string name) =>
-            typeof(PipeIPCServer).GetMethod(name, BindingFlags.NonPublic | BindingFlags.Instance)
-            ?? throw new Exception($"Invalid method '{name}'");
-
-        private void Server_MessageReceived(object? sender, ConnectionMessageEventArgs<PipeRequest?> e)
-        {
-            Task.Run(() =>
-            {
-                var start = DateTime.Now;
-                try
-                {
-                    if (e.Message == null) throw new Exception($"Invalid message");
-
-                    var method = e.Message.Method switch
-                    {
-                        Method.Query => QueryMethod,
-                        Method.QueryMultiple => QueryMultipleMethod,
-                        Method.Delete => DeleteMethod,
-                        Method.MultiDelete => MultiDeleteMethod,
-                        Method.Save => SaveMethod,
-                        Method.MultiSave => MultiSaveMethod,
-                        Method.Check2FA => Check2FAMethod,
-                        Method.Validate => ValidateMethod,
-                        Method.Ping => PingMethod,
-                        Method.Info => InfoMethod,
-                        Method.None or _ => throw new Exception($"Invalid method '{e.Message.Method}'")
-                    };
-
-                    if (e.Message.Type != null)
-                    {
-                        var entityType = GetEntity(e.Message.Type) ?? throw new Exception($"No entity '{e.Message.Type}'");
-                        method = method.MakeGenericMethod(entityType);
-                    }
-
-                    var response = method.Invoke(this, new object[] { e.Message, new RequestData(e) }) as PipeResponse;
-                    e.Connection.WriteAsync(response).ContinueWith(task =>
-                    {
-                        if (task.Exception != null)
-                        {
-                            Logger.Send(LogType.Error, "", $"Error in response: {CoreUtils.FormatException(task.Exception)}");
-                        }
-                    });
-                }
-                catch (Exception err)
-                {
-                    Logger.Send(LogType.Error, "", err.Message);
-                    if (e.Message != null)
-                    {
-                        var responseType = GetResponseType(e.Message.Method, e.Message.Type);
-                        if (responseType != null)
-                        {
-                            var response = (Activator.CreateInstance(responseType) as Response)!;
-                            response.Status = StatusCode.Error;
-                            response.Messages.Add(err.Message);
-                            e.Connection.WriteAsync(e.Message.Respond(response)).ContinueWith(task =>
-                            {
-                                if (task.Exception != null)
-                                {
-                                    Logger.Send(LogType.Error, "", $"Error in response: {CoreUtils.FormatException(task.Exception)}");
-                                }
-                            });
-                        }
-                    }
-                }
-            });
-        }
-
-        private void Server_ClientDisconnected(object? sender, H.Pipes.Args.ConnectionEventArgs<PipeRequest> e)
-        {
-            Logger.Send(LogType.Information, "", "Client Disconnected");
-
-            var sessionID = NotifyState.SessionMap.Where(x => x.Value.Connection == e.Connection).FirstOrDefault().Key;
-            NotifyState.SessionMap.TryRemove(sessionID, out var session);
-
-            e.Connection.DisposeAsync();
-        }
-
-        private void Server_ClientConnected(object? sender, H.Pipes.Args.ConnectionEventArgs<PipeRequest> e)
-        {
-            Logger.Send(LogType.Information, "", "Client Connected");
-        }
-
-        public void Dispose()
-        {
-            Server.DisposeAsync().AsTask().Wait();
-        }
-        ~PipeIPCServer()
-        {
-            Dispose();
-        }
-    }
-}

+ 2 - 2
inabox.client.ipc/IPCClientFactory.cs

@@ -1,6 +1,6 @@
 using InABox.Clients;
 using InABox.Core;
-using InABox.IPC.Shared;
+using InABox.IPC;
 using System;
 using System.Collections.Generic;
 using System.Linq;
@@ -24,7 +24,7 @@ namespace InABox.Client.IPC
             return client;
         }
 
-        private static void Client_OnPush(PipeRequest request)
+        private static void Client_OnPush(IPCMessage request)
         {
             if(request.Method == Method.Notification)
             {

+ 1 - 2
inabox.client.ipc/IPCClientTransport.cs

@@ -1,7 +1,6 @@
 using H.Pipes;
 using InABox.Core;
 using InABox.IPC;
-using InABox.IPC.Shared;
 using System.Collections.Concurrent;
 
 namespace InABox.Client.IPC
@@ -21,7 +20,7 @@ namespace InABox.Client.IPC
         /// <summary>
         /// A handler for any requests pushed from the server, i.e., not initialised by the client.
         /// </summary>
-        public delegate void PushEvent(PipeRequest request);
+        public delegate void PushEvent(IPCMessage request);
 
         public bool Disconnected { get; private set; }