예제 #1
0
파일: Group.cs 프로젝트: kuber123/sensenet
        /// <summary>
        /// After creation adds this group to the nearest parent <see cref="OrganizationalUnit"/> as a member.
        /// Do not use this method directly from your code.
        /// </summary>
        protected override void OnCreated(object sender, NodeEventArgs e)
        {
            base.OnCreated(sender, e);

            // insert this group to the security graph
            using (new SystemAccount())
            {
                var parent = GroupMembershipObserver.GetFirstOrgUnitParent(e.SourceNode);
                if (parent != null)
                {
                    SecurityHandler.AddGroupsToGroup(parent.Id, new[] { e.SourceNode.Id });
                }
            }

            var usersToAdd  = GetMemberUsers().Select(u => u.Id).ToArray();
            var groupsToAdd = GetMemberGroups().Select(g => g.Id).ToArray();

            if (usersToAdd.Length > 0 || groupsToAdd.Length > 0)
            {
                SecurityHandler.AddMembers(this.Id, usersToAdd, groupsToAdd);
            }
        }
        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);
            }
        }
예제 #3
0
파일: Group.cs 프로젝트: kuber123/sensenet
        /// <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);
            }
        }
예제 #4
0
        /// <summary>
        /// Clears the security storage copies ids of the full content tree structure from the repository
        /// to the security component. Security component must be available.
        /// WARNING! Use only in install scenarios.
        /// </summary>
        public void InstallDefaultSecurityStructure(InitialData data = null)
        {
            using (var op = SnTrace.System.StartOperation("Installing default security structure."))
            {
                using (new SystemAccount())
                {
                    CreateEntities();

                    var ed = _securityHandler.CreateAclEditor();
                    ed.Allow(Identifiers.PortalRootId, Identifiers.AdministratorsGroupId, false,
                             // ReSharper disable once CoVariantArrayConversion
                             PermissionType.BuiltInPermissionTypes);

                    var schema             = _storageSchema;
                    var memberPropertyType = schema.PropertyTypes["Members"];
                    var userNodeType       = schema.NodeTypes["User"];
                    var groupNodeType      = schema.NodeTypes["Group"];
                    if (data?.DynamicProperties != null)
                    {
                        foreach (var versionData in data.DynamicProperties)
                        {
                            if (versionData.DynamicProperties == null)
                            {
                                continue;
                            }

                            var        properties = versionData.ReferenceProperties;
                            List <int> references = null;
                            foreach (var property in properties)
                            {
                                if (property.Key.Name == "Members")
                                {
                                    references = (List <int>)property.Value;
                                    break;
                                }
                            }

                            if (references == null)
                            {
                                continue;
                            }

                            var versionId = versionData.VersionId;
                            var nodeId    = data.Versions.First(x => x.VersionId == versionId).NodeId;
                            var heads     = NodeHead.Get(references);

                            var userMembers  = new List <int>();
                            var groupMembers = new List <int>();
                            foreach (var head in heads)
                            {
                                var nodeType = head.GetNodeType();
                                if (nodeType.IsInstaceOfOrDerivedFrom(userNodeType))
                                {
                                    userMembers.Add(head.Id);
                                }
                                if (nodeType.IsInstaceOfOrDerivedFrom(groupNodeType))
                                {
                                    groupMembers.Add(head.Id);
                                }
                            }

                            _securityHandler.AddMembers(nodeId, userMembers, groupMembers);
                        }
                    }

                    if (data == null)
                    {
                        ed.Apply();
                    }
                    else
                    {
                        ed.Apply(ParseInitialPermissions(ed.Context, data.Permissions));
                    }
                }

                op.Successful = true;
            }
        }