private Token[] GetDynamic(string type) { var key = "ACL_GetDynamic_" + type; var result = (Token[])CacheAcl.GetCache(key); if (result == null) { try { lock (_dynamicAccessLock) { _dynamicWriteLock.WaitOne(); _dynamicWriteLock.Reset(); _numberOfReadsCountDownEvent.Signal(); _numberOfReadsCountDownEvent.Wait(); } result = (Token[])CacheAcl.GetCache(key); if (result == null) { result = GetDynamicTokensFromFile(type); CacheAcl.AddCache(key, result); } } finally { _numberOfReadsCountDownEvent.Reset(1); _dynamicWriteLock.Set(); } } return(result); }
public bool HasDynamicAccess <T>(T obj, string userName) { userName = PrepareUser(userName); Group[] groupsOfUser = null; var typeName = typeof(T).Name; var tokens = GetDynamic(typeName); try { lock (_dynamicAccessLock) { _dynamicWriteLock.WaitOne(); _numberOfReadsCountDownEvent.AddCount(); } if (tokens == null || tokens.Length == 0) // nothing found for this in ACL. so we return true. { return(true); } var key = $"DynamicAccess_{userName}_{typeName}_"; key += typeof(T).GetProperty(tokens[0].Name).GetValue(obj).ToString(); var result = (bool?)CacheAcl.GetCache(key); if (result.HasValue) { return(result.Value); } foreach (var token in tokens) { bool isAll = false; var propName = token.Name; var propValue = token.Value; if (string.IsNullOrWhiteSpace(propValue) || propValue.Trim() == "*") { isAll = true; } if (isAll || typeof(T).GetProperty(propName).GetValue(obj).ToString() == propValue) { var user = token.Users.FirstOrDefault(m => m.Name == userName); if (user != null) { result = user.HasAccess; } if (result.HasValue) { break; } if (groupsOfUser == null) { using (var service = new ActiveDirectoryService(ActiveDirectorySettings.Url, ActiveDirectorySettings.Username, ActiveDirectorySettings.Password)) { groupsOfUser = service.GetGroupsOfUser(userName, true); } if (groupsOfUser == null) { groupsOfUser = new Group[0]; } } var groupsInCommon = token.Groups.Where( m => groupsOfUser.Any( u => string.Equals(u.SamAccountName, m.Name, StringComparison.OrdinalIgnoreCase))).ToArray(); if (groupsInCommon.Any()) { if (groupsInCommon.Any(m => !m.HasAccess)) { result = false; } else { result = true; } break; } } } if (!result.HasValue) { result = false; } CacheAcl.AddCache(key, result.Value); return(result.Value); } finally { _numberOfReadsCountDownEvent.Signal(); } }