Acumatica Security
Hello,
this post is dedicated to understanding how security in Acumatica works. If to be precisive security of accounts.
Let's say you need in some way filter accounts for some user according to configuration at row level security screen ( GL104000 ).
In my case I had following records in database which correspondent to the following numbers:
Relation group mask : 16; 0; 0; 0
User group mask: 159; 96; 0; 0
Account group mask: 16; 0; 0; 0
How to join them? They are joined not by separated table, which has relations between groups and accounts or groups and users, but with usage of bit mask. It's very effective way to join and is much faster then holding adta in db. But the most complicated from viewpoint of understanding. Lets convert already mentioned numbers into bit masks:
Relation group mask :
00010000; 00000000; 00000000; 00000000
User group mask:
10011111; 11000000; 00000000; 00000000
Account group mask:
00010000; 00000000; 00000000; 00000000
From the bit mask you can notice that there is common bit between first byte in Account group mask and User group mask. Also there is common bit between "User group mask" and Relation group mask which means that user belongs to the group, and account belongs to the group. In order to work with them I wrote the following code:
public List<Account> GetAvailableCashAccounts() { var result = new List<Account>(); var userID = PXAccess.GetUserID(); var user = GetUsers().First(u => u.PKID == userID); var allAccounts = GetAccounts(); var groups = GetGroups(); foreach (var account in allAccounts) { foreach (var relationGroup in groups) { for (var i = 0; i < relationGroup.GroupMask.Length && i < account.GroupMask.Length; i++) { if ((relationGroup.GroupMask[i] & account.GroupMask[i]) == 0) continue; if ((account.GroupMask[i] & user.GroupMask[i]) == 0 || result.Find(a => a.AccountCD.Equals(account.AccountCD)) != null) continue; result.Add(account); } } } return result; }
As usually all your comments are welcomed, considered, premoderated, banned :)