private void SetRel(IEntity source, IEntity target, IEntity rel, Direction direction = Direction.Forward)
        {
            IEntityRelationshipCollection <IEntity> relationshipsCol = new EntityRelationshipCollection <IEntity>
            {
                target
            };

            source.SetRelationships(rel, relationshipsCol, direction);
            source.Save( );
        }
Exemplo n.º 2
0
        /// <summary>
        /// Multi-relationship setter implementation for strong types.
        /// </summary>
        /// <typeparam name="T">Type of entity being pointed to.</typeparam>
        /// <param name="alias">Relationship alias.</param>
        /// <param name="values">New entities to point to, or null.</param>
        /// <param name="direction">Relationship direction.</param>
        protected void SetRelationships <T>(string alias, IEntityCollection <T> values, Direction direction)
            where T : class, IEntity
        {
            IEntityRelationshipCollection <T> converted = null;

            if (values != null)
            {
                converted = new EntityRelationshipCollection <T>(values);
            }

            _entity.SetRelationships(alias, converted, direction);
        }
        public void Test_RelationshipInstance(string action, string fromPerms, string toPerms, Direction direction, bool saveBothEnds, bool haveFieldChanges, bool expectAllow)
        {
            if (fromPerms == "modify")
            {
                fromPerms = "read,modify";
            }
            if (toPerms == "modify")
            {
                toPerms = "read,modify";
            }

            // Create schema
            EntityType fromType = new EntityType();

            fromType.Inherits.Add(UserResource.UserResource_Type);
            fromType.Name = Guid.NewGuid().ToString();
            fromType.Save();

            EntityType toType = new EntityType();

            toType.Inherits.Add(UserResource.UserResource_Type);
            toType.Name = Guid.NewGuid().ToString();
            toType.Save();

            Relationship rel = new Relationship();

            rel.Name             = Guid.NewGuid().ToString();
            rel.FromType         = fromType;
            rel.ToType           = toType;
            rel.Cardinality_Enum = CardinalityEnum_Enumeration.ManyToMany;
            rel.Save();

            // Create data
            IEntity toInst = new Entity(toType);

            toInst.Save();
            IEntity fromInst = new Entity(fromType);

            if (action != "Create")
            {
                fromInst.SetRelationships(rel, new EntityRelationshipCollection <IEntity> {
                    toInst
                });
            }
            fromInst.Save();

            // Create test user
            UserAccount userAccount = Entity.Create <UserAccount>();

            userAccount.Name = Guid.NewGuid().ToString();
            userAccount.Save();

            // Grant access
            if (!string.IsNullOrEmpty(fromPerms))
            {
                new AccessRuleFactory().AddAllowByQuery(
                    userAccount.As <Subject>(),
                    fromType.As <SecurableEntity>(),
                    fromPerms.Split(',').Select(pa => new EntityRef(pa)),
                    TestQueries.Entities().ToReport());
            }
            if (!string.IsNullOrEmpty(toPerms))
            {
                new AccessRuleFactory().AddAllowByQuery(
                    userAccount.As <Subject>(),
                    toType.As <SecurableEntity>(),
                    toPerms.Split(',').Select(pa => new EntityRef(pa)),
                    TestQueries.Entities().ToReport());
            }

            // Test

            bool allowed = false;

            try
            {
                using (new SetUser(userAccount))
                {
                    IEntity source = Entity.Get(direction == Direction.Forward ? fromInst.Id : toInst.Id);
                    if (action != "Read")
                    {
                        source = source.AsWritable();
                    }
                    Func <IEntity> target = () => Entity.Get(direction == Direction.Forward ? toInst.Id : fromInst.Id);

                    IEntityRelationshipCollection <IEntity> relCol = null;

                    switch (action)
                    {
                    case "Read":
                        relCol = source.GetRelationships(rel.Id, direction);
                        IEntity entity = relCol.FirstOrDefault();
                        allowed = entity != null;
                        break;

                    case "Create":
                        relCol = new EntityRelationshipCollection <IEntity> {
                            target()
                        };
                        source.SetRelationships(rel, relCol);
                        if (haveFieldChanges)
                        {
                            source.SetField("core:name", Guid.NewGuid().ToString());
                        }
                        if (saveBothEnds)
                        {
                            Entity.Save(new[] { source, target() });
                        }
                        else
                        {
                            source.Save();
                        }
                        allowed = true;
                        break;

                    case "Remove":
                        relCol = source.GetRelationships(rel.Id, direction);
                        relCol.Remove(target());
                        source.SetRelationships(rel, relCol);
                        if (haveFieldChanges)
                        {
                            source.SetField("core:name", Guid.NewGuid().ToString());
                        }
                        if (saveBothEnds)
                        {
                            Entity.Save(new[] { source, target() });
                        }
                        else
                        {
                            source.Save();
                        }
                        allowed = true;
                        break;

                    case "Clear":
                        relCol = source.GetRelationships(rel.Id, direction);
                        relCol.Clear();
                        source.SetRelationships(rel, relCol);
                        if (haveFieldChanges)
                        {
                            source.SetField("core:name", Guid.NewGuid().ToString());
                        }
                        if (saveBothEnds)
                        {
                            Entity.Save(new[] { source, target() });
                        }
                        else
                        {
                            source.Save();
                        }
                        allowed = true;
                        break;

                    default:
                        throw new InvalidOperationException("Unknown " + action);
                    }
                }
                Assert.That(allowed, Is.EqualTo(expectAllow));
            }
            catch (PlatformSecurityException)
            {
                Assert.That(false, Is.EqualTo(expectAllow));
            }
        }
Exemplo n.º 4
0
        /// <summary>
        /// Given a update ac
        /// </summary>
        /// <param name="activityAs"></param>
        /// <param name="inputs"></param>
        /// <param name="entityToUpdate"></param>
        public static void UpdateEntityFromArgs(EntityWithArgsAndExits activityAs, ActivityInputs inputs, IEntity entityToUpdate)
        {
            // This activity may also have its own input arguments (as opposed to those on its type)
            // and these are grouped so we can update multiple fields, relationships etc.


            // find the list of base names (indexes) of the argument groups
            Entity.GetField(activityAs.InputArguments, new EntityRef("core:name"));

            IOrderedEnumerable <int> argGroups = GetInputArgumentGroups(activityAs);

            // process each group

            foreach (var baseName in argGroups.Select(g => g.ToString()))
            {
                var arg = activityAs.InputArguments.FirstOrDefault(p => p.Name == baseName);

                if (arg == null)
                {
                    Log("Failed to find input argument for activity {0} with name {1}", activityAs.Name, baseName);
                    continue;
                }

                if (!inputs.ContainsKey(arg))
                {
                    Log("Failed to input argument expression for activity {0} with name {1}", activityAs.Name, baseName);
                    continue;
                }

                var memberEntity = (IEntity)inputs[arg];

                if (memberEntity != null)
                {
                    var fieldEntity = memberEntity.Is <Field>() ? memberEntity.Cast <Field>() : null;
                    var relEntity   = memberEntity.Is <Relationship>() ? memberEntity.Cast <Relationship>() : null;

                    if (fieldEntity != null)
                    {
                        var valueArg = activityAs.InputArguments.FirstOrDefault(p => p.Name == baseName + "_value");
                        if (valueArg == null || !inputs.ContainsKey(valueArg))
                        {
                            Log("Failed to find input argument for activity {0} with name {1}", activityAs.Name,
                                baseName + "_value");
                        }
                        else
                        {
                            //Log("Updating field {0} {1} with value {2}", fieldEntity.Id, fieldEntity.Name,
                            //    inputs[valueArg]);

                            entityToUpdate.SetField(fieldEntity, inputs[valueArg]);
                        }
                    }
                    else if (relEntity != null)
                    {
                        var reverseArg = activityAs.InputArguments.FirstOrDefault(p => p.Name == baseName + "_reverse");
                        var replaceArg = activityAs.InputArguments.FirstOrDefault(p => p.Name == baseName + "_replace");

                        var cardinality = relEntity.Cardinality_Enum ?? CardinalityEnum_Enumeration.ManyToMany;

                        var direction = reverseArg != null && inputs.ContainsKey(reverseArg)
                                            ? (((bool?)inputs[reverseArg] ?? false)
                                                   ? Direction.Reverse
                                                   : Direction.Forward)
                                            : Direction.Forward;
                        var replaceExisting = (replaceArg != null && inputs.ContainsKey(replaceArg) &&
                                               ((bool?)inputs[replaceArg] ?? false)) ||
                                              cardinality == CardinalityEnum_Enumeration.OneToOne
                                              ||
                                              (direction == Direction.Forward &&
                                               cardinality == CardinalityEnum_Enumeration.ManyToOne)
                                              ||
                                              (direction == Direction.Reverse &&
                                               cardinality == CardinalityEnum_Enumeration.OneToMany);

                        //Log("Updating relationship {0} {1} direction={2} replace={3}", relEntity.Id, relEntity.Name,
                        //    direction,
                        //    replaceExisting);

                        var oldRelCollection = entityToUpdate.GetRelationships(relEntity, direction);

                        //Log("Before: relationship {0} {1} has {2} related entities", relEntity.Id, relEntity.Name,
                        //    relCollection.Count());

                        var relCollection = new EntityRelationshipCollection <IEntity>();    // We need to create a new collection and set the relationship to it to deal with a bug that occurs when a resource is cloned and then modified with a relationship set to the same value.


                        if (!replaceExisting)
                        {
                            foreach (var e in oldRelCollection)
                            {
                                relCollection.Add(e);
                            }
                        }

                        foreach (
                            var valueArg in
                            activityAs.InputArguments.Where(p => p.Name.StartsWith(baseName + "_value_")))
                        {
                            var value = inputs.ContainsKey(valueArg) ? inputs[valueArg] : null;

                            IEnumerable <IEntity> entityRefs;

                            if (value is IEntity)
                            {
                                entityRefs = new List <IEntity> {
                                    (IEntity)value
                                };
                            }
                            else
                            {
                                entityRefs = (IEnumerable <IEntity>)value;
                            }

                            if (entityRefs != null)
                            {
                                foreach (var entity in entityRefs)
                                {
                                    if (entity != null)
                                    {
                                        var relatedEntity = entity.As <Resource>();

                                        if (relatedEntity != null)
                                        {
                                            //Log(">> adding to relationship {0} {1}, related {2} {3}", relEntity.Id,
                                            //    relEntity.Name,
                                            //    relatedEntity.Id, relatedEntity.Name);

                                            relCollection.Add(relatedEntity);
                                        }
                                    }
                                }
                            }
                        }

                        entityToUpdate.SetRelationships(relEntity, relCollection, direction);

                        //Log("After: relationship {0} {1} has {2} related entities", relEntity.Id, relEntity.Name,
                        //    relCollection.Count());
                    }
                }
            }
        }
Exemplo n.º 5
0
        public void CloneWithOneToOneRelationship()
        {
            var x = DateTime.Now.ToUniversalTime().ToString("yyyyMMddHHmmss");

            #region Arrange

            var colour = new Definition();
            colour.Name = "Colour_" + x;
            colour.Save();
            var objectA = new Definition();
            objectA.Name = "ObjectA_" + x;
            objectA.Save();
            var objectB = new Definition();
            objectB.Name = "ObjectB_" + x;
            objectB.Inherits.Add(objectA.As <EntityType>());
            objectB.Save();

            var relationship = new Relationship();
            relationship.Name                    = "Object To Colour " + x;
            relationship.FromType                = objectA.As <EntityType>();
            relationship.ToType                  = colour.As <EntityType>();
            relationship.Cardinality_Enum        = CardinalityEnum_Enumeration.OneToOne;
            relationship.CloneAction_Enum        = CloneActionEnum_Enumeration.CloneEntities;
            relationship.ReverseCloneAction_Enum = CloneActionEnum_Enumeration.CloneEntities;
            relationship.Save();

            var red = Entity.Create(colour.Id);
            red.Save();
            red.SetField(new EntityRef("core", "name"), "Red." + red.Id);
            red.Save();
            var blue = Entity.Create(colour.Id);
            blue.Save();
            blue.SetField(new EntityRef("core", "name"), "Blue." + blue.Id);
            blue.Save();
            var green = Entity.Create(colour.Id);
            green.Save();
            green.SetField(new EntityRef("core", "name"), "Green." + green.Id);
            green.Save();

            var colours = new EntityRelationshipCollection <IEntity>();
            colours.Add(blue);

            var instanceA = Entity.Create(objectA.Id);
            instanceA.Save();
            instanceA.SetField(new EntityRef("core", "name"), "A." + instanceA.Id);
            instanceA.SetRelationships(relationship, colours);
            instanceA.Save();

            // Workflow Setup
            var cloneActivity = new CloneActivity();
            cloneActivity.Save();

            var nextActivity = (CloneImplementation)cloneActivity.As <WfActivity>().CreateWindowsActivity();
            var inputs       = new Dictionary <string, object>
            {
                { "Record", instanceA },
                { "Object", objectB } // core:newDefinitionCloneArgument
            };

            ToDelete.Add(cloneActivity.Id);
            ToDelete.Add(instanceA.Id);
            ToDelete.Add(red.Id);
            ToDelete.Add(blue.Id);
            ToDelete.Add(green.Id);
            ToDelete.Add(relationship.Id);
            ToDelete.Add(objectB.Id);
            ToDelete.Add(objectA.Id);
            ToDelete.Add(colour.Id);

            #endregion

            var result         = RunActivity(nextActivity, inputs);
            var clone          = ((IEntity)result["Record"]);
            var original       = Entity.Get(instanceA.Id);
            var originalColour = Entity.Get(blue.Id);

            clone.Id.Should().NotBe(original.Id);

            ToDelete.Add(clone.Id);

            clone.GetField(new EntityRef("core", "name")).Should().Be("A." + instanceA.Id);

            var related = clone.GetRelationships(relationship);
            related.Should().NotBeNull().And.NotBeEmpty();
            related.Count.Should().Be(1);

            var cloneColour = related.First();

            cloneColour.Id.Should().NotBe(originalColour.Id);

            ToDelete.Add(cloneColour.Id);

            cloneColour.GetField(new EntityRef("core", "name")).Should().Be("Blue." + blue.Id);
        }
Exemplo n.º 6
0
        public void CloneRefsWithBaseDefinition()
        {
            var x = DateTime.Now.ToUniversalTime().ToString("yyyyMMddHHmmss");

            #region Arrange

            // Types
            var userResource     = Entity.Get <EntityType>(new EntityRef("core", "userResource"));
            var myBaseDefinition = new Definition {
                Name = "clonebasedefinition" + x, Inherits = new EntityCollection <EntityType>(userResource.ToEnumerable())
            };
            myBaseDefinition.Save();

            var myRelatedDefinition = new Definition {
                Name = "clonerelateddefinition" + x, Inherits = new EntityCollection <EntityType>(userResource.ToEnumerable())
            };
            myRelatedDefinition.Save();

            var myBaseType    = Entity.Get <EntityType>(myBaseDefinition);
            var myRelatedType = Entity.Get <EntityType>(myRelatedDefinition);
            var myBaseToRelatedRelationship = new Relationship
            {
                FromType                = myBaseType,
                ToType                  = myRelatedType,
                Name                    = "clonebaserelationship" + x,
                Description             = "Clone With Base Definition",
                Cardinality             = Entity.Get <CardinalityEnum>(new EntityRef("core", "manyToMany")),
                CascadeDelete           = false,
                CascadeDeleteTo         = false,
                CloneAction_Enum        = CloneActionEnum_Enumeration.CloneReferences,
                ReverseCloneAction_Enum = CloneActionEnum_Enumeration.CloneReferences
            };
            myBaseToRelatedRelationship.Save();

            var myDefinitionA = new Definition {
                Name = "clonedefinitionA" + x, Inherits = new EntityCollection <EntityType>(myBaseType.ToEnumerable())
            };
            myDefinitionA.Save();

            var myDefinitionB = new Definition {
                Name = "clonedefinitionB" + x, Inherits = new EntityCollection <EntityType>(myBaseType.ToEnumerable())
            };
            myDefinitionB.Save();

            // Instances
            var rOne = new Entity(myRelatedDefinition);
            rOne.SetField(new EntityRef("core", "name"), "Related 1." + x);
            rOne.Save();

            var rTwo = new Entity(myRelatedDefinition);
            rTwo.SetField(new EntityRef("core", "name"), "Related 2." + x);
            rTwo.Save();

            var rCollection = new EntityRelationshipCollection <IEntity>();
            rCollection.Add(rOne);
            rCollection.Add(rTwo);

            var cA = new Entity(myDefinitionA);
            cA.SetField(new EntityRef("core", "name"), "Clone Me A." + x);
            cA.SetRelationships(myBaseToRelatedRelationship, rCollection);
            cA.Save();

            // Workflow Setup
            var cloneActivity = new CloneActivity();
            cloneActivity.Save();

            var nextActivity = (CloneImplementation)cloneActivity.As <WfActivity>().CreateWindowsActivity();
            var inputs       = new Dictionary <string, object>
            {
                { "Record", cA },
                { "Object", myDefinitionB } // core:newDefinitionCloneArgument
            };

            ToDelete.Add(cloneActivity.Id);
            ToDelete.Add(cA.Id);
            ToDelete.Add(myDefinitionA.Id);
            ToDelete.Add(myDefinitionB.Id);
            ToDelete.Add(myRelatedDefinition.Id);
            ToDelete.Add(myBaseDefinition.Id);

            #endregion

            var result   = RunActivity(nextActivity, inputs);
            var clone    = ((IEntity)result["Record"]);
            var original = Entity.Get(cA.Id);

            clone.Id.Should().NotBe(original.Id);

            ToDelete.Add(clone.Id);

            var rid = myBaseToRelatedRelationship.Id;

            var cloneRels = clone.GetRelationships(rid, Direction.Forward).ToList();
            cloneRels.Count.Should().Be(2);
            foreach (var cloneRel in cloneRels)
            {
                var revs = cloneRel.GetRelationships(rid, Direction.Reverse);
                revs.Select(r => r.Id).Should().Contain(new [] { original.Id, clone.Id });
            }

            var originalRels = original.GetRelationships(rid, Direction.Forward).ToList();

            originalRels.Count.Should().Be(2);
            originalRels.Select(o => o.Id).Should().BeEquivalentTo(cloneRels.Select(c => c.Id));
        }