Help with Deny Unless ACL to hide attachments

Marcel H_
Tera Guru

I am having some trouble getting a Deny Unless ACL working to hide attachments in the header of records on a specific table.

 

I have a table named u_contacts that already has ACLs to restrict visibility of records based on group membership using the following script:

answer = false;

var groupList = current.u_share_with_group.toString();

var group = new GlideRecord("sys_user_group");
group.addQuery("sys_idIN" + groupList);
group.query();

while (group.next()) {
    if (gs.getUser().isMemberOf(group.name.toString())) {
        answer = true;
    }
}

 

This is working as expected in an Allow If ACL, however what I need to do it hide any attachments on the record as well if this ACL fails. I had no luck using various Allow If configurations, and was only able to hide attachments by putting a Deny Unless ACL on the sys_attachment table.

 

This hides read for all attachments system wide though, and I can't seem to figure out the best way to target attachments only on the u_contacts table.

 

I think that what I need to do is the following, but can't seem to get it working quite right:

Table = sys_attachment

User has role snc_internal

Applies to attachments with table_name = u_contacts

User is a member of a group listed in the u_share_with_group field on the current record on u_contacts

 

2 ACCEPTED SOLUTIONS

Marcel H_
Tera Guru

I was able to get this working with the following script in a Deny Unless ACL

// Default to deny access
answer = false;

if (
    current.getValue('table_name') === 'u_contacts' ) 
{
    // Get the sys_id of the parent record
    var parentSysId = current.getValue('table_sys_id');

    // Query the parent table to get the group list
    var parentRecord = new GlideRecord(current.getValue('table_name'));
    if (parentRecord.get(parentSysId)) {
        var groupList = parentRecord.u_share_with_group.toString();

        // Check if groupList has any values
        if (groupList) {
            // Retrieve the user's group membership
            var userGroupIds = [];
            var userGroups = new GlideRecord('sys_user_grmember');
            userGroups.addQuery('user', gs.getUserID());
            userGroups.query();

            while (userGroups.next()) {
                userGroupIds.push(userGroups.group.toString());
            }

            // Check if the user is a member of any of the required groups
            var requiredGroups = groupList.split(',');
            for (var i = 0; i < requiredGroups.length; i++) {
                if (userGroupIds.includes(requiredGroups[i])) {
                    answer = true; // Allow access
                    break;
                }
            }
        }
    }
} else {
    // Allow attachments on other tables
    answer = true;
}

View solution in original post

Hi @Marcel H_ - This might be more efficient...

// Default to deny access
answer = false;

if (current.getValue('table_name') === 'u_contacts') {
    // Get the sys_id of the parent record
    var parentSysId = current.getValue('table_sys_id');

    // Query the parent table to get the group list
    var parentRecord = new GlideRecord('u_contacts');
    if (parentRecord.get(parentSysId)) {
        var groupList = parentRecord.u_share_with_group.toString();

        if (groupList) {
            // Query user groups and check for membership
            var userGroups = new GlideRecord('sys_user_grmember');
            userGroups.addQuery('user', gs.getUserID());
            userGroups.addQuery('group.sys_id', 'IN', groupList); // Filter directly by required groups
            userGroups.query();

            // If any match is found, allow access
            if (userGroups.hasNext()) {
                answer = true;
            }
        }
    }
} else {
    // Allow attachments on other tables
    answer = true;
}

Instead of collecting the user's group memberships into an array and comparing manually, the addQuery('group.sys_id', 'IN', groupList) directly filters user groups against the u_share_with_group values.

View solution in original post

2 REPLIES 2

Marcel H_
Tera Guru

I was able to get this working with the following script in a Deny Unless ACL

// Default to deny access
answer = false;

if (
    current.getValue('table_name') === 'u_contacts' ) 
{
    // Get the sys_id of the parent record
    var parentSysId = current.getValue('table_sys_id');

    // Query the parent table to get the group list
    var parentRecord = new GlideRecord(current.getValue('table_name'));
    if (parentRecord.get(parentSysId)) {
        var groupList = parentRecord.u_share_with_group.toString();

        // Check if groupList has any values
        if (groupList) {
            // Retrieve the user's group membership
            var userGroupIds = [];
            var userGroups = new GlideRecord('sys_user_grmember');
            userGroups.addQuery('user', gs.getUserID());
            userGroups.query();

            while (userGroups.next()) {
                userGroupIds.push(userGroups.group.toString());
            }

            // Check if the user is a member of any of the required groups
            var requiredGroups = groupList.split(',');
            for (var i = 0; i < requiredGroups.length; i++) {
                if (userGroupIds.includes(requiredGroups[i])) {
                    answer = true; // Allow access
                    break;
                }
            }
        }
    }
} else {
    // Allow attachments on other tables
    answer = true;
}

Hi @Marcel H_ - This might be more efficient...

// Default to deny access
answer = false;

if (current.getValue('table_name') === 'u_contacts') {
    // Get the sys_id of the parent record
    var parentSysId = current.getValue('table_sys_id');

    // Query the parent table to get the group list
    var parentRecord = new GlideRecord('u_contacts');
    if (parentRecord.get(parentSysId)) {
        var groupList = parentRecord.u_share_with_group.toString();

        if (groupList) {
            // Query user groups and check for membership
            var userGroups = new GlideRecord('sys_user_grmember');
            userGroups.addQuery('user', gs.getUserID());
            userGroups.addQuery('group.sys_id', 'IN', groupList); // Filter directly by required groups
            userGroups.query();

            // If any match is found, allow access
            if (userGroups.hasNext()) {
                answer = true;
            }
        }
    }
} else {
    // Allow attachments on other tables
    answer = true;
}

Instead of collecting the user's group memberships into an array and comparing manually, the addQuery('group.sys_id', 'IN', groupList) directly filters user groups against the u_share_with_group values.