问题
I have configured row level security, then I want to create sql view based on this to support for my custom report.
Updated, below is my view
SELECT
s.CompanyID
, DistributorID = s.BranchID
, s.SiteID
, s.SiteCD
, s.Descr
, s.Active
, IsDefault = s.UsrIsDefault
, u.Username
FROM
dbo.INSite s
FULL JOIN dbo.Users u ON u.CompanyID = s.CompanyID
WHERE
SUBSTRING(s.GroupMask, 1, 4) = ''
OR (0 = SUBSTRING(s.GroupMask, 1, 4) & (SELECT SUM(CONVERT(BIGINT, rg.GroupMask & -1))
FROM dbo.RelationGroup rg
WHERE rg.CompanyID = s.CompanyID AND rg.Active = 1 AND rg.SpecificType = 'PX.Objects.IN.INSite')
OR 0 <> SUBSTRING(s.GroupMask, 1, 4) & CONVERT(BIGINT, u.GroupMask))
But, it does not correctly
回答1:
It seems that you calculations on restriction groups are not correct:
Let me share with you how does it work. For each group system assign one byte:
- Group 1 - 0x8000 = 1000 0000 0000 0000
- Group 2 - 0x4000 = 0100 0000 0000 0000
- Group 3 - 0x2000 = 0010 0000 0000 0000
- Group 4 - 0x1000 = 0001 0000 0000 0000
- Group 5 - 0x0800 = 0000 1000 0000 0000
- Group 6 - 0x0400 = 0000 0100 0000 0000
- .....
When you assign an item to any group it actually sets the flags in the group masks: Lets assume vendor belongs to group 3 and group 6, than mask will be:
0010 0100 0000 0000 = 0x2400
You can see exactly this in group masks on each supported table.
Users are also belongs to groups by the same rule. Than system search for interceptions, to what groups belongs user and entity and calculate assess rights. Also do not forget that there are different types of groups that can be calculated differently (Group A, B, A Inverse, B Inverse)
In your case you join all entities to users that is not correct. I think you need to write some sort of the procedure/function that will get available groups for entity and user and join by that condition. May be you just need to find what user and entity have at least one same bit in the same position - this means that entity and user belongs to the same group - but this will work just for Group A.
Also the complexity is that SQL Server does not support bitwise operations between 2 binaries (https://msdn.microsoft.com/en-us/library/ms176122.aspx), so you have to convert it to int. To avoid the overflow, you have to get just a part of string and compare part by part. I prefer to try to get Groups from entity and user and do a bitwise operation bit by bit to ensure that there is no overflow.
Hope that it helps.
来源:https://stackoverflow.com/questions/38408210/acumatica-sql-view-based-on-row-level-security