示例#1
0
        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));
        }
示例#2
0
        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()));
        }
示例#3
0
        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()));
        }
示例#4
0
        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));
        }
示例#5
0
        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()));
        }
示例#6
0
        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);
        }
示例#7
0
        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);
        }
示例#8
0
        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);
        }
示例#10
0
        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);
        }
示例#11
0
        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()));
        }