299 lines
9.6 KiB
C#
299 lines
9.6 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Drawing;
|
|
using System.Linq;
|
|
using System.Text.RegularExpressions;
|
|
using System.Web;
|
|
using Bit.Core.Models.Domain;
|
|
using Bit.Core.Services;
|
|
using Newtonsoft.Json;
|
|
|
|
namespace Bit.Core.Utilities
|
|
{
|
|
public static class CoreHelpers
|
|
{
|
|
public static readonly string IpRegex =
|
|
"^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\." +
|
|
"(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\." +
|
|
"(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\." +
|
|
"(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$";
|
|
|
|
public static readonly string TldEndingRegex =
|
|
".*\\.(com|net|org|edu|uk|gov|ca|de|jp|fr|au|ru|ch|io|es|us|co|xyz|info|ly|mil)$";
|
|
|
|
public static readonly DateTime Epoc = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
|
|
|
|
public static long EpocUtcNow()
|
|
{
|
|
return (long)(DateTime.UtcNow - Epoc).TotalMilliseconds;
|
|
}
|
|
|
|
public static bool InDebugMode()
|
|
{
|
|
#if DEBUG
|
|
return true;
|
|
#else
|
|
return false;
|
|
#endif
|
|
}
|
|
|
|
public static string GetHostname(string uriString)
|
|
{
|
|
var uri = GetUri(uriString);
|
|
return string.IsNullOrEmpty(uri?.Host) ? null : uri.Host;
|
|
}
|
|
|
|
public static string GetHost(string uriString)
|
|
{
|
|
var uri = GetUri(uriString);
|
|
if (!string.IsNullOrEmpty(uri?.Host))
|
|
{
|
|
if (uri.IsDefaultPort)
|
|
{
|
|
return uri.Host;
|
|
}
|
|
else
|
|
{
|
|
return string.Format("{0}:{1}", uri.Host, uri.Port);
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
public static string GetDomain(string uriString)
|
|
{
|
|
var uri = GetUri(uriString);
|
|
if (uri == null)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
if (uri.Host == "localhost" || Regex.IsMatch(uri.Host, IpRegex))
|
|
{
|
|
return uri.Host;
|
|
}
|
|
try
|
|
{
|
|
if (DomainName.TryParseBaseDomain(uri.Host, out var baseDomain))
|
|
{
|
|
return baseDomain ?? uri.Host;
|
|
}
|
|
}
|
|
catch { }
|
|
return null;
|
|
}
|
|
|
|
public static Uri GetUri(string uriString)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(uriString))
|
|
{
|
|
return null;
|
|
}
|
|
var hasHttpProtocol = uriString.StartsWith("http://") || uriString.StartsWith("https://");
|
|
if (!hasHttpProtocol && !uriString.Contains("://") && uriString.Contains("."))
|
|
{
|
|
if (Uri.TryCreate("http://" + uriString, UriKind.Absolute, out var uri))
|
|
{
|
|
return uri;
|
|
}
|
|
}
|
|
if (Uri.TryCreate(uriString, UriKind.Absolute, out var uri2))
|
|
{
|
|
return uri2;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
public static void NestedTraverse<T>(List<TreeNode<T>> nodeTree, int partIndex, string[] parts,
|
|
T obj, T parent, char delimiter) where T : ITreeNodeObject
|
|
{
|
|
if (parts.Length <= partIndex)
|
|
{
|
|
return;
|
|
}
|
|
|
|
var end = partIndex == parts.Length - 1;
|
|
var partName = parts[partIndex];
|
|
foreach (var n in nodeTree)
|
|
{
|
|
if (n.Node.Name != parts[partIndex])
|
|
{
|
|
continue;
|
|
}
|
|
if (end && n.Node.Id != obj.Id)
|
|
{
|
|
// Another node with the same name.
|
|
nodeTree.Add(new TreeNode<T>(obj, partName, parent));
|
|
return;
|
|
}
|
|
NestedTraverse(n.Children, partIndex + 1, parts, obj, n.Node, delimiter);
|
|
return;
|
|
}
|
|
if (!nodeTree.Any(n => n.Node.Name == partName))
|
|
{
|
|
if (end)
|
|
{
|
|
nodeTree.Add(new TreeNode<T>(obj, partName, parent));
|
|
return;
|
|
}
|
|
var newPartName = string.Concat(parts[partIndex], delimiter, parts[partIndex + 1]);
|
|
var newParts = new List<string> { newPartName };
|
|
var newPartsStartFrom = partIndex + 2;
|
|
newParts.AddRange(new ArraySegment<string>(parts, newPartsStartFrom, parts.Length - newPartsStartFrom));
|
|
NestedTraverse(nodeTree, 0, newParts.ToArray(), obj, parent, delimiter);
|
|
}
|
|
}
|
|
|
|
public static TreeNode<T> GetTreeNodeObject<T>(List<TreeNode<T>> nodeTree, string id) where T : ITreeNodeObject
|
|
{
|
|
foreach (var n in nodeTree)
|
|
{
|
|
if (n.Node.Id == id)
|
|
{
|
|
return n;
|
|
}
|
|
else if (n.Children != null)
|
|
{
|
|
var node = GetTreeNodeObject(n.Children, id);
|
|
if (node != null)
|
|
{
|
|
return node;
|
|
}
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
public static Dictionary<string, string> GetQueryParams(string urlString)
|
|
{
|
|
try
|
|
{
|
|
if (Uri.TryCreate(urlString, UriKind.Absolute, out var uri))
|
|
{
|
|
return GetQueryParams(uri);
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
LoggerHelper.LogEvenIfCantBeResolved(ex);
|
|
}
|
|
return new Dictionary<string, string>();
|
|
}
|
|
|
|
public static Dictionary<string, string> GetQueryParams(Uri uri)
|
|
{
|
|
try
|
|
{
|
|
if (string.IsNullOrWhiteSpace(uri.Query))
|
|
{
|
|
return new Dictionary<string, string>();
|
|
}
|
|
|
|
var queryStringNameValueCollection = HttpUtility.ParseQueryString(uri.Query);
|
|
return queryStringNameValueCollection.AllKeys.Where(k => k != null).ToDictionary(k => k, k => queryStringNameValueCollection[k]);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
LoggerHelper.LogEvenIfCantBeResolved(ex);
|
|
}
|
|
return new Dictionary<string, string>();
|
|
}
|
|
|
|
public static string SerializeJson(object obj, bool ignoreNulls = false)
|
|
{
|
|
var jsonSerializationSettings = new JsonSerializerSettings();
|
|
if (ignoreNulls)
|
|
{
|
|
jsonSerializationSettings.NullValueHandling = NullValueHandling.Ignore;
|
|
}
|
|
return JsonConvert.SerializeObject(obj, jsonSerializationSettings);
|
|
}
|
|
|
|
public static string SerializeJson(object obj, JsonSerializerSettings jsonSerializationSettings)
|
|
{
|
|
return JsonConvert.SerializeObject(obj, jsonSerializationSettings);
|
|
}
|
|
|
|
public static T DeserializeJson<T>(string json, bool ignoreNulls = false)
|
|
{
|
|
var jsonSerializationSettings = new JsonSerializerSettings();
|
|
if (ignoreNulls)
|
|
{
|
|
jsonSerializationSettings.NullValueHandling = NullValueHandling.Ignore;
|
|
}
|
|
return JsonConvert.DeserializeObject<T>(json, jsonSerializationSettings);
|
|
}
|
|
|
|
public static string Base64UrlEncode(byte[] input)
|
|
{
|
|
var output = Convert.ToBase64String(input)
|
|
.Replace('+', '-')
|
|
.Replace('/', '_')
|
|
.Replace("=", string.Empty);
|
|
return output;
|
|
}
|
|
|
|
public static byte[] Base64UrlDecode(string input)
|
|
{
|
|
var output = input;
|
|
// 62nd char of encoding
|
|
output = output.Replace('-', '+');
|
|
// 63rd char of encoding
|
|
output = output.Replace('_', '/');
|
|
// Pad with trailing '='s
|
|
switch (output.Length % 4)
|
|
{
|
|
case 0:
|
|
// No pad chars in this case
|
|
break;
|
|
case 2:
|
|
// Two pad chars
|
|
output += "=="; break;
|
|
case 3:
|
|
// One pad char
|
|
output += "="; break;
|
|
default:
|
|
throw new InvalidOperationException("Illegal base64url string!");
|
|
}
|
|
// Standard base64 decoder
|
|
return Convert.FromBase64String(output);
|
|
}
|
|
|
|
public static T Clone<T>(T obj)
|
|
{
|
|
return JsonConvert.DeserializeObject<T>(JsonConvert.SerializeObject(obj));
|
|
}
|
|
|
|
public static string TextColorFromBgColor(string hexColor, int threshold = 166)
|
|
{
|
|
if (new ColorConverter().ConvertFromString(hexColor) is Color bgColor)
|
|
{
|
|
var luminance = bgColor.R * 0.299 + bgColor.G * 0.587 + bgColor.B * 0.114;
|
|
return luminance > threshold ? "#ff000000" : "#ffffffff";
|
|
}
|
|
|
|
return "#ff000000";
|
|
}
|
|
|
|
public static string StringToColor(string str, string fallback)
|
|
{
|
|
if (str == null)
|
|
{
|
|
return fallback;
|
|
}
|
|
var hash = 0;
|
|
for (var i = 0; i < str.Length; i++)
|
|
{
|
|
hash = str[i] + ((hash << 5) - hash);
|
|
}
|
|
var color = "#FF";
|
|
for (var i = 0; i < 3; i++)
|
|
{
|
|
var value = (hash >> (i * 8)) & 0xff;
|
|
color += Convert.ToString(value, 16).PadLeft(2, '0');
|
|
}
|
|
return color;
|
|
}
|
|
}
|
|
}
|