How can I restrict Read access to records via ACL, based on a User's Location?

Community Alums
Not applicable

Hey All, 

I'm trying to build an ACL structure for a scoped application, and one of my requirements is that my users should only be able to see/read records in an Inventory that are assigned to their location. My thoughts are to use an Advanced Script in my Table.None Read ACL: 

var user = gs.getUser();
if (user.location == current.location) {
	answer = true;
}
else answer = false;

But despite verifying that the User's Location (Location 5150) reference was equivalent to the Records' Location (Again, Location 5150), the script returns false every time (and to my frustration, I have no way to log it - gs.info, warn, etc. statements don't output anything, and I can't use gs.log() because scoped app). 

I've also tried cut+pasting the script into my Table.* Read ACL, and it ends up only blocking Read access to the Location reference field, which is even stranger to me. 

The overall structure that I have in place isn't too crazy or complex - I only have one other Read ACL in the system, without any scripts or conditions, and it's unrelated to the role I'm trying to restrict. I should also mention - the Locations referenced are from the cmn_location table, and the ACL I'm running is for a custom table within my scoped application. 

So, here I am now - wondering if I'm even approaching this problem the right way haha. Could you folks help me out? Is it just because the GlideRecord object I refer to in the script isn't for each specific record, or..? For that matter, why am I not able to use logs for this issue? 

Much appreciated,

Vellv

1 ACCEPTED SOLUTION

Community Alums
Not applicable

Got it! 

This ended up being my final code: 

//If the user is trying to read a record that doesn't relate to their store, the system should reject it. 
var user = gs.getUserID();
var gr = new GlideRecord('sys_user');
gr.get('sys_id', user);
gs.addInfoMessage('gr.location = '+gr.location+'; current.store_location: '+current.store_location);

if (gr.location == current.store_location || current.store_location == '') {
	answer = true;
}
else answer = false;

My initial issue was that I wasn't accessing the current user properly, and thus whenever I tried to compare the user.location to the current.store_location, I always failed (because undefined != sys_id). So, thanks to Nitesh, I was able to fix that, and get the initial script working. 

Then, with my user able to read existing records, and the list properly sorted...I couldn't see the form for a new Record. My if statement was just reliant on gr.location == current.store_location, and was missing a clause for a blank record, aka current.store_location == ''. Again, I got confused with some syntax and was trying to check for store_location == undefined (or null), and nothing was working. A blank string, however, solved my final problem. 

Thanks to everyone that helped me out!

View solution in original post

9 REPLIES 9

Community Alums
Not applicable

Alright, so the changes to the ACL script from @Nitesh got it working for the List and Form views, for everything except for whenever I load a new form...I updated the script to be as follows: 

var user = gs.getUserID();
var gr = new GlideRecord('sys_user');
gr.get('sys_id', user);

if (gr.location == current.store_location || current.store_location == null || current.store_location == undefined) {
	answer = true;
}
else answer = false;

However, now I'm running into an issue where I don't have read privileges whenever I go onto a 'New' Form for these tables. I'm not sure why, either - is it because of the value not yet being defined, or is it something else? 

p_espinar
Kilo Guru

 

Why do not you try with Business Rule before query?

Un saludo,
Pablo Espinar
Consultant at Econocom Spain

Please mark this response correct if I've answered your question. Thanks!

Community Alums
Not applicable

Because the requirement for my application is an absolute restriction on Read access to all related ACLs. 

Community Alums
Not applicable

Got it! 

This ended up being my final code: 

//If the user is trying to read a record that doesn't relate to their store, the system should reject it. 
var user = gs.getUserID();
var gr = new GlideRecord('sys_user');
gr.get('sys_id', user);
gs.addInfoMessage('gr.location = '+gr.location+'; current.store_location: '+current.store_location);

if (gr.location == current.store_location || current.store_location == '') {
	answer = true;
}
else answer = false;

My initial issue was that I wasn't accessing the current user properly, and thus whenever I tried to compare the user.location to the current.store_location, I always failed (because undefined != sys_id). So, thanks to Nitesh, I was able to fix that, and get the initial script working. 

Then, with my user able to read existing records, and the list properly sorted...I couldn't see the form for a new Record. My if statement was just reliant on gr.location == current.store_location, and was missing a clause for a blank record, aka current.store_location == ''. Again, I got confused with some syntax and was trying to check for store_location == undefined (or null), and nothing was working. A blank string, however, solved my final problem. 

Thanks to everyone that helped me out!

Glad you got it 🙂