Note: This solution can be applied only to the old Security System. In the new Security System, you can configure member permissions to grant access to the associated collections.
This example demonstrates a workaround for the S30570 suggestion while it is not implemented out-of-the-box.
Suppose, I have the Organization and Person classes. Each Person object can be associated with a number of Organization objects, and each Organization object can be associated with a number of Person objects (a many-to-many relationship, see the BusinessClasses.cs file):
[C#]publicclassPerson:XPObject{publicPerson(Sessionsession):base(session){}publicstringName{get{returnGetPropertyValue<string>("Name");}set{SetPropertyValue<string>("Name",value);}}[Association("Organizations-Persons2")]publicXPCollection<Organization>Organizations{get{returnGetCollection<Organization>("Organizations");}}}publicclassOrganization:XPObject{publicOrganization(Sessionsession):base(session){}publicstringFullName{get{returnGetPropertyValue<string>("FullName");}set{SetPropertyValue<string>("FullName",value);}}[Association("Organizations-Persons")]publicXPCollection<Person>Persons{get{returnGetCollection<Person>("Persons");}}}
And, an end-user needs to modify any Person object, including its "Organizations" collection ('Link' or 'Unlink' organization objects), but he or she should not modify any property of an Organization object.
To accomplish this, I grant all operations under the Person objects and grant only the Read operation over the Organization objects (see the Updater.cs file):
[C#]userRole.AddPermission(newObjectAccessPermission(typeof(object),ObjectAccess.AllAccess,ObjectAccessModifier.Allow));userRole.AddPermission(newObjectAccessPermission(typeof(Person),ObjectAccess.AllAccess,ObjectAccessModifier.Allow));userRole.AddPermission(newObjectAccessPermission(typeof(Organization),ObjectAccess.ChangeAccess,ObjectAccessModifier.Deny));
With these permissions, I have achieved the necessary behavior, except for that an end-user cannot modify the Organizations collection property. This is a restriction of the current implementation of the XAF Security system.
To avoid it, I introduce a new class and manually allow modifying the "Organizations" property in the code (see the AllowManyToMany_ObjectAccessComparer.cs file):
[C#]publicclassAllowManyToMany_ObjectAccessComparer:ObjectAccessComparer{publicoverrideboolIsSubsetOf(ObjectAccessPermissionsourcePermission,ObjectAccessPermissiontargetPermission){if(sourcePermission.AccessItemList.Count== 1){ParticularAccessItemsourceAccessItem=sourcePermission.AccessItemList[0];if(typeof(Organization).IsAssignableFrom(sourceAccessItem.ObjectType)&&sourceAccessItem.Access==ObjectAccess.Write&&sourceAccessItem.Modifier==ObjectAccessModifier.Allow){if(sourcePermission.Contexts!=null&&sourcePermission.Contexts.CollectionPropertyContext!=null&&sourcePermission.Contexts.CollectionPropertyContext.CollectionPropertyName=="Organizations"&&typeof(Person).IsAssignableFrom(sourcePermission.Contexts.CollectionPropertyContext.MasterObjectType)){returntrue;}}}returnbase.IsSubsetOf(sourcePermission,targetPermission);}}
and set this class as the current ObjectAccessComparer in the main.cs and global.aspx.cs files:
[C#]ObjectAccessComparerBase.SetCurrentComparer(newAllowManyToMany_ObjectAccessComparer());
Thanks,
Dan