Initial Commit
This commit is contained in:
280
TomcatServer/PlutoServer.MSL/Connectors/SystemAccessVerifier.cs
Normal file
280
TomcatServer/PlutoServer.MSL/Connectors/SystemAccessVerifier.cs
Normal file
@@ -0,0 +1,280 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace PlutoServer.MSL.Connectors
|
||||
{
|
||||
/// <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
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user