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.

How to configure 'read' access control for sys_user table to allow non-admin users to read

Patrick Tipps1
Tera Contributor

I'm working on catalog items. I have fields that are being populated when I'm logged in as admin and are not being populated when I'm not. I figure it's an ACL issue. I look through the ACLs for the sys_user table and can't seem to find what's preventing non-admin users from reading from the table.

 

Does this access control not allow for everyone to read from the table?

Screenshot 2023-10-16 135933.png

Context:

I have a catalog item that has several fields that are populated with an onLoad catalog client script.

Catalog client script:

 

// Function that triggers when the ServiceNow form loads.
function onLoad() {

    // Check if the user ID is undefined.
    if (!g_user.userID) {
		
        // Show an alert if the user ID is undefined.
        alert('User ID is undefined');
        return;
    }
    
    // Initialize a GlideAjax object to fetch user details.
    var glideAjax = new GlideAjax('PopulateCatalogDefaults');
    
    // Add parameters to the GlideAjax object.
    glideAjax.addParam('sysparm_name', 'getUserDetails');
    glideAjax.addParam('sysparm_userID', g_user.userID);
    // Execute the GlideAjax call and use populateFields function as the callback.
    glideAjax.getXML(populateFields);
}

// Callback function to populate the form fields based on the GlideAjax response.
function populateFields(response) {
    // Parse the XML response to get the "answer" attribute.
    var answer = response.responseXML.documentElement.getAttribute("answer");
    
    // Convert the "answer" attribute to a JavaScript object.
    var userObj = JSON.parse(answer);
    
    // Populate the 'users_person_number' field with the user's sys ID.
	g_form.clearValue('users_person_number');
    g_form.setValue('users_person_number', userObj.userSysId);
}

 

Here is the script include that's being called:

 

// Declare a new class called PopulateCatalogDefaults.
var PopulateCatalogDefaults = Class.create();

// Extend the PopulateCatalogDefaults class from AbstractAjaxProcessor.
PopulateCatalogDefaults.prototype = Object.extendsObject(AbstractAjaxProcessor, {
    
    // Define a method called getUserDetails.
    getUserDetails: function(userID) {
        
        // Create an empty object to store user information.
        var userInfo = {};
        
        // Initialize a GlideRecord object for the 'sys_user' table.
        var userGR = new GlideRecord('sys_user');
        
        // Get the user ID from the incoming parameter.
        var g_userId = this.getParameter('sysparm_userID');

        // Query the 'sys_user' table for the given user ID.
        if (userGR.get(g_userId)) {
            
            // Populate the userInfo object with the user's unique sys ID.
            userInfo.userSysId = userGR.getUniqueValue();
        }
        
        // Return the userInfo object as a JSON-formatted string.
        return JSON.stringify(userInfo);
    },
    
    // Specify the type of the class as 'PopulateCatalogDefaults'.
    type: 'PopulateCatalogDefaults'
});

 

7 REPLIES 7

Hi there.

'users_person_number' is actually a reference field that points to the sys_user table. Sorry, should have mentioned that earlier.

 

And I have done what you've suggested. I removed my log statements when I posted my code snippet. I am successfully getting the user's sys_id passed to the script include. I log "g_userid" and I get a result for both myself with admin and a user I'm impersonating who doesn't have admin.

var g_userId = this.getParameter('sysparm_userID');

But the value is not being returned by GlideAjax when the user is not admin. I've alerted the response from the "answer" attribute in the GlideAjax response and I only get a response when I'm admin.

 

Jim Coyne
Kilo Patron

Not sure if you figured out the problem BUT what you should really be doing in this particular case is setting the "Default value" of the variable instead with "javascript:gs.getUserID();".  Get the data from the server right from the start.  No point going from the server to the client and then back to the server via GlideAjax to get your data. Plus, the way you have the client script setup, ANOTHER call to the server is required in order to get the display value of the record when you set the value of the variable.

 

Take a look at this article - TNT: Returning Data from GlideAjax Calls for a better way to set things up.

Pato_Herrera
Tera Contributor

hello, try this.. In my case work fine!