- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
04-16-2015 01:05 PM
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
Solved! Go to Solution.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
05-01-2015 02:58 AM
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;
},
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
04-16-2015 03:55 PM
This one is tricky as the possibility of having an ACL that runs for a bit of time is high.
I think you need two ACLs:
- The first is easy and straight forward - ACL that allows access if the person is referenced in the table
- A second one that allows access if the person is a manager of the employee referenced in the table, or the manager of the manager. You will have to decide the max number of iterations you will have (manager of manager of manager of manager ...) so you won ´t run in a endless loop.
You should do this via script, returning true if you detected that the current person trying to see the record is in the manager chain.
I hope it helps.
Best of luck,
Felipe
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
04-17-2015 03:21 AM
Think about the next:
1/ Save at [sys_user] row the upper manager chain:
+ A
+ B
+ D
+ E
+ C
+ F
So, A.manager_chain = ["A"] , B.manager_chain = ["B","A"], D.manager_chain = ["D","B","A"], F.manager_chain = ["F","C","A"] and so on.
So, from this moment, it's only necessary to look for the manager at the entire [sys_user] looking for the manager in the manager_chain.
2/ Create a Business Rule to rebuild the manager chain for each user that has been affected by a manager change, looking for the old manager at the chain in order to rebuild that nodes. (Easy Script, but slightly expensive to run if the manager changed is in a hight level)... I think this is not so frequently to change a manager...
- Two passes, ( ¿O(n)?) --> 1 : Look for the candidates to reconstruct; 2 : Reconstruct candidates --> No iterative
3/ ACL will check for all registers that references the user at the manager_chain. (I added the user at the chain in order to do only one query, for the direct reference, and managed_by also). (Cheap to run an easy to code).
Finally, in this way, you can also show to user his little slaves from a related list, for example...
This is more or less as LDAP nodes works with the ou's...
Best Regards
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
04-30-2015 09:28 AM
Thx, thought about that as well: prepping sys_user and building a lookup table to limit the number of recursive queries.. But for now I am going to skip it as the usage on this table is not going to be much.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
04-30-2015 09:21 AM
Hi,
Thanks for replies. As scripted ACL I have used:
var answer = current.contract_administrator == gs.getUserID() ||
gs.getUser().isMemberOf('SpecialGroup') ||
XXX.managementChainCheck(current, 'account_administrator', gs.getUserID());
as script include function:
XXX.managementChainCheck : function(row, column, logged_in_user) {
gs.addInfoMessage("managementChainCheck| liu: " + logged_in_user + " column: " + column);
// if this user has a manager and recursion up the chain is below 10 we will evaluate
for (i = 0; !row[column].manager.isNil() && i < 10; i++) {
gs.addInfoMessage("managementChainCheck|manager (" + i + ") m: " + row[column].manager);
// is this user's manager the currently logged in one?
if (row[column].manager == logged_in_user) {
return true;
} else {
// go one up the management chain
row = new GlideRecord('sys_user').get(row[column].manager);
}
}
return false;
},
The ACL "works":
1) my function is called
2) the employee's first manager is being compared correctly. first for loop iteration is ok (so a manager's sees the rows of a report)
but getting the gliderecord of an employee's manager does not appear to work I have not done a lot of coding yet.. Any suggestions ?