/// <summary> /// Slow method for mapping all the possible inconsistencies in the /// repository and the security component's stored and cached values. /// </summary> /// <param name="contentIds">List of all content ids in the repository.</param> /// <param name="groupIds">List of all the security containers in the repository. It will be enumerated once.</param> private static SecurityConsistencyResult CheckSecurityConsistency(IEnumerable <int> contentIds, IEnumerable <int> groupIds) { var result = new SecurityConsistencyResult(); result.StartTimer(); var secCachedEntities = SecurityHandler.GetCachedEntities(); CheckSecurityEntityConsistency(contentIds, secCachedEntities, result); CheckMembershipConsistency(groupIds, result); CheckAceConsistency(result, secCachedEntities); result.StopTimer(); return(result); }
private static void CheckAceConsistency(SecurityConsistencyResult result, IDictionary <int, SecurityEntity> secCachedEntities) { // Checks whether every ACE in the security db is valid for the repository: EntityId and IdentityId are // exist as SecurityEntity. var storedAces = SecurityHandler.SecurityContext.DataProvider.LoadAllPermissionEntries(); foreach (var storedAce in storedAces) { if (!secCachedEntities.ContainsKey(storedAce.EntityId)) { result.AddInvalidAceMissingEntity(storedAce); } if (!secCachedEntities.ContainsKey(storedAce.IdentityId)) { result.AddInvalidAceMissingIdentity(storedAce); } } }
private static void CheckMembershipConsistency(IEnumerable <int> groupIds, SecurityConsistencyResult result) { var secuCache = SecurityHandler.SecurityContext.GetCachedMembershipForConsistencyCheck(); var secuDb = SecurityHandler.SecurityContext.DataProvider.GetMembershipForConsistencyCheck(); var repo = new List <long>(); foreach (var head in groupIds.Select(NodeHead.Get).Where(h => h != null)) { var groupIdBase = Convert.ToInt64(head.Id) << 32; var userMembers = new List <int>(); var groupMembers = new List <int>(); CollectSecurityIdentityChildren(head, userMembers, groupMembers); foreach (var userId in userMembers) { repo.Add(groupIdBase + userId); } foreach (var groupId in groupMembers) { repo.Add(groupIdBase + groupId); } } // --------------------------------------------------------- var missingInSecuCache = repo.Except(secuCache); foreach (var relation in missingInSecuCache) { result.AddMissingMembershipFromCache(unchecked ((int)(relation >> 32)), unchecked ((int)(relation & 0xFFFFFFFF))); } var missingInSecuDb = repo.Except(secuDb); foreach (var relation in missingInSecuDb) { result.AddMissingMembershipFromSecurityDb(unchecked ((int)(relation >> 32)), unchecked ((int)(relation & 0xFFFFFFFF))); } var unknownInSecuCache = secuCache.Except(repo); foreach (var relation in unknownInSecuCache) { result.AddUnknownMembershipInCache(unchecked ((int)(relation >> 32)), unchecked ((int)(relation & 0xFFFFFFFF))); } var unknownInSecuDb = secuDb.Except(repo); foreach (var relation in unknownInSecuDb) { result.AddUnknownMembershipInSecurityDb(unchecked ((int)(relation >> 32)), unchecked ((int)(relation & 0xFFFFFFFF))); } // --------------------------------------------------------- IEnumerable <long> missingInFlattening, unknownInFlattening; SecurityHandler.SecurityContext.GetFlatteningForConsistencyCheck(out missingInFlattening, out unknownInFlattening); foreach (var relation in missingInFlattening) { result.AddMissingRelationFromFlattenedUsers(unchecked ((int)(relation >> 32)), unchecked ((int)(relation & 0xFFFFFFFF))); } foreach (var relation in unknownInFlattening) { result.AddMissingRelationFromFlattenedUsers(unchecked ((int)(relation >> 32)), unchecked ((int)(relation & 0xFFFFFFFF))); } }
private static void CheckSecurityEntityConsistency(IEnumerable <int> contentIds, IDictionary <int, SecurityEntity> secCachedEntities, SecurityConsistencyResult result) { var secDbEntities = SecurityHandler.SecurityContext.DataProvider.LoadSecurityEntities().ToList(); // convert to list, because we will modify this collection var foundEntities = new List <StoredSecurityEntity>(); foreach (var contentId in contentIds) { var nh = NodeHead.Get(contentId); // content exists in the index but not in the db (deleted manually from the db) if (nh == null) { result.AddMissingEntityFromRepository(contentId); continue; } var secEntity = secDbEntities.FirstOrDefault(se => se.Id == contentId); if (secEntity == null || secEntity.ParentId != nh.ParentId || secEntity.OwnerId != nh.OwnerId) { // not found in the security db, or found it but with different properties result.AddMissingEntityFromSecurityDb(nh); continue; } // move correctly found entities to a temp list foundEntities.Add(secEntity); secDbEntities.Remove(secEntity); } // the remaining ones are not in SN repo foreach (var secEntity in secDbEntities) { result.AddMissingEntityFromRepository(secEntity.Id); } // find entities that are in db but not in memory foreach (var secDbEntityId in secDbEntities.Concat(foundEntities).Select(dbe => dbe.Id).Except(secCachedEntities.Keys)) { result.AddMissingEntityFromSecurityCache(secDbEntityId); } // find entities that are in memory but not in db foreach (var cachedEntityId in secCachedEntities.Keys.Except(secDbEntities.Concat(foundEntities).Select(dbe => dbe.Id))) { result.AddMissingEntityFromSecurityDb(cachedEntityId); } }