Join the #BuildWithBuildAgent Challenge! Get recognized, earn exclusive swag, and inspire the ServiceNow Community with what you can build using Build Agent.  Join the Challenge.

ACL for HR Case

Jon23
Mega Sage

We are currently implementing HR Service Management and have a requirement where an assignment group can restrict case access to their assignment group only.

I have achieved this by adding a new field on the form 'Restrict Case Access' and a new read ACL rule:

HR_ACL.PNG

Everything appears to work as expected, however, my question is, should I be using 'hr_Factory.getSecurityManager(current, gs).canRead()' as many of the other HR ACL rules appear to be using - after reading the wiki I am confused on how to work with these custom wrappers.

Am i creating issue for myself by not using the wrappers?

22 REPLIES 22

Hi Ahmed Hmeid,



Thank you for taking the time to provide a detailed explanation and example - what you are describing makes (some ) sense and I would prefer to work with the ServiceNow code as it was intended.



I am going to re-write my ACL to use the wrapper instead which will hopefully cement my understanding of it


Ahmed Hmeid, I am making some progress and have my script include being called; here's what I have so far - does this look correct based on my original ACL?



var plt_hr_caseSecurityManager = Class.create();



plt_hr_caseSecurityManager.prototype = Object.extendsObject(hr_caseSecurityManager ,{



      canRead: function() {



              if (this._gr.isNewRecord()) {


                      this._logDebug("[canRead] New record, granting access");


                      return true;


              }



              // Check the hr role and not restricted


              if (this._gs.hasRole(hr.ROLE_HR_CASE_READER) || this.u_restrict_case_access == 'false') {


                      return true;


              }



              // Check the hr role and restricted


              if (this._gs.hasRole(hr.ROLE_HR_MANAGER) || this.u_restrict_case_access == 'true') {


                      return true;


              }



              // Check if it's the user who assigned to the case


              if (this._isAssignedTo()) {


                      this._logDebug("[canRead] Granting access to assigned_to");


                      return true;


              }



              // Check if it's the user who opened the case


              if (this._isOpenedBy()) {


                      this._logDebug("[canRead] Granting access to opened_by");


                      return true;


              }



              // Check if it's the user who the case was opened for


              if (this._isOpenedFor()) {


                      this._logDebug("[canRead] Granting access to opened_for");


                      return true;


              }



              // Check if it's a user in the watch list field


              if (this._isInWatchList()) {


                      this._logDebug("[canRead] Granting access to watch list user");


                      return true;


              }



              this._logDebug("[canRead] Denying access to record for " + this._gs.getUserName());



              return false;


      },



      type: 'plt_hr_CaseSecurityManager'



});


Your script looks good. If I were doing it, I would probably modify the function "canRead" as follows:





/** PLEASE TEST


     


    This should work, but the code comes with no warranty.


**/



var plt_hr_caseSecurityManager = Class.create();


plt_hr_caseSecurityManager.prototype = Object.extendsObject(hr_caseSecurityManager ,{


        canRead: function() {


                    // Insert here your override logic


                      // Say for example you want to allow "Xyz" role to have permission




                  /*


                            if(... ) {


                            }


                  */





                  // Now for the other cases simply use the default logic.


                  return hr_caseSecurityManager.prototype.canRead.call(this);


        },




        type: 'plt_hr_CaseSecurityManager'  


});


Jayaprakash Pasala, thanks for your advice, however i'm still not able to get this to work.



I get the following error in the log:



org.mozilla.javascript.EcmaError: "plt_hr_caseSecurityManager" is not defined.


    Caused by error in Script Include: 'hr_Factory' at line 53




        50:             switch (_gr.getTableName()) {


        51:                 case "hr_case":


        52: gs.log("JW-DEBUG: HR CASE");


==>   53:                         return plt_hr_caseSecurityManager(_gr, _gs);


        54:                 default:


        55: gs.log("JW-DEBUG: DEFAULT");


        56:                         return hr_BaseFactory.getSecurityManager(_gr, _gs);





This is the hr_Factory script include:


var hr_Factory = Class.create();




/**


* Returns a new instance of a wrapper type for the given GlideRecord


*/


hr_Factory.wrap = function(_gr, _gs) {


      var wrapperType = hr_Factory.getWrapperType(_gr.getTableName());


      return new wrapperType(_gr, _gs);


};




/**


* Returns the correct wrapper to instantiate based on the table provided.


*


* This function needs to be changed to allow for the addition of more script includes.


*


* Bellow is an example change that would be made to the function if the hr_Case script include was extended.


* Note that we've added the check for hr_case to return the new type, all other type requests are handled by the base factory.


*


*         switch (tableName + "") {


*             case hr.TABLE_CASE:


*                     return cust_hr_Case // name of the new script include that extends hr_case;


*             default:


*                     return hr_BaseFactory.getWrapperType(tableName);


*         }


*/




hr_Factory.getWrapperType = function(tableName) {


      return hr_BaseFactory.getWrapperType(tableName);


};






/**


* Returns a new instance of a security manager for the given GlideRecord.


*


* The same changes will be needed (as above) if the security managers are extended.


*/




/*


// *** Original Baseline Code ****


hr_Factory.getSecurityManager = function(_gr, _gs) {


      return hr_BaseFactory.getSecurityManager(_gr, _gs);


};


*/






// PLT Extended Code




hr_Factory.getSecurityManager = function(_gr, _gs) {




          switch (_gr.getTableName()) {


              case "hr_case":


gs.log("JW-DEBUG: HR CASE");


                      return plt_hr_caseSecurityManager(_gr, _gs);


              default:


gs.log("JW-DEBUG: DEFAULT");


                      return hr_BaseFactory.getSecurityManager(_gr, _gs);


          }




};


Hi,



You should change the error line to (this should fix it):



plt_hr_caseSecurityManager.getSecurityManager(_gr, _gs);




thanks,


JP