ACL and permissions based upon employee's manager, and the manager's manager

erikbos
Giga Contributor

Hi,

I have got a security   requirement for a table.

- Each employee only sees the rows in a table where he/she is referenced.

- Each employee's manager can see his own rows and the rows of the employees reporting to him

- Each manager's manager can see his own rows and the rows of the employees reporting to him

[etc]

In my SN instance each user has its manager referenced (as imported from Active Directory) Each manager does not have its reports listed in sys_user. So going "up" the tree is easy, but I am not sure if it possible to traverse down is possible.

What would be the best approach such security requirement?

thx

e

1 ACCEPTED SOLUTION

Felipe, thanks for your quick follow up.



row = new GlideRecord('sys_user').get(row[column].manager);



does not work as I initially thought: it returns the output of the get() method which is true or false. Not a new object for a particular user. Oops


My code was flawed, I have rewritten the function and it now works properly. Function code:



// check if a user is the management chain of another user


managementChainCheck : function(employee, manager) {


  // direct report ?


  if (employee.manager == manager)


            return true;



  row = new GlideRecord('sys_user');


  var manager_to_check = employee.manager;



  // let's go up the management chain 10 times


  for (i = 0; i < 10; i++) {


            row.get(manager_to_check);


            if (row.manager == manager) {


                      return true;


            } else {


                      // Not found, let's try this employee's manager


                      manager_to_check = row.manager;


            }


  }


  return false;


},



View solution in original post

10 REPLIES 10

Erik, try out the following:




      row = new GlideRecord('sys_user').get(row[column].manager.sys_id);



(just add .sys_id on the manager reference)



Let us know what you got. Also please share the infoMessages results you are seeing as we can check what is going on with the values.



Good luck!


Felipe, thanks for your quick follow up.



row = new GlideRecord('sys_user').get(row[column].manager);



does not work as I initially thought: it returns the output of the get() method which is true or false. Not a new object for a particular user. Oops


My code was flawed, I have rewritten the function and it now works properly. Function code:



// check if a user is the management chain of another user


managementChainCheck : function(employee, manager) {


  // direct report ?


  if (employee.manager == manager)


            return true;



  row = new GlideRecord('sys_user');


  var manager_to_check = employee.manager;



  // let's go up the management chain 10 times


  for (i = 0; i < 10; i++) {


            row.get(manager_to_check);


            if (row.manager == manager) {


                      return true;


            } else {


                      // Not found, let's try this employee's manager


                      manager_to_check = row.manager;


            }


  }


  return false;


},



Well done Erik! I am pretty sure this solves the issue of many developers out there.



One thing I ´d like you to pay attention is, during the execution of the ACL do you see only the function call to the script include, or do you see the entire code on the ACL?



"Why?" would one ask back, and the reason why I am making that question is because ACL script fails when you put a commentary in the code, because then the ACL processor-ish will consider the remaining of the code as a comment and therefore will not execute it.



So take a look and be safe.



Cheers!



Felipe


Hi Felipe, the code works just fine with the comments in the called function as shown. In the ACL definition the script code does not have comments. It's just a one-line over multiple lines:



var answer = current.XXX == gs.getUserID() ||


  gs.getUser().isMemberOf('YYY') ||


  (new ZZZ()).managementChainCheck(current.XXX, gs.getUserID());


Nice Erik, well done!