project BLF > class BRole > method ValidateComponent

Description

Write here all tests on database update (new / modify / delete) that cannot be coded with a validation mask.
The type of update can be found in tc_status (N/C/D).
If you find incorrect data, you must write an entry in tFcMessages (using SetMessage) and set the return status of this method to either +1 or -1.
Return status +1 = data will still be accepted.
Return status -1 = data will not be accepted.
This method is run from SetPublicTables, before transferring the received data into the class temp-tables.


Parameters


oiReturnStatusoutputinteger


Internal usage


unused


program code (program/brole.p)

define buffer Resources1 for Resources.
define buffer Resources2 for Resources.
define buffer SODCategory1 for SODCategory.
define buffer SODCategory2 for SODCategory.
define buffer UsrRoleCompany1 for UsrRoleCompany.
define buffer UsrRoleCompany2 for UsrRoleCompany.


vcRolesForSODViolationCheck = "".
/*fill the t_sRoleResource.Resource_ID if t_sRoleResource.tcResourceURI is filled*/
/*when comming from the UI the t_sRoleResource.tcResourceURI is not supposed to be filled*/
/*so this part is practically skiped*/
for each t_sRoleResource where
         t_sRoleResource.tcResourceURI <> ? and
         t_sRoleResource.tcResourceURI <> '' and
        (t_sRoleResource.tc_Status = 'C':U or
         t_sRoleResource.tc_Status = 'N':U) on error undo, throw:

    find Resources1 where Resources1.ResourceURI = t_sRoleResource.tcResourceURI no-lock no-error.
    if available Resources1 
    then assign t_sRoleResource.Resource_ID = Resources1.Resource_ID.
    else do:
        /*give error that resource does not exist*/
        assign vcMessage = trim(#T-23'Cannot find resource with URI $1.':255(8864)T-23#)
               oiReturnStatus = -1.
        <M-22 run SetMessage
           (input  vcMessage (icMessage), 
            input  t_sRoleResource.tcResourceURI (icArguments), 
            input  't_sRoleResource.tcResourceURI':U (icFieldName), 
            input  t_sRoleResource.tcResourceURI (icFieldValue), 
            input  'E':U (icType), 
            input  3 (iiSeverity), 
            input  t_sRoleResource.tc_Rowid (icRowid), 
            input  'BLF-186':U (icFcMsgNumber), 
            input  '' (icFcExplanation), 
            input  '' (icFcIdentification), 
            input  '' (icFcContext), 
            output viFcReturnSuper (oiReturnStatus)) in BRole>
        assign t_sRoleResource.Resource_ID = -1.
    end.    /* available Resources1 */
end. /*for each t_sRoleResource where*/
   
<ANCESTOR-CODE>

For Each t_sRole Where 
         t_sRole.tc_Status = 'C':U on error undo, throw:
    Find t_iRole Where 
         t_iRole.tc_Rowid = t_sRole.tc_Rowid No-error.
    If Not Available t_iRole Or
       t_sRole.RoleName <> t_iRole.RoleName
    Then Do:
        Assign vcMessage = Trim(#T-15'It is not possible to change the role name.':100(8209)T-15#)
               oiReturnStatus = -1.
        <M-16 run SetMessage
           (input  vcMessage (icMessage), 
            input  '' (icArguments), 
            input  't_sRole.RoleName':U (icFieldName), 
            input  t_sRole.RoleName (icFieldValue), 
            input  'E':U (icType), 
            input  3 (iiSeverity), 
            input  t_sRole.tc_Rowid (icRowid), 
            input  'BLF-185':U (icFcMsgNumber), 
            input  '' (icFcExplanation), 
            input  '' (icFcIdentification), 
            input  '' (icFcContext), 
            output viFcReturnSuper (oiReturnStatus)) in BRole>
    End.         
End. /*For Each t_sRole Where*/     

if can-find (Syst where Syst.SystSODActive <> false)    /* active or activating */
then do:
    vlBlockViolations = can-find (Syst where Syst.SystSODActive and Syst.SystSODBlockViolations).
    
    /* ================================================================= */
    /* Validate rule 1 always when SOD is active.                        */
    /* (also on new roles)                                               */
    /* ================================================================= */
    for each t_sRole where
             t_sRole.RoleSODException = no and
             t_sRole.tc_Status <> "D" on error undo, throw:
        
        empty temp-table tSODValidation.
            
        if vcActivityCode = "Permissions"
        or can-find (first t_sRoleResource where
                           t_sRoleResource.tc_ParentRowid = t_sRole.tc_Rowid and
                           t_sRoleResource.tc_Status = "N")
        or (vlBlockViolations and
            can-find (first t_iRole where
                            t_iRole.tc_Rowid = t_sRole.tc_Rowid and
                            t_iRole.RoleSODException = yes))
        then for each t_sRoleResource where
                      t_sRoleResource.tc_ParentRowid = t_sRole.tc_Rowid and
                      t_sRoleResource.Resource_ID <> 0 and
                      t_sRoleResource.Resource_ID <> ? and
                      t_sRoleResource.tc_Status   <> "D",
                first Resources1 fields (Resource_ID ResourceURI SODcategory_ID) no-lock where
                      Resources1.Resource_ID = t_sRoleResource.Resource_ID and
                      Resources1.SODcategory_ID <> 0,
                first SODCategory1 fields (SODCategory_ID SODCategoryCode) no-lock where
                      SODCategory1.SODCategory_ID = Resources1.SODCategory_ID on error undo, throw:
                
            for each SODExclusion fields (SODCategory1_ID SODCategory2_ID) no-lock where
                     SODExclusion.SODCategory1_ID = Resources1.SODCategory_ID,
                each tSODValidation where
                     tSODValidation.tiSODCategoryID = SODExclusion.SODCategory2_ID,
                each b_sRoleResource where
                     b_sRoleResource.tc_Rowid = tSODValidation.tcRoleResourceRowid,
               first Resources2 fields (Resource_ID ResourceURI) no-lock where
                     Resources2.Resource_ID = b_sRoleResource.Resource_ID,
               first SODCategory2 fields (SODCategory_ID SODCategoryCode) no-lock where
                     SODCategory2.SODCategory_ID = SODExclusion.SODCategory2_ID on error undo, throw:

                if t_sRoleResource.tc_Status = "N"
                then do:
                    viErrorsReported = viErrorsReported + 1.
                    if viErrorsReported > 100
                    then return.

                    oiReturnStatus = -1.
                    vcMessage = #T-17'SOD Violation ERROR':255(551800099)T-17# + ": "
                              + #T-55'This resource ($1) of category $2 is in conflict with another resource ($3) of category $4.':255(648296585)T-55# + " "
                              + #T-74'Please change Role Permissons to reflect the SOD Matrix Configuration for Categories $2 and $4.':255(79899251)T-74#.
                    vcArg = Resources1.ResourceURI + chr(2)
                          + SODCategory1.SODCategoryCode + chr(2)
                          + Resources2.ResourceURI + chr(2)
                          + SODCategory2.SODCategoryCode.
                    <M-34 run SetMessage
                       (input  vcMessage (icMessage), 
                        input  vcArg (icArguments), 
                        input  'tRoleResource.tcResourceURI' (icFieldName), 
                        input  t_sRoleResource.tcResourceURI (icFieldValue), 
                        input  'E' (icType), 
                        input  3 (iiSeverity), 
                        input  t_sRoleResource.tc_Rowid (icRowid), 
                        input  'BLF-432':U:U (icFcMsgNumber), 
                        input  '' (icFcExplanation), 
                        input  '' (icFcIdentification), 
                        input  '' (icFcContext), 
                        output viFcReturnSuper (oiReturnStatus)) in BRole>
                end.
                else
                if b_sRoleResource.tc_Status = "N"
                or vlBlockViolations
                then do:
                    viErrorsReported = viErrorsReported + 1.
                    if viErrorsReported > 100
                    then return.

                    oiReturnStatus = -1.
                    vcMessage = #T-19'SOD Violation ERROR':255(551800099)T-19# + ": "
                              + #T-6'This resource ($1) of category $2 is in conflict with another resource ($3) of category $4.':255(648296585)T-6# + " "
                              + #T-49'Please change Role Permissons to reflect the SOD Matrix Configuration for Categories $2 and $4.':255(79899251)T-49#.
                    vcArg = Resources2.ResourceURI + chr(2)
                          + SODCategory2.SODCategoryCode + chr(2)
                          + Resources1.ResourceURI + chr(2)
                          + SODCategory1.SODCategoryCode.
                    <M-35 run SetMessage
                       (input  vcMessage (icMessage), 
                        input  vcArg (icArguments), 
                        input  'tRoleResource.tcResourceURI' (icFieldName), 
                        input  b_sRoleResource.tcResourceURI (icFieldValue), 
                        input  'E' (icType), 
                        input  3 (iiSeverity), 
                        input  b_sRoleResource.tc_Rowid (icRowid), 
                        input  'BLF-433':U:U (icFcMsgNumber), 
                        input  '' (icFcExplanation), 
                        input  '' (icFcIdentification), 
                        input  '' (icFcContext), 
                        output viFcReturnSuper (oiReturnStatus)) in BRole>
                end.
                else do:
                    /* When the violation is not created in this transaction, do not raise an error but only a warning. */
                    if oiReturnStatus  = 0
                    then oiReturnStatus  = 1.
                    
                    if viWarningsReported < 100
                    then do:
                        viWarningsReported = viWarningsReported + 1.
                        vcMessage = #T-54'SOD Violation WARNING':255(241150131)T-54# + ": "
                                  + #T-7'This resource ($1) of category $2 is in conflict with another resource ($3) of category $4.':255(648296585)T-7# + " "
                                  + #T-51'Please change Role Permissons to reflect the SOD Matrix Configuration for Categories $2 and $4.':255(79899251)T-51#.
                        vcArg = Resources2.ResourceURI + chr(2)
                              + SODCategory2.SODCategoryCode + chr(2)
                              + Resources1.ResourceURI + chr(2)
                              + SODCategory1.SODCategoryCode.
                        <M-92 run SetMessage
                           (input  vcMessage (icMessage), 
                            input  vcArg (icArguments), 
                            input  'tRoleResource.tcResourceURI' (icFieldName), 
                            input  b_sRoleResource.tcResourceURI (icFieldValue), 
                            input  'W' (icType), 
                            input  3 (iiSeverity), 
                            input  b_sRoleResource.tc_Rowid (icRowid), 
                            input  'blf-96456':U (icFcMsgNumber), 
                            input  '' (icFcExplanation), 
                            input  '' (icFcIdentification), 
                            input  '' (icFcContext), 
                            output viFcReturnSuper (oiReturnStatus)) in BRole>
                    end.
                end.
            end.    /* each tSODValidation */

            create tSODValidation.
            assign tSODValidation.tiSODCategoryID     = Resources1.SODCategory_ID
                   tSODValidation.tcRoleResourceRowid = t_sRoleResource.tc_Rowid.
        end.    /* each t_sRoleResource */
    end.    /* each t_sRole */
    
    /* ================================================================= */
    /* Validate rule 2 only when it is blocking.                         */
    /* (Skip new roles as they cannot have members yet.)                 */
    /* ================================================================= */
    if vlBlockViolations
    then for each t_sRole where
                  t_sRole.RoleSODException = no and
                 (t_sRole.tc_Status = "C" or
                  t_sRole.tc_Status = "") on error undo, throw:
    
        vlAllResources = can-find (first t_iRole where
                                         t_iRole.tc_Rowid = t_sRole.tc_Rowid and
                                         t_iRole.RoleSODException = yes).
    
        for each t_sRoleResource where
                 t_sRoleResource.tc_ParentRowid = t_sRole.tc_Rowid and
                (t_sRoleResource.tc_Status <> "D" or vlAllResources = no) and
                (t_sRoleResource.tc_Status = "N" or vlAllResources = yes),
           first Resources1 fields (Resource_ID ResourceURI SODcategory_ID) no-lock where
                 Resources1.Resource_ID = t_sRoleResource.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 */
            for each UsrRoleCompany1 fields (Role_ID Usr_ID Company_ID Domain_ID) no-lock where
                     UsrRoleCompany1.Role_ID = t_sRole.Role_ID,
                each UsrRoleCompany2 fields (Role_ID Usr_ID Company_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 Role fields (Role_ID RoleName RoleSODException) no-lock where
                     Role.Role_ID = UsrRoleCompany2.Role_ID and
                     Role.RoleSODException = no,
                each RoleResource fields (Role_ID Resource_ID) no-lock where
                     RoleResource.Role_ID = Role.Role_ID,
                each Resources2 fields (Resource_ID ResourceURI SODCategory_ID) no-lock where
                     Resources2.Resource_ID = RoleResource.Resource_ID and
                     Resources2.SODcategory_ID <> 0,
                each SODExclusion fields (SODCategory1_ID SODCategory2_ID) no-lock where
                     SODExclusion.SODCategory1_ID = Resources1.SODcategory_ID and
                     SODExclusion.SODCategory2_ID = Resources2.SODcategory_ID on error undo, throw:

                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:
                    vlConflictFound = yes.
                    viErrorsReported = viErrorsReported + 1.
                    if viErrorsReported > 100
                    then return.

                    vcSODCompanyCode = "".
                    for first Company fields (Company_ID CompanyCode) no-lock where
                              Company.Company_ID = UsrRoleCompany1.Company_ID:
                        vcSODCompanyCode = Company.CompanyCode.
                    end.
                    
                    vcSODUserName = "".
                    for first Usr fields (Usr_ID UsrName) no-lock where
                              Usr.Usr_ID = UsrRoleCompany1.Usr_ID:
                        vcSODUserName = Usr.UsrName.
                    end.
            
                    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.

                    oiReturnStatus = -1.
                    vcContext = #T-1'User Name':17(7033)T-1# + " = " + vcSODUserName + chr(10)
                              + #T-82'Entity Code':24(8770)T-82# + " = " + vcSODCompanyCode + chr(10)
                              + #T-88'Role 1 Name':20(733738256)T-88# + " = " + t_sRole.RoleName + chr(10)
                              + #T-79'Resource 1 URI':20(998717657)T-79# + " = " + Resources1.ResourceURI + chr(10)
                              + #T-39'SOD category 1 code':20(583998413)T-39# + " = " + vcSODCategoryCode1 + chr(10)
                              + #T-73'Role 2 Name':20(73458301)T-73# + " = " + Role.RoleName + chr(10)
                              + #T-27'Resource 2 URI':20(117798426)T-27# + " = " + Resources2.ResourceURI + chr(10)
                              + #T-13'SOD category 2 code':20(52834825)T-13# + " = " + vcSODCategoryCode2.
                    <M-42 run SetMessage
                       (input  #T-62'Cannot add resource to role: SOD conflict found for user $1.':255(792087702)T-62# (icMessage), 
                        input  vcSODUserName (icArguments), 
                        input  'tRoleResource.tcResourceURI' (icFieldName), 
                        input  t_sRoleResource.tcResourceURI (icFieldValue), 
                        input  'E' (icType), 
                        input  3 (iiSeverity), 
                        input  t_sRoleResource.tc_Rowid (icRowid), 
                        input  'blf-506528':U (icFcMsgNumber), 
                        input  '' (icFcExplanation), 
                        input  '' (icFcIdentification), 
                        input  vcContext (icFcContext), 
                        output viFcReturnSuper (oiReturnStatus)) in BRole>
                end.    /* vlPolicyException = no */
            end.    /* each UsrRoleCompany1 */
        end.    /* each t_sRoleResource */
    end.    /* each t_sRole */
    else for each t_sRole where
                  t_sRole.RoleSODException = no and
                 (t_sRole.tc_Status = "C" or
                  t_sRole.tc_Status = "") on error undo, throw:
        if can-find (first t_iRole where
                           t_iRole.tc_Rowid = t_sRole.tc_Rowid and
                           t_iRole.RoleSODException = yes)
        or can-find (first t_sRoleResource where
                           t_sRoleResource.tc_ParentRowid = t_sRole.tc_Rowid and
                           t_sRoleResource.tc_Status = "N")
        then if vcRolesForSODViolationCheck = ""
             then vcRolesForSODViolationCheck = string(t_sRole.Role_ID).
             else vcRolesForSODViolationCheck = vcRolesForSODViolationCheck + "," + string(t_sRole.Role_ID).
    end.    /* each t_sRole */

end. /* SystSODActive = yes */


/* ==================================================================================================== */
/* Ensure field Role.RoleModuleURI can only be set when activity = MaintainRolesForModuleURI            */
/* Ensure Roles with RoleModuleURI filled can only be removed when activity = MaintainRolesForModuleURI */
/* ==================================================================================================== */
if vcActivityCode <> "MaintainRolesForModuleURI":U
then do :
    for each t_sRole where 
             (t_sRole.tc_Status = "N":U     and 
              t_sRole.RoleModuleURI <> "":U and 
              t_sRole.RoleModuleURI <> ?)       OR
             (t_sRole.tc_Status = "C":U and 
              can-find (first t_iRole where 
                              t_iRole.tc_Rowid       = t_sRole.tc_Rowid and 
                              t_iRole.RoleModuleURI <> t_sRole.RoleModuleURI)) : 
        assign vcMessage      = trim(substitute(#T-47'Attribute &1 of role &2 can only be set in activity &3':250(565098834)T-47#,trim(#T-70'Module URI':20(145219100)T-70#),t_sRole.RoleName,"MaintainRolesForModuleURI":U)) + chr(10) + 
                                trim(substitute(#T-780'Current activity: &1':250(52810599)T-780#,vcActivityCode)).
               oiReturnStatus = -1.
        <M-93 run SetMessage
           (input  vcMessage (icMessage), 
            input  '':U (icArguments), 
            input  'tRole.RoleModuleURI':U (icFieldName), 
            input  t_sRole.RoleModuleURI (icFieldValue), 
            input  'E':U (icType), 
            input  3 (iiSeverity), 
            input  t_sRole.tc_Rowid (icRowid), 
            input  'blf-516547':U (icFcMsgNumber), 
            input  '':U (icFcExplanation), 
            input  '':U (icFcIdentification), 
            input  '':U (icFcContext), 
            output viFcReturnSuper (oiReturnStatus)) in BRole>            
    end. /* for each t_sRole where  */    
    for each t_sRole where 
             t_sRole.tc_Status = "D":U and   
             can-find (first t_iRole where 
                             t_iRole.tc_Rowid       = t_sRole.tc_Rowid and 
                             t_iRole.RoleModuleURI <> "":U and 
                             t_iRole.RoleModuleURI <> ?) : 
        assign vcMessage      = trim(substitute(#T-26'Role &1 can only be deleted using activity &2 because attribute &3 is filled for this role.':250(153175570)T-26#,t_sRole.RoleName,"MaintainRolesForModuleURI":U,trim(#T-90'Module URI':20(145219100)T-90#))) + chr(10) + 
                                trim(substitute(#T-69'Current activity: &1':250(52810599)T-69#,vcActivityCode)).
               oiReturnStatus = -1.
        <M-62 run SetMessage
           (input  vcMessage (icMessage), 
            input  '':U (icArguments), 
            input  'tRole.RoleModuleURI':U (icFieldName), 
            input  t_sRole.RoleModuleURI (icFieldValue), 
            input  'E':U (icType), 
            input  3 (iiSeverity), 
            input  t_sRole.tc_Rowid (icRowid), 
            input  'blf-426014':U (icFcMsgNumber), 
            input  '':U (icFcExplanation), 
            input  '':U (icFcIdentification), 
            input  '':U (icFcContext), 
            output viFcReturnSuper (oiReturnStatus)) in BRole>            
    end. /* for each t_sRole where  */
end. /* if vcActivityCode <> "MaintainRolesForModuleURI":U */


finally:
    if viErrorsReported > 100
    then do:
        <M-37 run SetMessage
           (input  #T-60'Validation is aborted after 100 errors were reported.':255(415735840)T-60# (icMessage), 
            input  '' (icArguments), 
            input  '' (icFieldName), 
            input  '' (icFieldValue), 
            input  'W' (icType), 
            input  3 (iiSeverity), 
            input  '' (icRowid), 
            input  'blf-708347':U (icFcMsgNumber), 
            input  '' (icFcExplanation), 
            input  '' (icFcIdentification), 
            input  '' (icFcContext), 
            output viFcReturnSuper (oiReturnStatus)) in BRole>
    end.
end finally.