//[TestCase("core:modify", false, true)] // unsupported //[TestCase("core:delete", false, false)] // unsupported //[TestCase( "core:modify,core:delete", false, true )] // unsupported public void Test_Save(string permissionAliases, bool canGetEntity, bool canSaveEntity) { UserAccount userAccount = null; EntityType entityType = null; IEntity entity1 = null; IEntity entity2 = null; IEntity loadedEntity; userAccount = Entity.Create <UserAccount>(); userAccount.Name = "Test user " + Guid.NewGuid().ToString(); userAccount.Save(); entityType = new EntityType(); entityType.Inherits.Add(UserResource.UserResource_Type); entityType.Save(); entity1 = Entity.Create(new EntityRef(entityType)); entity1.SetField("core:name", "A"); entity1.Save(); entity2 = Entity.Create(new EntityRef(entityType)); entity2.SetField("core:name", "B"); entity2.Save(); if (permissionAliases.Length > 0) { new AccessRuleFactory().AddAllowByQuery(userAccount.As <Subject>(), entityType.As <SecurableEntity>(), permissionAliases.Split(',').Select(x => new EntityRef(x)), TestQueries.EntitiesWithNameA().ToReport()); } using (new SetUser(userAccount)) { // Only check read permission, even when getting a writable version loadedEntity = null; Assert.That(() => loadedEntity = Entity.Get <IEntity>(new EntityRef(entity1), true), canGetEntity ? (Constraint)Is.EqualTo(entity1).Using(EntityRefComparer.Instance) : (Constraint)Throws.TypeOf <PlatformSecurityException>(), "Entity 1 Get is incorrect"); Assert.That(() => Entity.Get <IEntity>(new EntityRef(entity2), true), Throws.TypeOf <PlatformSecurityException>(), "Entity 2 access failed"); if (canGetEntity) { // Requires modify permission Assert.That(() => loadedEntity.Save(), canSaveEntity ? (Constraint)Throws.Nothing : (Constraint)Throws.TypeOf <PlatformSecurityException>()); } } }
public void Test_BasicSecurity() { UserAccount userAccount = null; EntityType entityType = null; IEntity entity1 = null; IEntity entity2 = null; userAccount = Entity.Create <UserAccount>(); userAccount.Name = "GetEntitiesOfType test user " + Guid.NewGuid().ToString(); userAccount.Save(); entityType = new EntityType(); entityType.Inherits.Add(UserResource.UserResource_Type); entityType.Save(); entity1 = Entity.Create(new EntityRef(entityType)); entity1.SetField("core:name", "A"); entity1.Save(); entity2 = Entity.Create(new EntityRef(entityType)); entity2.SetField("core:name", "B"); entity2.Save(); new AccessRuleFactory().AddAllowReadQuery(userAccount.As <Subject>(), entityType.As <SecurableEntity>(), TestQueries.EntitiesWithNameA().ToReport()); // Sanity Check. Check directly to avoid any caching or side effect issue. IDictionary <long, bool> results = new EntityAccessControlChecker().CheckAccess( new[] { new EntityRef(entity1), new EntityRef(entity2) }, new[] { Permissions.Read }, new EntityRef(userAccount)); Assert.That(results, Has.Exactly(1).Property("Key").EqualTo(entity1.Id).And.Property("Value").True, "EntityAccessControlChecker.CheckAccess: No access to Entity ID 1"); Assert.That(results, Has.Exactly(1).Property("Key").EqualTo(entity2.Id).And.Property("Value").False, "EntityAccessControlChecker.CheckAccess: Access to Entity ID 2"); using (new SetUser(userAccount)) { IEnumerable <IEntity> entities = Entity.GetInstancesOfType(entityType, true, "name"); Assert.That(entities.Count(), Is.EqualTo(1), "Entity.GetInstancesOfType: Incorrect count"); Assert.That(entities, Has.Exactly(1).Property("Id").EqualTo(entity1.Id), "Entity.GetInstancesOfType: Incorrect Id"); } }
public virtual void TestFixtureSetup() { EntityType entityType; try { DatabaseContext = DatabaseContext.GetContext(true); RunAsDefaultTenant = new RunAsDefaultTenant(); RunAsDefaultTenant.BeforeTest(null); entityType = EDC.ReadiNow.Model.Entity.Create <EntityType>(); entityType.Inherits.Add(UserResource.UserResource_Type); entityType.Save(); Entities = CreateEntities(entityType, MatchingName); // Ensure the results are ordered Query = TestQueries.Entities(entityType); Query.OrderBy.Add(new OrderByItem() { Expression = new ColumnReference() { ColumnId = Query.SelectColumns[0].ColumnId }, Direction = OrderByDirection.Ascending }); UserAccount = new UserAccount(); UserAccount.Save(); new AccessRuleFactory().AddAllowReadQuery(UserAccount.As <Subject>(), entityType.As <SecurableEntity>(), TestQueries.EntitiesWithNameA(entityType).ToReport()); } catch (Exception ex) { Console.Error.WriteLine("Setup failed: " + ex); if (DatabaseContext != null) { DatabaseContext.Dispose(); } throw; } }
private IEnumerable <TestCaseData> Test_GetReferencedFields_Source() { // Using a Func<StructuredQuery> rather than a straight StructuredQuery to // avoid issues with NUnit and using a CallContext in a TestCaseSource method. yield return(new TestCaseData((Func <StructuredQuery>)(() => TestQueries.Entities()), new string[0])); yield return(new TestCaseData((Func <StructuredQuery>)(() => TestQueries.EntitiesWithNameA()), new[] { "core:name" })); yield return(new TestCaseData((Func <StructuredQuery>)(() => TestQueries.EntitiesWithDescription()), new[] { "core:description" })); yield return(new TestCaseData((Func <StructuredQuery>)(() => TestQueries.EntitiesOrderByDescription()), new[] { "core:description" })); yield return(new TestCaseData((Func <StructuredQuery>)(() => TestQueries.EntitiesWithNameDescription("a", "a")), new[] { "core:name", "core:description" })); yield return(new TestCaseData((Func <StructuredQuery>)(() => TestQueries.EntitiesWithNameAndDescriptionInResults("a")), new [] { "core:name", "core:description" })); yield return(new TestCaseData((Func <StructuredQuery>)(() => TestQueries.AccessRulesWithNamedPermission("read")), new[] { "core:name", "core:accessRuleEnabled" })); yield return(new TestCaseData((Func <StructuredQuery>)(() => TestQueries.ActiveUsersInRole("administrators")), new[] { "core:name", "core:alias" })); }
//[TestCase("core:modify", false)] // unsupported //[TestCase("core:delete", true)] // unsupported //[TestCase("core:modify,core:delete", true)] // unsupported public void Test_Delete(string permissionAliases, bool canDeleteEntity1) { UserAccount userAccount = null; EntityType entityType = null; IEntity entity1 = null; IEntity entity2 = null; userAccount = Entity.Create <UserAccount>(); userAccount.Name = "Test user " + Guid.NewGuid().ToString(); userAccount.Save(); entityType = new EntityType(); entityType.Inherits.Add(UserResource.UserResource_Type); entityType.Save(); entity1 = Entity.Create(new EntityRef(entityType)); entity1.SetField("core:name", "A"); entity1.Save(); entity2 = Entity.Create(new EntityRef(entityType)); entity2.SetField("core:name", "B"); entity2.Save(); if (permissionAliases.Length > 0) { new AccessRuleFactory().AddAllowByQuery(userAccount.As <Subject>(), entityType.As <SecurableEntity>(), permissionAliases.Split(',').Select(x => new EntityRef(x)), TestQueries.EntitiesWithNameA().ToReport()); } using (new SetUser(userAccount)) { Assert.That(() => entity1.Delete(), canDeleteEntity1 ? (Constraint)Throws.Nothing : (Constraint)Throws.TypeOf <PlatformSecurityException>()); Assert.That(() => Entity.Get <IEntity>(new EntityRef(entity2)), Throws.TypeOf <PlatformSecurityException>(), "Entity 2 delete somehow worked"); } }
public void Test_Filter_ActionRequiresParentModifyAccess(string parentEntityPermissions, string childEntityPermissions) { SecurityActionMenuItemFilter securityActionMenuItemFilter; UserAccount userAccount; EntityType parentEntityType; EntityType childEntityType; IEntity parentEntity; IEntity childEntity; const string viewResourceActionAlias = "console:viewResourceAction"; const string editResourceActionAlias = "console:editResourceAction"; const string deleteResourceActionAlias = "console:deleteResourceAction"; const string addRelationshipActionAlias = "console:addRelationshipAction"; const string removeRelationshipActionAlias = "console:removeRelationshipAction"; var splitParentEntityPermissions = parentEntityPermissions.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries); var splitChildEntityPermissions = childEntityPermissions.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries); userAccount = new UserAccount(); userAccount.Name = "Test user " + Guid.NewGuid(); userAccount.Save(); // parent parentEntityType = new EntityType(); parentEntityType.Inherits.Add(UserResource.UserResource_Type); parentEntityType.Save(); parentEntity = Entity.Create(new EntityRef(parentEntityType)); parentEntity.SetField("core:name", "A"); // "A" so it will match the access rule parentEntity.Save(); // related child entity childEntityType = new EntityType(); childEntityType.Inherits.Add(UserResource.UserResource_Type); childEntityType.Save(); childEntity = Entity.Create(new EntityRef(childEntityType)); childEntity.SetField("core:name", "B"); // "B" so it will match the access rule childEntity.Save(); // grant accesses // parent entity new AccessRuleFactory().AddAllowByQuery( userAccount.As <Subject>(), parentEntityType.As <SecurableEntity>(), splitParentEntityPermissions.Select(s => new EntityRef(s)), TestQueries.EntitiesWithNameA().ToReport()); // child entity new AccessRuleFactory().AddAllowByQuery( userAccount.As <Subject>(), childEntityType.As <SecurableEntity>(), splitChildEntityPermissions.Select(s => new EntityRef(s)), TestQueries.EntitiesWithNameB().ToReport()); // actions var dummyRequest = new ActionRequestExtended(); Func <ActionRequestExtended, ActionMenuItem, ActionTargetInfo> dummyHandler = (a, i) => new ActionTargetInfo(); var actions = new List <ActionMenuItemInfo>(); foreach (string menuItemAlias in new[] { viewResourceActionAlias, editResourceActionAlias, addRelationshipActionAlias, removeRelationshipActionAlias, deleteResourceActionAlias, }) { actions.Add(Entity.Get <ActionMenuItem>(menuItemAlias).ToInfo(dummyRequest, null, dummyHandler)); } actions.Add(new ActionMenuItemInfo { EntityId = childEntityType.Id, HtmlActionState = "createForm", IsNew = true }); // filter actions using (new SetUser(userAccount)) { securityActionMenuItemFilter = new SecurityActionMenuItemFilter(); securityActionMenuItemFilter.Filter(parentEntity.Id, new[] { childEntity.Id }, actions); } // checks if (splitParentEntityPermissions.Contains("core:read") && splitParentEntityPermissions.Contains("core:modify")) { Assert.That(actions, Has.Exactly(1).Property("Alias").EqualTo(addRelationshipActionAlias), "Missing add relationship resource action"); Assert.That(actions, Has.Exactly(1).Property("Alias").EqualTo(removeRelationshipActionAlias), "Missing remove relationship resource action"); // child create if (splitChildEntityPermissions.Contains("core:create")) { Assert.That(actions, Has.Exactly(1).Property("HtmlActionState").EqualTo("createForm"), "Missing create resource action"); } else { Assert.That(actions, Has.None.Property("HtmlActionState").EqualTo("createForm"), "Create resource action should not be available"); } // child read if (splitChildEntityPermissions.Contains("core:read")) { Assert.That(actions, Has.Exactly(1).Property("Alias").EqualTo(viewResourceActionAlias), "Missing view resource action"); } else { Assert.That(actions, Has.None.Property("Alias").EqualTo(viewResourceActionAlias), "View resource action should not be available"); } // child modify if (splitChildEntityPermissions.Contains("core:modify")) { Assert.That(actions, Has.Exactly(1).Property("Alias").EqualTo(editResourceActionAlias), "Missing edit resource action"); } else { Assert.That(actions, Has.None.Property("Alias").EqualTo(editResourceActionAlias), "Edit resource action should not be available"); } // child delete if (splitChildEntityPermissions.Contains("core:delete")) { Assert.That(actions, Has.Exactly(1).Property("Alias").EqualTo(deleteResourceActionAlias), "Missing delete resource action"); } else { Assert.That(actions, Has.None.Property("Alias").EqualTo(deleteResourceActionAlias), "Delete resource action should not be available"); } } else if (splitParentEntityPermissions.Contains("core:read") && !splitParentEntityPermissions.Contains("core:modify")) { Assert.That(actions, Has.None.Property("Alias").EqualTo(addRelationshipActionAlias), "Add relationship action should not be available"); Assert.That(actions, Has.None.Property("Alias").EqualTo(removeRelationshipActionAlias), "Remove relationship action should not be available"); // child create Assert.That(actions, Has.None.Property("HtmlActionState").EqualTo("createForm"), "Create resource action should not be available"); // child read if (splitChildEntityPermissions.Contains("core:read")) { Assert.That(actions, Has.Exactly(1).Property("Alias").EqualTo(viewResourceActionAlias), "Missing view resource action"); } else { Assert.That(actions, Has.None.Property("Alias").EqualTo(viewResourceActionAlias), "View resource action should not be available"); } // child modify if (splitChildEntityPermissions.Contains("core:modify")) { Assert.That(actions, Has.Exactly(1).Property("Alias").EqualTo(editResourceActionAlias), "Missing edit resource action"); } else { Assert.That(actions, Has.None.Property("Alias").EqualTo(editResourceActionAlias), "Edit resource action should not be available"); } // child delete Assert.That(actions, Has.None.Property("Alias").EqualTo(deleteResourceActionAlias), "Delete resource action should not be available"); } }
public void Test_GetActions_Security_MultipleSelection(string entity1Name, string entity2Name, bool expectedResult) { ActionRequestExtended actionRequest; ActionResponse response; Report report; UserAccount userAccount; ActionMenuItem deleteActionMenuItem; IList <ActionMenuItemInfo> flattenedResults; EntityType entityType; IEntity entity1; IEntity entity2; entityType = Entity.Create <EntityType>(); entityType.Inherits.Add(UserResource.UserResource_Type); entityType.Save(); entity1 = Entity.Create(entityType); entity1.SetField("core:name", entity1Name); entity1.Save(); entity2 = Entity.Create(entityType); entity2.SetField("core:name", entity2Name); entity2.Save(); userAccount = Entity.Create <UserAccount>(); userAccount.Name = "Action service test " + Guid.NewGuid( ).ToString( ); userAccount.Save(); new AccessRuleFactory( ).AddAllowReadQuery( userAccount.As <Subject>( ), Entity.Get <SecurableEntity>(Entity.Get <EntityType>("core:report")), TestQueries.Entities(new EntityRef("core:report")).ToReport( )); deleteActionMenuItem = Entity.Get <ActionMenuItem>("console:deleteResourceAction"); Assert.That(deleteActionMenuItem, Is.Not.Null, "No delete menu item"); new AccessRuleFactory().AddAllowByQuery( userAccount.As <Subject>(), entityType.As <SecurableEntity>(), new [] { Permissions.Read, Permissions.Delete }, TestQueries.EntitiesWithNameA(entityType).ToReport()); report = TestQueries.EntitiesWithNameA(entityType).ToReport(); report.Save(); actionRequest = new ActionRequestExtended { SelectedResourceIds = new[] { entity1.Id, entity2.Id }, LastSelectedResourceId = entity1.Id, CellSelectedResourceId = -1, ReportId = report.Id, HostResourceIds = new long[0], HostTypeIds = new List <long>(), AdditionalData = new Dictionary <string, object>(), ActionDisplayContext = ActionContext.ContextMenu }; using (new SetUser(userAccount)) { response = new ActionService().GetActions(actionRequest); } flattenedResults = response.Actions.SelectMany(Flatten).ToList(); Assert.That(flattenedResults, Has.Exactly(expectedResult ? 1 : 0).Property("Id").EqualTo(deleteActionMenuItem.Id), "Delete menu incorrect"); }
public void Test_GetImplicitRelated(string instructions, bool expectReturned) { if (_runner == "EntityInfoService") { Assert.Ignore(); } bool securesTo = instructions.Contains("securesTo"); bool securesFrom = instructions.Contains("securesFrom"); bool isReverse = instructions.Contains("reverse"); UserAccount userAccount; EntityType entityType; Relationship relationship; IEntity entity; IEntity relatedEntity; // Create user userAccount = Entity.Create <UserAccount>(); userAccount.Name = "Test user " + Guid.NewGuid(); userAccount.Save(); // Create type (used for both ends) entityType = new EntityType(); entityType.Inherits.Add(UserResource.UserResource_Type); entityType.Save(); // Create relationship relationship = new Relationship(); relationship.Cardinality_Enum = CardinalityEnum_Enumeration.ManyToMany; relationship.FromType = entityType; relationship.ToType = entityType; relationship.SecuresTo = securesTo; relationship.SecuresFrom = securesFrom; relationship.Save(); // Create related entity (the one that may or may not be visible) relatedEntity = Entity.Create(new EntityRef(entityType)); relatedEntity.SetField("core:name", "B"); // "B" so it does not match the access rule relatedEntity.Save(); // Create initial entity (the one that will be explicitly granted permissions, and queried) entity = Entity.Create(new EntityRef(entityType)); entity.SetField("core:name", "A"); // "A" so it will match the access rule var relInstances = entity.GetRelationships(relationship.Id, isReverse ? Direction.Reverse : Direction.Forward); relInstances.Add(relatedEntity); entity.SetRelationships(relationship.Id, relInstances, isReverse ? Direction.Reverse : Direction.Forward); entity.Save(); // Grant access to initial entity new AccessRuleFactory().AddAllowReadQuery(userAccount.As <Subject>(), entityType.As <SecurableEntity>(), TestQueries.EntitiesWithNameA().ToReport()); // Build request string query = string.Format("name,{0}#{1}.name", isReverse ? "-" : "", relationship.Id); EntityMemberRequest request = EntityRequestHelper.BuildRequest(query); var svc = GetService(); // Run request EntityData result; using (new SetUser(userAccount)) { result = svc.GetEntityData(new EntityRef(entity.Id), request); } // Check results Assert.That(result, Is.Not.Null); Assert.That(result.Relationships, Has.Exactly(1).Not.Null); if (expectReturned) { Assert.That(result.Relationships[0].Instances, Has.Exactly(1).Not.Null); Assert.That(result.Relationships[0].Instances[0].Entity.Id.Id, Is.EqualTo(relatedEntity.Id)); } else { Assert.That(result.Relationships[0].Instances, Is.Empty); } }
public void Test_Writeable_Related_Entity(string toPermissionAliases, bool toEntityWriteable) { var userAccount = Entity.Create <UserAccount>(); userAccount.Name = "Test user " + Guid.NewGuid(); userAccount.Save(); var fromType = new EntityType(); fromType.Inherits.Add(UserResource.UserResource_Type); fromType.Save(); var toType = new EntityType(); toType.Inherits.Add(UserResource.UserResource_Type); toType.Save(); var relationship = new Relationship { FromType = fromType, ToType = toType }; relationship.Save(); IEntity fromEntity = Entity.Create(new EntityRef(fromType)); fromEntity.SetField("core:name", "A"); fromEntity.Save(); IEntity toEntity = Entity.Create(new EntityRef(toType)); toEntity.SetField("core:name", "B"); toEntity.SetRelationships(relationship, new EntityRelationshipCollection <IEntity>() { fromEntity }, Direction.Reverse); toEntity.Save(); // Read / modify from type new AccessRuleFactory().AddAllowByQuery(userAccount.As <Subject>(), fromType.As <SecurableEntity>(), new List <EntityRef> { new EntityRef("core:read"), new EntityRef("core:modify") }, TestQueries.EntitiesWithNameA().ToReport()); if (toPermissionAliases.Length > 0) { // Access to to type new AccessRuleFactory().AddAllowByQuery(userAccount.As <Subject>(), toType.As <SecurableEntity>(), toPermissionAliases.Split(',').Select(x => new EntityRef(x)), TestQueries.EntitiesWithNameB().ToReport()); } using (new SetUser(userAccount)) { // The from entity should be able to be retrieved var fromEntityWriteable = Entity.Get <IEntity>(new EntityRef(fromEntity), true); Assert.AreEqual(fromEntity.Id, fromEntityWriteable.Id); // Check access to to entity IEntity entity = fromEntityWriteable.GetRelationships(relationship, Direction.Forward).FirstOrDefault( ); IEntity toEntityFromRel = null; if (entity != null) { toEntityFromRel = entity.Entity; } if (toPermissionAliases.Length > 0) { Assert.AreEqual(toEntity.Id, toEntityFromRel.Id); var toEntityWrite = toEntityFromRel.AsWritable(); toEntityWrite.SetField("core:description", "Test"); if (toEntityWriteable) { // Should be able to save Assert.DoesNotThrow(() => toEntityWrite.Save()); } else { // Should not be able to save Assert.That(toEntityWrite.Save, Throws.TypeOf <PlatformSecurityException>(), "Entity access is incorrect. Should notbe able to save."); } } else { // We do not have read access to the to entity so it should be null Assert.IsNull(toEntityFromRel); } } }
Role CreateDerivedRole(Role parent) { var role = Entity.Create <Role>(); role.Name = "test role " + Guid.NewGuid(); role.IncludesRoles.Add(parent); role.Save(); new AccessRuleFactory().AddAllowReadQuery(role.As <Subject>(), Person.Person_Type.As <SecurableEntity>(), TestQueries.EntitiesWithNameA().ToReport()); return(role); }