public void BuildAndSecureResults_WriteOnlyFields() { BulkRequestResult bulkRequestResult; long administratorUserAccountId; EntityRequest entityRequest; IList <EntityData> results; EntityData result; EntityRef passwordField; EntityRef nameField; PasswordPolicy passwordPolicy; administratorUserAccountId = Entity.GetId("core:administratorUserAccount"); Assert.That(administratorUserAccountId, Is.Positive, "Administrator account missing"); passwordField = new EntityRef("core:password"); Assert.That(passwordField.Entity.As <Field>(), Has.Property("IsFieldWriteOnly").True); nameField = new EntityRef("core:name"); passwordPolicy = Entity.Get <PasswordPolicy>("core:passwordPolicyInstance"); Assert.That(passwordPolicy, Is.Not.Null, "Password policy missing"); // Build the results entityRequest = new EntityRequest { QueryType = QueryType.Basic, Entities = new [] { new EntityRef("core:administratorUserAccount") }, RequestString = "name, password", Hint = "NUnit test" }; bulkRequestResult = BulkResultCache.GetBulkResult(entityRequest); results = BulkRequestResultConverter.BuildAndSecureResults( bulkRequestResult, new[] { administratorUserAccountId }, SecurityOption.SkipDenied).ToList(); Assert.That(results, Has.Count.EqualTo(1), "Incorrect number of results"); result = results.FirstOrDefault(); Assert.That(result, Is.Not.Null); Assert.That(result.Fields, Has.Count.EqualTo(2), "Incorrect number of fields"); Assert.That( result.Fields, Has.Exactly(1) .Property("FieldId").EqualTo(nameField) .And.Property("Value").Property("Value").EqualTo("Administrator"), "Incorrect password field value"); Assert.That( result.Fields, Has.Exactly(1) .Property("FieldId").EqualTo(passwordField) .And.Property("Value").Property("Value").EqualTo( new string('*', passwordPolicy.MinimumPasswordLength ?? WriteOnlyFieldReadValueGenerator.DefaultWriteOnlyStringResultLength)), "Incorrect password field value"); }
/// <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); }
/// <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); }