예제 #1
0
        public bool TryGetValue(string key, out SocketQuery val)
        {
            var query = new SocketQuery()
            {
                Left = _socket
            };

            query.ConnectorsLoader(() => new ConnectorCollection(query));
            query.DescriptorLoader(() => _mechanics.DescribeConnector(key));
            query.ConnectorQueryLoader(() => {
                return(_mechanics.Connectors(_socket.ContentPart, ConnectorCriteria.Auto, key).ForPart <ConnectorPart>());
            });
            query.ConnectorItemsLoader(() => {
                var list = _draftedConnectors == null ? query.ConnectorQuery.List() : _draftedConnectors.Where(d => d.ContentItem.ContentType == key);
                // Map right items to connectors' lazy loaders
                // TODO: Dangerous (recursion etc.) but actually safer than it looks
                var dict = list.ToDictionary <ConnectorPart, ConnectorPart, Func <SocketsPart> >(conn => conn, conn =>
                                                                                                 () => {
                    // Right item
                    var part2 = query.RightContent.FirstOrDefault(c => c.Id == conn.RightContentItemId);
                    if (part2 == null)
                    {
                        Logger.Debug("Connector {0} has invalid right item Id {1}. The item may have been deleted.", conn.Id, conn.RightContentItemId);
                    }
                    conn.RightContentField.Loader(() => part2);

                    return(part2);
                }
                                                                                                 );
                foreach (var item in list)
                {
                    item.RightContentField.Loader(dict[item]);
                }
                ;
                return(list);
            });
            // TODO: Does liberal use of ToArray() here actually clone the array each time?
            //                query.RightConnectorTypeNames = new Lazy<IEnumerable<string>>(() => socketContext.Connector.Settings.ListAllowedContentRight().ToArray());
            // socketContext.RightConnectorTypes = new Lazy<IEnumerable<ContentTypePartDefinition>>(socketContext.Select(...));
            query.RightContentLoader(() => {
                var connectorRightTypes = query.Descriptor.Settings.ListAllowedContentRight();
                return(_mechanics.RightItemsFromConnectors(query.ConnectorItems, connectorRightTypes.ToArray(), !_socket.ContentItem.IsPublished() && _socket.ContentItem.VersionRecord != null && _socket.ContentItem.VersionRecord.Latest));
            });
            val = query;
            return(true);
        }
        public void Checking(CheckAccessContext context)
        {
            // TODO: We could actually implement *denied* permissions. Maybe in Adjust(...)
            if (context.Granted)
            {
                return;
            }

            // TODO: Do we need to move to Adjusted so we can check per-type permissions? I general they're irrelevant since here we check against a specific content *item*.

            // TODO: Check this works with versioning. Will the authoritative item still get security check?
            // NOTE: I had to repeat a lot of code from RolesBasedAuthorizationService. Not brilliantly neat but I couldn't see any other way.

            // TODO: There's a lot of querying going on here, especially when groups are involved. Need indexing on left/right Ids *definitely* as well as other
            // optimisation / caching methods.

            // Check we have user and content
            // TODO: Could have EffectiveRolesPart on group itself; this would mean all users get that role (kind of dangerous tho!)
            if (context.User == null)
            {
                return;
            }
            if (context.Content == null)
            {
                return;
            }

            var userItem = context.User.ContentItem;
            // Find relationships between content and the User type
            var perms = _relationsService.Connectors(context.Content, userItem, "ContentToEffectingUser").List();

            if (perms.Count() == 0)
            {
                return;
            }

            // Find roles effected by this relationship
            IEnumerable <String> rolesToExamine = perms.SelectMany(p => p.As <EffectiveRolesPart>().ListEffectiveRoles());

            // Find groups from content
            var groups = _relationsService.Connectors(context.Content, "GroupContentToGroup").List();

            // Find any links to user
            foreach (var g in groups)
            {
                var userInGroup = _relationsService.Connectors(g.LeftContentItemId, userItem.Id, "GroupToMemberUser").List();
                if (userInGroup.Any())
                {
                    // Firstly, any group roles the user has are applied
                    rolesToExamine = rolesToExamine.Union(userInGroup.SelectMany(ug => ug.As <EffectiveRolesPart>().ListEffectiveRoles()));
                    // And apply any roles the whole group has
                    var groupToContent = _relationsService.Connectors(g.LeftContentItemId, context.Content.Id, "GroupToGroupContent").List();
                    rolesToExamine = rolesToExamine.Union(groupToContent.SelectMany(ug => ug.As <EffectiveRolesPart>().ListEffectiveRoles()));
                }
            }

            // Determine which set of permissions would satisfy the access check
            var grantingNames = PermissionNames(context.Permission, Enumerable.Empty <string>()).Distinct().ToArray();

            foreach (var role in rolesToExamine)
            {
                foreach (var permissionName in _roleService.GetPermissionsForRoleByName(role))
                {
                    string possessedName = permissionName;
                    if (grantingNames.Any(grantingName => String.Equals(possessedName, grantingName, StringComparison.OrdinalIgnoreCase)))
                    {
                        context.Granted = true;
                    }

                    if (context.Granted)
                    {
                        break;
                    }
                }
                // End as soon as it's granted
                if (context.Granted)
                {
                    break;
                }
            }
        }