Hi everyone,
I'm looking for some advice on the best D365FO security design for the following scenario.
Let's assume these users currently have access to a button through their existing roles:
| User | Existing Role |
|---|
| User1 | System Admin |
| User2 | IT Admin |
| User3 | Role1 |
| User4 | Role2 |
| User5 | Role3 |
| User6 | Role2 |
| User7 | Role3 |
In the normal scenario, all of these users should continue to have access to the button.
However, when the current record meets a specific condition (for example, ID1 and ID2 are both populated), only some users should still be able to use the button.
For example:
| User | Access when IDs are populated |
|---|
| User1 | ✅ |
| User2 | ✅ |
| User3 | ✅ |
| User4 | ❌ |
| User5 | ❌ |
| User6 | ✅ |
| User7 | ✅ |
Notice that User4 and User6 both have Role2, but only User6 should retain access. Likewise, User5 and User7 both have Role3, but only User7 should retain access.
To achieve this, we're introducing a new security role that will be assigned only to the users who should retain access in this specific scenario, alongside their existing operational roles. The role will contain a new duty, which in turn contains the privilege required for this button.
Since the condition depends on the current record, the logic has to be evaluated in X++.
public boolean isButtonEnabled()
{
boolean ret;
ret = next isPostRejectionEnabled();
if (ret && this.isIDsPopulated())
{
ret = this.annsHasRejectionAccess();
}
return ret;
}
public boolean isIDsPopulated()
{
return this.Id1 != '' && this.Id2 != '';
}
public boolean hasButtonAccess()
{
SecurityUserRole securityUserRole;
SecurityRole securityRole;
select firstonly RecId from securityUserRole
where securityUserRole.User == curUserId()
&& securityUserRole.AssignmentStatus == RoleAssignmentStatus::Enabled
exists join securityRole
where securityUserRole.SecurityRole == securityRole.RecId
&& (securityRole.AotName == '-SYSADMIN-'
|| securityRole.AotName == 'ITAdmin'
|| securityRole.AotName == 'NewRole');
return securityUserRole.RecId != 0;
}
Given this requirement, is there a better D365FO security design than checking the user's roles in hasButtonAccess()? For example, would you check a duty, a privilege, or use another approach?