Initial Commit

This commit is contained in:
2016-07-27 00:32:34 -04:00
commit 8d162b2035
701 changed files with 188672 additions and 0 deletions

View File

@@ -0,0 +1,84 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>8.0.30703</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{F2A07C3D-6858-421E-9A13-8ADF07372397}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>ChoiceMSLConnect</RootNamespace>
<AssemblyName>ChoiceMSLConnect</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>..\Target\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<PlatformTarget>x86</PlatformTarget>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>..\Target\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<PlatformTarget>x86</PlatformTarget>
</PropertyGroup>
<ItemGroup>
<Reference Include="RemObjects.InternetPack, Version=7.0.63.1055, Culture=neutral, PublicKeyToken=3df3cad1b7aa5098, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\3rdParty\RemObjects\Server\RemObjects.InternetPack.dll</HintPath>
</Reference>
<Reference Include="RemObjects.SDK, Version=7.0.63.1055, Culture=neutral, PublicKeyToken=3df3cad1b7aa5098, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\3rdParty\RemObjects\Server\RemObjects.SDK.dll</HintPath>
</Reference>
<Reference Include="RemObjects.SDK.ZLib, Version=7.0.63.1055, Culture=neutral, PublicKeyToken=3df3cad1b7aa5098, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\3rdParty\RemObjects\Server\RemObjects.SDK.ZLib.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
<Reference Include="Yaulw, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\3rdParty\Sdaleo\Yaulw.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="MSLApi.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="RegistrationWrapper.cs" />
<Compile Include="SystemAccessVerifier.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Pluto.MSL.Api\Pluto.MSL.Api.csproj">
<Project>{B794609D-A93E-41E3-9291-84FC73412347}</Project>
<Name>Pluto.MSL.Api</Name>
</ProjectReference>
<ProjectReference Include="..\RegistrationAPI\RegistrationAPI.csproj">
<Project>{D8974253-F538-4AA6-B567-48B7CD574888}</Project>
<Name>RegistrationAPI</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectView>ShowAllFiles</ProjectView>
</PropertyGroup>
</Project>

View File

@@ -0,0 +1,65 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Pluto.Api;
namespace ChoiceMSLConnect
{
/// <summary>
/// MSL API for Choice
/// </summary>
public static class MSLApi
{
/// <summary>
/// Is it a valid UserApiKey? Only if there is a Pin, it is valid.
/// </summary>
/// <param name="UserApiKey"></param>
/// <returns>true if it is valid, false otherwise</returns>
public static bool IsValidUserApiKey(string UserApiKey)
{
if (!String.IsNullOrEmpty(UserApiKey))
{
string Pin = RegistrationWrapper.RetrievePinForUserApiKey(UserApiKey);
return !String.IsNullOrEmpty(Pin);
}
return false;
}
/// <summary>
/// PostBilling to MSL Client
/// </summary>
/// <param name="UserApiKey"></param>
/// <param name="billingPost"></param>
/// <exception cref="Invalid BillingPost"></exception>
/// <exception cref="Invalid ApiKey"></exception>
/// <exception cref="Client Unreachable"></exception>
public static bool PostBilling(string UserApiKey, bool bCheckClientConnectivityPriorCall, BillingPost1 billingPost)
{
if(billingPost == null)
throw new Exception("Invalid BillingPost");
bool bIsValidUserKey = IsValidUserApiKey(UserApiKey);
if(!bIsValidUserKey)
throw new Exception("Invalid ApiKey");
string ip;
int port;
if (RegistrationWrapper.GetApiMobile(UserApiKey, bCheckClientConnectivityPriorCall, out ip, out port))
{
Pluto.MSL.Api.API.SetNetworkSettings(ip, (uint)port);
SystemAccessVerifier verifier = new SystemAccessVerifier(UserApiKey);
bool bSuccess = Pluto.MSL.Api.API.PostBilling(verifier.SystemApiKey, billingPost);
return bSuccess;
}
else
{
throw new Exception("Client Unreachable");
}
}
}
}

View File

@@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("ChoiceMSLConnect")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("ChoiceMSLConnect")]
[assembly: AssemblyCopyright("Copyright © 2013")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("9758d003-f979-4466-b644-ea8eedae5d2a")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View File

@@ -0,0 +1,201 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Pluto.Api;
using System.Net;
using Pluto.Registration;
namespace ChoiceMSLConnect
{
internal static class RegistrationWrapper
{
// Allow the Registration wrapper to let the Service enter into a different 'disconnected' state
internal static int HasConnectivityErrorCountInARow = 0;
internal static int HasConnectivityErrorCountMaxBeforeStateChange = 10;
internal static string RegistrationHOST = "";
internal static uint RegistrationPORT = 0;
private const string DEFAULT_REGISTRATION_HOST_N_PORT_URL = "http://ppsmobile.mckesson.com/mobile1/REGURL.htm";
private const string DEFAULT_REGISTRATION_HOST_URL = "ppsmobile.mckesson.com";
private const int DEFAULT_REGISTRATION_CHANNEL_PORT = 443;
#region Connectivity
/// <summary>
/// Check to make sure we can communicate with the Registration Service.
/// Check the Server's ip & port for connectivity as well as that this
/// computer has connectivity.
/// This way we won't throw any connectivity errors, which is good.
/// </summary>
/// <returns>true, if successfully can connect, false otherwise</returns>
private static bool HasConnectivity()
{
try
{
bool bCanConnect = false;
bool bUseConfiguration = true;
// Try the overwritten Registration Host and Port first, if exists
if (RegistrationHOST != "" && RegistrationPORT > 0)
{
bCanConnect = Yaulw.Net.IPHostHelper.HasConnectivity(RegistrationHOST, RegistrationPORT, 0);
if (bCanConnect)
bUseConfiguration = false;
}
// Else, fall-back on the configuration, if we couldn't connect
if (!bCanConnect)
{
bCanConnect = Yaulw.Net.IPHostHelper.HasConnectivity(DEFAULT_REGISTRATION_HOST_URL, (uint)DEFAULT_REGISTRATION_CHANNEL_PORT, 0);
if (bCanConnect)
bUseConfiguration = true;
}
if (bCanConnect)
{
if (bUseConfiguration)
{
IPAddress ip = Yaulw.Net.IPHostHelper.GetIpForHost(DEFAULT_REGISTRATION_HOST_URL);
RegistrationAPI.API.SetNetworkSettings(ip.ToString(), (uint)DEFAULT_REGISTRATION_CHANNEL_PORT);
}
else
{
IPAddress ip = Yaulw.Net.IPHostHelper.GetIpForHost(RegistrationHOST);
RegistrationAPI.API.SetNetworkSettings(ip.ToString(), RegistrationPORT);
}
HasConnectivityErrorCountInARow = 0;
}
else
{
// Try to retrieve the latest Host and Port Setting online
try
{
string HostNPortSetOnline = Yaulw.Net.WCHelper.ScreenScrapeFromURL(DEFAULT_REGISTRATION_HOST_N_PORT_URL);
if (!String.IsNullOrEmpty(HostNPortSetOnline))
{
RegistrationHOST = HostNPortSetOnline.Split(';')[0];
RegistrationPORT = uint.Parse(HostNPortSetOnline.Split(';')[1]);
}
}
catch (Exception)
{
/* ignore */
}
// Try to connection one more time
if (RegistrationHOST != "" && RegistrationPORT > 0)
bCanConnect = Yaulw.Net.IPHostHelper.HasConnectivity(RegistrationHOST, RegistrationPORT, 0);
// if we can connect, we are Golden
if (bCanConnect)
{
IPAddress ip = Yaulw.Net.IPHostHelper.GetIpForHost(RegistrationHOST);
RegistrationAPI.API.SetNetworkSettings(ip.ToString(), RegistrationPORT);
HasConnectivityErrorCountInARow = 0;
}
else
{
// Connectivity Errors too plentiful - Change the state of the service to reflect that
if (HasConnectivityErrorCountInARow >= HasConnectivityErrorCountMaxBeforeStateChange)
{
//PlutoService.state = HostGUIDstate.no_connectivity;
}
else
{
HasConnectivityErrorCountInARow++;
}
}
}
return bCanConnect;
}
catch (Exception)
{
}
return false;
}
#endregion
#region Register Methods
/// <summary>
/// Retrieve Pin for UserApiKey
/// </summary>
/// <param name="UserApiKey"></param>
/// <returns></returns>
public static string RetrievePinForUserApiKey(string UserApiKey)
{
try
{
if (!String.IsNullOrEmpty(UserApiKey) && HasConnectivity())
{
string Pin = RegistrationAPI.API.RetrieveUserApiKeyPin(UserApiKey);
return Pin;
}
}
catch (Exception)
{
/* ignore */
}
return String.Empty;
}
/// <summary>
/// Get Api Mobile IP/Port and * optionally * check Connectivity
/// </summary>
/// <returns>true if can connect (only bCheckConnectivity is true), else true if it can get IP/port, false otherwise</returns>
public static bool GetApiMobile(string UserApiKey, bool bCheckConnectivity, out string ip, out int port)
{
ip = String.Empty;
port = 0;
try
{
if (!String.IsNullOrEmpty(UserApiKey) && HasConnectivity())
{
SystemAccessVerifier verifier = new SystemAccessVerifier(UserApiKey);
Host host = RegistrationAPI.API.GetApiMobile(verifier.SystemApiKey);
ip = host.host;
port = host.port;
if (bCheckConnectivity)
return RegistrationAPI.API.IsApiMobileReachable(verifier.SystemApiKey);
else
return true;
}
}
catch (Exception)
{
/* ignore */
}
return false;
}
/// <summary>
/// Get Api Mobile IP/Port
/// </summary>
/// <returns></returns>
public static bool GetApiMobileSystem(string SystemApiKey, out string ip, out int port)
{
ip = String.Empty;
port = 0;
try
{
if (!String.IsNullOrEmpty(SystemApiKey) && HasConnectivity())
{
Host host = RegistrationAPI.API.GetApiMobile(SystemApiKey);
ip = host.host;
port = host.port;
return RegistrationAPI.API.IsApiMobileReachable(SystemApiKey);
}
}
catch (Exception)
{
/* ignore */
}
return false;
}
#endregion
}
}

View File

@@ -0,0 +1,280 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ChoiceMSLConnect
{
/// <summary>
/// This class is copied (Stripped down to it's core, with all unneccessary stuff for this instance removed)
/// from Registration Server's SystemAccessVerifier.
/// All new code should go there. No Pin is generated here. The pin for a userkey
/// should always be generated at the registration server.
/// This class however can be used to convert a SystemApiKey to a UserApiKey, usefull for what we are
/// trying to do in this service
/// </summary>
internal class SystemAccessVerifier
{
#region Consts
const int SYSTEM_API_KEY_LENGTH = 22;
const int USER_API_KEY_LENGTH = 20;
const int PIN_LENGTH = 6;
const string SYSTEM_API_KEY_BEGIN_MARKER = "$";
const string SYSTEM_API_KEY_END_MARKER = "#";
internal static readonly string LETTER_CHARS = "AZXVGLTCIRKPNOMQJSHUFWDEYB";
internal static int GET_LETTER_CHARS_COUNT { get { return LETTER_CHARS.Length; } }
#endregion
#region System Api Key
private string _systemApiKey = String.Empty;
internal string SystemApiKey
{
get
{
return _systemApiKey;
}
set
{
if (ValidateSystemKey(value))
_systemApiKey = value.ToUpper().Trim();
}
}
private static bool ValidateSystemKey(string key)
{
if (!String.IsNullOrEmpty(key))
key = key.ToUpper().Trim();
// $247B2CB4A437EB74C62#M
if (!String.IsNullOrEmpty(key) && key.Length == SYSTEM_API_KEY_LENGTH &&
key[0] == Char.Parse(SYSTEM_API_KEY_BEGIN_MARKER) && key[SYSTEM_API_KEY_LENGTH - 2] == Char.Parse(SYSTEM_API_KEY_END_MARKER) &&
Char.IsLetter(key[SYSTEM_API_KEY_LENGTH - 1]))
{
// AllAreLettersOrDigit?
for (int i = 1; i < SYSTEM_API_KEY_LENGTH - 2; ++i)
{
if (!Char.IsLetterOrDigit(key[i]))
return false;
}
return true;
}
return false;
}
#endregion
#region User Api Key
private string _UserApiKey = String.Empty;
internal string UserApiKey
{
get
{
return _UserApiKey;
}
set
{
if (ValidateUserKey(value))
_UserApiKey = value.ToUpper().Trim();
}
}
private static bool ValidateUserKey(string key)
{
if (!String.IsNullOrEmpty(key))
key = key.ToUpper().Trim();
//247BQCB4A-37EB-4C62M
if (!String.IsNullOrEmpty(key) && key.Length == USER_API_KEY_LENGTH &&
Char.IsLetter(key[USER_API_KEY_LENGTH - 1]) &&
Char.IsLetter(key[4]) && key[9] == '-' && key[14] == '-')
{
// Perform Product Security check
char productType = key[USER_API_KEY_LENGTH - 1];
int v = (int)productType % GET_LETTER_CHARS_COUNT;
if (key[4] == LETTER_CHARS[v])
return true;
}
return false;
}
#endregion
#region Product Type
private char _productType = '\0';
internal char ProductType { get { return Char.ToUpper(_productType); } }
internal bool IsValidProductType { get { return (_productType != '\0'); } }
#endregion
#region Construction
internal SystemAccessVerifier(string userApiKey)
{
if (!String.IsNullOrEmpty(userApiKey))
userApiKey = userApiKey.ToUpper().Trim();
if (ValidateUserKey(userApiKey))
{
UserApiKey = userApiKey;
ConvertUserToSystemApiKey();
_productType = GetProductTypeFromSystemApiKey(SystemApiKey);
}
}
#endregion
#region Private Converters
private void ConvertUserToSystemApiKey()
{
if (ValidateUserKey(UserApiKey))
{
// 247BQCB4A-37EB-4C62M
StringBuilder sb = new StringBuilder(UserApiKey);
char productType = sb[USER_API_KEY_LENGTH - 1];
sb.Remove(USER_API_KEY_LENGTH - 1, 1);
// Add More Randomness into this (nobody will ever know :S)
// Dynamic Calc for 2 - 2, 12 - 4
int a = (int)'A';
int z = (int)'Z';
int ic = (int)sb[2];
if ((ic - 2 >= a) && (ic <= z))
sb[2] = (char)(ic - 2);
ic = sb[12];
if ((ic - 4 >= a) && (ic <= z))
sb[12] = (char)(ic - 4);
//Otherway arround arbitrary swap (just in case)
// Swap 3 to 10, and 5 to 16
char c = sb[3];
sb[3] = sb[10];
sb[10] = c;
c = sb[5];
sb[5] = sb[16];
sb[16] = c;
// Assign '-'
sb[4] = '-';
// How clever :S
string s = ReverseString(sb.ToString());
int n = 0;
sb = new StringBuilder(s);
for (int i = 0; i < s.Length; ++i)
{
if (s[i] == '-')
{
sb[i] = (s[n]);
n++;
}
else
{
sb[i] = (s[i]);
}
}
// $247B2CB4A437EB74C62#M
s = SYSTEM_API_KEY_BEGIN_MARKER + sb.ToString() + SYSTEM_API_KEY_END_MARKER + Char.ToUpper(productType);
SystemApiKey = s;
}
}
#endregion
#region Internal Statics
internal static char GetProductTypeFromSystemApiKey(string systemApiKey)
{
if (ValidateSystemKey(systemApiKey))
return Char.ToUpper(systemApiKey[SYSTEM_API_KEY_LENGTH - 1]);
else
return '\0';
}
#endregion
#region Private static Key Generation Helper Functions
private static string ReverseString(string str)
{
if (!String.IsNullOrEmpty(str))
{
Stack<char> stack = new Stack<char>();
foreach (char c in str)
stack.Push(c);
StringBuilder sb = new StringBuilder();
while (stack.Count > 0)
sb.Append(stack.Pop());
return sb.ToString();
}
return String.Empty;
}
/// <summary>
/// Perform checksum on string
/// </summary>
/// <param name="strAboutToBeChecksummed"></param>
/// <returns>Checksum</returns>
private static int PerformChecksum(string strAboutToBeChecksummed)
{
if (!String.IsNullOrEmpty(strAboutToBeChecksummed))
{
int nChecksum = 0;
for (int i = 0; i < strAboutToBeChecksummed.Length; ++i)
{
if (Char.IsDigit(strAboutToBeChecksummed[i]))
nChecksum = nChecksum + int.Parse(strAboutToBeChecksummed[i].ToString());
}
return nChecksum;
}
return 0;
}
/// <summary>
/// Dash a String every Nth Character
/// </summary>
/// <returns>a dashed string</returns>
private static string MakeIntoDashSeperatedString(string strAboutToBeDashed, int DashEveryNthCharacter)
{
if (!String.IsNullOrEmpty(strAboutToBeDashed))
{
StringBuilder sb = new StringBuilder();
for (int i = 0; i < strAboutToBeDashed.Length; i++)
{
if ((i != 0) && ((i % DashEveryNthCharacter) == 0))
sb.Append("-");
sb.Append(strAboutToBeDashed[i]);
}
return sb.ToString();
}
return String.Empty;
}
/// <summary>
/// Undash a String
/// </summary>
/// <returns>a string without dashes</returns>
private static string MakeIntoDashUnseperatedString(string strAboutToBeUndashed)
{
if (!String.IsNullOrEmpty(strAboutToBeUndashed))
return strAboutToBeUndashed.Replace("-", "");
return String.Empty;
}
/// <summary>
/// Check if the passed in string contains only digits
/// </summary>
/// <param name="strToCheckForDigits">string to check for digits for</param>
/// <returns>true, if all digits are numbers</returns>
private static bool ContainsOnlyDigits(string strToCheckForDigits)
{
if (!String.IsNullOrEmpty(strToCheckForDigits))
{
for (int i = 0; i < strToCheckForDigits.Length; ++i)
{
if (!Char.IsDigit(strToCheckForDigits[i]))
return false;
}
return true;
}
return false;
}
#endregion
}
}