| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308 | using System;using System.Collections.Generic;using System.Diagnostics;using System.Diagnostics.CodeAnalysis;using System.IO;using System.Linq;using System.Net.NetworkInformation;namespace InABox.Core{    public static class LicenseUtils    {        #region Mac Addresses                public static String[] GetMacAddresses()        {            return NetworkInterface                .GetAllNetworkInterfaces()                .Where(nic =>                    nic.OperationalStatus == OperationalStatus.Up &&                    nic.NetworkInterfaceType != NetworkInterfaceType.Loopback)                .Select(nic => nic.GetPhysicalAddress().ToString()).ToArray();        }        public static bool ValidateMacAddresses(String[] addresses)        {            var hardware = GetMacAddresses();            return hardware.Any(addresses.Contains);        }                #endregion                #region License Generation                public static LicenseData RenewLicense(LicenseData oldLicense, DateTime renewed, DateTime newExpiry, DateTime renewAvailable, String[] addresses)        {            return new LicenseData            {                LastRenewal = renewed,                Expiry = newExpiry,                CustomerID = oldLicense?.CustomerID ?? Guid.Empty,                RenewalAvailable = renewAvailable,                Addresses = addresses,                IsDynamic = oldLicense?.IsDynamic ?? false            };        }                private static readonly byte[] LicenseKey = Convert.FromBase64String("dCyTyQkj1o1rqJJQlT+Jcnkxr+OQnO4KCoF/b+6cx54=");                public static string? EncryptLicenseRequest(LicenseRequest request)        {            return Encryption.EncryptV2(Serialization.Serialize(request), LicenseKey);        }                public static bool TryEncryptLicenseRequest(LicenseRequest request, [NotNullWhen(true)] out string? result, [NotNullWhen(false)] out string? error)        {            return Encryption.TryEncryptV2(Serialization.Serialize(request), LicenseKey, out result, out error);        }                /// <summary>        /// Decrypts <paramref name="request"/>.        /// </summary>        /// <param name="request">The request to decrypt.</param>        /// <returns>        /// The new license request, or <see langword="null"/> if errors occurred.        /// </returns>        public static bool TryDecryptLicenseRequest(string data, [NotNullWhen(true)] out LicenseRequest? result, [NotNullWhen(false)] out string? error)        {            if (!Encryption.TryDecryptV2(data, LicenseKey, out var decrypted, out error))            {                result = null;                return false;            }            result = Serialization.Deserialize<LicenseRequest>(decrypted);            if(result == null)            {                error = "Request deserialization failed";                return false;            }            return true;        }        /// <summary>        /// Decrypts <paramref name="request"/>, throwing an <see cref="Exception"/> on fail.        /// </summary>        /// <param name="request">The data to decrypt.</param>        /// <returns>        /// The new license request.        /// </returns>        public static LicenseRequest DecryptLicenseRequest(string data)        {            if (!TryDecryptLicenseRequest(data, out var result, out var error))                throw new Exception(error);            return result;        }        /// <summary>        /// Encrypts the license data.        /// </summary>        /// <param name="license">The license to encrypt.</param>        /// <returns>        /// The encrypted data.        /// </returns>        public static string? EncryptLicense(LicenseData license)        {            return Encryption.EncryptV2(Serialization.Serialize(license), LicenseKey);        }                public static bool TryEncryptLicense(LicenseData license, [NotNullWhen(true)] out string? result, [NotNullWhen(false)] out string? error)        {            return Encryption.TryEncryptV2(Serialization.Serialize(license), LicenseKey, out result, out error);        }        /// <summary>        /// Decrypts <paramref name="license"/>.        /// </summary>        /// <param name="license">The license to decrypt.</param>        /// <returns>        /// The new license data, or <see langword="null"/> if errors occurred.        /// </returns>        public static bool TryDecryptLicense(string data, [NotNullWhen(true)] out LicenseData? result, [NotNullWhen(false)] out string? error)        {            if (!Encryption.TryDecryptV2(data, LicenseKey, out var decrypted, out error))            {                result = null;                return false;            }            result = Serialization.Deserialize<LicenseData>(decrypted);            if(result == null)            {                error = "License deserialization failed";                return false;            }            return true;        }        /// <summary>        /// Decrypts <paramref name="license"/>, throwing an <see cref="Exception"/> on fail.        /// </summary>        /// <param name="license">The license to decrypt.</param>        /// <returns>        /// The new license data.        /// </returns>        public static LicenseData DecryptLicense(string data)        {            if (!TryDecryptLicense(data, out var result, out var error))                throw new Exception(error);            return result;        }        #endregion        #region Fees & Discounts        private static readonly Dictionary<String, double> _licensefees = new Dictionary<String, double>();        private static readonly Dictionary<int, double> _periods = new Dictionary<int, double>();        private static readonly Dictionary<int, double> _userDiscounts = new Dictionary<int, double>();        public static double GetLicenseFee(String type)        {            return _licensefees.GetValueOrDefault(type, 0);        }        public static double GetLicenseFee<T>() where T : LicenseToken        {            return GetLicenseFee(typeof(T).EntityName());        }        public static IEnumerable<String> LicenseTypes()        {            return _licensefees.Keys;        }        public static double GetUserDiscount(int users)        {            var key = _userDiscounts.Keys                .Where(x => x <= users)                .DefaultIfEmpty(-1)                .Max();            if (key == -1)                return 0;            return _userDiscounts[key];        }        public static double GetTimeDiscount(int months)        {            var period = _periods.Keys                .Where(x => x <= months)                .DefaultIfEmpty(-1)                .Max();            if (period == -1)                return 0;            return _periods[period];        }        public static IEnumerable<int> TimeDiscountLevels()        {            return _periods.Keys;        }        public static double CalculateLicenseFee(Dictionary<String, int> licenses, int time)        {            double licensefee = 0.00F;            foreach (var license in licenses.Keys)                if (_licensefees.ContainsKey(license))                    licensefee += _licensefees[license] * licenses[license];            var users = licenses.Values.OrderBy(x => x).LastOrDefault();            var userdiscount = GetUserDiscount(users);            var timediscount = GetTimeDiscount(time);            var result = licensefee * ((100.0F - userdiscount) / 100.0F) * ((100.0F - timediscount) / 100.0F);            return result;        }        public static void LoadSummary(LicenseFeeResponse feeResponse)        {            _licensefees.Clear();            _periods.Clear();            _userDiscounts.Clear();            foreach (var license in feeResponse.LicenseFees)                _licensefees[license.Key] = license.Value;            foreach (var (months, period) in feeResponse.TimeDiscounts)                _periods[months] = period;            foreach (var (users, discount) in feeResponse.UserDiscounts)                _userDiscounts[users] = discount;        }        /// <summary>        /// Gets a map from entities to their associated licenses.        /// </summary>        /// <returns>A map of entity types to license types.</returns>        public static Dictionary<Type, Type> LicenseMap()        {            var result = new Dictionary<Type, Type>();            var licenses = CoreUtils.TypeList(                AppDomain.CurrentDomain.GetAssemblies(),                myType =>                    myType.IsClass                    && !myType.IsAbstract                    && !myType.IsGenericType                    && myType.IsSubclassOf(typeof(LicenseToken))            ).ToArray();            var entities = CoreUtils.TypeList(                AppDomain.CurrentDomain.GetAssemblies(),                myType =>                    myType.IsClass                    && !myType.IsAbstract                    && !myType.IsGenericType                    && myType.IsSubclassOf(typeof(Entity))            ).ToArray();            foreach (var entity in entities)            {                var lic = entity.GetInterfaces()                    .FirstOrDefault(x => x.IsConstructedGenericType && x.GetGenericTypeDefinition() == typeof(ILicense<>));                result[entity] = lic?.GenericTypeArguments.FirstOrDefault();            }            return result;        }        public static void SaveLicenseSummary(string filename)        {            var entitymap = LicenseMap();            var summary = new List<string> { "\"License Token\",\"Class Name\"" };            foreach (var mapentry in entitymap.OrderBy(x => x.Value))                summary.Add(string.Format("\"{0}\",\"{1}\"", mapentry.Value?.GetCaption(), mapentry.Value.EntityName()));            File.WriteAllLines(filename, summary.ToArray());        }        public static void Reset()        {            _licensefees.Clear();            _periods.Clear();            _userDiscounts.Clear();        }        #endregion    }    public class LicenseFeeRequest    {        public Guid RegistrationID { get; set; }    }        public class LicenseFeeResponse    {        public LicenseFeeResponse()        {            LicenseFees = new Dictionary<string, double>();            TimeDiscounts = new Dictionary<int, double>();            UserDiscounts = new Dictionary<int, double>();        }                public Dictionary<string, double> LicenseFees { get; set; }        public Dictionary<int, double> TimeDiscounts { get; set; }        public Dictionary<int, double> UserDiscounts { get; set; }    }}
 |