project BLF > class BSODViolationRule1 > method CheckRule1

Description

This method will check the current database situation for violations to SOD rule 1 and register new conflicts. Check can be done for a single role, for a single SOD category, or for the entire system.


Parameters


iiRoleIDinputinteger
iiSODCategoryIDinputinteger
oiReturnStatusoutputintegerReturn status of the method.


Internal usage


BLF
method BResource.PostTransaction
method BRole.PostTransaction
method BSODCategoryExclusion.PostTransaction
method BSystem.PostTransaction


program code (program1/bsodviolationrule1.p)

define buffer RoleResource1 for RoleResource.
define buffer RoleResource2 for RoleResource.
define buffer Resources1 for Resources.
define buffer Resources2 for Resources.
define buffer SODCategory1 for SODCategory.
define buffer SODCategory2 for SODCategory.

/* ================================================================= */
/* Make a list of roles to validate.                                 */
/* ================================================================= */
if iiSODCategoryID = 0
then do:
    <Q-25 run RoleByIDName (all) (Read) (NoCache)
       (input iiRoleID, (RoleID)
        input '', (RoleName)
        output dataset tqRoleByIDName) in BRole >
end.
else for each Resources1 fields (Resource_ID SODCategory_ID) no-lock where
              Resources1.SODCategory_ID = iiSODCategoryID,
         each RoleResource1 fields (Role_ID Resource_ID) no-lock where
              RoleResource1.Resource_ID = Resources1.Resource_ID,
         each Role fields (Role_ID RoleName RoleIsActive RoleSODException) no-lock where
              Role.Role_ID = RoleResource1.Role_ID and
              Role.RoleSODException = no
              break by Role.Role_ID on error undo, throw:
    if first-of (Role.Role_ID)
    then do:
        create tqRoleByIDName.
        assign tqRoleByIDName.tcRoleName = Role.RoleName
               tqRoleByIDName.tiRole_ID = Role.Role_ID
               tqRoleByIDName.tlRoleIsActive = Role.RoleIsActive
               tqRoleByIDName.tlRoleSODException = Role.RoleSODException.
    end.    /* first-of (Role.Role_ID) */
end.    /* each Resources1 */

/* ================================================================= */
/* Validate role by role (1 role = 1 transaction)                    */
/* ================================================================= */
for each tqRoleByIDName where tqRoleByIDName.tlRoleSODException = no on error undo, throw:

    <M-3 run DataLoad
       (input  '' (icRowids), 
        input  '' (icPkeys), 
        input  '' (icObjectIds), 
        input  'for each SODViolation1 where SODViolation1.Role_ID = ' + string(tqRoleByIDName.tiRole_ID) (icFreeform), 
        input  no (ilKeepPrevious), 
        output viFcReturnSuper (oiReturnStatus)) in BSODViolationRule1>
    if viFcReturnSuper = -4
    then viFcReturnSuper = 0.
    if viFcReturnSuper <> 0
    then oiReturnStatus = viFcReturnSuper.
    if viFcReturnSuper < 0
    then return.
    
    for each RoleResource1 fields (Role_ID Resource_ID) no-lock where
             RoleResource1.Role_ID = tqRoleByIDName.tiRole_ID,
        each Resources1 fields (Resource_ID ResourceURI SODCategory_ID) no-lock where
             Resources1.Resource_ID = RoleResource1.Resource_ID and
           ((Resources1.SODCategory_ID <> 0 and iiSODCategoryID = 0) or
            (Resources1.SODCategory_ID = iiSODCategoryID and iiSODCategoryID <> 0)),
        each SODExclusion fields (SODCategory1_ID SODCategory2_ID SODExclusionLevel) no-lock where
             SODExclusion.SODCategory1_ID = Resources1.SODCategory_ID,
        each Resources2 fields (Resource_ID ResourceURI SODCategory_ID) no-lock where
             Resources2.SODCategory_ID = SODExclusion.SODCategory2_ID,
        each RoleResource2 fields (Role_ID Resource_ID) no-lock where
             RoleResource2.Resource_ID = Resources2.Resource_ID and
             RoleResource2.Role_ID = tqRoleByIDName.tiRole_ID,
        each SODCategory1 fields (SODCategory_ID SODCategoryCode) no-lock where
             SODCategory1.SODCategory_ID = SODExclusion.SODCategory1_ID,
        each SODCategory2 fields (SODCategory_ID SODCategoryCode) no-lock where
             SODCategory2.SODCategory_ID = SODExclusion.SODCategory2_ID on error undo, throw:
        
        vlAdded = no.
        
        /* conflict found. Check if it is already known */
        find first tSODViolation1 where
                   tSODViolation1.Role_ID         = tqRoleByIDName.tiRole_ID and
                   tSODViolation1.SODCategory2_ID = SODCategory1.SODCategory_ID and
                   tSODViolation1.SODCategory1_ID = SODCategory2.SODCategory_ID no-error.
        if available tSODViolation1
        then assign vlSwitch = yes.
        else do:
            find first tSODViolation1 where
                       tSODViolation1.Role_ID         = tqRoleByIDName.tiRole_ID and
                       tSODViolation1.SODCategory1_ID = SODCategory1.SODCategory_ID and
                       tSODViolation1.SODCategory2_ID = SODCategory2.SODCategory_ID no-error.
            if available tSODViolation1
            then assign vlSwitch = no.
            else do:
                <M-15 run AddDetailLine
                   (input  'SODViolation1' (icTable), 
                    input  '' (icParentRowid), 
                    output viFcReturnSuper (oiReturnStatus)) in BSODViolationRule1>
                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 SODCategory1.SODCategoryCode > SODCategory2.SODCategoryCode
                then assign tSODViolation1.Role_ID         = tqRoleByIDName.tiRole_ID
                            tSODViolation1.SODCategory1_ID = SODCategory2.SODCategory_ID
                            tSODViolation1.SODCategory2_ID = SODCategory1.SODCategory_ID
                            vlSwitch = yes.
                else assign tSODViolation1.Role_ID         = tqRoleByIDName.tiRole_ID
                            tSODViolation1.SODCategory1_ID = SODCategory1.SODCategory_ID
                            tSODViolation1.SODCategory2_ID = SODCategory2.SODCategory_ID
                            vlSwitch = no.
            end.
        end.
        
        if not can-find (first tSODViolation1R where
                               tSODViolation1R.tc_ParentRowid = tSODViolation1.tc_Rowid and
                               tSODViolation1R.SODViolation1RCategory = (if vlSwitch then 2 else 1) and
                               tSODViolation1R.Resource_ID = Resources1.Resource_ID)
        then do:
            <M-16 run AddDetailLine
               (input  'SODViolation1R' (icTable), 
                input  tSODViolation1.tc_Rowid (icParentRowid), 
                output viFcReturnSuper (oiReturnStatus)) in BSODViolationRule1>
            if viFcReturnSuper <> 0
            then oiReturnStatus = viFcReturnSuper.
            if viFcReturnSuper < 0
            then return.
            assign tSODViolation1R.SODViolation1_ID = tSODViolation1.SODViolation1_ID
                   tSODViolation1R.SODViolation1RCategory = (if vlSwitch then 2 else 1)
                   tSODViolation1R.Resource_ID = Resources1.Resource_ID
                   vlAdded = yes.
        end.
        
        if not can-find (first tSODViolation1R where
                               tSODViolation1R.tc_ParentRowid = tSODViolation1.tc_Rowid and
                               tSODViolation1R.SODViolation1RCategory = (if vlSwitch then 1 else 2) and
                               tSODViolation1R.Resource_ID = Resources2.Resource_ID)
        then do:
            <M-17 run AddDetailLine
               (input  'SODViolation1R' (icTable), 
                input  tSODViolation1.tc_Rowid (icParentRowid), 
                output viFcReturnSuper (oiReturnStatus)) in BSODViolationRule1>
            if viFcReturnSuper <> 0
            then oiReturnStatus = viFcReturnSuper.
            if viFcReturnSuper < 0
            then return.
            assign tSODViolation1R.SODViolation1_ID = tSODViolation1.SODViolation1_ID
                   tSODViolation1R.SODViolation1RCategory = (if vlSwitch then 1 else 2)
                   tSODViolation1R.Resource_ID = Resources2.Resource_ID
                   vlAdded = yes.
        end.
            
        if vlAdded
        then do:
            if vhBSODLogInst = ?
            then do:
                <I-28 {bFcAddToTransaction
                     &CLASS           = "BSODLog"}>
            end.
            <M-29 run AddLogEntry
               (input  {&SODLOG-RULE1} (icRule), 
                input  {&SODLOG-STATUS-VIOLATION} (icStatus), 
                input  '' (icUsrLogin), 
                input  '' (icDomainCode), 
                input  '' (icCompanyCode), 
                input  tqRoleByIDName.tcRoleName (icRole1Name), 
                input  '' (icRole2Name), 
                input  SODCategory1.SODCategoryCode (icCategory1Code), 
                input  SODCategory2.SODCategoryCode (icCategory2Code), 
                input  Resources1.ResourceURI (icResource1URI), 
                input  Resources2.ResourceURI (icResource2URI), 
                input  SODExclusion.SODExclusionLevel (icExclusionLevel)) in BSODLog>
        end.
    end.    /* each RoleResource1 */

    if vhBSODLogInst <> ?
    then do:
        <I-30 {bFcCloseInstance
             &CLASS           = "BSODLog"}>

        <M-18 run ValidateBC  (output viFcReturnSuper (oiReturnStatus)) in BSODViolationRule1>    
        if viFcReturnSuper <> 0
        then oiReturnStatus = viFcReturnSuper.
        if viFcReturnSuper < 0
        then return.
    
        <M-19 run AdditionalUpdates  (output viFcReturnSuper (oiReturnStatus)) in BSODViolationRule1>
        if viFcReturnSuper <> 0
        then oiReturnStatus = viFcReturnSuper.
        if viFcReturnSuper < 0
        then return.
    
        <M-20 run DataSave  (output viFcReturnSuper (oiReturnStatus)) in BSODViolationRule1>
        if viFcReturnSuper <> 0
        then oiReturnStatus = viFcReturnSuper.
        if viFcReturnSuper < 0
        then return.
        
        vhBSODLogInst = ?.    /* stopped by the transaction component in DataSave */
        viBSODLogID   = 0.
    end.    /* vhBSODLogInst <> ? */
end.    /* each tqRoleByIDName */