< Summary

Class:SharpHoundCommonLib.Cache
Assembly:SharpHoundCommonLib
File(s):D:\a\SharpHoundCommon\SharpHoundCommon\src\CommonLib\Cache.cs
Covered lines:49
Uncovered lines:46
Coverable lines:95
Total lines:193
Line coverage:51.5% (49 of 95)
Covered branches:7
Total branches:36
Branch coverage:19.4% (7 of 36)

Metrics

MethodBranch coverage Cyclomatic complexity NPath complexity Sequence coverage
.cctor()100%10100%
.ctor()100%10100%
AddDomainSidMapping(...)0%200%
GetDomainSidMapping(...)50%20100%
AddMachineSid(...)50%20100%
GetMachineSid(...)50%20100%
AddPrefixedValue(...)0%200%
AddType(...)0%200%
AddGCCache(...)25%40100%
GetGCCache(...)50%20100%
GetPrefixedValue(...)0%200%
GetIDType(...)0%200%
GetPrefixKey(...)100%100%
CreateNewCache(...)100%20100%
SetCacheInstance(...)100%100%
GetCacheStats()100%100%
GetCacheInstance()100%100%
CreateMissingDictionaries()0%1200%

File(s)

D:\a\SharpHoundCommon\SharpHoundCommon\src\CommonLib\Cache.cs

#LineLine coverage
 1using System;
 2using System.Collections.Concurrent;
 3using System.ComponentModel;
 4using System.Runtime.Serialization;
 5using SharpHoundCommonLib.Enums;
 6
 7namespace SharpHoundCommonLib
 8{
 9    [DataContract]
 10    public class Cache
 11    {
 12        //Leave these here until we switch back to Newtonsoft which doesn't suck
 13        // [DataMember]private ConcurrentDictionary<string, string[]> _globalCatalogCache;
 14        //
 15        // [DataMember]private ConcurrentDictionary<string, Label> _idToTypeCache;
 16        //
 17        // [DataMember]private ConcurrentDictionary<string, string> _machineSidCache;
 18        //
 19        // [DataMember]private ConcurrentDictionary<string, string> _sidToDomainCache;
 20        //
 21        // [DataMember]private ConcurrentDictionary<string, string> _valueToIDCache;
 22
 123        private static Version defaultVersion = new(1, 0, 0);
 24
 225        private Cache()
 226        {
 227            ValueToIdCache = new ConcurrentDictionary<string, string>();
 228            IdToTypeCache = new ConcurrentDictionary<string, Label>();
 229            GlobalCatalogCache = new ConcurrentDictionary<string, string[]>();
 230            MachineSidCache = new ConcurrentDictionary<string, string>();
 231            SIDToDomainCache = new ConcurrentDictionary<string, string>();
 232        }
 33
 234        [DataMember] public ConcurrentDictionary<string, string[]> GlobalCatalogCache { get; private set; }
 35
 236        [DataMember] public ConcurrentDictionary<string, Label> IdToTypeCache { get; private set; }
 37
 238        [DataMember] public ConcurrentDictionary<string, string> MachineSidCache { get; private set; }
 39
 240        [DataMember] public ConcurrentDictionary<string, string> SIDToDomainCache { get; private set; }
 41
 242        [DataMember] public ConcurrentDictionary<string, string> ValueToIdCache { get; private set; }
 343        [DataMember] public DateTime CacheCreationDate { get; set; }
 444        [DataMember] public Version CacheCreationVersion { get; set; }
 45
 1146        [IgnoreDataMember] private static Cache CacheInstance { get; set; }
 47
 48        /// <summary>
 49        ///     Add a SID to/from Domain mapping to the cache
 50        /// </summary>
 51        /// <param name="key"></param>
 52        /// <param name="value"></param>
 53        internal static void AddDomainSidMapping(string key, string value)
 054        {
 055            CacheInstance?.SIDToDomainCache.TryAdd(key, value);
 056        }
 57
 58        /// <summary>
 59        ///     Get a SID to Domain or Domain to SID mapping
 60        /// </summary>
 61        /// <param name="key"></param>
 62        /// <param name="value"></param>
 63        /// <returns></returns>
 64        internal static bool GetDomainSidMapping(string key, out string value)
 165        {
 166            if (CacheInstance != null) return CacheInstance.SIDToDomainCache.TryGetValue(key, out value);
 167            value = null;
 168            return false;
 169        }
 70
 71        /// <summary>
 72        ///     Add a Domain SID -> Computer SID mapping to the cache
 73        /// </summary>
 74        /// <param name="key"></param>
 75        /// <param name="value"></param>
 76        internal static void AddMachineSid(string key, string value)
 477        {
 478            CacheInstance?.MachineSidCache.TryAdd(key, value);
 479        }
 80
 81        internal static bool GetMachineSid(string key, out string value)
 482        {
 483            if (CacheInstance != null) return CacheInstance.MachineSidCache.TryGetValue(key, out value);
 484            value = null;
 485            return false;
 486        }
 87
 88        internal static void AddPrefixedValue(string key, string domain, string value)
 089        {
 090            CacheInstance?.ValueToIdCache.TryAdd(GetPrefixKey(key, domain), value);
 091        }
 92
 93        internal static void AddType(string key, Label value)
 094        {
 095            CacheInstance?.IdToTypeCache.TryAdd(key, value);
 096        }
 97
 98        internal static void AddGCCache(string key, string[] value)
 199        {
 1100            CacheInstance?.GlobalCatalogCache?.TryAdd(key, value);
 1101        }
 102
 103        internal static bool GetGCCache(string key, out string[] value)
 1104        {
 1105            if (CacheInstance != null) return CacheInstance.GlobalCatalogCache.TryGetValue(key.ToUpper(), out value);
 1106            value = null;
 1107            return false;
 1108        }
 109
 110        internal static bool GetPrefixedValue(string key, string domain, out string value)
 0111        {
 0112            if (CacheInstance != null)
 0113                return CacheInstance.ValueToIdCache.TryGetValue(GetPrefixKey(key, domain), out value);
 0114            value = null;
 0115            return false;
 0116        }
 117
 118        internal static bool GetIDType(string key, out Label value)
 0119        {
 0120            if (CacheInstance != null) return CacheInstance.IdToTypeCache.TryGetValue(key, out value);
 0121            value = Label.Base;
 0122            return false;
 0123        }
 124
 125        private static string GetPrefixKey(string key, string domain)
 0126        {
 0127            return $"{key}|{domain}";
 0128        }
 129
 130        /// <summary>
 131        ///     Creates a new empty cache instance
 132        /// </summary>
 133        /// <returns></returns>
 134        public static Cache CreateNewCache(Version version = null)
 2135        {
 2136            if (version == null)
 1137            {
 1138                version = defaultVersion;
 1139            }
 2140            return new Cache
 2141            {
 2142                CacheCreationVersion = version,
 2143                CacheCreationDate = DateTime.Now.Date
 2144            };
 2145        }
 146
 147        /// <summary>
 148        ///     Sets the cache instance being used by the common library
 149        /// </summary>
 150        /// <param name="cache"></param>
 151        public static void SetCacheInstance(Cache cache)
 0152        {
 0153            CacheInstance = cache;
 0154            CreateMissingDictionaries();
 0155        }
 156
 157        /// <summary>
 158        ///     Gets stats from the currently loaded cache
 159        /// </summary>
 160        /// <returns></returns>
 161        public string GetCacheStats()
 0162        {
 163            try
 0164            {
 0165                return
 0166                    $"{IdToTypeCache.Count} ID to type mappings.\n {ValueToIdCache.Count} name to SID mappings.\n {Machi
 167            }
 0168            catch
 0169            {
 0170                return "";
 171            }
 0172        }
 173
 174        /// <summary>
 175        ///     Returns the currently loaded cache instance
 176        /// </summary>
 177        /// <returns></returns>
 178        public static Cache GetCacheInstance()
 0179        {
 0180            return CacheInstance;
 0181        }
 182
 183        private static void CreateMissingDictionaries()
 0184        {
 0185            CacheInstance ??= new Cache();
 0186            CacheInstance.IdToTypeCache ??= new ConcurrentDictionary<string, Label>();
 0187            CacheInstance.GlobalCatalogCache ??= new ConcurrentDictionary<string, string[]>();
 0188            CacheInstance.MachineSidCache ??= new ConcurrentDictionary<string, string>();
 0189            CacheInstance.SIDToDomainCache ??= new ConcurrentDictionary<string, string>();
 0190            CacheInstance.ValueToIdCache ??= new ConcurrentDictionary<string, string>();
 0191        }
 192    }
 193}