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; } } }