A small immutable class to describe Identities and GroupMemberships independently of a Context.
All properties mirror the same properties on Zetbox.Base.Identity.
Exemple #1
0
        private void CreateTestData()
        {
            ZetboxPrincipal principal1, principal2, principal3;

            {
                srvCtx = scope.Resolve<IZetboxServerContext>();

                var grpAdmin = Zetbox.NamedObjects.Base.Groups.Administrator.Find(srvCtx);
                var grpEveryOne = Zetbox.NamedObjects.Base.Groups.Everyone.Find(srvCtx);

                // Create Identities
                admin = srvCtx.Create<Identity>();
                admin.DisplayName = "Administrator";
                admin.UserName = "******";
                admin.Groups.Add(grpAdmin);
                admin.Groups.Add(grpEveryOne);

                identity1 = srvCtx.Create<Identity>();
                identity1.DisplayName = "User 1";
                identity1.UserName = "******";
                identity1.Groups.Add(grpEveryOne);

                identity2 = srvCtx.Create<Identity>();
                identity2.DisplayName = "User 2";
                identity2.UserName = "******";
                identity2.Groups.Add(grpEveryOne);

                identity3_low = srvCtx.Create<Identity>();
                identity3_low.DisplayName = "User 3 with low privileges";
                identity3_low.UserName = "******";

                ma1 = srvCtx.Create<Mitarbeiter>();
                ma1.Name = identity1.DisplayName;
                ma1.Identity = identity1;

                ma2 = srvCtx.Create<Mitarbeiter>();
                ma2.Name = identity2.DisplayName;
                ma2.Identity = identity2;

                ma3_low = srvCtx.Create<Mitarbeiter>();
                ma3_low.Name = identity3_low.DisplayName;
                ma3_low.Identity = identity3_low;

                srvCtx.SubmitChanges();
            }

            principal1 = new ZetboxPrincipal(identity1.ID, identity1.UserName, identity1.DisplayName, identity1.Groups.Select(g => new ZetboxPrincipalGroup(g.ID, g.Name, g.ExportGuid)));
            principal2 = new ZetboxPrincipal(identity2.ID, identity2.UserName, identity2.DisplayName, identity2.Groups.Select(g => new ZetboxPrincipalGroup(g.ID, g.Name, g.ExportGuid)));
            principal3 = new ZetboxPrincipal(identity3_low.ID, identity3_low.UserName, identity3_low.DisplayName, identity3_low.Groups.Select(g => new ZetboxPrincipalGroup(g.ID, g.Name, g.ExportGuid)));

            {
                // Create 3 identity context
                var ctx = scope.Resolve<ServerZetboxContextFactory>().Invoke(principal1);

                // Create TestData with Identity 1
                prj1 = ctx.Create<Projekt>();
                prj1.Name = "Project User 1";
                prj1.Mitarbeiter.Add(ctx.Find<Mitarbeiter>(ma1.ID));
                CreateTasks(ctx, prj1);

                // Create TestData with Identity 1, common
                prjCommon = ctx.Create<Projekt>();
                prjCommon.Name = "Project Common";
                prjCommon.Mitarbeiter.Add(ctx.Find<Mitarbeiter>(ma1.ID));
                prjCommon.Mitarbeiter.Add(ctx.Find<Mitarbeiter>(ma2.ID));
                CreateTasks(ctx, prjCommon);

                ctx.SubmitChanges();

                prj1ID = prj1.ID;
                prjCommonID = prjCommon.ID;
            }

            {
                var ctx = scope.Resolve<ServerZetboxContextFactory>().Invoke(principal2);

                // Create TestData with Identity 2
                prj2 = ctx.Create<Projekt>();
                prj2.Name = "Project User 2";
                prj2.Mitarbeiter.Add(ctx.Find<Mitarbeiter>(ma2.ID));
                CreateTasks(ctx, prj2);
                ctx.SubmitChanges();

                prj2ID = prj2.ID;
            }

            id1Ctx = scope.Resolve<ServerZetboxContextFactory>().Invoke(principal1);
            id2Ctx = scope.Resolve<ServerZetboxContextFactory>().Invoke(principal2);
            id3Ctx_low = scope.Resolve<ServerZetboxContextFactory>().Invoke(principal3);

            prj1 = id1Ctx.Find<Projekt>(prj1ID);
            prjCommon = id1Ctx.Find<Projekt>(prjCommonID);
            prj2 = id2Ctx.Find<Projekt>(prj2ID);

            // Fix security tables
            // Own test checks if this works during object modifications too
            var connectionString = config.Server.GetConnectionString(Helper.ZetboxConnectionStringKey);
            using (var db = scope.ResolveNamed<ISchemaProvider>(connectionString.SchemaProvider))
            {
                db.Open(connectionString.ConnectionString);
                db.ExecRefreshRightsOnProcedure(db.GetProcedureName("projekte", "RefreshRightsOn_Projekte"));
                db.ExecRefreshRightsOnProcedure(db.GetProcedureName("projekte", "RefreshRightsOn_Tasks"));
                db.ExecRefreshRightsOnProcedure(db.GetProcedureName("projekte", "RefreshRightsOn_Auftraege"));
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="cls"></param>
        /// <param name="principal"></param>
        /// <returns>Returns null if not mentioned in any group membership</returns>
        public static Zetbox.API.AccessRights? GetGroupAccessRights(this ObjectClass cls, ZetboxPrincipal principal)
        {
            if (cls == null) throw new ArgumentNullException("cls");
            if (principal == null) throw new ArgumentNullException("principal");
            cls = cls.GetRootClass();
            var groups = principal.Groups.ToLookup(i => i.ExportGuid);

            Zetbox.App.Base.AccessRights? result = null;

            foreach (var gm in cls.AccessControlList.OfType<GroupMembership>())
            {
                if (groups.Contains(gm.Group.ExportGuid))
                {
                    if (result == null) result = 0;
                    result = result.Value | (gm.Rights ?? 0);
                }
            }

            return (Zetbox.API.AccessRights?)result;
        }