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
oiReturnStatus | output | integer | |
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.