How to only to check child table acl in script

EshikaAgrawal
ServiceNow Employee

Hi,

Below script worked but problem is it's returning child+parent level fields, is there any way to avoid parent level fields? basically dont want to run loop for parent table fields

(function process(request, response) {

    var result = {

        table: 'testtab',

        fieldsChecked: [],

        allReadable: true

    };

 

    var gr = new GlideRecord('test_tab');

    if (!gr.isValid()) {

        response.setStatus(400);

        return { error: 'Invalid table: testtab' };

    }

 

    gr.query();

    if (!gr.next()) {

        response.setStatus(404);

        return { error: 'No records found in testtab' };

    }

 

    //  Dynamically get all field names (including inherited)

    var fieldList = gr.getFields(); // Vector of GlideElements

    var fieldNames = [];

 

    for (var i = 0; i < fieldList.size(); i++) {

        var glideElement = fieldList.get(i);

        fieldNames.push(glideElement.getName());

    }

 

 

    function checkFieldReadAccess(gr, fieldNames) {

        var failedFields = [];

        for (var i = 0; i < fieldNames.length; i++) {

            var field = fieldNames[i];

            var element = gr.getElement(field);

            var canRead = element && element.canRead();

            result.fieldsChecked.push({

                field: field,

                canRead: canRead,

                element:element

            });

            if (!canRead) {

                failedFields.push(element);

            }

        }

        return failedFields.length === 0;

    }

 

    result.allReadable = checkFieldReadAccess(gr, fieldNames);

 

    response.setStatus(200);

    return result;

 

})(request, response);

 

 

Tried==> var fieldNames = gr.getED().getFieldNames();  but its not working

 

2. Also, like we have canRead() for checking read similarly do we have these checks for query_range or report_view or list_edit in script?

8 REPLIES 8

Ankur Bawiskar
Tera Patron

@EshikaAgrawal 

try this

1) you need to query sys_dictionary to get only child fields

2) there is no way to check query_range, report_view, list_edit operations directly using GlideRecord

Try to use GlideSecurityManager API

GlideSecurityManager - Global 

Something like this

var sm = GlideSecurityManager.get();
var grInc = new GlideRecord('incident');
var path = 'record/incident/list_edit.work_notes';

gs.info(sm.hasRightsTo(path, grInc));

To get only child fields

var tableName = 'test_tab';
var gr = new GlideRecord(tableName);
gr.query();
if (!gr.next()) {
    return { error: 'No records found in ' + tableName };
}

// Get only child fields
var dictGR = new GlideRecord('sys_dictionary');
dictGR.addQuery('name', tableName);
dictGR.addQuery('internal_type', '!=', 'collection');
dictGR.query();

var childFieldNames = [];
while (dictGR.next()) {
    childFieldNames.push(dictGR.element.toString());
}

// Check read access
var result = { table: tableName, fieldsChecked: [], allReadable: true };
for (var i = 0; i < childFieldNames.length; i++) {
    var field = childFieldNames[i];
    var element = gr.getElement(field);
    var canRead = element && element.canRead();
    result.fieldsChecked.push({
        field: field,
        canRead: canRead
    });
    if (!canRead) result.allReadable = false;
}

return result;

If my response helped please mark it correct and close the thread so that it benefits future readers.

@EshikaAgrawal 

Hope you are doing good.

Did my reply answer your question?

If my response helped please mark it correct and close the thread so that it benefits future readers.

@Ankur Bawiskar no, it didn't work, it's still fetching all parent table records

 

 

var tableName = 'sectest';
var gr = new GlideRecord(tableName);
gr.query();
if (!gr.next()) {
gs.info('No records found in ' + tableName);
} else {
var dictGR = new GlideRecord('sys_dictionary');
dictGR.addQuery('name', tableName);
dictGR.addQuery('internal_type', '!=', 'collection');
dictGR.query();

var childFieldNames = [];
while (dictGR.next()) {
childFieldNames.push(dictGR.element.toString());
}

var result = { table: tableName, fieldsChecked: [], allReadable: true };
for (var i = 0; i < childFieldNames.length; i++) {
var field = childFieldNames[i];
var element = gr.getElement(field);
var canRead = element && element.canRead();
result.fieldsChecked.push({
field: field,
canRead: canRead
});
if (!canRead) result.allReadable = false;
}

gs.info(JSON.stringify(result));
}

gs.info("hi");

SANDEEP28
Mega Sage

@EshikaAgrawal You can use below code. It will only give you child fields

function isInheritedField(tableName, fieldName) {
    var td = GlideTableDescriptor.get(tableName);
    var ed = td.getElementDescriptor(fieldName);

    if (ed != null) {
        var originTable = ed.getTableName();
        if (originTable != tableName) {
            return true;
        } else {
            return false;
        }
    }
}



var tableName = 'incident';
var gr = new GlideRecord(tableName);
gr.query();
if (!gr.next()) {
    gs.info('No records found in ' + tableName);
} else {
    var dictGR = new GlideRecord('sys_dictionary');
    dictGR.addQuery('name', tableName);
    dictGR.query();

    var childFieldNames = [];
    while (dictGR.next()) {
        if (!isInheritedField(tableName, dictGR.getValue('element'))) {
            childFieldNames.push(dictGR.element.toString());
        }
    }
}

var result = {
    table: tableName,
    fieldsChecked: [],
    allReadable: true
};
for (var i = 0; i < childFieldNames.length; i++) {
    var field = childFieldNames[i];
    var element = gr.getElement(field);
    var canRead = element && element.canRead();
    result.fieldsChecked.push({
        field: field,
        canRead: canRead
    });
    if (!canRead) result.allReadable = false;
}

gs.info(JSON.stringify(result));

 

If I could help you with your Query then, please hit the Thumb Icon and mark as Correct !!