Hide Incident Form Section depending in IP address in the sys_user_login_history table

John Johnson
Kilo Sage

Hello Smart People!

I have been trying to hide an incident form section like 'notes' for users outside of an IP CIDR. Everything i've tried has not worked. With what i'm doing, it is always hidden or not hidden.  Is it because im using the 'user login history' table?

I am looking for some examples of ways others have done this in their systems.  I have tried with Business rules, Client Scripts, and UI Policies with no success.

 

I appreciate your assistance in advance!

14 REPLIES 14

CIDR Check

var CidrCheck_OLD = Class.create();
CidrCheck_OLD.prototype = {
    initialize: function (cidrs) {
        var prop = gs.getProperty('x_tc.security.allowed_cidrs', 'IPCIDR', 'IPCIDR2');
        this.allowedCidrs = Array.isArray(cidrs) && cidrs.length ? cidrs : prop.split(/\s*,\s*/);
    },

    // Is the current session IP allowed?
    isClientIpAllowed: function () {
        var ip = gs.getSession().getClientIP();
        return this.isIpAllowed(ip);
    },

    // IPv4 check against allowed CIDR list
    isIpAllowed: function (ip) {
        ip = this._normalizeIPv4(ip);
        if (!ip) return false;
        for (var i = 0; i < this.allowedCidrs.length; i++) {
            if (this._isInCidr(ip, this.allowedCidrs[i])) return true;
        }
        return false;
    },

    // Normalize IPv6-mapped IPv4 
    _normalizeIPv4: function (ip) {
        if (!ip) return null;
        if (ip.indexOf(':') > -1 && ip.indexOf('.') > -1) {
            ip = ip.substring(ip.lastIndexOf(':') + 1);
        }
        if (ip.indexOf(':') > -1) {
            return null; // pure IPv6 -> not allowed by default
        }
        return ip;
    },

    _isInCidr: function (ip, cidr) {
        if (!ip || !cidr) return false;
        var parts = cidr.split('/');
        if (parts.length !== 2) return false;
        var baseIp = this._ipToInt(parts[0]);
        var ipInt = this._ipToInt(ip);
        var prefix = parseInt(parts[1], 10);
        if (isNaN(baseIp) || isNaN(ipInt) || isNaN(prefix) || prefix < 0 || prefix > 32) return false;
        var mask = prefix === 0 ? 0 : (-1 << (32 - prefix)) >>> 0;
        return ((ipInt & mask) >>> 0) === ((baseIp & mask) >>> 0);
    },

    _ipToInt: function (ip) {
        var octets = ip.split('.');
        if (octets.length !== 4) return NaN;
        for (var i = 0; i < 4; i++) {
            var n = parseInt(octets[i], 10);
            if (isNaN(n) || n < 0 || n > 255) return NaN;
            octets[i] = n;
        }
        return (((octets[0] << 24) | (octets[1] << 16) | (octets[2] << 8) | octets[3]) >>> 0);
    },

    type: 'CidrCheck_OLD'
};

IP AJAX

var IpAjax = Class.create();
IpAjax.prototype = Object.extendsObject(AbstractAjaxProcessor, {
    isClientIpAllowed: function () {
        var allowed = new CidrCheck().isClientIpAllowed();
        return allowed ? 'true' : 'false';
    },

    type: 'IpAjax'
});

Hide patient info outside trusted network

function onLoad() {
    var targetFields = [
        'u_patient_name',
        'u_patient_id',
        'u_date_of_service',
        'u_epic_department',
        'u_epic_note'
    ];

    var sectionName = 'patient_information'; // update if your internal name differs

    function hideSection(name) {
        try {
            if (g_form.setSectionDisplay) {
                g_form.setSectionDisplay(name, false);
            } else if (g_form.collapseSection) {
                g_form.collapseSection(name);
            }
        } catch (e) {}
    }

    try {
        var ga = new GlideAjax('IpAjax');
        ga.addParam('sysparm_name', 'isClientIpAllowed');
        ga.getXMLAnswer(function (answer) {
            var allowed = (answer === 'true');
            if (!allowed) {
                // Hide each field (belt-and-suspenders along with section hide)
                for (var i = 0; i < targetFields.length; i++) {
                    var f = targetFields[i];
                    if ((g_form.getControl && g_form.getControl(f)) || (g_form.hasField && g_form.hasField(f))) {
                        g_form.setDisplay(f, false);
                        g_form.setMandatory(f, false);
                    }
                }
                // Hide the entire section
                hideSection(sectionName);

                g_form.addInfoMessage('You are outside the trusted network. The Patient Information section is hidden.');
            }
        });
    } catch (e) {}
}

READ ACLs on each field

g_form.getSectionNames();

 

WRITE ACLs on each field 

answer=new CidrCheck().isClientIpAllowed();

Business Rule ' restrict patient info fields outside network'

(function executeRule(current, previous /*null when async*/) {
    var sensitiveChanged =
        current.u_patient_name.changes() ||
        current.u_patient_id.changes() ||
        current.u_date_of_service.changes() ||
        current.u_epic_department.changes() ||
        current.u_epic_note.changes();

    if (!sensitiveChanged)
        return;

    if (!new CidrCheck().isClientIpAllowed()) {
        gs.addErrorMessage('Editing of protected fields is restricted outside the trusted network.');
        current.setAbortAction(true);
    }
})(current, previous);