From: Janusz Dobrowolski Date: Sat, 10 Oct 2009 12:29:22 +0000 (+0000) Subject: Changed access control extensions support for modules/plugins to use unique extension... X-Git-Tag: v2.4.2~19^2~1151 X-Git-Url: https://delta.frontaccounting.com/gitweb/?p=fa-stable.git;a=commitdiff_plain;h=e933b7e5bcdf8cddd62778abfb373564388c2485 Changed access control extensions support for modules/plugins to use unique extension ids. --- diff --git a/admin/db/maintenance_db.inc b/admin/db/maintenance_db.inc index 5984094f..f018ea1d 100644 --- a/admin/db/maintenance_db.inc +++ b/admin/db/maintenance_db.inc @@ -21,7 +21,7 @@ function array_natsort($aryData, $strIndex, $strSortBy, $strSortType=false) { // if the parameters are invalid - if (!is_array($aryData) || !$strIndex || !$strSortBy) + if (!is_array($aryData) || !$strSortBy) // return the array return $aryData; @@ -29,9 +29,9 @@ function array_natsort($aryData, $strIndex, $strSortBy, $strSortType=false) $arySort = $aryResult = array(); // loop through the array - foreach ($aryData as $aryRow) + foreach ($aryData as $key => $aryRow) // set up the value in the array - $arySort[$aryRow[$strIndex]] = $aryRow[$strSortBy]; + $arySort[$strIndex ? $aryRow[$strIndex] : $key] = $aryRow[$strSortBy]; // apply the natural sort natsort($arySort); @@ -42,13 +42,16 @@ function array_natsort($aryData, $strIndex, $strSortBy, $strSortType=false) arsort($arySort); // loop through the sorted and original data - foreach ($arySort as $arySortKey => $arySorted) - foreach ($aryData as $aryOriginal) - // if the key matches - if ($aryOriginal[$strIndex]==$arySortKey) - // add it to the output array - array_push($aryResult, $aryOriginal); - + foreach ($arySort as $arySortKey => $arySorted) + if($strIndex) + { + foreach ($aryData as $aryOriginal) + // if the key matches + if ($aryOriginal[$strIndex]==$arySortKey) + // add it to the output array + array_push($aryResult, $aryOriginal); + } else + $aryResult[$arySortKey] = $aryData[$arySortKey]; // return the return return $aryResult; } @@ -120,24 +123,23 @@ function write_config_db($new = false) return 0; } -function write_extensions($extensions=null, $company = null) +function write_extensions($extensions=null, $company = -1) { - global $path_to_root, $installed_extensions; + global $path_to_root, $installed_extensions, $next_extension_id; if (!isset($extensions)) { $extensions = $installed_extensions; } - - $exts = array_natsort($extensions, 'name', 'name'); - $extensions = $exts; - $n = count($exts); +// $exts = array_natsort($extensions, 'name', 'name'); +// $extensions = $exts; $msg = " '); +"/* List of installed additional modules and plugins. If adding extensions manually + to the list make sure they have unique, so far not used extension_ids as a keys, + and \$next_extension_id is also updated. 'name' - name for identification purposes; 'type' - type of extension: 'module' or 'plugin' @@ -147,8 +149,10 @@ function write_extensions($extensions=null, $company = null) 'title' - is the menu text (for plugin) or new tab name 'active' - current status of extension 'acc_file' - (optional) file name with \$security_areas/\$security_sections extensions; - related to 'path'. -*/\n\n"; + related to 'path' + 'access' - security area code in string form +*/ +\n\$next_extension_id = $next_extension_id; // unique id for next installed extension\n\n"; else $msg .= "/* @@ -157,15 +161,12 @@ function write_extensions($extensions=null, $company = null) */\n\n"; $msg .= "\$installed_extensions = array (\n"; - if ($n > 0) - $msg .= "\t0 => "; - for ($i = 0; $i < $n; $i++) + foreach($extensions as $i => $ext) { - if ($i > 0) - $msg .= "\t\t"; + $msg .= "\t$i => "; $msg .= "array ( "; $t = ''; - foreach($extensions[$i] as $key => $val) { + foreach($ext as $key => $val) { $msg .= $t."'$key' => '$val',\n"; $t = "\t\t\t"; } @@ -173,7 +174,7 @@ function write_extensions($extensions=null, $company = null) } $msg .= "\t);\n?>"; - $filename = $path_to_root . (isset($company) ? '/company/'.$company : '') + $filename = $path_to_root . ($company==-1 ? '' : '/company/'.$company) .'/installed_extensions.php'; // Check if the file is writable first. diff --git a/admin/security_roles.php b/admin/security_roles.php index 5617eb79..ef7e23ed 100644 --- a/admin/security_roles.php +++ b/admin/security_roles.php @@ -22,6 +22,17 @@ include_once($path_to_root . "/includes/access_levels.inc"); include_once($path_to_root . "/admin/db/security_db.inc"); $new_role = get_post('role')=='' || get_post('cancel') || get_post('clone'); +//-------------------------------------------------------------------------------------------------- +// Following compare function is used for sorting areas +// in such a way that security areas defined by module/plugin +// is properly placed under related section regardless of +// unique extension number +// +function comp_areas($area1, $area2) +{ + return ($area1[0]&0xffff)-($area2[0]&0xffff); +} + //-------------------------------------------------------------------------------------------------- if (list_updated('role')) { $Ajax->activate('details'); @@ -64,14 +75,20 @@ if (get_post('addupdate')) $sections = array(); $areas = array(); foreach($_POST as $p =>$val) { - if (substr($p,0,4) == 'Area') - $areas[] = substr($p, 4); + if (substr($p,0,4) == 'Area') { + $a = substr($p, 4); + if (($a&~0xffff) && (($a&0xff00)<(99<<8))) { + $sections[] = $a&~0xff; // add extended section for plugins + } + $areas[] = $a; + } if (substr($p,0,7) == 'Section') $sections[] = substr($p, 7); } - - sort($areas); - sort($sections); + uasort($areas, 'comp_areas'); + + $sections = array_values($sections); + _vd($sections); if ($new_role) { add_security_role($_POST['name'], $_POST['description'], $sections, $areas); @@ -114,7 +131,7 @@ if (get_post('cancel')) if (!isset($_POST['role']) || get_post('clone') || list_updated('role')) { $id = get_post('role'); $clone = get_post('clone'); -// clear_data(); + unset($_POST); if ($id) { $row = get_security_role($id); @@ -161,7 +178,6 @@ if (get_post('_show_inactive_update')) { } if (find_submit('_Section')) { $Ajax->activate('details'); -// set_focus(''); } //----------------------------------------------------------------------------------------------- div_start('details'); @@ -174,16 +190,22 @@ end_table(1); start_table("$table_style width=40%"); $k = $j = 0; //row colour counter - $m = 0; - asort($security_areas); // in the case installed external modules has added some lines + $ext = $sec = $m = -1; + uasort($security_areas,'comp_areas'); foreach($security_areas as $area =>$parms ) { // system setup areas are accessable only for site admins i.e. // admins of first registered company - if (user_company() && (($parms[0]&~0xff) == SS_SADMIN)) continue; - - if (($parms[0]&~0xff) != $m) + if (user_company() && (($parms[0]&0xff00) == SS_SADMIN)) continue; + + $newsec = ($parms[0]>>8)&0xff; + $newext = $parms[0]>>16; + if ($newsec != $sec || (($newext != $ext) && ($newsec>99))) { // features set selection + $ext = $newext; + $sec = $newsec; $m = $parms[0] & ~0xff; +// if(!isset($security_sections[$m])) +// display_error(sprintf("Bad section %X:", $m)); label_row($security_sections[$m].':', checkbox( null, 'Section'.$m, null, true, _("On/off set of features")), diff --git a/includes/access_levels.inc b/includes/access_levels.inc index b35890bd..4a43331a 100644 --- a/includes/access_levels.inc +++ b/includes/access_levels.inc @@ -19,6 +19,10 @@ Every security section can contain up to 256 different areas. External modules can extend security roles system by adding rows to $security_sections and $security_areas using section codes >=100. + Security areas and sections created by extension modules/plugins + have dynamically assigned 3-byte integer codes. The highest byte is zero + for sections/areas defined in this file, and extid+1 for those defined + by extensions */ define('SS_SADMIN', 1<<8); // site admin define('SS_SETUP', 2<<8); // company level setup @@ -245,15 +249,57 @@ $security_areas =array( . on any page with non-standard security areas . in security roles editor The call should be placed between session.inc inclusion and page() call. + Up to 155 security sections and 155 security areas for any extension can be installed. */ function add_access_extensions() { - global $path_to_root, $security_areas, $security_sections, $installed_extensions; + global $security_areas, $security_sections, $installed_extensions; - foreach($installed_extensions as $ext) { - if (@$ext['active'] && isset($ext['acc_file'])) - include($path_to_root.($ext['type'] == 'plugin' ? '/modules/':'/').$ext['path'].'/'.$ext['acc_file']); + foreach($installed_extensions as $extid => $ext) { + $scode = 100; + $acode = 100; + $accext = get_access_extensions($extid); + $extsections = $accext[1]; + $extareas = $accext[0]; + $extcode = $extid<<16; + + $trans = array(); + foreach($extsections as $code =>$name) { + $trans[$code] = $scode<<8; + // reassign section codes + $security_sections[$trans[$code]|$extcode] = $name; + $scode++; + } + foreach($extareas as $code => $area) { + $section = $area[0]&0xff00; + // extension modules: + // if area belongs to nonstandard section + // use translated section codes and + // preserve lower part of area code + if (isset($trans[$section])) { + $section = $trans[$section]; + } + // otherwise assign next available + // area code >99 + $area[0] = $extcode | $section | ($acode++); + $security_areas[$code] = $area; + } } } +/* + Helper function to retrieve extension access definitions in isolated environment. +*/ +function get_access_extensions($id) { + global $path_to_root, $installed_extensions; + + $ext = $installed_extensions[$id]; + + $security_sections = $security_areas = array(); + + if (isset($ext['acc_file'])) + include($path_to_root.($ext['type'] == 'plugin' ? '/modules/':'/').$ext['path'].'/'.$ext['acc_file']); + + return array($security_areas, $security_sections); +} ?> \ No newline at end of file diff --git a/includes/current_user.inc b/includes/current_user.inc index bb265047..5aa5e641 100644 --- a/includes/current_user.inc +++ b/includes/current_user.inc @@ -127,7 +127,6 @@ class current_user function can_access($page_level) { global $security_groups, $security_areas; - if (isset($security_groups)) { return $this->company == 0 && in_array(20, $security_groups[$this->access]); @@ -135,7 +134,7 @@ class current_user if ($page_level === 'SA_OPEN') return true; - $code = @$security_areas[$page_level][0]; + $code = $security_areas[$page_level][0]; // only first registered company has site admin privileges return $code && in_array($code, $this->role_set) @@ -147,11 +146,11 @@ class current_user return $this->can_access($page_level); } - function get_db_connection() + function get_db_connection($id=-1) { global $db_connections; - $connection = $db_connections[$this->company]; + $connection = $db_connections[$id == -1 ? $this->company : $id]; //print_r($connection); diff --git a/index.php b/index.php index aa0e763e..ab6764f0 100644 --- a/index.php +++ b/index.php @@ -14,6 +14,7 @@ ini_set('xdebug.auto_trace',1); include_once("includes/session.inc"); + add_access_extensions(); $app = &$_SESSION["App"]; if (isset($_GET['application'])) $app->selected_application = $_GET['application']; diff --git a/installed_extensions.php b/installed_extensions.php index b83e3cfb..8afb638b 100644 --- a/installed_extensions.php +++ b/installed_extensions.php @@ -1,7 +1,8 @@ '); +/* List of installed additional modules and plugins. If adding extensions manually + to the list make sure they have unique, so far not used extension_ids as a keys, + and $next_extension_id is also updated. 'name' - name for identification purposes; 'type' - type of extension: 'module' or 'plugin' @@ -11,9 +12,12 @@ 'title' - is the menu text (for plugin) or new tab name 'active' - current status of extension 'acc_file' - (optional) file name with $security_areas/$security_sections extensions; - related to 'path'. + related to 'path' + 'access' - security area code in string form */ +$next_extension_id = 1; // unique id for next installed extension + $installed_extensions = array ( ); ?> \ No newline at end of file