public void Sharing_Eval_CheckPermissions() { EnsureRepository(); Tools.SetMembership(CurrentContext.Security, "U1:G1"); // Root permission for G1. The U1 is a member for it. SetAcl("+E1| Normal|+G1:_+_______________+"); // FullControl + Run // One level down: The sharing permits many more but only local. SetAcl("+E2|Sharing|-U1:___________+++++++"); // Save // Two level down: The sharing permits less than on parent. SetAcl("+E5|Sharing|+U1:_____________+++++"); // Open PermissionValue see, open, save, run; var ctx = CurrentContext.Security; var entityId = Id("E1"); // Root see = ctx.GetPermission(entityId, PermissionType.FullControl); open = ctx.GetPermission(entityId, PermissionType.FullControl); save = ctx.GetPermission(entityId, PermissionType.FullControl); run = ctx.GetPermission(entityId, PermissionType.FullControl); Assert.AreEqual(PermissionValue.Allowed, see); Assert.AreEqual(PermissionValue.Undefined, open); Assert.AreEqual(PermissionValue.Undefined, save); Assert.AreEqual(PermissionValue.Allowed, run); Assert.IsTrue(ctx.HasPermission(entityId, PermissionType.FullControl, PermissionType.FullControl)); entityId = Id("E2"); // E1/E2 see = ctx.GetPermission(entityId, PermissionType.FullControl); open = ctx.GetPermission(entityId, PermissionType.FullControl); save = ctx.GetPermission(entityId, PermissionType.FullControl); run = ctx.GetPermission(entityId, PermissionType.FullControl); Assert.AreEqual(PermissionValue.Allowed, see); Assert.AreEqual(PermissionValue.Allowed, open); Assert.AreEqual(PermissionValue.Allowed, save); Assert.AreEqual(PermissionValue.Allowed, run); Assert.IsTrue(ctx.HasPermission(entityId, PermissionType.FullControl, PermissionType.FullControl)); entityId = Id("E6"); // E1/E2/E6 see = ctx.GetPermission(entityId, PermissionType.FullControl); open = ctx.GetPermission(entityId, PermissionType.FullControl); save = ctx.GetPermission(entityId, PermissionType.FullControl); run = ctx.GetPermission(entityId, PermissionType.FullControl); Assert.AreEqual(PermissionValue.Allowed, see); Assert.AreEqual(PermissionValue.Undefined, open); Assert.AreEqual(PermissionValue.Undefined, save); Assert.AreEqual(PermissionValue.Allowed, run); Assert.IsTrue(ctx.HasPermission(entityId, PermissionType.FullControl, PermissionType.FullControl)); entityId = Id("E14"); // E1/E2/E5/E14 see = ctx.GetPermission(entityId, PermissionType.FullControl); open = ctx.GetPermission(entityId, PermissionType.FullControl); save = ctx.GetPermission(entityId, PermissionType.FullControl); run = ctx.GetPermission(entityId, PermissionType.FullControl); Assert.AreEqual(PermissionValue.Allowed, see); Assert.AreEqual(PermissionValue.Allowed, open); Assert.AreEqual(PermissionValue.Undefined, save); Assert.AreEqual(PermissionValue.Allowed, run); Assert.IsTrue(ctx.HasPermission(entityId, PermissionType.FullControl, PermissionType.FullControl)); }
public void Sharing_Acl_BreakAll_Unbreak_NormalizeOne() { EnsureRepository(); var ctx = CurrentContext.Security; Tools.SetMembership(ctx, "U1:G1,G2"); SetAcl("+E1|Sharing|+G1:______________+"); SetAcl("+E1| Normal|+G1:_____________+_"); SetAcl("+E2| Normal|+G1:____________+__"); SetAcl("+E3| Normal|+G2:_____________+_"); var ed = ctx.CreateAclEditor(); ed.BreakInheritance(Id("E5"), new[] { EntryType.Normal, EntryType.Sharing }); ed.BreakInheritance(Id("E8"), new[] { EntryType.Normal, EntryType.Sharing }); ed.Apply(); // ACTION ed = ctx.CreateAclEditor(); ed.UnbreakInheritance(Id("E5"), new[] { EntryType.Normal }); ed.UnbreakInheritance(Id("E8"), new[] { EntryType.Normal }); ed.Apply(); // ASSERT var entries5 = ctx.GetExplicitEntries(Id("E5")); // E1/E2/E5 var entries8 = ctx.GetExplicitEntries(Id("E8")); // E1/E3/E8 Assert.AreEqual(1, entries5.Count); Assert.AreEqual("Sharing|+G1:_______________________________________________________________+", Tools.ReplaceIds(entries5[0].ToString())); Assert.AreEqual(1, entries8.Count); Assert.AreEqual("Sharing|+G1:_______________________________________________________________+", Tools.ReplaceIds(entries8[0].ToString())); }
public void Sharing_Acl_BreakOperation_EverythingCopied() { EnsureRepository(); var ctx = CurrentContext.Security; Tools.SetMembership(ctx, "U1:G1,G2"); SetAcl("+E1|Sharing|+G1:______________+"); SetAcl("+E1| Normal|+G1:_____________+_"); SetAcl("+E2| Normal|+G1:____________+__"); SetAcl("+E3| Normal|+G2:_____________+_"); // ACTION var ed = ctx.CreateAclEditor(); ed.BreakInheritance(Id("E5"), new[] { EntryType.Normal, EntryType.Sharing }); ed.BreakInheritance(Id("E8"), new[] { EntryType.Normal, EntryType.Sharing }); ed.Apply(); // ASSERT var entries5 = ctx.GetExplicitEntries(Id("E5")) // E1/E2/E5 .OrderBy(x => x.EntryType).ThenBy(x => x.IdentityId).ToList(); var entries8 = ctx.GetExplicitEntries(Id("E8")) // E1/E3/E8 .OrderBy(x => x.EntryType).ThenBy(x => x.IdentityId).ToList(); Assert.AreEqual(2, entries5.Count); Assert.AreEqual("Normal|+G1:_____________________________________________________________++_", Tools.ReplaceIds(entries5[0].ToString())); Assert.AreEqual("Sharing|+G1:_______________________________________________________________+", Tools.ReplaceIds(entries5[1].ToString())); Assert.AreEqual(3, entries8.Count); Assert.AreEqual("Normal|+G1:______________________________________________________________+_", Tools.ReplaceIds(entries8[0].ToString())); Assert.AreEqual("Normal|+G2:______________________________________________________________+_", Tools.ReplaceIds(entries8[1].ToString())); Assert.AreEqual("Sharing|+G1:_______________________________________________________________+", Tools.ReplaceIds(entries8[2].ToString())); }
public void Sharing_Eval_HasPermission_OverBreak() { EnsureRepository(); var ctx = CurrentContext.Security; Tools.SetMembership(ctx, "U1:G1"); SetAcl("+E1|Sharing|+G1:______________+"); SetAcl("-E2| Normal|+G1:_____________+_"); Assert.IsFalse(ctx.HasPermission(Id("E2"), PermissionType.FullControl)); Assert.IsTrue(ctx.HasPermission(Id("E2"), PermissionType.FullControl)); }
public void Sharing_GetAcl() { EnsureRepository(); var ctx = CurrentContext.Security; Tools.SetMembership(ctx, "U1:G1"); SetAcl("+E1| Normal|+G1:______________+"); // 0x1 SetAcl("+E1|Sharing|+G1:___________+___"); // 0x8 SetAcl("+E2| Normal|+G1:_____________+_"); // 0x2 SetAcl("+E2|Sharing|+G1:__________+____"); // 0x10 SetAcl("+E2| Normal|-G1:____________+__"); // 0x4 local SetAcl("+E2|Sharing|-G1:_________+_____"); // 0x20 local // ACTION 1 root, default filter (Normal) var entries = ctx.GetAcl(Id("E1")).Entries .OrderBy(x => x.LocalOnly).ThenBy(x => x.EntryType).ToList(); Assert.AreEqual("Normal|+G1:_______________________________________________________________+", Tools.ReplaceIds(entries[0].ToString())); // ACTION 2 child, default filter (Normal) entries = ctx.GetAcl(Id("E2")).Entries .OrderBy(x => x.LocalOnly).ThenBy(x => x.EntryType).ToList(); Assert.AreEqual("Normal|+G1:______________________________________________________________++", Tools.ReplaceIds(entries[0].ToString())); Assert.AreEqual("Normal|-G1:_____________________________________________________________+__", Tools.ReplaceIds(entries[1].ToString())); // ACTION 3 root, Normal only entries = ctx.GetAcl(Id("E1"), EntryType.Normal).Entries .OrderBy(x => x.LocalOnly).ThenBy(x => x.EntryType).ToList(); Assert.AreEqual("Normal|+G1:_______________________________________________________________+", Tools.ReplaceIds(entries[0].ToString())); // ACTION 4 child, Normal only entries = ctx.GetAcl(Id("E2"), EntryType.Normal).Entries .OrderBy(x => x.LocalOnly).ThenBy(x => x.EntryType).ToList(); Assert.AreEqual("Normal|+G1:______________________________________________________________++", Tools.ReplaceIds(entries[0].ToString())); Assert.AreEqual("Normal|-G1:_____________________________________________________________+__", Tools.ReplaceIds(entries[1].ToString())); // ACTION 3 root, Sharing only entries = ctx.GetAcl(Id("E1"), EntryType.Sharing).Entries .OrderBy(x => x.LocalOnly).ThenBy(x => x.EntryType).ToList(); Assert.AreEqual("Sharing|+G1:____________________________________________________________+___", Tools.ReplaceIds(entries[0].ToString())); // ACTION 4 child, Sharing only entries = ctx.GetAcl(Id("E2"), EntryType.Sharing).Entries .OrderBy(x => x.LocalOnly).ThenBy(x => x.EntryType).ToList(); Assert.AreEqual("Sharing|+G1:___________________________________________________________++___", Tools.ReplaceIds(entries[0].ToString())); Assert.AreEqual("Sharing|-G1:__________________________________________________________+_____", Tools.ReplaceIds(entries[1].ToString())); }
public void Sharing_AclEd_DefaultDoesNotSeeSharingEntries() { EnsureRepository(); var ctx = CurrentContext.Security; Tools.SetMembership(ctx, "U1:G1"); SetAcl("+E1| Normal|+G1:______________+"); SetAcl("+E2|Sharing|+G1:____________+__"); // ACTION 1 var ed = ctx.CreateAclEditor(); ed.Allow("E2", "G1", "_____________+_"); // ASSERT 1 (edited entry is brand new so not merged with the existing sharing entry) var edAcls = new AclEditorAccessor(ed).Acls; Assert.AreEqual(Id("E2"), edAcls.Count == 0 ? 0 : edAcls.First().Key); var entry = edAcls[Id("E2")].Entries.FirstOrDefault(); Assert.IsNotNull(entry); Assert.AreEqual(EntryType.Normal, entry.EntryType); Assert.AreEqual(0x2ul, entry.AllowBits); // ACTION 2 ed.Apply(); // ASSERT 2 var eff = ctx.GetEffectiveEntries(Id("E2")).OrderBy(x => x.EntryType).ToList(); Assert.AreEqual(2, eff.Count); Assert.AreEqual(0x3ul, eff[0].AllowBits); Assert.AreEqual(0x4ul, eff[1].AllowBits); var exp = ctx.GetExplicitEntries(Id("E2")).OrderBy(x => x.EntryType).ToList(); Assert.AreEqual(2, exp.Count); Assert.AreEqual(0x2ul, exp[0].AllowBits); Assert.AreEqual(0x4ul, exp[1].AllowBits); }
public void Sharing_Acl_ExplicitEntries_NotMerged() { EnsureRepository(); var ctx = CurrentContext.Security; Tools.SetMembership(ctx, "U1:G1"); // ACTION 1 SetAcl("+E1| Normal|+G1:_____________++"); // ASSERT 1 var storedAces = ctx.DataProvider.LoadAllAces().ToArray(); Assert.AreEqual(1, storedAces.Length); Assert.AreEqual(EntryType.Normal, storedAces[0].EntryType); Assert.AreEqual(0x3ul, storedAces[0].AllowBits); var entries = ctx.GetExplicitEntries(Id("E1")); Assert.AreEqual(1, entries.Count); Assert.AreEqual(0x3ul, entries[0].AllowBits); Assert.AreEqual(EntryType.Normal, entries[0].EntryType); // ACTION 2 SetAcl("+E1|Sharing|+G1:___________++__"); // ASSERT 2 storedAces = ctx.DataProvider.LoadAllAces().ToArray(); Assert.AreEqual(2, storedAces.Length); Assert.AreEqual(0x3ul, storedAces[0].AllowBits); Assert.AreEqual(EntryType.Normal, storedAces[0].EntryType); Assert.AreEqual(0xCul, storedAces[1].AllowBits); Assert.AreEqual(EntryType.Sharing, storedAces[1].EntryType); entries = ctx.GetExplicitEntries(Id("E1")); Assert.AreEqual(2, entries.Count); Assert.AreEqual(0x3ul, entries[0].AllowBits); Assert.AreEqual(EntryType.Normal, entries[0].EntryType); Assert.AreEqual(0xCul, entries[1].AllowBits); Assert.AreEqual(EntryType.Sharing, entries[1].EntryType); }
public void Sharing_GetAcl_FirstAclIsNotRelevant() { EnsureRepository(); var ctx = CurrentContext.Security; Tools.SetMembership(ctx, "U1:G1"); SetAcl("+E1| Normal|+G1:___________++++"); // 0x1 SetAcl("+E2|Sharing|+G1:_______++++____"); // 0x10 // ACTION 1: default filter (Normal) var entry = ctx.GetAcl(Id("E5")).Entries.First(); Assert.AreEqual("Normal|+G1:____________________________________________________________++++", Tools.ReplaceIds(entry.ToString())); // ACTION 2: Normal only entry = ctx.GetAcl(Id("E5"), EntryType.Normal).Entries.First(); Assert.AreEqual("Normal|+G1:____________________________________________________________++++", Tools.ReplaceIds(entry.ToString())); // ACTION 3: Sharing only entry = ctx.GetAcl(Id("E5"), EntryType.Sharing).Entries.First(); Assert.AreEqual("Sharing|+G1:________________________________________________________++++____", Tools.ReplaceIds(entry.ToString())); }
public void Linq_PermQuery_GetRelatedPermissions() { var ctx = CurrentContext.Security; Tools.SetMembership(CurrentContext.Security, "U4:G4"); ctx.CreateAclEditor() .Allow(Id("E1"), Id("G4"), false, PermissionType.Custom04) .Allow(Id("E42"), Id("G4"), false, PermissionType.Custom04) .Apply(); ctx.CreateAclEditor(EntryType.Sharing) .Allow(Id("E4"), Id("U8"), false, PermissionType.Open) .Allow(Id("E41"), Id("U8"), false, PermissionType.Open) .Apply(); // sample output: "U1:p0:1,p1:2|U2:|U3:p3:2" string ResultToString(Dictionary <string, Dictionary <int, int> > result) { var x = result.Select(item => { var sb = new StringBuilder(); sb.Append(item.Key); foreach (var permCount in item.Value) { sb.Append(":").Append($"p{permCount.Key}:{permCount.Value}"); } return(sb.ToString()); }).ToArray(); return(string.Join("|", x)); } var identityNames = new[] { "U1", "U2", "U3", "U4", "U8" }; // ---- ALLOWED var expectedAllowedPermCounts = "U1:p32:3:p34:4|U2:p32:2|U3|U4|U8"; var allowedPermCountsByIdentities = ResultToString(identityNames .Select(identityName => new { id = identityName, permissionCounters = ctx .GetRelatedPermissions(Id("E32"), PermissionLevel.Allowed, true, Id(identityName), i => true) .Where(x => x.Value != 0).ToDictionary(x => x.Key.Index, x => x.Value) }) .ToDictionary(x => x.id, x => x.permissionCounters)); var allowedPermCountsByIdentitiesLinq = ResultToString(identityNames .Select(identityName => new { id = identityName, permissionCounters = PermissionQueryWithLinq_GetRelatedPermissions(ctx, Id("E32"), Id(identityName), PermissionLevel.Allowed) .Where(x => x.Value != 0).ToDictionary(x => x.Key.Index, x => x.Value) }) .ToDictionary(x => x.id, x => x.permissionCounters)); Assert.AreEqual(allowedPermCountsByIdentities, allowedPermCountsByIdentitiesLinq); Assert.AreEqual(expectedAllowedPermCounts, allowedPermCountsByIdentities); // ---- DENIED var expectedDeniedPermCounts = "U1|U2|U3:p32:4|U4|U8"; var deniedPermCountsByIdentities = ResultToString(identityNames .Select(identityName => new { id = identityName, permissionCounters = ctx .GetRelatedPermissions(Id("E32"), PermissionLevel.Denied, true, Id(identityName), i => true) .Where(x => x.Value != 0).ToDictionary(x => x.Key.Index, x => x.Value) }) .ToDictionary(x => x.id, x => x.permissionCounters)); var deniedPermCountsByIdentitiesLinq = ResultToString(identityNames .Select(identityName => new { id = identityName, permissionCounters = PermissionQueryWithLinq_GetRelatedPermissions(ctx, Id("E32"), Id(identityName), PermissionLevel.Denied) .Where(x => x.Value != 0).ToDictionary(x => x.Key.Index, x => x.Value) }) .ToDictionary(x => x.id, x => x.permissionCounters)); Assert.AreEqual(deniedPermCountsByIdentities, deniedPermCountsByIdentitiesLinq); Assert.AreEqual(expectedDeniedPermCounts, deniedPermCountsByIdentities); // ALLOWED OR DENIED var expectedAllPermCounts = "U1:p32:3:p34:4|U2:p32:2|U3:p32:4|U4|U8"; var allPermCountsByIdentities = ResultToString(identityNames .Select(identityName => new { id = identityName, permissionCounters = ctx .GetRelatedPermissions(Id("E32"), PermissionLevel.AllowedOrDenied, true, Id(identityName), i => true) .Where(x => x.Value != 0).ToDictionary(x => x.Key.Index, x => x.Value) }) .ToDictionary(x => x.id, x => x.permissionCounters)); var allPermCountsByIdentitiesLinq = ResultToString(identityNames .Select(identityName => new { id = identityName, permissionCounters = PermissionQueryWithLinq_GetRelatedPermissions(ctx, Id("E32"), Id(identityName), PermissionLevel.AllowedOrDenied) .Where(x => x.Value != 0).ToDictionary(x => x.Key.Index, x => x.Value) }) .ToDictionary(x => x.id, x => x.permissionCounters)); Assert.AreEqual(allPermCountsByIdentities, allPermCountsByIdentitiesLinq); Assert.AreEqual(expectedAllPermCounts, allPermCountsByIdentities); }
public void Sharing_Acl_EffectiveEntries_Filtered() { EnsureRepository(); var ctx = CurrentContext.Security; Tools.SetMembership(ctx, "U1:G1"); SetAcl("+E1| Normal|+G1:______________+"); // 0x1 SetAcl("+E1|Sharing|+G1:___________+___"); // 0x8 SetAcl("+E2| Normal|+G1:_____________+_"); // 0x2 SetAcl("+E2|Sharing|+G1:__________+____"); // 0x10 SetAcl("+E2| Normal|-G1:____________+__"); // 0x4 local SetAcl("+E2|Sharing|-G1:_________+_____"); // 0x20 local // ACTION 1: query without filter + local entries var entries = ctx.GetEffectiveEntries(Id("E2")); // ASSERT 1 Assert.AreEqual(4, entries.Count); Assert.AreEqual(2, entries.Count(x => x.EntryType == EntryType.Normal)); Assert.AreEqual(2, entries.Count(x => x.EntryType == EntryType.Sharing)); Assert.AreEqual(2, entries.Count(x => x.LocalOnly)); Assert.AreEqual(2, entries.Count(x => !x.LocalOnly)); // ACTION 2: query without filter, no local entries entries = ctx.GetEffectiveEntries(Id("E5")); // ASSERT 2 Assert.AreEqual(2, entries.Count); Assert.AreEqual(1, entries.Count(x => x.EntryType == EntryType.Normal)); Assert.AreEqual(1, entries.Count(x => x.EntryType == EntryType.Sharing)); Assert.AreEqual(0, entries.Count(x => x.LocalOnly)); Assert.AreEqual(2, entries.Count(x => !x.LocalOnly)); // ACTION 3: query + filter Normal + local entries entries = ctx.GetEffectiveEntries(Id("E2"), null, EntryType.Normal); // ASSERT 3 Assert.AreEqual(2, entries.Count); Assert.AreEqual(0x3ul, entries.First(x => !x.LocalOnly).AllowBits); Assert.AreEqual(0x4ul, entries.First(x => x.LocalOnly).AllowBits); Assert.AreEqual(EntryType.Normal, entries[0].EntryType); Assert.AreEqual(EntryType.Normal, entries[1].EntryType); // ACTION 4: query + filter Sharing + local entries entries = ctx.GetEffectiveEntries(Id("E2"), null, EntryType.Sharing); // ASSERT 4 Assert.AreEqual(2, entries.Count); Assert.AreEqual(0x18ul, entries.First(x => !x.LocalOnly).AllowBits); Assert.AreEqual(0x20ul, entries.First(x => x.LocalOnly).AllowBits); Assert.AreEqual(EntryType.Sharing, entries[0].EntryType); Assert.AreEqual(EntryType.Sharing, entries[1].EntryType); // ACTION 5: query + filter Normal, no local entries entries = ctx.GetEffectiveEntries(Id("E5"), null, EntryType.Normal); // ASSERT 5 Assert.AreEqual(1, entries.Count); Assert.AreEqual(0x3ul, entries[0].AllowBits); Assert.AreEqual(EntryType.Normal, entries[0].EntryType); // ACTION 6: query + filter Sharing, no local entries entries = ctx.GetEffectiveEntries(Id("E5"), null, EntryType.Sharing); // ASSERT 6 Assert.AreEqual(1, entries.Count); Assert.AreEqual(0x18ul, entries[0].AllowBits); Assert.AreEqual(EntryType.Sharing, entries[0].EntryType); }
public void Sharing_Acl_ExplicitEntries_Filtered() { EnsureRepository(); var ctx = CurrentContext.Security; Tools.SetMembership(ctx, "U1:G1"); SetAcl("+E1| Normal|+G1:______________+"); // 0x1 SetAcl("+E1|Sharing|+G1:___________+___"); // 0x8 SetAcl("+E2| Normal|+G1:_____________+_"); // 0x2 SetAcl("+E2|Sharing|+G1:__________+____"); // 0x10 SetAcl("+E2| Normal|-G1:____________+__"); // 0x4 local SetAcl("+E2|Sharing|-G1:_________+_____"); // 0x20 local // ACTION 1: query without filter + local entries var entries = ctx.GetExplicitEntries(Id("E2")) .OrderBy(x => x.LocalOnly).ThenBy(x => x.EntryType).ToList(); // ASSERT 1 Assert.AreEqual(4, entries.Count); Assert.AreEqual("Normal|+G1:______________________________________________________________+_", Tools.ReplaceIds(entries[0].ToString())); Assert.AreEqual("Sharing|+G1:___________________________________________________________+____", Tools.ReplaceIds(entries[1].ToString())); Assert.AreEqual("Normal|-G1:_____________________________________________________________+__", Tools.ReplaceIds(entries[2].ToString())); Assert.AreEqual("Sharing|-G1:__________________________________________________________+_____", Tools.ReplaceIds(entries[3].ToString())); // ACTION 2: query without filter, no local entries entries = ctx.GetExplicitEntries(Id("E1")) .OrderBy(x => x.LocalOnly).ThenBy(x => x.EntryType).ToList(); // ASSERT 2 Assert.AreEqual(2, entries.Count); Assert.IsTrue(!entries[0].LocalOnly && entries[0].EntryType == EntryType.Normal); Assert.IsTrue(!entries[1].LocalOnly && entries[1].EntryType == EntryType.Sharing); Assert.AreEqual("Normal|+G1:_______________________________________________________________+", Tools.ReplaceIds(entries[0].ToString())); Assert.AreEqual("Sharing|+G1:____________________________________________________________+___", Tools.ReplaceIds(entries[1].ToString())); // ACTION 3: query + filter Normal + local entries entries = ctx.GetExplicitEntries(Id("E2"), null, EntryType.Normal) .OrderBy(x => x.LocalOnly).ThenBy(x => x.EntryType).ToList(); // ASSERT 3 Assert.AreEqual(2, entries.Count); Assert.AreEqual("Normal|+G1:______________________________________________________________+_", Tools.ReplaceIds(entries[0].ToString())); Assert.AreEqual("Normal|-G1:_____________________________________________________________+__", Tools.ReplaceIds(entries[1].ToString())); // ACTION 4: query + filter Sharing + local entries entries = ctx.GetExplicitEntries(Id("E2"), null, EntryType.Sharing) .OrderBy(x => x.LocalOnly).ThenBy(x => x.EntryType).ToList(); // ASSERT 4 Assert.AreEqual(2, entries.Count); Assert.AreEqual("Sharing|+G1:___________________________________________________________+____", Tools.ReplaceIds(entries[0].ToString())); Assert.AreEqual("Sharing|-G1:__________________________________________________________+_____", Tools.ReplaceIds(entries[1].ToString())); // ACTION 5: query + filter Normal, no local entries entries = ctx.GetExplicitEntries(Id("E1"), null, EntryType.Normal); // ASSERT 5 Assert.AreEqual(1, entries.Count); Assert.AreEqual("Normal|+G1:_______________________________________________________________+", Tools.ReplaceIds(entries[0].ToString())); // ACTION 6: query + filter Sharing, no local entries entries = ctx.GetExplicitEntries(Id("E1"), null, EntryType.Sharing); // ASSERT 6 Assert.AreEqual("Sharing|+G1:____________________________________________________________+___", Tools.ReplaceIds(entries[0].ToString())); }