< Summary

Class:SharpHoundCommonLib.Cache
Assembly:SharpHoundCommonLib
File(s):D:\a\SharpHoundCommon\SharpHoundCommon\src\CommonLib\Cache.cs
Covered lines:50
Uncovered lines:53
Coverable lines:103
Total lines:205
Line coverage:48.5% (50 of 103)
Covered branches:8
Total branches:40
Branch coverage:20% (8 of 40)

Metrics

MethodBranch coverage Cyclomatic complexity NPath complexity Sequence coverage
.cctor()100%10100%
.ctor()100%10100%
AddSidToDomain(...)0%200%
GetDomainSidMapping(...)0%200%
AddMachineSid(...)50%20100%
GetMachineSid(...)50%20100%
AddConvertedValue(...)50%20100%
AddPrefixedValue(...)0%200%
AddType(...)50%20100%
AddGCCache(...)25%40100%
GetGCCache(...)50%20100%
GetConvertedValue(...)0%200%
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
 1446        [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 AddSidToDomain(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)
 065        {
 066            if (CacheInstance != null) return CacheInstance.SIDToDomainCache.TryGetValue(key, out value);
 067            value = null;
 068            return false;
 069        }
 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 AddConvertedValue(string key, string value)
 289        {
 290            CacheInstance?.ValueToIdCache.TryAdd(key, value);
 291        }
 92
 93        internal static void AddPrefixedValue(string key, string domain, string value)
 094        {
 095            CacheInstance?.ValueToIdCache.TryAdd(GetPrefixKey(key, domain), value);
 096        }
 97
 98        internal static void AddType(string key, Label value)
 299        {
 2100            CacheInstance?.IdToTypeCache.TryAdd(key, value);
 2101        }
 102
 103        internal static void AddGCCache(string key, string[] value)
 1104        {
 1105            CacheInstance?.GlobalCatalogCache?.TryAdd(key, value);
 1106        }
 107
 108        internal static bool GetGCCache(string key, out string[] value)
 1109        {
 1110            if (CacheInstance != null) return CacheInstance.GlobalCatalogCache.TryGetValue(key, out value);
 1111            value = null;
 1112            return false;
 1113        }
 114
 115        internal static bool GetConvertedValue(string key, out string value)
 0116        {
 0117            if (CacheInstance != null) return CacheInstance.ValueToIdCache.TryGetValue(key, out value);
 0118            value = null;
 0119            return false;
 0120        }
 121
 122        internal static bool GetPrefixedValue(string key, string domain, out string value)
 0123        {
 0124            if (CacheInstance != null)
 0125                return CacheInstance.ValueToIdCache.TryGetValue(GetPrefixKey(key, domain), out value);
 0126            value = null;
 0127            return false;
 0128        }
 129
 130        internal static bool GetIDType(string key, out Label value)
 0131        {
 0132            if (CacheInstance != null) return CacheInstance.IdToTypeCache.TryGetValue(key, out value);
 0133            value = Label.Base;
 0134            return false;
 0135        }
 136
 137        private static string GetPrefixKey(string key, string domain)
 0138        {
 0139            return $"{key}|{domain}";
 0140        }
 141
 142        /// <summary>
 143        ///     Creates a new empty cache instance
 144        /// </summary>
 145        /// <returns></returns>
 146        public static Cache CreateNewCache(Version version = null)
 2147        {
 2148            if (version == null)
 1149            {
 1150                version = defaultVersion;
 1151            }
 2152            return new Cache
 2153            {
 2154                CacheCreationVersion = version,
 2155                CacheCreationDate = DateTime.Now.Date
 2156            };
 2157        }
 158
 159        /// <summary>
 160        ///     Sets the cache instance being used by the common library
 161        /// </summary>
 162        /// <param name="cache"></param>
 163        public static void SetCacheInstance(Cache cache)
 0164        {
 0165            CacheInstance = cache;
 0166            CreateMissingDictionaries();
 0167        }
 168
 169        /// <summary>
 170        ///     Gets stats from the currently loaded cache
 171        /// </summary>
 172        /// <returns></returns>
 173        public string GetCacheStats()
 0174        {
 175            try
 0176            {
 0177                return
 0178                    $"{IdToTypeCache.Count} ID to type mappings.\n {ValueToIdCache.Count} name to SID mappings.\n {Machi
 179            }
 0180            catch
 0181            {
 0182                return "";
 183            }
 0184        }
 185
 186        /// <summary>
 187        ///     Returns the currently loaded cache instance
 188        /// </summary>
 189        /// <returns></returns>
 190        public static Cache GetCacheInstance()
 0191        {
 0192            return CacheInstance;
 0193        }
 194
 195        private static void CreateMissingDictionaries()
 0196        {
 0197            CacheInstance ??= new Cache();
 0198            CacheInstance.IdToTypeCache ??= new ConcurrentDictionary<string, Label>();
 0199            CacheInstance.GlobalCatalogCache ??= new ConcurrentDictionary<string, string[]>();
 0200            CacheInstance.MachineSidCache ??= new ConcurrentDictionary<string, string>();
 0201            CacheInstance.SIDToDomainCache ??= new ConcurrentDictionary<string, string>();
 0202            CacheInstance.ValueToIdCache ??= new ConcurrentDictionary<string, string>();
 0203        }
 204    }
 205}