/// <summary>
        /// Constructor
        /// </summary>
        /// <param name="tenantId">The tenant to which this graph applies.</param>
        /// <param name="unsecuredGraphData">The bulk entity request result that backs this graph.</param>
        internal GraphEntityGraph(long tenantId, BulkRequestResult unsecuredGraphData)
        {
            if (unsecuredGraphData == null)
            {
                throw new ArgumentNullException("unsecuredGraphData");
            }

            TenantId            = tenantId;
            _unsecuredGraphData = unsecuredGraphData;
        }
        /// <summary>
        /// Loads a graph of entities and returns the root.
        /// </summary>
        /// <param name="ids">The root entity of the graph.</param>
        /// <param name="preloadQuery">The entity member request of what related content to load.</param>
        /// <param name="securityOption"></param>
        /// <returns>An IEntity that represents the root node, or null if it could not be found.</returns>
        private IEnumerable <IEntity> GetImpl(IEnumerable <long> ids, string preloadQuery, SecurityOption securityOption)
        {
            CheckActivation( );

            if (ids == null)
            {
                throw new ArgumentNullException("ids");
            }
            if (preloadQuery == null)
            {
                throw new ArgumentNullException("preloadQuery");
            }

            // Check IDs
            // (implemented within 'select' to participate in the single-pass only)
            Func <long, EntityRef> checkAndConvertId = id =>
            {
                if (EntityId.IsTemporary(id))
                {
                    throw new InvalidOperationException("GraphEntityRepository cannot load temporary entities.");
                }
                return(new EntityRef(id));
            };

            var entityRefs = ids.Select(checkAndConvertId);

            EntityRequest request = new EntityRequest(entityRefs, preloadQuery, "GraphEntityRepository");

            // Load data, unsecured, via EntityInfoService cache
            BulkRequestResult unsecuredResult = BulkResultCache.GetBulkResult(request);

            List <long> loadedRootEntities = unsecuredResult.RootEntitiesList;

            if (loadedRootEntities.Count == 0)
            {
                return(EmptyEntityList);
            }

            // Create the graph
            long tenantId = RequestContext.TenantId;
            var  graph    = new SecuredGraphEntityDataRepository(tenantId, unsecuredResult, EntityAccessControlService);

            // Secure the root entities
            IReadOnlyCollection <long> securedRootEntityIds = graph.SecureList(loadedRootEntities, securityOption);

            // Create wrappers
            IEnumerable <IEntity> result = securedRootEntityIds.Select(id => new GraphEntity(id, graph));

            return(result);
        }
Example #3
0
        /// <summary>
        ///     Sets up this instance.
        /// </summary>
        void IDataSource.Setup(IProcessingContext context)
        {
            if (RootEntities == null)
            {
                throw new InvalidOperationException("RootEntities is not set.");
            }

            // Perform demand on root entity(ies).
            if (DemandReadPermission)
            {
                EntityAccessControlService.Demand(RootEntities.Select(id => new EntityRef(id)).ToList( ), new[]
                {
                    Permissions.Read
                });
            }

            using (new TenantAdministratorContext(TenantId))
            {
                _aliasFieldId        = WellKnownAliases.CurrentTenant.Alias;
                _reverseAliasFieldId = WellKnownAliases.CurrentTenant.ReverseAlias;

                // Get the instance to be exported
                IEnumerable <IEntity> instances = EntityRepository.Get(RootEntities);
                ICollection <long>    typeIds   = instances.Select(inst => inst.TypeIds.FirstOrDefault( )).Distinct().ToList();
                if (typeIds.Count == 0)
                {
                    typeIds = new[] { WellKnownAliases.CurrentTenant.Resource }
                }
                ;

                // Generate a cloning request factory for loading the data
                CloneEntityMemberRequestFactory requestFactory = new CloneEntityMemberRequestFactory(EntityRepository);
                EntityMemberRequest             memberRequest  = requestFactory.CreateRequest(typeIds);

                EntityRequest entityRequest = new EntityRequest
                {
                    Request  = memberRequest,
                    Entities = RootEntities.Select(id => new EntityRef(id))
                };

                // Load data, unsecured, via EntityInfoService cache
                _bulkResult = BulkResultCache.GetBulkResult(entityRequest);

                // Load all UpgradeIDs
                IEnumerable <long> allIds = _bulkResult.AllEntities.Keys
                                            .Union(_bulkResult.Relationships.Keys.Select(k => k.TypeId))
                                            .Union(_bulkResult.FieldValues.Keys.Select(k => k.FieldId));

                _idToUpgradeId = UpgradeIdProvider.GetUpgradeIds(allIds);

                IEnumerable <long>         relTypes      = _bulkResult.Relationships.Keys.Select(key => key.TypeId).Distinct( );
                IEnumerable <Relationship> relationships = EntityRepository.Get <Relationship>(relTypes);
                _relationshipTypeCache = relationships.ToDictionary(
                    rel => _idToUpgradeId[rel.Id],
                    rel => new RelationshipTypeEntry
                {
                    CloneAction        = rel.CloneAction_Enum,
                    ReverseCloneAction = rel.ReverseCloneAction_Enum,
                    Alias        = rel.Alias,
                    ReverseAlias = rel.ReverseAlias
                });

                LoadDocumentCaches(context);
            }

            // Read permissions - for reading internal entities
            if (DemandReadPermission)
            {
                _canRead = BulkRequestResultSecurityHelper.GetEntityReadability(Factory.EntityAccessControlService, _bulkResult);
            }
            else
            {
                _canRead = id => true;
            }
        }

        /// <summary>
        ///     Loads the application metadata.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <returns></returns>
        /// <exception cref="System.InvalidOperationException">@Invalid package Id</exception>
        Metadata IDataSource.GetMetadata(IProcessingContext context)
        {
            List <Guid> roots = new List <Guid>( );

            foreach (long rootId in RootEntities)
            {
                Guid rootGuid;
                if (_idToUpgradeId.TryGetValue(rootId, out rootGuid))
                {
                    roots.Add(rootGuid);
                }
            }

            var metadata = new Metadata
            {
                AppName      = "Exported data",
                AppVerId     = Guid.Empty,
                AppId        = Guid.Empty,
                Description  = "Exported data",
                Name         = "Exported data",
                Version      = "1.0",
                RootEntities = roots,
                //Dependencies = solutionDependencies,
                Type                     = SourceType.DataExport,
                PlatformVersion          = SystemInfo.PlatformVersion,
                RelationshipTypeCallback = GetRelationshipMetadata
            };


            return(metadata);
        }
Example #4
0
 /// <summary>
 /// Constructor.
 /// </summary>
 /// <param name="tenantId">Tenant that the data applies to.</param>
 /// <param name="unsecuredGraphData">Underlying graph data.</param>
 /// <param name="entityAccessControlService">Security service.</param>
 internal SecuredGraphEntityDataRepository(long tenantId, BulkRequestResult unsecuredGraphData, IEntityAccessControlService entityAccessControlService) : base(tenantId, unsecuredGraphData)
 {
     _entityAccessControlService = entityAccessControlService;
 }