/// <summary>
        /// Gets the form calculation dependencies.
        /// </summary>
        /// <param name="formRef">The form reference.</param>
        /// <returns></returns>
        /// <exception cref="System.ArgumentNullException"></exception>
        public FormVisibilityCalcDependenciesResponse GetFormCalculationDependencies(EntityRef formRef)
        {
            var response = new FormVisibilityCalcDependenciesResponse();

            if (formRef == null)
            {
                throw new ArgumentNullException(nameof(formRef));
            }

            EntityData formEntityData = null;

            // Get the form entity data for non gen forms
            if (!EntityTemporaryIdAllocator.IsAllocatedId(formRef.Id))
            {
                try
                {
                    formEntityData = GetFormAsEntityData(formRef.Id, false);
                }
                catch (Exception ex)
                {
                    EventLog.Application.WriteError("Failed to get form with id {0}. Unable to get form control visibility calculation dependencies. Error: {1}.", formRef.Id, ex);
                }
            }

            if (formEntityData == null)
            {
                return(response);
            }

            using (new SecurityBypassContext())
            {
                // Have form. Get any visibility calculations
                IDictionary <long, string> controlVisibilityCalculations = GetControlVisibilityCalculations(formEntityData);

                long entityTypeId = GetTypeToEditWithForm(formEntityData);

                if (controlVisibilityCalculations.Count > 0 && entityTypeId > 0)
                {
                    // Now we have all the calculations
                    IDictionary <long, IExpression> compiledExpressions         = CompileVisibilityCalculations(new EntityRef(entityTypeId), controlVisibilityCalculations);
                    IDictionary <long, VisibilityCalcDependencies> dependencies = GetControlVisibilityCalcDependencies(compiledExpressions);
                    if (dependencies.Count > 0)
                    {
                        response.VisibilityCalcDependencies = dependencies;
                    }
                }
            }

            return(response);
        }
Exemplo n.º 2
0
        public void Test_TemporaryIds(long id, bool shouldRaiseException)
        {
            UserAccount             userAccount = null;
            EntityType              entityType  = null;
            MockRepository          mockRepository;
            Mock <IEntity>          mockEntity         = null;
            Mock <IEntityInternal>  mockEntityInternal = null;
            EntityModificationToken entityModificationToken;

            userAccount      = Entity.Create <UserAccount>();
            userAccount.Name = "Test user " + Guid.NewGuid().ToString();
            userAccount.Save();

            entityType = new EntityType();
            entityType.Inherits.Add(UserResource.UserResource_Type);
            entityType.Save();

            new AccessRuleFactory().AddAllowCreate(userAccount.As <Subject>(),
                                                   entityType.As <SecurableEntity>());

            // Mock an Entity. Yes, I am completely insane.
            mockRepository = new MockRepository(MockBehavior.Loose);
            mockEntity     = mockRepository.Create <IEntity>();
            mockEntity.SetupGet(e => e.TypeIds).Returns(() => new[] { entityType.Id });
            mockEntity.SetupGet(e => e.EntityTypes).Returns(() => new[] { entityType });
            mockEntity.Setup(e => e.IsReadOnly).Returns(() => false);
            mockEntity.SetupGet(e => e.Id).Returns(() => id);
            mockEntityInternal = mockEntity.As <IEntityInternal>();
            mockEntityInternal.SetupGet(ei => ei.IsTemporaryId).Returns(() => EntityTemporaryIdAllocator.IsAllocatedId(id));
            entityModificationToken = new EntityModificationToken();
            mockEntityInternal.SetupGet(ei => ei.ModificationToken).Returns(() => entityModificationToken);

            using (new SetUser(userAccount))
            {
                Assert.That(() => Entity.Save(new [] { mockEntity.Object }, false),
                            shouldRaiseException ? (Constraint)Throws.Nothing : Throws.TypeOf <PlatformSecurityException>());
            }
        }
Exemplo n.º 3
0
        /// <summary>
        /// Walk the entity data tree, first creating any new entities, then updating
        /// the entities and finally deleting any marked for delete.
        /// </summary>
        /// <param name="entityDataRoot">The entity data root.</param>
        /// <param name="persistChanges">If false, the entities are created in memory, but not persisted.</param>
        /// <param name="retries">The retries.</param>
        /// <returns>
        /// A mapping of old to new entity ids.
        /// </returns>
        /// <exception cref="System.ArgumentException">entityData.TypeIds must be set when creating new instances.
        /// or
        /// Attempted to create an entity using a temporary entity Id</exception>
        /// <exception cref="System.InvalidOperationException">Entity ID was not set and DataState was not create.
        /// or
        /// Entity not found. Id= + entityDataNode.Id
        /// or
        /// We have a newly created object that was not marked as DataState.Create. Id= + entityDataNode.Id</exception>
        private Dictionary <long, IEntity> CreateUpdateDeleteImpl(EntityData entityDataRoot, bool persistChanges, int retries = 0)
        {
            Dictionary <long, IEntity> entityMap = null;

            DatabaseContext.RunWithRetry(() =>
            {
                var originalRootState = entityDataRoot.DataState;

                // get the distinct nodes so we only have to walk the tree once
                var distinctNodes = WalkEntityDataTree(entityDataRoot, null);

                // ensure any deleted or created items cause entities that refer to them to be marked as changed
                CascadeUpRelationshipChanges(distinctNodes);

                /////
                // Track the created id's.
                /////
                entityMap = new Dictionary <long, IEntity>();

                var toSave   = new List <IEntity>();
                var toDelete = new HashSet <long>();

                //
                // Create the entities but do not save them
                //
                foreach (var entityDataNode in distinctNodes)
                {
                    if (entityDataNode.DataState == DataState.Create)
                    {
                        bool hasId = entityDataNode.Id != null && entityDataNode.Id.HasId;
                        long id    = hasId ? entityDataNode.Id.Id : -1;

                        if (!persistChanges && !hasId && !string.IsNullOrWhiteSpace(entityDataNode.Id?.Alias))
                        {
                            // entity ref has no id but has an alias
                            // resolve alias to id rather than creating a temp
                            id    = entityDataNode.Id.ResolveId();
                            hasId = true;
                        }

                        if (entityDataNode.TypeIds == null || entityDataNode.TypeIds.Count <= 0)
                        {
                            throw new ArgumentException("entityData.TypeIds must be set when creating new instances.");
                        }

                        if (entityDataNode.TypeIds.Any(tid => tid.Id > 0 && EntityTemporaryIdAllocator.IsAllocatedId(tid.Id)))
                        {
                            throw new ArgumentException("Attempted to create an entity using a temporary entity Id");
                        }

                        Entity newEntity = !persistChanges && hasId ? new Entity(entityDataNode.TypeIds, id) : new Entity(entityDataNode.TypeIds);

                        // if we were not given an Id to use as a reference, use new temporary one.
                        if (!hasId)
                        {
                            id = newEntity.Id;
                            entityDataNode.Id = id;
                        }

                        toSave.Add(newEntity);
                        entityMap[id]            = newEntity;
                        entityDataNode.DataState = DataState.Update;
                    }
                    else
                    {
                        if (entityDataNode.Id == null)
                        {
                            throw new InvalidOperationException("Entity ID was not set and DataState was not create.");
                        }
                        long id = entityDataNode.Id.Id;

                        if (id > 0 && !entityMap.ContainsKey(id))
                        {
                            entityMap[id] = Entity.Get(id);
                            if (entityMap[id] == null && entityDataNode.DataState != DataState.Delete)
                            {
                                throw new InvalidOperationException("Entity not found. Id=" + entityDataNode.Id);
                            }
                        }

                        // This is not a nice test for a new node, but I don't have a better one
                        if (entityDataNode.DataState == DataState.Update && id > EntityId.MinTemporary)
                        {
                            throw new InvalidOperationException("We have a newly created object that was not marked as DataState.Create. Id=" + entityDataNode.Id);
                        }
                    }
                }

                // Update the entities in memory
                UpdateImpl(distinctNodes, entityMap, toSave, toDelete);

                // Persist changes
                if (persistChanges)
                {
                    // Gather the ids for deletion
                    var delete = toDelete.Select(d => new EntityRef(d)).ToList();

                    delete.AddRange(distinctNodes.Where(n => n.DataState == DataState.Delete).Select(n => n.Id));

                    // Check delete permissions before the update takes place
                    EntityAccessControlService.Demand(delete, new[] { Permissions.Read, Permissions.Delete });

                    // Save all the created and changed entities (allowing entities to move from nodes deleted above)
                    Entity.Save(toSave.Distinct());

                    using (new SecurityBypassContext())
                    {
                        Entity.Delete(delete);
                    }
                }

                // Return the root entity
                if (originalRootState == DataState.Delete)
                {
                    entityMap = null;
                }
            });

            return(entityMap);
        }
Exemplo n.º 4
0
        public bool OnBeforeSave(IEnumerable <IEntity> entities, IDictionary <string, object> state)
        {
            foreach (Document document in from entity in entities where entity.Is <Document>() select entity.AsWritable <Document>())
            {
                // Populate the document revision
                DocumentRevision revision          = Entity.Create <DocumentRevision>();
                bool             createNewRevision = false;
                bool             initialRevision   = false;
                if (EntityTemporaryIdAllocator.IsAllocatedId(document.Id))
                {
                    // Populate the initial version string for the document
                    revision.VersionComments = @"Initial Version";
                    revision.Version         = @"1.0";
                    revision.Name            = revision.Version;
                    createNewRevision        = true;
                    initialRevision          = true;
                }
                else
                {
                    DocumentRevision currentRevision = document.CurrentDocumentRevision;

                    if (currentRevision?.FileDataHash != document.FileDataHash)
                    {
                        // Extract the version number and increment it
                        string newRevision = string.Format("{0}.0", Convert.ToInt32(currentRevision.Version.Split('.')[0]) + 1);
                        revision.VersionComments = document.Description;  // Need to modify the document entity to include a hidden field for comments ??
                        revision.Version         = newRevision;
                        revision.Name            = newRevision;
                        createNewRevision        = true;
                    }
                }

                if (createNewRevision)
                {
                    revision.FileExtension = document.FileExtension;
                    revision.ModifiedDate  = DateTime.UtcNow;
                    revision.Size          = document.Size;

                    // Get the entity that represents the user
                    UserAccount userAccount = Entity.Get <UserAccount>(RequestContext.GetContext().Identity.Id);

                    // Associate the revision to the account
                    revision.RevisionUpdatedBy = userAccount;
                    // Associate the file to this revision
                    revision.FileDataHash = document.FileDataHash;


                    SaveGraph saveGraph = EventTargetStateHelper.GetSaveGraph(state);
                    saveGraph.Entities[revision.Id] = revision;

                    document.CurrentDocumentRevision = revision;

                    // Associate the document to the revision (documentHasDocumentRevision - used for version history listing)
                    document.DocumentHasDocumentRevision.Add(revision);

                    // Associate the last created user to the document
                    if (initialRevision)
                    {
                        document.DocumentCreatedBy = userAccount;
                    }

                    // Associate the last modified user to the document
                    document.DocumentModifiedBy = userAccount;
                }

                document.DocumentHasDocumentType = document.DocumentFileType;

                if (document.InFolder == null)
                {
                    // Default document dumping ground if not specified
                    document.InFolder = Entity.Get <DocumentFolder>(new EntityRef("core", "documentsDocumentFolder"));
                }
            }
            return(false);
        }
        /// <summary>
        ///     Gets the form data.
        /// </summary>
        /// <param name="request">The request.</param>
        /// <returns></returns>
        public FormDataResponse GetFormData(FormDataRequest request)
        {
            if (request == null)
            {
                throw new ArgumentNullException(nameof(request));
            }

            var entityIdRef = new EntityRef(request.EntityId);

            // Get the entity data
            EntityData entityData = BulkRequestRunner.GetEntityData(entityIdRef, request.Query, request.Hint);

            // Set the result to NotFound for Basic and BasicWithDemand only
            if (entityData == null)
            {
                return(null);
            }

            var        formId         = new EntityRef(request.FormId).Id;
            EntityData formEntityData = null;

            // Get the form entity data for non gen forms
            if (!EntityTemporaryIdAllocator.IsAllocatedId(formId))
            {
                try
                {
                    formEntityData = GetFormAsEntityData(formId, false);
                }
                catch (Exception ex)
                {
                    EventLog.Application.WriteError("Failed to get form with id {0}. Unable to get initial form control visibility. Error: {1}.", formId, ex);
                }
            }

            ISet <long> initiallyHiddenControls = null;

            if (formEntityData == null)
            {
                return(PackageFormDataResponse(entityData, null));
            }

            IDictionary <long, IExpression> compiledExpressions = null;
            IDictionary <long, string>      controlVisibilityCalculations;

            using (new SecurityBypassContext())
            {
                // Have form. Get any visibility calculations
                controlVisibilityCalculations = GetControlVisibilityCalculations(formEntityData);

                long entityTypeId = GetTypeToEditWithForm(formEntityData);

                if (controlVisibilityCalculations.Count > 0 && entityTypeId > 0)
                {
                    // Now we have all the calculations
                    compiledExpressions = CompileVisibilityCalculations(new EntityRef(entityTypeId), controlVisibilityCalculations);
                }
            }

            if (controlVisibilityCalculations.Count > 0)
            {
                initiallyHiddenControls = GetHiddenControls(entityIdRef.Entity, controlVisibilityCalculations.Keys, compiledExpressions);
            }

            return(PackageFormDataResponse(entityData, initiallyHiddenControls));
        }