internal static void SetBits(SenseNet.Security.PermissionBitMask permissionMask) { ulong allowBits = permissionMask.AllowBits; ulong denyBits = permissionMask.DenyBits; var perms = PermissionType.PermissionTypes.ToArray(); var values = new SenseNet.Security.PermissionValue[perms.Length]; foreach (var perm in perms) { values[perm.Index] = GetValue(allowBits, denyBits, perm); } foreach (var perm in perms) { if (values[perm.Index] == SenseNet.Security.PermissionValue.Allowed) { SetBits(ref allowBits, ref denyBits, perm, SenseNet.Security.PermissionValue.Allowed); } } foreach (var perm in perms) { if (values[perm.Index] == SenseNet.Security.PermissionValue.Denied) { SetBits(ref allowBits, ref denyBits, perm, SenseNet.Security.PermissionValue.Denied); } } permissionMask.AllowBits = allowBits; permissionMask.DenyBits = denyBits; }
/// <summary> /// Sets the allowed and denied permissions by the passed bitmask. /// This method can not reset any allowed or denied. /// </summary> /// <param name="entityId">The requested entity.</param> /// <param name="identityId">The requested identity.</param> /// <param name="localOnly">Determines whether the edited entry is inheritable or not.</param> /// <param name="permissionMask">Contains one or more permissions to allow or deny.</param> /// <returns>A reference to this instance for calling more operations.</returns> public new SnAclEditor Set(int entityId, int identityId, bool localOnly, SenseNet.Security.PermissionBitMask permissionMask) { SetBits(permissionMask); base.Set(entityId, identityId, localOnly, permissionMask); return(this); }
private static void CollectPermissionsFromLocalAces(List <AceInfo> aces, PermissionBitMask localBits) { foreach (var ace in aces) { localBits.AllowBits |= ace.AllowBits; localBits.DenyBits |= ace.DenyBits; } }
/// <summary> /// Resets the allowed and denied permissions by the passed bitmask. /// </summary> /// <param name="entityId">The requested entity.</param> /// <param name="identityId">The requested identity.</param> /// <param name="localOnly">False if the edited entry is inheritable.</param> /// <param name="permissionMask">Contains one or more permissions to allow or deny.</param> /// <returns>A reference to this instance for calling more operations.</returns> public AclEditor Reset(int entityId, int identityId, bool localOnly, PermissionBitMask permissionMask) { var ace = EnsureAce(entityId, identityId, localOnly); ace.AllowBits &= ~permissionMask.AllowBits; ace.DenyBits &= ~permissionMask.DenyBits; return(this); }
private static bool HasBitsByExpliciteAces(List <AceInfo> aces, PermissionLevel level, ulong mask) { var permBits = new PermissionBitMask(); foreach (var ace in aces) { permBits.AllowBits |= ace.AllowBits; permBits.DenyBits |= ace.DenyBits; } return(HasBits(permBits, level, mask)); }
/****************************************************************************************************** Related Permissions */ public static Dictionary <PermissionTypeBase, int> GetRelatedPermissions(SecurityContext context, int entityId, PermissionLevel level, bool explicitOnly, int identityId, Func <int, bool> isEnabled) { if (!explicitOnly) { throw new NotSupportedException("Not supported in this version. Use explicitOnly = true"); } SecurityEntity.EnterReadLock(); try { var counters = new int[PermissionTypeBase.PermissionCount]; var identities = new[] { identityId }; var root = SecurityEntity.GetEntitySafe(context, entityId, true); foreach (var entity in new EntityTreeWalker(root)) { // step forward if there is no any setting if (!entity.HasExplicitAcl) { continue; } if (!isEnabled(entity.Id)) { continue; } // if breaked, adding existing parent-s effective identities because all identities are related. var localBits = new PermissionBitMask(); if (!entity.IsInherited && entity.Parent != null) { CollectPermissionsFromLocalAces(context.Evaluator.GetEffectiveEntriesSafe(entity.Parent.Id, identities), localBits); } // adding explicite identities CollectPermissionsFromAces(context.Evaluator.GetExplicitEntriesSafe(entity.Id, identities), level, counters, localBits); } var result = new Dictionary <PermissionTypeBase, int>(); for (var i = 0; i < PermissionTypeBase.PermissionCount; i++) { result.Add(PermissionTypeBase.GetPermissionTypeByIndex(i), counters[i]); } return(result); } finally { SecurityEntity.ExitReadLock(); } }
/// <summary> /// Returns a value that has combined bitmasks of the parameters. /// </summary> public static PermissionBitMask operator |(PermissionTypeBase pt1, PermissionTypeBase pt2) { var pmask1 = new PermissionBitMask { AllowBits = pt1.Mask }; var pmask2 = new PermissionBitMask { AllowBits = pt2.Mask }; return(new PermissionBitMask { AllowBits = pmask1.AllowBits | pmask2.AllowBits, DenyBits = pmask1.DenyBits | pmask2.DenyBits }); }
private bool HasBitsByEffectiveAces(List <AceInfo> aces, PermissionLevel level, ulong mask) { var permBits = new PermissionBitMask(); foreach (var ace in aces) { if (!ace.LocalOnly) { permBits.AllowBits |= ace.AllowBits; permBits.DenyBits |= ace.DenyBits; } } return(HasBits(permBits, level, mask)); }
/// <summary> /// Resets the allowed and denied permissions by the passed bitmask. /// </summary> /// <param name="entityId">The requested entity.</param> /// <param name="identityId">The requested identity.</param> /// <param name="localOnly">Determines whether the edited entry is inheritable or not.</param> /// <param name="permissionMask">Contains one or more permissions to allow or deny.</param> /// <returns>A reference to this instance for calling more operations.</returns> public new SnAclEditor Reset(int entityId, int identityId, bool localOnly, SenseNet.Security.PermissionBitMask permissionMask) { var permissionsToReset = new List <SenseNet.Security.PermissionTypeBase>(); var bits = permissionMask.AllowBits | permissionMask.DenyBits; for (var i = 0; i < PermissionType.PermissionCount; i++) { if ((bits & (1uL << i)) != 0) { permissionsToReset.Add(PermissionType.GetByIndex(i)); } } ClearPermission(entityId, identityId, localOnly, permissionsToReset.ToArray()); return(this); }
private static bool HasBits(PermissionBitMask permBits, PermissionLevel level, ulong permissionMask) { switch (level) { case PermissionLevel.Allowed: return((permBits.AllowBits & permissionMask) != 0); case PermissionLevel.Denied: return((permBits.DenyBits & permissionMask) != 0); case PermissionLevel.AllowedOrDenied: return(((permBits.AllowBits | permBits.DenyBits) & permissionMask) != 0); default: throw new NotSupportedException("Not supported PermissionLevel: " + level); } }
public static Dictionary <PermissionTypeBase, int> GetExplicitPermissionsInSubtree(SecurityContext context, int entityId, int[] identities, bool includeRoot) { SecurityEntity.EnterReadLock(); try { var counters = new int[PermissionTypeBase.PermissionCount]; var root = SecurityEntity.GetEntitySafe(context, entityId, true); foreach (var entity in new EntityTreeWalker(root)) { // step forward if there is no any setting if (!entity.HasExplicitAcl || (entity.Id == entityId && !includeRoot)) { continue; } // if breaked, adding existing parent-s effective identities because all identities are related. var localBits = new PermissionBitMask(); if (!entity.IsInherited && entity.Parent != null && (includeRoot || entity.Parent.Id != entityId)) { CollectPermissionsFromLocalAces(context.Evaluator.GetEffectiveEntriesSafe(entity.Parent.Id, identities), localBits); } // adding explicite identities CollectPermissionsFromAces(context.Evaluator.GetExplicitEntriesSafe(entity.Id, identities), PermissionLevel.AllowedOrDenied, counters, localBits); } var result = new Dictionary <PermissionTypeBase, int>(); for (var i = 0; i < PermissionTypeBase.PermissionCount; i++) { result.Add(PermissionTypeBase.GetPermissionTypeByIndex(i), counters[i]); } return(result); } finally { SecurityEntity.ExitReadLock(); } }
private static void CollectPermissionsFromAces(List <AceInfo> aces, PermissionLevel level, int[] counters, PermissionBitMask localBits) { // Aggregate aces and switch of the 'used bits' in the local only permission bit set. foreach (var ace in aces) { SetPermissionsCountersByPermissionLevel(counters, level, ace.AllowBits, ace.DenyBits); localBits.AllowBits &= ~ace.AllowBits; localBits.DenyBits &= ~ace.DenyBits; } // Finally play the rest bits (all breaked bits are switched in that is not used in any explicit entry) SetPermissionsCountersByPermissionLevel(counters, level, localBits.AllowBits, localBits.DenyBits); }
/// <summary> /// Returns permission changes in the predefined axis (All, ParentChain, Subtree) of the specified entity. /// A permission is changed when the parent permission and local permission are not equal. /// The collection can be prefiltered with a relatedIdentity parameter. /// This operation is thread safe. The thread safety uses system resources, so to minimize these, /// it's strongly recommended processing as fast as possible. /// </summary> /// <param name="entityId">The Id of the focused entity.</param> /// <param name="relatedIdentities">Identity filter. Null or empty means inactive filter.</param> /// <param name="handleBreaks">Controls the permission inheritance handling.</param> /// <returns>The IEnumerable<PermissionChange> to further filtering.</returns> public IEnumerable <PermissionChange> GetPermissionChanges(int entityId, IEnumerable <int> relatedIdentities, BreakOptions handleBreaks = BreakOptions.Default) { var identities = relatedIdentities?.ToArray(); var isIdentityFilterActive = identities != null && identities.Length > 0; foreach (var entity in GetEntities(entityId, handleBreaks)) { if (entity.Acl == null) { continue; } if (entity.IsInherited) { foreach (var entry in entity.Acl.Entries) { // skip local only if this is not the root if (entity.Id != entityId || !entry.LocalOnly) { // filter by related identities if (!isIdentityFilterActive || identities.Contains(entry.IdentityId)) { yield return(new PermissionChange(entity, entry)); } } } } else { var effectiveEntries = _context.Evaluator.GetEffectiveEntriesSafe(entity.Parent.Id, identities); var localEntries = entity.Acl.Entries .Where(e => (entity.Id != entityId || !e.LocalOnly) && // ReSharper disable once AssignNullToNotNullAttribute (!isIdentityFilterActive || identities.Contains(e.IdentityId))) .ToList(); // Aggregate effective and local bits per identity foreach (var effectiveEntry in effectiveEntries) { var localEntry = localEntries.FirstOrDefault(e => e.IdentityId == effectiveEntry.IdentityId && e.EntryType == effectiveEntry.EntryType); var aggregatedBits = new PermissionBitMask { AllowBits = effectiveEntry.AllowBits, DenyBits = effectiveEntry.DenyBits }; if (localEntry != null) { aggregatedBits.AllowBits |= localEntry.AllowBits; aggregatedBits.DenyBits |= localEntry.DenyBits; // Remove processed item from local entries. localEntries.Remove(localEntry); } yield return(new PermissionChange ( entity, effectiveEntry.IdentityId, effectiveEntry.EntryType, aggregatedBits )); } // New local entries that are not exist in parent's effective ACEs foreach (var localEntry in localEntries) { yield return(new PermissionChange(entity, localEntry)); } } } }