From 6dc84604d6ac1aca039e8e6a440c83070235842a Mon Sep 17 00:00:00 2001 From: Rod Roark Date: Wed, 8 Feb 2017 08:20:38 -0800 Subject: [PATCH] Access Control Improvements (#473) * Access control for layout based encounter forms. * Corrections from review. --- interface/forms/LBF/new.php | 17 ++- interface/forms/LBF/printable.php | 19 ++- interface/forms/LBF/report.php | 14 ++ interface/main/left_nav.php | 22 +++- interface/main/tabs/menu/menu_updates.php | 72 +++++----- interface/patient_file/encounter/forms.php | 25 +++- interface/patient_file/encounter/new_form.php | 18 ++- interface/super/edit_layout_props.php | 183 ++++++++++++++++++++++++++ interface/super/edit_list.php | 72 +++++----- 9 files changed, 359 insertions(+), 83 deletions(-) create mode 100644 interface/super/edit_layout_props.php diff --git a/interface/forms/LBF/new.php b/interface/forms/LBF/new.php index ac82482d4..05d424a9f 100644 --- a/interface/forms/LBF/new.php +++ b/interface/forms/LBF/new.php @@ -1,6 +1,6 @@ + * Copyright (C) 2009-2017 Rod Roark * * LICENSE: This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -102,6 +102,21 @@ $tmp = sqlQuery("SELECT title, option_value, notes FROM list_options WHERE " . $formtitle = $tmp['title']; $formhistory = 0 + $tmp['option_value']; +// Extract parameters from this form's list item entry. +$jobj = json_decode($tmp['notes'], true); +if (!empty($jobj['columns'])) $CPR = intval($jobj['columns']); +if (!empty($jobj['issue' ])) $LBF_ISSUE_TYPE = $jobj['issue']; +if (!empty($jobj['aco' ])) $LBF_ACO = explode('|', $jobj['aco']); + +// Check access control. +if (!acl_check('admin', 'super') && !empty($LBF_ACO)) { + $auth_aco_write = acl_check($LBF_ACO[0], $LBF_ACO[1], '', 'write' ); + $auth_aco_addonly = acl_check($LBF_ACO[0], $LBF_ACO[1], '', 'addonly'); + if (!$auth_aco_write && !($auth_aco_addonly && !$formid)) { + die(xlt('Access denied')); + } +} + if (empty($is_lbf)) { $fname = $GLOBALS['OE_SITE_DIR'] . "/LBF/$formname.plugin.php"; if (file_exists($fname)) include_once($fname); diff --git a/interface/forms/LBF/printable.php b/interface/forms/LBF/printable.php index e0ba2dd23..3448edc65 100644 --- a/interface/forms/LBF/printable.php +++ b/interface/forms/LBF/printable.php @@ -1,5 +1,5 @@ +// Copyright (C) 2009-2017 Rod Roark // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License @@ -22,10 +22,23 @@ $CPR = 4; // cells per row // The form name is passed to us as a GET parameter. $formname = isset($_GET['formname']) ? $_GET['formname'] : ''; -$tmp = sqlQuery("SELECT title FROM list_options WHERE " . - "list_id = 'lbfnames' AND option_id = ? AND activity = 1 LIMIT 1", array($formname) ); +$tmp = sqlQuery("SELECT title, notes FROM list_options WHERE " . + "list_id = 'lbfnames' AND option_id = ? AND activity = 1 LIMIT 1", array($formname)); $formtitle = $tmp['title']; +// Extract parameters from this form's list item entry. +$jobj = json_decode($tmp['notes'], true); +if (!empty($jobj['columns'])) $CPR = intval($jobj['columns']); +if (!empty($jobj['size' ])) $FONTSIZE = intval($jobj['size']); + +// Check access control. +if (!empty($jobj['aco'])) $LBF_ACO = explode('|', $jobj['aco']); +if (!acl_check('admin', 'super') && !empty($LBF_ACO)) { + if (!acl_check($LBF_ACO[0], $LBF_ACO[1])) { + die(xlt('Access denied')); + } +} + $fres = sqlStatement("SELECT * FROM layout_options " . "WHERE form_id = ? AND uor > 0 " . "ORDER BY group_name, seq", array($formname) ); diff --git a/interface/forms/LBF/report.php b/interface/forms/LBF/report.php index 5c307a6ac..058d47538 100644 --- a/interface/forms/LBF/report.php +++ b/interface/forms/LBF/report.php @@ -15,6 +15,20 @@ include_once($GLOBALS["srcdir"] . "/api.inc"); function lbf_report($pid, $encounter, $cols, $id, $formname, $no_wrap = false) { require_once($GLOBALS["srcdir"] . "/options.inc.php"); + + // Extract parameters from this form's list item entry. + $tmp = sqlQuery("SELECT notes FROM list_options WHERE " . + "list_id = 'lbfnames' AND option_id = ? AND activity = 1", array($formname)); + $jobj = json_decode($tmp['notes'], true); + + // Check access control. + if (!empty($jobj['aco'])) $LBF_ACO = explode('|', $jobj['aco']); + if (!acl_check('admin', 'super') && !empty($LBF_ACO)) { + if (!acl_check($LBF_ACO[0], $LBF_ACO[1])) { + die(xlt('Access denied')); + } + } + $arr = array(); $shrow = getHistoryData($pid); $fres = sqlStatement("SELECT * FROM layout_options " . diff --git a/interface/main/left_nav.php b/interface/main/left_nav.php index 65afd5591..67c54c154 100644 --- a/interface/main/left_nav.php +++ b/interface/main/left_nav.php @@ -1083,13 +1083,17 @@ $(document).ready(function(){ $lres = sqlStatement("SELECT * FROM list_options " . "WHERE list_id = 'lbfnames' AND activity = 1 ORDER BY seq, title"); -if (sqlNumRows($lres)) { - while ($lrow = sqlFetchArray($lres)) { - $option_id = $lrow['option_id']; // should start with LBF - $title = $lrow['title']; - genMiscLink('RBot','cod','2',xl_form_title($title), - "patient_file/encounter/load_form.php?formname=$option_id"); +while ($lrow = sqlFetchArray($lres)) { + $option_id = $lrow['option_id']; // should start with LBF + $title = $lrow['title']; + // Check ACO attribute, if any, of this LBF. + $jobj = json_decode($lrow['notes'], true); + if (!empty($jobj['aco'])) { + $tmp = explode('|', $jobj['aco']); + if (!acl_check($tmp[0], $tmp[1])) continue; } + genMiscLink('RBot','cod','2',xl_form_title($title), + "patient_file/encounter/load_form.php?formname=$option_id"); } include_once("$srcdir/registry.inc"); $reg = getRegistered(); @@ -1390,6 +1394,12 @@ if (!empty($reg)) { while ($lrow = sqlFetchArray($lres)) { $option_id = $lrow['option_id']; // should start with LBF $title = $lrow['title']; + // Check ACO attribute, if any, of this LBF. + $jobj = json_decode($lrow['notes'], true); + if (!empty($jobj['aco'])) { + $tmp = explode('|', $jobj['aco']); + if (!acl_check($tmp[0], $tmp[1])) continue; + } genPopLink($title, "../forms/LBF/printable.php?formname=$option_id"); } ?> diff --git a/interface/main/tabs/menu/menu_updates.php b/interface/main/tabs/menu/menu_updates.php index 02874896d..7d53e2b91 100644 --- a/interface/main/tabs/menu/menu_updates.php +++ b/interface/main/tabs/menu/menu_updates.php @@ -55,45 +55,51 @@ function update_modules_menu(&$menu_list) } } } -function update_visit_forms(&$menu_list) -{ - $baseURL="/interface/patient_file/encounter/load_form.php?formname="; - $menu_list->children=array(); -$lres = sqlStatement("SELECT * FROM list_options " . - "WHERE list_id = 'lbfnames' AND activity = 1 ORDER BY seq, title"); -if (sqlNumRows($lres)) { + +// This creates menu entries for all encounter forms. +// +function update_visit_forms(&$menu_list) { + $baseURL = "/interface/patient_file/encounter/load_form.php?formname="; + $menu_list->children = array(); + // LBF Visit forms + $lres = sqlStatement("SELECT * FROM list_options " . + "WHERE list_id = 'lbfnames' AND activity = 1 ORDER BY seq, title"); while ($lrow = sqlFetchArray($lres)) { $option_id = $lrow['option_id']; // should start with LBF $title = $lrow['title']; - $formURL=$baseURL . urlencode($option_id); - $formEntry=new stdClass(); - $formEntry->label=xl_form_title($title); - $formEntry->url=$formURL; - $formEntry->requirement=2; - $formEntry->target='enc'; - array_push($menu_list->children,$formEntry); + $formURL = $baseURL . urlencode($option_id); + $formEntry = new stdClass(); + $formEntry->label = xl_form_title($title); + $formEntry->url = $formURL; + $formEntry->requirement = 2; + $formEntry->target = 'enc'; + // Plug in ACO attribute, if any, of this LBF. + $jobj = json_decode($lrow['notes'], true); + if (!empty($jobj['aco'])) { + $formEntry->acl_req = explode('|', $jobj['aco']); + } + array_push($menu_list->children, $formEntry); } -} - - $reg = getRegistered(); - if (!empty($reg)) { - foreach ($reg as $entry) { - $option_id = $entry['directory']; - $title = trim($entry['nickname']); - if ($option_id == 'fee_sheet' ) continue; - if ($option_id == 'newpatient') continue; - if (empty($title)) $title = $entry['name']; - - $formURL=$baseURL . urlencode($option_id); - $formEntry=new stdClass(); - $formEntry->label=xl_form_title($title); - $formEntry->url=$formURL; - $formEntry->requirement=2; - $formEntry->target='enc'; - array_push($menu_list->children,$formEntry); - } + // Traditional forms + $reg = getRegistered(); + if (!empty($reg)) { + foreach ($reg as $entry) { + $option_id = $entry['directory']; + $title = trim($entry['nickname']); + if ($option_id == 'fee_sheet' ) continue; + if ($option_id == 'newpatient') continue; + if (empty($title)) $title = $entry['name']; + $formURL = $baseURL . urlencode($option_id); + $formEntry = new stdClass(); + $formEntry->label = xl_form_title($title); + $formEntry->url = $formURL; + $formEntry->requirement = 2; + $formEntry->target = 'enc'; + array_push($menu_list->children, $formEntry); } + } } + function menu_update_entries(&$menu_list) { global $menu_update_map; diff --git a/interface/patient_file/encounter/forms.php b/interface/patient_file/encounter/forms.php index 2deabadaa..fa13924ec 100644 --- a/interface/patient_file/encounter/forms.php +++ b/interface/patient_file/encounter/forms.php @@ -550,11 +550,26 @@ if ( $esign->isButtonViewable() ) { // skip forms whose 'deleted' flag is set to 1 if ($iter['deleted'] == 1) continue; - // Skip forms that we are not authorized to see. - if (($auth_notes_a) || - ($auth_notes && $iter['user'] == $_SESSION['authUser']) || - ($auth_relaxed && ($formdir == 'sports_fitness' || $formdir == 'podiatry'))) ; - else continue; + if (substr($formdir,0,3) == 'LBF') { + // Skip LBF forms that we are not authorized to see. + $lrow = sqlQuery("SELECT * FROM list_options WHERE " . + "list_id = 'lbfnames' AND option_id = ? AND activity = 1", + array($formdir)); + if (!empty($lrow)) { + $jobj = json_decode($lrow['notes'], true); + if (!empty($jobj['aco'])) { + $tmp = explode('|', $jobj['aco']); + if (!acl_check($tmp[0], $tmp[1])) continue; + } + } + } + else { + // Skip non-LBF forms that we are not authorized to see. + if (($auth_notes_a) || + ($auth_notes && $iter['user'] == $_SESSION['authUser']) || + ($auth_relaxed && ($formdir == 'sports_fitness' || $formdir == 'podiatry'))) ; + else continue; + } // $form_info = getFormInfoById($iter['id']); if (strtolower(substr($iter['form_name'],0,5)) == 'camos') { diff --git a/interface/patient_file/encounter/new_form.php b/interface/patient_file/encounter/new_form.php index 6ae920336..aed15ccbf 100644 --- a/interface/patient_file/encounter/new_form.php +++ b/interface/patient_file/encounter/new_form.php @@ -233,12 +233,20 @@ if ( $encounterLocked === false ) { if(!$StringEcho){ $StringEcho= '
    '; } - $StringEcho.= "
  • ".xl('Layout Based') ."
    "; + $StringEcho.= "
  • " . + xl('Layout Based') . "
  • "; while ($lrow = sqlFetchArray($lres)) { - $option_id = $lrow['option_id']; // should start with LBF - $title = $lrow['title']; - $StringEcho.= ""; + $option_id = $lrow['option_id']; // should start with LBF + $title = $lrow['title']; + // Check ACO attribute, if any, of this LBF. + $jobj = json_decode($lrow['notes'], true); + if (!empty($jobj['aco'])) { + $tmp = explode('|', $jobj['aco']); + if (!acl_check($tmp[0], $tmp[1])) continue; + } + $StringEcho .= ""; } } } diff --git a/interface/super/edit_layout_props.php b/interface/super/edit_layout_props.php new file mode 100644 index 000000000..071363420 --- /dev/null +++ b/interface/super/edit_layout_props.php @@ -0,0 +1,183 @@ + + * + * LICENSE: This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * You should have received a copy of the GNU General Public License + * along with this program. If not, see ;. + * + * @package OpenEMR + * @author Rod Roark + * @link http://www.open-emr.org + */ + +$sanitize_all_escapes = true; +$fake_register_globals = false; + +require_once("../globals.php"); +require_once("$srcdir/acl.inc"); +require_once("$phpgacl_location/gacl_api.class.php"); + +$info_msg = ""; + +// Check authorization. +$thisauth = acl_check('admin', 'super'); +if (!$thisauth) die(xlt('Not authorized')); + +$opt_line_no = intval($_GET['lineno']); +?> + + + +<?php echo xlt("Edit Layout Properties"); ?> + + + + + + + + + + + + + + + +
    +
    + +
    " . xl_form_title($title) . "
    " . xl_form_title($title) . "
    + + + + + + + + + + + + + + + + +
    + + + +
    + + + +
    + + + +
    + +

    +' onclick='submitProps()' /> + +  +' onclick='window.close()' /> +

    + + + + + + diff --git a/interface/super/edit_list.php b/interface/super/edit_list.php index 81f31f8fc..b04271ebe 100644 --- a/interface/super/edit_list.php +++ b/interface/super/edit_list.php @@ -396,7 +396,11 @@ function writeOptionLine($option_id, $title, $seq, $default, $value, $mapping='' } else { echo " "; echo ""; + attr($notes) . "' size='25' maxlength='255' class='optin' "; + if ($list_id == 'lbfnames') { + echo "onclick='edit_layout_props($opt_line_no)' "; + } + echo "/>"; echo "\n"; } if($list_id == 'apptstat') { @@ -708,6 +712,12 @@ function select_clin_term_code(e) { dlgopen('../patient_file/encounter/find_code_popup.php?codetype=', '_blank', 500, 400); } +// This invokes the popup to edit properties in the "notes" column. +function edit_layout_props(lineno) { + var layoutid = document.forms[0]['opt[' + lineno + '][id]'].value; + dlgopen('edit_layout_props.php?layout_id=' + layoutid + '&lineno=' + lineno, '_blank', 600, 300); +} + // This is for callback by the find-code popup. function set_related(codetype, code, selector, codedesc) { if (typeof(current_sel_name) == 'undefined' && typeof(current_sel_clin_term) == 'undefined') @@ -929,35 +939,37 @@ while ($row = sqlFetchArray($res)) { -- 2.11.4.GIT