Running business rule as admin aka async not working?

akaupisch
Kilo Guru

I have a business rule that runs after someone inserts, updates or deletes a time card. The point is to calculate the actual personnel cost of a project in real time (or near real time). At first, I had this run as an 'after' business rule. However, when it runs, it runs with the roles of the user who submitted the time card. As time cards are locked down, the calculation only returns that users time cards, thus the entire project actual personnel cost is off. I verified my code works as if I run it through my admin account, it works just fine.

So, I need to run the biz rule as admin. The only way I know how is to run it as async. However, even if I do it as async, it still only pulls back that users time cards and not every ones on the project. Any other way to get a biz rule to run as admin?

here's the code of the biz rule:

var projectID = current.u_project_task.u_parent_project.sys_id;

var proj = new GlideRecord('pm_project');

if (!proj.get(projectID))

      return;

var oldValue = proj.u_work_cost;

var newValue = 0;

// calculate expense lines

var els = new GlideRecord('fm_expense_line');

els.addQuery('task', projectID);

els.query();

while (els.next())

      newValue += parseFloat(els.amount.getReferenceValue());

// calculate personnel

var rr = new GlideRecord('resource_role');

rr.get(gs.getProperty('tbc.resource.role.blended'));

var blendedRate = rr.hourly_rate;

var tcs = new GlideRecord('time_card');

tcs.addQuery('u_project_task.u_parent_project', projectID);

tcs.addQuery('state', 'NOT IN', 'Pending,Rejected');

tcs.query();

while (tcs.next())

      newValue += (tcs.total * blendedRate);

// update project

var delta = oldValue - newValue;

gs.info('***** oldValue: ' + oldValue + ' - ' + newValue);

proj.u_work_cost = newValue;

proj.update();

As you can see, nothing fancy and nothing that references the logged in user. Simply the gliderecord call to time_card is only returning that users timecards not everyone, and as async, it should be, right?

I'm on istanbul

8 REPLIES 8

I want to restrict users from seeing other users time cards. I do not, however, want the business rule to exclude those time cards.


Then check the ACLs and ensure users can only view/manipulate their own time cards (i.e.: record-level protection against the creator)


hence the reason to need to run the business rule as an admin.


That's not a justifiable reason.   That's an easier approach but a very insecure one, and runs the risk of a confused deputy exploit.



The correct approach would be to determine what permissions are needed to change specific fields but not others, and apply those as ACL rules.


So I think I'm understanding what you are saying, if I open just the 'total' field on the time card to everyone, but leave everything else locked down as it is now, the calculation should work but the users wont be able to see anything else? If they go into a time_card view, won't it show them all the time cards and all the totals just without any other info? I'll experiment with it, but just wanted to ensure I'm understanding what you are saying. Thanks


I'll experiment with it, but just wanted to ensure I'm understanding what you are saying. Thanks


I've just re-read your original post and may have misunderstood your requirements....



Just to confirm:


  1. this calculation should be executed whenever anyone updates a timecard
  2. the calculation requires access to data not present in the submitting user's timecard - so needs privileged access
  3. users should not be able to see data for other users, just theirs


If that's the case, then perhaps the delegation idea is still valid: users remain within their context and ACLs (or a BR) restricts their visibility to only their owned records, but an account with higher read-only access is able to perform the calculations.



So, much like your original idea... but not as admin.   It'd be safer to have another account that has:


  • read-only access to specific fields required by the calculation
  • write access only to the field containing the result of the calculation.

(much like Ankur mentioned)



One question that could be mooted: does this info need to happen in real-time?   Could presenting it as a report or homepage gadget work, something that's updated daily on a scheduled job?



(I'd prefer the real-time trigger, but I don't know if the transactions have more writes than reads, hence the possible performance bottleneck)


Ankur Bawiskar
Tera Patron
Tera Patron

Hi Adam,



I did find one read ACL in my demo instance for that table which allows to view and write only time cards if logged in user is present in the User field or has timecard_admin role.



Regards


Ankur


Regards,
Ankur
✨ Certified Technical Architect  ||  ✨ 9x ServiceNow MVP  ||  ✨ ServiceNow Community Leader