protected override void OnNodeMoved(object sender, NodeOperationEventArgs e) { // We do not have to deal with content outside of the IMS folder, because // moving local groups does not involve any membership change. if (!e.OriginalSourcePath.StartsWith(RepositoryStructure.ImsFolderPath + RepositoryPath.PathSeparator) && !e.SourceNode.Path.StartsWith(RepositoryStructure.ImsFolderPath + RepositoryPath.PathSeparator)) { return; } base.OnNodeMoved(sender, e); var movedUsers = new List <int>(); var movedGroups = new List <int>(); // if the moved content is an identity, put it into the appropriate list if (e.SourceNode is User) { movedUsers.Add(e.SourceNode.Id); } else if (e.SourceNode is Group || e.SourceNode is OrganizationalUnit) { movedGroups.Add(e.SourceNode.Id); } else { // If the moved content is an irrelevant container (e.g. a folder), collect relevant (first-level) child content (users, groups // and child orgunits even inside simple subfolders). These are already moved to the new location, but we only need their ids. using (new SystemAccount()) { CollectSecurityIdentityChildren(NodeHead.Get(e.SourceNode.Path), movedUsers, movedGroups); } } // empty collections: nothing to do if (movedUsers.Count == 0 && movedGroups.Count == 0) { return; } // find the original parent orgunit (if there was one) var parent = Node.LoadNode(RepositoryPath.GetParentPath(e.OriginalSourcePath)); var originalParentId = 0; var targetParentId = 0; if (parent is OrganizationalUnit) { originalParentId = parent.Id; } else { using (new SystemAccount()) { parent = GetFirstOrgUnitParent(parent); if (parent != null) { originalParentId = parent.Id; } } } // find the target parent orgunit (if there is one) using (new SystemAccount()) { parent = GetFirstOrgUnitParent(e.SourceNode); if (parent != null) { targetParentId = parent.Id; } } // remove relevant child content from the original parent org unit (if it is different from the target) if (originalParentId > 0 && originalParentId != targetParentId) { SecurityHandler.RemoveMembers(originalParentId, movedUsers, movedGroups); } // add the previously collected identities to the target orgunit (if it is different from the original) if (targetParentId > 0 && originalParentId != targetParentId) { SecurityHandler.AddMembers(targetParentId, movedUsers, movedGroups); } }
/// <summary> /// Updates the membership modifications in the sensenet security database. /// Do not use this method directly from your code. /// </summary> protected void UpdateMembership(NodeEventArgs e) { if (e.ChangedData == null) { return; } // load and parse member list var membersData = e.ChangedData.FirstOrDefault(cd => string.Compare(cd.Name, MEMBERS, StringComparison.InvariantCulture) == 0); if (membersData == null) { return; } var oldMembers = (membersData.Original as string ?? string.Empty).Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(m => Convert.ToInt32(m)).ToArray(); var newMembers = (membersData.Value as string ?? string.Empty).Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(m => Convert.ToInt32(m)).ToArray(); var addedIdentities = newMembers.Except(oldMembers); var removedIdentities = oldMembers.Except(newMembers); // I chose collecting arrays over LINQ here because this way we enumerate and load nodeheads only once var ntUser = ActiveSchema.NodeTypes["User"]; var ntGroup = ActiveSchema.NodeTypes["Group"]; var usersToAdd = new List <int>(); var usersToRemove = new List <int>(); var groupsToAdd = new List <int>(); var groupsToRemove = new List <int>(); // collect users and groups to add foreach (var nodeHead in addedIdentities.Select(NodeHead.Get).Where(nh => nh != null)) { if (nodeHead.GetNodeType().IsInstaceOfOrDerivedFrom(ntUser)) { usersToAdd.Add(nodeHead.Id); } else if (nodeHead.GetNodeType().IsInstaceOfOrDerivedFrom(ntGroup)) { groupsToAdd.Add(nodeHead.Id); } } // collect users and groups to remove foreach (var nodeHead in removedIdentities.Select(NodeHead.Get).Where(nh => nh != null)) { if (nodeHead.GetNodeType().IsInstaceOfOrDerivedFrom(ntUser)) { usersToRemove.Add(nodeHead.Id); } else if (nodeHead.GetNodeType().IsInstaceOfOrDerivedFrom(ntGroup)) { groupsToRemove.Add(nodeHead.Id); } } if (usersToRemove.Count > 0 || groupsToRemove.Count > 0) { SecurityHandler.RemoveMembers(this.Id, usersToRemove, groupsToRemove); } if (usersToAdd.Count > 0 || groupsToAdd.Count > 0) { SecurityHandler.AddMembers(this.Id, usersToAdd, groupsToAdd); } }