Description
This method will check the current database situation for violations to SOD rule 2 and register new conflicts. Check can be done for a single user, a single role, for a single SOD category, or for the entire system.
Parameters
iiUsrID | input | integer | |
iiRoleID | input | integer | |
iiSODCategoryID | input | integer | |
icUsrLogin | input | character | |
oiReturnStatus | output | integer | Return status of the method. |
Internal usage
BLF
program code (program1/bsodviolationrule2.p)
define buffer Resources1 for Resources.
define buffer Resources2 for Resources.
define buffer RoleResource1 for RoleResource.
define buffer RoleResource2 for RoleResource.
define buffer Role1 for Role.
define buffer Role2 for Role.
define buffer UsrRoleCompany1 for UsrRoleCompany.
define buffer UsrRoleCompany2 for UsrRoleCompany.
if iiSODCategoryID = 0
then do:
/* ================================================================= */
/* Validate by user : make a list of users to validate. */
/* ================================================================= */
empty temp-table tUsersForCheckRule2.
if iiUsrID = 0
then for each Role fields (Role_ID RoleName RoleSODException) no-lock where
(Role.Role_ID = iiRoleID or iiRoleID = 0) and
Role.RoleSODException = no,
each UsrRoleCompany fields (Usr_ID Role_ID Company_ID) no-lock where
UsrRoleCompany.Role_ID = Role.Role_ID,
first Usr fields (Usr_ID UsrLogin) no-lock where
Usr.Usr_ID = UsrRoleCompany.Usr_ID,
first Company fields (Company_ID CompanyCode Domain_ID) no-lock where
Company.Company_ID = UsrRoleCompany.Company_ID,
first Domains fields (Domain_ID DomainCode) no-lock where
Domains.Domain_ID = Company.Domain_ID on error undo, throw:
create tUsersForCheckRule2.
assign tUsersForCheckRule2.tiUsrId = Usr.Usr_ID
tUsersForCheckRule2.tcUserLogin = Usr.UsrLogin
tUsersForCheckRule2.tiCompany_ID = Company.Company_ID
tUsersForCheckRule2.tcCompanyCode = Company.CompanyCode
tUsersForCheckRule2.tiDomain_ID = Domains.Domain_ID
tUsersForCheckRule2.tcDomainCode = Domains.DomainCode
tUsersForCheckRule2.tiRole_ID = Role.Role_ID
tUsersForCheckRule2.tcRoleName = Role.RoleName.
end. /* each Role */
else for first Usr fields (Usr_ID UsrLogin) no-lock where
Usr.Usr_ID = iiUsrID,
each UsrRoleCompany fields (Usr_ID Role_ID Company_ID) no-lock where
UsrRoleCompany.Usr_ID = Usr.Usr_ID,
first Role fields (Role_ID RoleName RoleSODException) no-lock where
Role.Role_ID = UsrRoleCompany.Role_ID and
Role.RoleSODException = no,
first Company fields (Company_ID CompanyCode Domain_ID) no-lock where
Company.Company_ID = UsrRoleCompany.Company_ID,
first Domains fields (Domain_ID DomainCode) no-lock where
Domains.Domain_ID = Company.Domain_ID on error undo, throw:
create tUsersForCheckRule2.
assign tUsersForCheckRule2.tiUsrId = Usr.Usr_ID
tUsersForCheckRule2.tcUserLogin = Usr.UsrLogin
tUsersForCheckRule2.tiCompany_ID = Company.Company_ID
tUsersForCheckRule2.tcCompanyCode = Company.CompanyCode
tUsersForCheckRule2.tiDomain_ID = Domains.Domain_ID
tUsersForCheckRule2.tcDomainCode = Domains.DomainCode
tUsersForCheckRule2.tiRole_ID = Role.Role_ID
tUsersForCheckRule2.tcRoleName = Role.RoleName.
end. /* first Usr */
/* =========================================================================== */
/* Remove users with only one role as they cannot ever have a rule 2 violation */
/* =========================================================================== */
if iiRoleID = 0
then for each tUsersForCheckRule2 break by tUsersForCheckRule2.tiUsrId by tUsersForCheckRule2.tiCompany_ID:
if first-of(tUsersForCheckRule2.tiCompany_ID)
and last-of(tUsersForCheckRule2.tiCompany_ID)
then delete tUsersForCheckRule2.
end.
/* ================================================================= */
/* Validate user by user (1 user = 1 transaction) */
/* ================================================================= */
for each tUsersForCheckRule2 break by tUsersForCheckRule2.tiUsrId on error undo, throw:
if first-of (tUsersForCheckRule2.tiUsrId)
then do:
<M-5 run DataLoad
(input '' (icRowids),
input '' (icPkeys),
input '' (icObjectIds),
input 'for each SODViolation2 where SODViolation2.Usr_ID = ' + string(tusersForCheckRule2.tiUsrId) (icFreeform),
input no (ilKeepPrevious),
output viFcReturnSuper (oiReturnStatus)) in BSODViolationRule2>
if viFcReturnSuper = -4
then viFcReturnSuper = 0.
if viFcReturnSuper <> 0
then oiReturnStatus = viFcReturnSuper.
if viFcReturnSuper < 0
then return.
end. /* first-of (tUsersForCheckRule2.tiUsrId) */
for each RoleResource1 fields (Role_ID Resource_ID) no-lock where
RoleResource1.Role_ID = tUsersForCheckRule2.tiRole_ID,
first Resources1 fields (Resource_ID ResourceURI SODCategory_ID) no-lock where
Resources1.Resource_ID = RoleResource1.Resource_ID and
Resources1.SODcategory_ID <> 0
break by Resources1.SODcategory_ID on error undo, throw:
/* If no violations are found for a SOD category then skip validations for all next resources in this SOD category.
* If violations are found keep validating because violations must be reported on resource level.
*/
if first-of (Resources1.SODcategory_ID)
then vlConflictFound = no.
if first-of (Resources1.SODcategory_ID)
or vlConflictFound
then
/* Lookup user-company combinations with access to current edited role and to any other role with access to any resource from a conflicting category */
if iiRoleID = 0
then
for each bUsersForCheckRule2 where
bUsersForCheckRule2.tiUsrId = tUsersForCheckRule2.tiUsrId and
bUsersForCheckRule2.tiCompany_ID = tUsersForCheckRule2.tiCompany_ID and
bUsersForCheckRule2.tiRole_ID > tUsersForCheckRule2.tiRole_ID, /* yes > not <>, to avoid checking A-B and B-A */
each Role fields (Role_ID RoleName RoleSODException) no-lock where
Role.Role_ID = bUsersForCheckRule2.tiRole_ID and
Role.RoleSODException = no,
each RoleResource2 fields (Role_ID Resource_ID) no-lock where
RoleResource2.Role_ID = Role.Role_ID,
each Resources2 fields (Resource_ID ResourceURI SODCategory_ID) no-lock where
Resources2.Resource_ID = RoleResource2.Resource_ID and
Resources2.SODcategory_ID <> 0,
each SODExclusion fields (SODCategory1_ID SODCategory2_ID SODExclusionLevel) no-lock where
SODExclusion.SODCategory1_ID = Resources1.SODcategory_ID and
SODExclusion.SODCategory2_ID = Resources2.SODcategory_ID on error undo, throw:
vlAdded = no.
vlPolicyException = no.
for each SODException fields (SODException_ID Usr_ID) no-lock where
SODException.Usr_ID = bUsersForCheckRule2.tiUsrId:
if can-find (first SODExceptionLn where
SODExceptionLn.SODException_ID = SODException.SODException_ID and
SODExceptionLn.SODCategory1_ID = Resources1.SODcategory_ID and
SODExceptionLn.SODCategory2_ID = Resources2.SODcategory_ID and
(SODExceptionLn.Company_ID = bUsersForCheckRule2.tiCompany_ID or SODExceptionLn.Company_ID = 0) and
(SODExceptionLn.Domain_ID = bUsersForCheckRule2.tiDomain_ID or SODExceptionLn.Domain_ID = 0))
or can-find (first SODExceptionLn where
SODExceptionLn.SODException_ID = SODException.SODException_ID and
SODExceptionLn.SODCategory1_ID = Resources2.SODcategory_ID and
SODExceptionLn.SODCategory2_ID = Resources1.SODcategory_ID and
(SODExceptionLn.Company_ID = bUsersForCheckRule2.tiCompany_ID or SODExceptionLn.Company_ID = 0) and
(SODExceptionLn.Domain_ID = bUsersForCheckRule2.tiDomain_ID or SODExceptionLn.Domain_ID = 0))
then do:
vlPolicyException = yes.
leave.
end.
end. /* each SODException */
if vlPolicyException = no
then do:
vlConflictFound = yes.
vcSODCategoryCode1 = "".
for first SODCategory fields (SODCategory_ID SODCategoryCode) no-lock where
SODCategory.SODCategory_ID = Resources1.SODcategory_ID:
vcSODCategoryCode1 = SODCategory.SODCategoryCode.
end.
vcSODCategoryCode2 = "".
for first SODCategory fields (SODCategory_ID SODCategoryCode) no-lock where
SODCategory.SODCategory_ID = Resources2.SODcategory_ID:
vcSODCategoryCode2 = SODCategory.SODCategoryCode.
end.
/* conflict found. Check if it is already known */
find first tSODViolation2 where
tSODViolation2.Usr_ID = tUsersForCheckRule2.tiUsrId and
tSODViolation2.Domain_ID = tUsersForCheckRule2.tiDomain_ID and
tSODViolation2.Company_ID = tUsersForCheckRule2.tiCompany_ID and
tSODViolation2.Role2_ID = tUsersForCheckRule2.tiRole_ID and
tSODViolation2.SODCategory2_ID = Resources1.SODCategory_ID and
tSODViolation2.Role1_ID = Role.Role_ID and
tSODViolation2.SODCategory1_ID = Resources2.SODCategory_ID no-error.
if available tSODViolation2
then assign vlSwitch = yes.
else do:
find first tSODViolation2 where
tSODViolation2.Usr_ID = tUsersForCheckRule2.tiUsrId and
tSODViolation2.Domain_ID = tUsersForCheckRule2.tiDomain_ID and
tSODViolation2.Company_ID = tUsersForCheckRule2.tiCompany_ID and
tSODViolation2.Role1_ID = tUsersForCheckRule2.tiRole_ID and
tSODViolation2.SODCategory1_ID = Resources1.SODCategory_ID and
tSODViolation2.Role2_ID = Role.Role_ID and
tSODViolation2.SODCategory2_ID = Resources2.SODCategory_ID no-error.
if available tSODViolation2
then assign vlSwitch = no.
else do:
<M-74 run AddDetailLine
(input 'SODViolation2' (icTable),
input '' (icParentRowid),
output viFcReturnSuper (oiReturnStatus)) in BSODViolationRule2>
if viFcReturnSuper <> 0
then oiReturnStatus = viFcReturnSuper.
if viFcReturnSuper < 0
then return.
/* BLF-4424
* Conflicts should always be reported as 'A conflicts with B', never as 'B conflicts with A'.
*/
if vcSODCategoryCode1 > vcSODCategoryCode2
then assign tSODViolation2.Usr_ID = tUsersForCheckRule2.tiUsrId
tSODViolation2.Domain_ID = tUsersForCheckRule2.tiDomain_ID
tSODViolation2.Company_ID = tUsersForCheckRule2.tiCompany_ID
tSODViolation2.Role1_ID = Role.Role_ID
tSODViolation2.SODCategory1_ID = Resources2.SODCategory_ID
tSODViolation2.Role2_ID = tUsersForCheckRule2.tiRole_ID
tSODViolation2.SODCategory2_ID = Resources1.SODCategory_ID
vlSwitch = yes.
else assign tSODViolation2.Usr_ID = tUsersForCheckRule2.tiUsrId
tSODViolation2.Domain_ID = tUsersForCheckRule2.tiDomain_ID
tSODViolation2.Company_ID = tUsersForCheckRule2.tiCompany_ID
tSODViolation2.Role1_ID = tUsersForCheckRule2.tiRole_ID
tSODViolation2.SODCategory1_ID = Resources1.SODCategory_ID
tSODViolation2.Role2_ID = Role.Role_ID
tSODViolation2.SODCategory2_ID = Resources2.SODCategory_ID
vlSwitch = no.
end. /* available tSODViolation2 */
end. /* available tSODViolation2 */
if not can-find (first tSODViolation2R where
tSODViolation2R.tc_ParentRowid = tSODViolation2.tc_Rowid and
tSODViolation2R.SODViolation2RCategory = (if vlSwitch then 2 else 1) and
tSODViolation2R.Resource_ID = Resources1.Resource_ID)
then do:
<M-89 run AddDetailLine
(input 'SODViolation2R' (icTable),
input tSODViolation2.tc_Rowid (icParentRowid),
output viFcReturnSuper (oiReturnStatus)) in BSODViolationRule2>
if viFcReturnSuper <> 0
then oiReturnStatus = viFcReturnSuper.
if viFcReturnSuper < 0
then return.
assign tSODViolation2R.SODViolation2_ID = tSODViolation2.SODViolation2_ID
tSODViolation2R.SODViolation2RCategory = (if vlSwitch then 2 else 1)
tSODViolation2R.Resource_ID = Resources1.Resource_ID
vlAdded = yes.
end. /* can-find (first tSODViolation2R) */
if not can-find (first tSODViolation2R where
tSODViolation2R.tc_ParentRowid = tSODViolation2.tc_Rowid and
tSODViolation2R.SODViolation2RCategory = (if vlSwitch then 1 else 2) and
tSODViolation2R.Resource_ID = Resources2.Resource_ID)
then do:
<M-45 run AddDetailLine
(input 'SODViolation2R' (icTable),
input tSODViolation2.tc_Rowid (icParentRowid),
output viFcReturnSuper (oiReturnStatus)) in BSODViolationRule2>
if viFcReturnSuper <> 0
then oiReturnStatus = viFcReturnSuper.
if viFcReturnSuper < 0
then return.
assign tSODViolation2R.SODViolation2_ID = tSODViolation2.SODViolation2_ID
tSODViolation2R.SODViolation2RCategory = (if vlSwitch then 1 else 2)
tSODViolation2R.Resource_ID = Resources2.Resource_ID
vlAdded = yes.
end. /* can-find (first tSODViolation2R) */
if vlAdded
then do:
if vhBSODLog7Inst = ?
then do:
<I-85 {bFcAddToTransaction
&CLASS = "BSODLog"}>
end.
<M-43 run AddLogEntry
(input {&SODLOG-RULE2} (icRule),
input {&SODLOG-STATUS-VIOLATION} (icStatus),
input tUsersForCheckRule2.tcUserLogin (icUsrLogin),
input tUsersForCheckRule2.tcDomainCode (icDomainCode),
input tUsersForCheckRule2.tcCompanyCode (icCompanyCode),
input tUsersForCheckRule2.tcRoleName (icRole1Name),
input Role.RoleName (icRole2Name),
input vcSODCategoryCode1 (icCategory1Code),
input vcSODCategoryCode2 (icCategory2Code),
input Resources1.ResourceURI (icResource1URI),
input Resources2.ResourceURI (icResource2URI),
input SODExclusion.SODExclusionLevel (icExclusionLevel)) in BSODLog>
end.
end. /* vlPolicyException = no */
end. /* each bUsersForCheckRule2 */
else
for each UsrRoleCompany fields (Role_ID Usr_ID Company_ID Domain_ID) no-lock where
UsrRoleCompany.Usr_ID = tUsersForCheckRule2.tiUsrId and
UsrRoleCompany.Company_ID = tUsersForCheckRule2.tiCompany_ID and
UsrRoleCompany.Role_ID <> tUsersForCheckRule2.tiRole_ID,
each Role fields (Role_ID RoleName RoleSODException) no-lock where
Role.Role_ID = UsrRoleCompany.Role_ID and
Role.RoleSODException = no,
each RoleResource2 fields (Role_ID Resource_ID) no-lock where
RoleResource2.Role_ID = Role.Role_ID,
each Resources2 fields (Resource_ID ResourceURI SODCategory_ID) no-lock where
Resources2.Resource_ID = RoleResource2.Resource_ID and
Resources2.SODcategory_ID <> 0,
each SODExclusion fields (SODCategory1_ID SODCategory2_ID SODExclusionLevel) no-lock where
SODExclusion.SODCategory1_ID = Resources1.SODcategory_ID and
SODExclusion.SODCategory2_ID = Resources2.SODcategory_ID on error undo, throw:
vlAdded = no.
vlPolicyException = no.
for each SODException fields (SODException_ID Usr_ID) no-lock where
SODException.Usr_ID = UsrRoleCompany.Usr_ID:
if can-find (first SODExceptionLn where
SODExceptionLn.SODException_ID = SODException.SODException_ID and
SODExceptionLn.SODCategory1_ID = Resources1.SODcategory_ID and
SODExceptionLn.SODCategory2_ID = Resources2.SODcategory_ID and
(SODExceptionLn.Company_ID = UsrRoleCompany.Company_ID or SODExceptionLn.Company_ID = 0) and
(SODExceptionLn.Domain_ID = UsrRoleCompany.Domain_ID or SODExceptionLn.Domain_ID = 0))
or can-find (first SODExceptionLn where
SODExceptionLn.SODException_ID = SODException.SODException_ID and
SODExceptionLn.SODCategory1_ID = Resources2.SODcategory_ID and
SODExceptionLn.SODCategory2_ID = Resources1.SODcategory_ID and
(SODExceptionLn.Company_ID = UsrRoleCompany.Company_ID or SODExceptionLn.Company_ID = 0) and
(SODExceptionLn.Domain_ID = UsrRoleCompany.Domain_ID or SODExceptionLn.Domain_ID = 0))
then do:
vlPolicyException = yes.
leave.
end.
end. /* each SODException */
if vlPolicyException = no
then do:
vlConflictFound = yes.
vcSODCategoryCode1 = "".
for first SODCategory fields (SODCategory_ID SODCategoryCode) no-lock where
SODCategory.SODCategory_ID = Resources1.SODcategory_ID:
vcSODCategoryCode1 = SODCategory.SODCategoryCode.
end.
vcSODCategoryCode2 = "".
for first SODCategory fields (SODCategory_ID SODCategoryCode) no-lock where
SODCategory.SODCategory_ID = Resources2.SODcategory_ID:
vcSODCategoryCode2 = SODCategory.SODCategoryCode.
end.
/* conflict found. Check if it is already known */
find first tSODViolation2 where
tSODViolation2.Usr_ID = tUsersForCheckRule2.tiUsrId and
tSODViolation2.Domain_ID = tUsersForCheckRule2.tiDomain_ID and
tSODViolation2.Company_ID = tUsersForCheckRule2.tiCompany_ID and
tSODViolation2.Role2_ID = tUsersForCheckRule2.tiRole_ID and
tSODViolation2.SODCategory2_ID = Resources1.SODCategory_ID and
tSODViolation2.Role1_ID = Role.Role_ID and
tSODViolation2.SODCategory1_ID = Resources2.SODCategory_ID no-error.
if available tSODViolation2
then assign vlSwitch = yes.
else do:
find first tSODViolation2 where
tSODViolation2.Usr_ID = tUsersForCheckRule2.tiUsrId and
tSODViolation2.Domain_ID = tUsersForCheckRule2.tiDomain_ID and
tSODViolation2.Company_ID = tUsersForCheckRule2.tiCompany_ID and
tSODViolation2.Role1_ID = tUsersForCheckRule2.tiRole_ID and
tSODViolation2.SODCategory1_ID = Resources1.SODCategory_ID and
tSODViolation2.Role2_ID = Role.Role_ID and
tSODViolation2.SODCategory2_ID = Resources2.SODCategory_ID no-error.
if available tSODViolation2
then assign vlSwitch = no.
else do:
<M-19 run AddDetailLine
(input 'SODViolation2' (icTable),
input '' (icParentRowid),
output viFcReturnSuper (oiReturnStatus)) in BSODViolationRule2>
if viFcReturnSuper <> 0
then oiReturnStatus = viFcReturnSuper.
if viFcReturnSuper < 0
then return.
/* BLF-4424
* Conflicts should always be reported as 'A conflicts with B', never as 'B conflicts with A'.
*/
if vcSODCategoryCode1 > vcSODCategoryCode2
then assign tSODViolation2.Usr_ID = tUsersForCheckRule2.tiUsrId
tSODViolation2.Domain_ID = tUsersForCheckRule2.tiDomain_ID
tSODViolation2.Company_ID = tUsersForCheckRule2.tiCompany_ID
tSODViolation2.Role1_ID = Role.Role_ID
tSODViolation2.SODCategory1_ID = Resources2.SODCategory_ID
tSODViolation2.Role2_ID = tUsersForCheckRule2.tiRole_ID
tSODViolation2.SODCategory2_ID = Resources1.SODCategory_ID
vlSwitch = yes.
else assign tSODViolation2.Usr_ID = tUsersForCheckRule2.tiUsrId
tSODViolation2.Domain_ID = tUsersForCheckRule2.tiDomain_ID
tSODViolation2.Company_ID = tUsersForCheckRule2.tiCompany_ID
tSODViolation2.Role1_ID = tUsersForCheckRule2.tiRole_ID
tSODViolation2.SODCategory1_ID = Resources1.SODCategory_ID
tSODViolation2.Role2_ID = Role.Role_ID
tSODViolation2.SODCategory2_ID = Resources2.SODCategory_ID
vlSwitch = no.
end. /* available tSODViolation2 */
end. /* available tSODViolation2 */
if not can-find (first tSODViolation2R where
tSODViolation2R.tc_ParentRowid = tSODViolation2.tc_Rowid and
tSODViolation2R.SODViolation2RCategory = (if vlSwitch then 2 else 1) and
tSODViolation2R.Resource_ID = Resources1.Resource_ID)
then do:
<M-20 run AddDetailLine
(input 'SODViolation2R' (icTable),
input tSODViolation2.tc_Rowid (icParentRowid),
output viFcReturnSuper (oiReturnStatus)) in BSODViolationRule2>
if viFcReturnSuper <> 0
then oiReturnStatus = viFcReturnSuper.
if viFcReturnSuper < 0
then return.
assign tSODViolation2R.SODViolation2_ID = tSODViolation2.SODViolation2_ID
tSODViolation2R.SODViolation2RCategory = (if vlSwitch then 2 else 1)
tSODViolation2R.Resource_ID = Resources1.Resource_ID
vlAdded = yes.
end. /* can-find (first tSODViolation2R) */
if not can-find (first tSODViolation2R where
tSODViolation2R.tc_ParentRowid = tSODViolation2.tc_Rowid and
tSODViolation2R.SODViolation2RCategory = (if vlSwitch then 1 else 2) and
tSODViolation2R.Resource_ID = Resources2.Resource_ID)
then do:
<M-21 run AddDetailLine
(input 'SODViolation2R' (icTable),
input tSODViolation2.tc_Rowid (icParentRowid),
output viFcReturnSuper (oiReturnStatus)) in BSODViolationRule2>
if viFcReturnSuper <> 0
then oiReturnStatus = viFcReturnSuper.
if viFcReturnSuper < 0
then return.
assign tSODViolation2R.SODViolation2_ID = tSODViolation2.SODViolation2_ID
tSODViolation2R.SODViolation2RCategory = (if vlSwitch then 1 else 2)
tSODViolation2R.Resource_ID = Resources2.Resource_ID
vlAdded = yes.
end. /* can-find (first tSODViolation2R) */
if vlAdded
then do:
if vhBSODLog7Inst = ?
then do:
<I-17 {bFcAddToTransaction
&CLASS = "BSODLog"}>
end.
<M-18 run AddLogEntry
(input {&SODLOG-RULE2} (icRule),
input {&SODLOG-STATUS-VIOLATION} (icStatus),
input tUsersForCheckRule2.tcUserLogin (icUsrLogin),
input tUsersForCheckRule2.tcDomainCode (icDomainCode),
input tUsersForCheckRule2.tcCompanyCode (icCompanyCode),
input tUsersForCheckRule2.tcRoleName (icRole1Name),
input Role.RoleName (icRole2Name),
input vcSODCategoryCode1 (icCategory1Code),
input vcSODCategoryCode2 (icCategory2Code),
input Resources1.ResourceURI (icResource1URI),
input Resources2.ResourceURI (icResource2URI),
input SODExclusion.SODExclusionLevel (icExclusionLevel)) in BSODLog>
end.
end. /* vlPolicyException = no */
end. /* each UsrRoleCompany */
end. /* each RoleResource1 */
if last-of (tUsersForCheckRule2.tiUsrId)
and vhBSODLog7Inst <> ?
then do:
<I-25 {bFcCloseInstance
&CLASS = "BSODLog"}>
<M-22 run ValidateBC (output viFcReturnSuper (oiReturnStatus)) in BSODViolationRule2>
if viFcReturnSuper <> 0
then oiReturnStatus = viFcReturnSuper.
if viFcReturnSuper < 0
then return.
<M-23 run AdditionalUpdates (output viFcReturnSuper (oiReturnStatus)) in BSODViolationRule2>
if viFcReturnSuper <> 0
then oiReturnStatus = viFcReturnSuper.
if viFcReturnSuper < 0
then return.
<M-24 run DataSave (output viFcReturnSuper (oiReturnStatus)) in BSODViolationRule2>
if viFcReturnSuper <> 0
then oiReturnStatus = viFcReturnSuper.
if viFcReturnSuper < 0
then return.
vhBSODLog7Inst = ?. /* stopped by the transaction component in DataSave */
viBSODLog7ID = 0.
end. /* last-of (tUsersForCheckRule2.tiUsrId) */
end. /* each tUsersForCheckRule2 */
end.
else for each Resources1 fields (Resource_ID ResourceURI SODCategory_ID) no-lock where
Resources1.SODCategory_ID = iiSODCategoryID,
each RoleResource1 fields (Resource_ID Role_ID) no-lock where
RoleResource1.Resource_ID = Resources1.Resource_ID,
each Role1 fields (Role_ID RoleName RoleSODException) no-lock where
Role1.Role_ID = RoleResource1.Role_ID and
Role1.RoleSODException = no,
each UsrRoleCompany1 fields (Usr_ID Role_ID Company_ID Domain_ID) no-lock where
UsrRoleCompany1.Role_ID = Role1.Role_ID,
each UsrRoleCompany2 fields (Usr_ID Role_ID Company_ID Domain_ID) no-lock where
UsrRoleCompany2.Usr_ID = UsrRoleCompany1.Usr_ID and
UsrRoleCompany2.Company_ID = UsrRoleCompany1.Company_ID and
UsrRoleCompany2.Role_ID <> UsrRoleCompany1.Role_ID,
each Role2 fields (Role_ID RoleName RoleSODException) no-lock where
Role2.Role_ID = UsrRoleCompany2.Role_ID and
Role2.RoleSODException = no,
each RoleResource2 fields (Resource_ID ) no-lock where
RoleResource2.Role_ID = Role2.Role_ID,
each Resources2 fields (Resource_ID ResourceURI SODCategory_ID) no-lock where
Resources2.Resource_ID = RoleResource2.Resource_ID,
each SODExclusion fields (SODCategory1_ID SODCategory2_ID SODExclusionLevel) no-lock where
SODExclusion.SODCategory1_ID = Resources1.SODCategory_ID and
SODExclusion.SODCategory2_ID = Resources2.SODCategory_ID
break by UsrRoleCompany1.Usr_ID on error undo, throw:
/* ================================================================= */
/* Validate a single SOD category. */
/* ================================================================= */
if first-of (UsrRoleCompany1.Usr_ID)
then do:
<M-62 run DataLoad
(input '' (icRowids),
input '' (icPkeys),
input '' (icObjectIds),
input 'for each SODViolation2 where SODViolation2.Usr_ID = ' + string(UsrRoleCompany1.Usr_ID) (icFreeform),
input no (ilKeepPrevious),
output viFcReturnSuper (oiReturnStatus)) in BSODViolationRule2>
if viFcReturnSuper = -4
then viFcReturnSuper = 0.
if viFcReturnSuper <> 0
then oiReturnStatus = viFcReturnSuper.
if viFcReturnSuper < 0
then return.
end. /* first-of (UsrRoleCompany1.Usr_ID) */
/* Skip resources for which an exception exists */
vlAdded = no.
vlPolicyException = no.
for each SODException fields (SODException_ID Usr_ID) no-lock where
SODException.Usr_ID = UsrRoleCompany1.Usr_ID:
if can-find (first SODExceptionLn where
SODExceptionLn.SODException_ID = SODException.SODException_ID and
SODExceptionLn.SODCategory1_ID = Resources1.SODcategory_ID and
SODExceptionLn.SODCategory2_ID = Resources2.SODcategory_ID and
(SODExceptionLn.Company_ID = UsrRoleCompany1.Company_ID or SODExceptionLn.Company_ID = 0) and
(SODExceptionLn.Domain_ID = UsrRoleCompany1.Domain_ID or SODExceptionLn.Domain_ID = 0))
or can-find (first SODExceptionLn where
SODExceptionLn.SODException_ID = SODException.SODException_ID and
SODExceptionLn.SODCategory1_ID = Resources2.SODcategory_ID and
SODExceptionLn.SODCategory2_ID = Resources1.SODcategory_ID and
(SODExceptionLn.Company_ID = UsrRoleCompany1.Company_ID or SODExceptionLn.Company_ID = 0) and
(SODExceptionLn.Domain_ID = UsrRoleCompany1.Domain_ID or SODExceptionLn.Domain_ID = 0))
then do:
vlPolicyException = yes.
leave.
end.
end. /* each SODException */
if vlPolicyException = no
then do:
vcSODCategoryCode1 = "".
for first SODCategory fields (SODCategory_ID SODCategoryCode) no-lock where
SODCategory.SODCategory_ID = Resources1.SODcategory_ID:
vcSODCategoryCode1 = SODCategory.SODCategoryCode.
end.
vcSODCategoryCode2 = "".
for first SODCategory fields (SODCategory_ID SODCategoryCode) no-lock where
SODCategory.SODCategory_ID = Resources2.SODcategory_ID:
vcSODCategoryCode2 = SODCategory.SODCategoryCode.
end.
/* conflict found. Check if it is already known */
find first tSODViolation2 where
tSODViolation2.Usr_ID = UsrRoleCompany1.Usr_ID and
tSODViolation2.Domain_ID = UsrRoleCompany1.Domain_ID and
tSODViolation2.Company_ID = UsrRoleCompany1.Company_ID and
tSODViolation2.Role2_ID = Role1.Role_ID and
tSODViolation2.SODCategory2_ID = Resources1.SODCategory_ID and
tSODViolation2.Role1_ID = Role2.Role_ID and
tSODViolation2.SODCategory1_ID = Resources2.SODCategory_ID no-error.
if available tSODViolation2
then assign vlSwitch = yes.
else do:
find first tSODViolation2 where
tSODViolation2.Usr_ID = UsrRoleCompany1.Usr_ID and
tSODViolation2.Domain_ID = UsrRoleCompany1.Domain_ID and
tSODViolation2.Company_ID = UsrRoleCompany1.Company_ID and
tSODViolation2.Role1_ID = Role1.Role_ID and
tSODViolation2.SODCategory1_ID = Resources1.SODCategory_ID and
tSODViolation2.Role2_ID = Role2.Role_ID and
tSODViolation2.SODCategory2_ID = Resources2.SODCategory_ID no-error.
if available tSODViolation2
then assign vlSwitch = no.
else do:
<M-28 run AddDetailLine
(input 'SODViolation2' (icTable),
input '' (icParentRowid),
output viFcReturnSuper (oiReturnStatus)) in BSODViolationRule2>
if viFcReturnSuper <> 0
then oiReturnStatus = viFcReturnSuper.
if viFcReturnSuper < 0
then return.
/* BLF-4424
* Conflicts should always be reported as 'A conflicts with B', never as 'B conflicts with A'.
*/
if vcSODCategoryCode1 > vcSODCategoryCode2
then assign tSODViolation2.Usr_ID = UsrRoleCompany1.Usr_ID
tSODViolation2.Domain_ID = UsrRoleCompany1.Domain_ID
tSODViolation2.Company_ID = UsrRoleCompany1.Company_ID
tSODViolation2.Role1_ID = Role2.Role_ID
tSODViolation2.SODCategory1_ID = Resources2.SODCategory_ID
tSODViolation2.Role2_ID = Role1.Role_ID
tSODViolation2.SODCategory2_ID = Resources1.SODCategory_ID
vlSwitch = yes.
else assign tSODViolation2.Usr_ID = UsrRoleCompany1.Usr_ID
tSODViolation2.Domain_ID = UsrRoleCompany1.Domain_ID
tSODViolation2.Company_ID = UsrRoleCompany1.Company_ID
tSODViolation2.Role1_ID = Role1.Role_ID
tSODViolation2.SODCategory1_ID = Resources1.SODCategory_ID
tSODViolation2.Role2_ID = Role2.Role_ID
tSODViolation2.SODCategory2_ID = Resources2.SODCategory_ID
vlSwitch = no.
end. /* not available tSODViolation2 */
end. /* not available tSODViolation2 */
if not can-find (first tSODViolation2R where
tSODViolation2R.tc_ParentRowid = tSODViolation2.tc_Rowid and
tSODViolation2R.SODViolation2RCategory = (if vlSwitch then 2 else 1) and
tSODViolation2R.Resource_ID = Resources1.Resource_ID)
then do:
<M-95 run AddDetailLine
(input 'SODViolation2R' (icTable),
input tSODViolation2.tc_Rowid (icParentRowid),
output viFcReturnSuper (oiReturnStatus)) in BSODViolationRule2>
if viFcReturnSuper <> 0
then oiReturnStatus = viFcReturnSuper.
if viFcReturnSuper < 0
then return.
assign tSODViolation2R.SODViolation2_ID = tSODViolation2.SODViolation2_ID
tSODViolation2R.SODViolation2RCategory = (if vlSwitch then 2 else 1)
tSODViolation2R.Resource_ID = Resources1.Resource_ID
vlAdded = yes.
end. /* not can-find (first tSODViolation2R) */
if not can-find (first tSODViolation2R where
tSODViolation2R.tc_ParentRowid = tSODViolation2.tc_Rowid and
tSODViolation2R.SODViolation2RCategory = (if vlSwitch then 1 else 2) and
tSODViolation2R.Resource_ID = Resources2.Resource_ID)
then do:
<M-79 run AddDetailLine
(input 'SODViolation2R' (icTable),
input tSODViolation2.tc_Rowid (icParentRowid),
output viFcReturnSuper (oiReturnStatus)) in BSODViolationRule2>
if viFcReturnSuper <> 0
then oiReturnStatus = viFcReturnSuper.
if viFcReturnSuper < 0
then return.
assign tSODViolation2R.SODViolation2_ID = tSODViolation2.SODViolation2_ID
tSODViolation2R.SODViolation2RCategory = (if vlSwitch then 1 else 2)
tSODViolation2R.Resource_ID = Resources2.Resource_ID
vlAdded = yes.
end. /* not can-find (first tSODViolation2R) */
if vlAdded
then do:
if vhBSODLog7Inst = ?
then do:
<I-87 {bFcAddToTransaction
&CLASS = "BSODLog"}>
end.
vcSODDomainCode = "".
for first Domains fields (Domain_ID DomainCode) no-lock where
Domains.Domain_ID = UsrRoleCompany1.Domain_ID:
vcSODDomainCode = Domains.DomainCode.
end.
vcSODCompanyCode = "".
for first Company fields (Company_ID CompanyCode) no-lock where
Company.Company_ID = UsrRoleCompany1.Company_ID:
vcSODCompanyCode = Company.CompanyCode.
end.
vcSODUserLogin = "".
for first Usr fields (Usr_ID UsrLogin) no-lock where
Usr.Usr_ID = UsrRoleCompany1.Usr_ID:
vcSODUserLogin = Usr.UsrLogin.
end.
<M-33 run AddLogEntry
(input {&SODLOG-RULE2} (icRule),
input {&SODLOG-STATUS-VIOLATION} (icStatus),
input vcSODUserLogin (icUsrLogin),
input vcSODDomainCode (icDomainCode),
input vcSODCompanyCode (icCompanyCode),
input Role1.RoleName (icRole1Name),
input Role2.RoleName (icRole2Name),
input vcSODCategoryCode1 (icCategory1Code),
input vcSODCategoryCode2 (icCategory2Code),
input Resources1.ResourceURI (icResource1URI),
input Resources2.ResourceURI (icResource2URI),
input SODExclusion.SODExclusionLevel (icExclusionLevel)) in BSODLog>
end. /* vlAdded */
if last-of (UsrRoleCompany1.Usr_ID)
and vhBSODLog7Inst <> ?
then do:
<I-10 {bFcCloseInstance
&CLASS = "BSODLog"}>
<M-69 run ValidateBC (output viFcReturnSuper (oiReturnStatus)) in BSODViolationRule2>
if viFcReturnSuper <> 0
then oiReturnStatus = viFcReturnSuper.
if viFcReturnSuper < 0
then return.
<M-38 run AdditionalUpdates (output viFcReturnSuper (oiReturnStatus)) in BSODViolationRule2>
if viFcReturnSuper <> 0
then oiReturnStatus = viFcReturnSuper.
if viFcReturnSuper < 0
then return.
<M-66 run DataSave (output viFcReturnSuper (oiReturnStatus)) in BSODViolationRule2>
if viFcReturnSuper <> 0
then oiReturnStatus = viFcReturnSuper.
if viFcReturnSuper < 0
then return.
vhBSODLog7Inst = ?. /* stopped by the transaction component in DataSave */
viBSODLog7ID = 0.
end. /* last-of (UsrRoleCompany1.Usr_ID) */
end. /* vlPolicyException = no */
end. /* each Resources1 */
finally:
empty temp-table tUsersForCheckRule2.
end finally.