private UserPermissions GetUserPermissions(File file, IUser user) { using (new SystemAccount()) { var entries = file.Security.GetEffectiveEntries(); var identities = new List <int> { user.Id }; // get all groups of the user, including Owners if necessary identities.AddRange(SecurityHandler.GetGroupsWithOwnership(file.Id, user)); var allowBits = 0UL; var denyBits = 0UL; foreach (var entry in entries) { if (identities.Contains(entry.IdentityId)) { allowBits |= entry.AllowBits; denyBits |= entry.DenyBits; } } allowBits = allowBits & ~denyBits; if (IsReadOnlyMode) { return(new UserPermissions { Write = false, RestrictedViewOnly = 0 == (allowBits & PermissionType.Open.Mask) && 0 != (allowBits & (PermissionType.Preview.Mask + PermissionType.PreviewWithoutWatermark.Mask + PermissionType.PreviewWithoutRedaction.Mask)), Create = false, }); } return(new UserPermissions { Write = (allowBits & PermissionType.Save.Mask) > 0, RestrictedViewOnly = 0 == (allowBits & PermissionType.Open.Mask) && 0 != (allowBits & (PermissionType.Preview.Mask + PermissionType.PreviewWithoutWatermark.Mask + PermissionType.PreviewWithoutRedaction.Mask)), Create = false }); } }
private static object GetPermissionInfo(Content content, string identity, bool singleContent) { // This method assembles an object containing identity information (basic fields and all groups), // inherited and subtree permissions that can be serialized and sent to the client. // If the singleContent parameter is true, permissions will be collected and returned // only for the provided content. Otherwise the result object will contain permission infos for // the children of the provided content and not the root. if (string.IsNullOrEmpty(identity)) { throw new ArgumentException("Please provide an identity path"); } var user = Node.Load <User>(identity); if (user == null) { throw new ArgumentException("Identity must be an existing user."); } // collect all groups for the user var groups = Node.LoadNodes(SecurityHandler.GetGroupsWithOwnership(content.Id, user)).Select(n => Content.Create(n)).ToArray(); var identityInfo = new IdentityInfo { Path = user.Path, Name = user.Name, DisplayName = user.DisplayName, Groups = groups.Select(g => new GroupInfo { DisplayName = g.DisplayName, Name = g.Name, Path = g.Path }).ToArray() }; // identities include all groups and the user itself var identities = groups.Select(g => g.Id).Concat(new[] { user.Id }).ToArray(); // If we have to collect permissions for the provided content, we will need its parent // to check inherited permissions. If children are in the focus than the parent is the // provided content itself. var parent = singleContent ? content.ContentHandler.Parent : content.ContentHandler; var effectiveParentEntries = parent == null || !parent.Security.HasPermission(PermissionType.SeePermissions) ? new AceInfo[0] : parent.Security.GetEffectiveEntries(EntryType.Normal).Where(e => identities.Contains(e.IdentityId) && !e.LocalOnly).ToArray(); var permissionsTypes = PermissionType.BuiltInPermissionTypes.Select(p => new PermissionInfo { Index = p.Index, Name = p.Name }).ToArray(); // Collect all entries on the parent that are not local-only therefore // have effect on children. foreach (var entry in permissionsTypes) { if (effectiveParentEntries.Any(e => e.GetPermissionValues()[entry.Index] == PermissionValue.Denied)) { entry.Type = "effectivedeny"; } else if (effectiveParentEntries.Any(e => e.GetPermissionValues()[entry.Index] == PermissionValue.Allowed)) { entry.Type = "effectiveallow"; } else { entry.Type = "off"; } } if (singleContent) { // collect permissions for the provided single content return(new { d = new { identity = identityInfo, permissionInfo = GetPermissionInfo(content, identities, permissionsTypes) } }); } // alternatively, collect permissions for child elements return(new { d = new { identity = identityInfo, results = content.Children.DisableAutofilters().AsEnumerable() .Select(child => GetPermissionInfo(child, identities, permissionsTypes)).ToArray() } }); }