//------------------------------------------------------------------------------ // // This code was generated by a tool. // Runtime Version:2.0.50727.4971 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. // //------------------------------------------------------------------------------ namespace Pluto.Registration { using System; using RemObjects.SDK; using RemObjects.SDK.Types; using RemObjects.SDK.Server; using RemObjects.SDK.Server.ClassFactories; using System.Net; using System.Net.Sockets; using System.Diagnostics; using RegistrationServer; using Yaulw.Assembly; using Yaulw.File; using Yaulw.Tools; [RemObjects.SDK.Server.ClassFactories.StandardClassFactory()] [RemObjects.SDK.Server.Service(Name = "Registration", InvokerClass = typeof(Registration_Invoker), ActivatorClass = typeof(Registration_Activator))] public class Registration : RemObjects.SDK.Server.Service, IRegistration { private System.ComponentModel.Container components = null; public Registration() : base() { this.InitializeComponent(); } private void InitializeComponent() { } protected override void Dispose(bool aDisposing) { if (aDisposing) { if ((this.components != null)) { this.components.Dispose(); } } base.Dispose(aDisposing); } #region Logging /// /// For Logging to a File /// internal static Logging Logger = null; /// /// Setup the Logger Object, should be done only once at when the application starts /// internal static void Setup_Logger() { if (Logger == null) { // Default Log File Settings const int LOG_FILE_FILE_SIZE_IN_MB = 4; const int LOG_FILE_NUM_OF_BACKUPS = 2; const string FILE_EXTENSION_LOG_DEFAULT = "log"; // Default Log File Name N Path Settings string Path = AssemblyW.SpecializedAssemblyInfo.GetAssemblyPath(AssemblyW.AssemblyST.Entry); string LogFileNameNPath = PathNaming.PathEndsWithSlash(Path) + AssemblyW.GetAssemblyName(AssemblyW.AssemblyST.Entry) + "." + FILE_EXTENSION_LOG_DEFAULT; // Log Config Logging_Configuration config = new Logging_Configuration(); config.LogFileNameNPath = LogFileNameNPath; config.maxFileSizeInMB = LOG_FILE_FILE_SIZE_IN_MB; config.numOfBackupLogFiles = LOG_FILE_NUM_OF_BACKUPS; config.Log4NetDetailPatternLayout = "%date{dd MMM HH:mm:ss,fff} %level - %message%newline"; config.LogCallingType = false; config.LogCallingFunction = false; config.Detail = Logging_Detail.DEBUG; config.UseExclusiveFileLock = false; // Now just create the Logger Logger = Logging.AddGlobalLoggerConfiguration(AssemblyW.GetAssemblyName(AssemblyW.AssemblyST.Entry), config); // Make a Debug Message show, Logger.Info("Logger Started at:{0}", DateTime.Now.ToString()); } } #endregion #region IMP Get Registration Server (could be Important for Migration) /// /// Get Host and IP of the Registration Server, /// useful when we plan on switching later /// /// /// public virtual Host GetRegistrationServer(string SystemApiKey) { // For now only pass out * this service's configuration * var host = new Host(); host.host = Configuration.Url; host.port = Configuration.Port; return host; } #endregion #region Retrieve IP n Port Stuff /// /// Get Mobile Host /// /// /// public virtual Host GetApiHostMobile(string SystemApiKey) { Host host = new Host(); try { int p; string h; string n; if (DataAccessLayer.RetrieveIPMobileAndPort(SystemApiKey, out h, out p, out n)) { host.host = h; host.port = p; host.practiceName = n; } } catch (Exception e) { Logger.Error("GetApiHostMobile Error", e); } return host; } /// /// Get Wifi Host /// /// /// public virtual Host GetApiHostWifi(string SystemApiKey) { Host host = new Host(); try { int p; string h; string n; if (DataAccessLayer.RetrieveIPWifiAndPort(SystemApiKey, out h, out p, out n)) { host.host = h; host.port = p; host.practiceName = n; } } catch (Exception e) { Logger.Error("GetApiHostMobile Error", e); } return host; } #endregion #region MSLConnect Call-Ins /// /// Register a New Server Practice /// /// /// /// /// /// /// public virtual bool RegisterNewServerPractice(string PracticeName, Server server, string serverType, out string UserApiKey, out string UserApiPin) { UserApiKey = String.Empty; UserApiPin = String.Empty; try { // One IP must exist! bound to a Practice ~otherwise, what is the point if ((String.IsNullOrEmpty(server.InternalIP) && String.IsNullOrEmpty(server.ExternalIP)) || String.IsNullOrEmpty(PracticeName)) { Logger.Error("RegisterNewServerPractice at least one IP must be passed in and a Practice Name"); return false; } if (String.IsNullOrEmpty(server.HostGUID)) { Logger.Error("Server HostGUID must be passed in"); return false; } if (String.IsNullOrEmpty(serverType)) { Logger.Error("serverType must be passed in"); return false; } // create GUID from HostGUID Guid guid = new Guid(server.HostGUID); Logger.Info("RegisterNewServerPractice called() for Practice {0} Product {1} Host_GUID {2}", PracticeName, serverType, server.HostGUID); // Make sure that the SystemApiKey doesn't already exist * Do this up to 15 times just in case* // more than that would be terrible system api key algorigthm bool bIsUniqueSystemKey = false; string SystemApiKey = SystemAccessVerifier.GenerateNewSystemApiKey(serverType[0]); for (int i = 0; i < 10; ++i) { bIsUniqueSystemKey = !DataAccessLayer.System_Api_Key_Exist(SystemApiKey); if (bIsUniqueSystemKey) break; else SystemApiKey = SystemAccessVerifier.GenerateNewSystemApiKey(serverType[0]); } // We should only get here if we can validly insert a record with non-existing System Key if (bIsUniqueSystemKey) { bool bRegisterSuccess = DataAccessLayer.RegisterNewServerPractice(SystemApiKey, guid, server.InternalIP, server.ExternalIP, (uint)server.Port, PracticeName); if (bRegisterSuccess) { SystemAccessVerifier verifier = new SystemAccessVerifier(SystemApiKey); UserApiKey = verifier.UserApiKey; UserApiPin = verifier.Pin; return bRegisterSuccess; } } else { Logger.Error("RegisterNewServerPractice Error: System Key '{0}' already exists. 10x wasn't enought to generate a new one. Very Illogical!", SystemApiKey); } } catch (Exception e) { Logger.Error("RegisterNewServerPractice Error", e); } return false; } /// /// Retrieve the System API Key for a UserApiKey and UserApiPin /// /// /// /// public virtual string RegisterNewClient(string UserApiKey, string UserApiPin) { try { // Check all our inputs if (!String.IsNullOrEmpty(UserApiKey) && !String.IsNullOrEmpty(UserApiPin) ) { // Retrieve the System Key from their credentials string SystemApiKey = String.Empty; SystemAccessVerifier verifier = new SystemAccessVerifier(UserApiKey, UserApiPin); if (!String.IsNullOrEmpty(verifier.SystemApiKey)) { // Check to make sure that this system key exists if (!DataAccessLayer.System_Api_Key_Exist(verifier.SystemApiKey)) { Logger.Error("System Key '{2}' retrieval failed for registering a New Client with UserApiKey '{0}' and Pin '{1}'", UserApiKey, UserApiPin, verifier.SystemApiKey); return String.Empty; } return verifier.SystemApiKey; } else { Logger.Error("System Key '{2}' verification failed for registering a New Client with UserApiKey '{0}' and Pin '{1}'", UserApiKey, UserApiPin, verifier.SystemApiKey); } } } catch (Exception e) { Logger.Error("RegisterNewServerPractice Error", e); } return String.Empty; } /// /// Retrieve Pin for a Client /// /// /// public virtual string RetrieveNewClientPin(string UserApiKey) { try { if (!String.IsNullOrEmpty(UserApiKey)) { string Pin = SystemAccessVerifier.RetrieveUserApkiKeyPin(UserApiKey); if (!String.IsNullOrEmpty(Pin)) return Pin; else Logger.Error("Failed to retrieve Pin for UserApiKey:{0}", UserApiKey); } } catch (Exception e) { Logger.Error("RetrieveNewClientPin Error", e); } return String.Empty; } /// /// Update the Server /// /// /// public virtual bool UpdateServer(Server server) { try { Guid guid = new Guid(server.HostGUID); bool bSuccess = DataAccessLayer.UpdateServer(guid, server.InternalIP, server.ExternalIP, (uint)server.Port); return bSuccess; } catch (Exception e) { Logger.Error("UpdateServer Error", e); } return false; } /// /// Update Practice Name /// /// /// /// /// public virtual bool UpdatePracticeName(string UserApiKey, string UserApiPin, string PracticeName) { try { // Retrieve the System Key from their credentials string SystemApiKey = String.Empty; SystemAccessVerifier verifier = new SystemAccessVerifier(UserApiKey, UserApiPin); if (!String.IsNullOrEmpty(verifier.SystemApiKey)) { bool bSuccess = UpdatePracticeName2(verifier.SystemApiKey, PracticeName); return bSuccess; } else Logger.Error("Failed to Retrieve SystemApiKey for UserApiKey:{0} and Pin:{1}", UserApiKey, UserApiPin); } catch (Exception e) { Logger.Error("UpdatePracticeName Error", e); } return false; } /// /// Update Practice Name 2 /// /// /// /// public virtual bool UpdatePracticeName2(string SystemApiKey, string PracticeName) { try { bool bSuccess = DataAccessLayer.UpdatePracticeName(SystemApiKey, PracticeName); return bSuccess; } catch (Exception e) { Logger.Error("UpdatePracticeName2 Error", e); } return false; } /// /// Same really as IsServerReachable except that it can be called by just passing in /// a System API Key /// /// /// public virtual bool IsClientReachable(string SystemApiKey) { Host host = GetApiHostMobile(SystemApiKey); Server server = new Server(); server.ExternalIP = host.host; server.Port = host.port; bool bCanConnect = IsServerReachable(server); if (!bCanConnect) Logger.Error("IsClientReachable call to IsServerReachable returned false"); return bCanConnect; } /// /// Check to see if the specified external IP address and port can be reached from here /// Must be on a different port than this server is running on /// /// /// public virtual bool IsServerReachable(Server server) { // To Do: in the future! - Check to see if the IP address is not private range, // no need to do a port open on a private IP address, we should never be called with a private IP! // if we do that is an error. IPAddress ip = IPAddress.None; if (String.IsNullOrEmpty(server.ExternalIP) || server.Port == Configuration.Port || !IPAddress.TryParse(server.ExternalIP, out ip) || !Yaulw.Net.IPHostHelper.IsValidIPv4Address(ip, false)) { Logger.Error("Invalid IP/configuration passed into IsServerReachable IP:{0} Port:{1}", ip, server.Port); return false; } bool bCanConnect = Yaulw.Net.IPHostHelper.IsPortOpen(ip, server.Port); return bCanConnect; } /// /// Calls Pluto API on the specified server and port to try to get the HOST GUID /// from there. This is done on purpose to check that the service that is up could /// actually belong to ourselves /// /// Valid Server Object with the external IP set and valid port /// will return the HOST GUID of the Pluto Instance, if found, otherwise "" public virtual string RetrieveHostGUIDForServerFromInternet(Server server) { try { IPAddress ip = IPAddress.None; if (String.IsNullOrEmpty(server.ExternalIP) || server.Port == Configuration.Port || !IPAddress.TryParse(server.ExternalIP, out ip) || !Yaulw.Net.IPHostHelper.IsValidIPv4Address(ip, false)) { Logger.Error("Invalid IP/configuration passed into RetrieveHostGUIDForServerFromInternet IP:{0} Port:{1}", ip, server.Port); return String.Empty; } // Try to use Pluto Api to retrieve the Pluto instance's HOST GUID Pluto.MSL.Api.API.SetNetworkSettings(ip.ToString(), (uint)server.Port); string FoundHostGuid = Pluto.MSL.Api.API.GetHostGUID(); if (!String.IsNullOrEmpty(FoundHostGuid)) return FoundHostGuid; } catch (Exception e) { Logger.Error("RetrieveHostGUIDForServerFromInternet Error", e); } return String.Empty; } #endregion #region Pluto AddOns /// /// Checks to see if the Host GUID exists on the Database /// /// /// public virtual bool DoesServerHostGUIDExist(string HostGUID) { try { Guid guid = new Guid(HostGUID); bool bExists = DataAccessLayer.Host_Guid_Exist(guid); return bExists; } catch (Exception e) { Logger.Error("DoesServerHostGUIDExist Error", e); } return false; } /// /// Updates the version for the specified Host GUID /// /// /// public virtual void ServerHasBeenUpdated(string HostGUID, string Version) { try { Guid guid = new Guid(HostGUID); DataAccessLayer.HostHasBeenUpdated(guid, Version); } catch (Exception e) { Logger.Error("ServerHasBeenUpdated Error", e); } } /// /// GetClients used for internal / corporate /// /// /// public virtual Client[] GetClients(bool IsInternal) { try { Client[] clients = DataAccessLayer.GetClients(IsInternal); return clients; } catch (Exception e) { Logger.Error("GetClients Error", e); } return null; } #endregion } }