Projekt

Obecné

Profil

« Předchozí | Další » 

Revize 1741

Přidáno uživatelem Ondřej Fibich před asi 12 roky(ů)

Opravy:

- SQL injections v ACL a ARO
- #377: Naktere pristupove skupiny uzivateu by nemely byt mazatelne
- #378: Pristupova prava nededi z rodice

Zobrazit rozdíly:

freenetis/branches/1.1/application/i18n/cs_CZ/texts.php
'cannot delete, there are other records depending on this one' => 'Nelze smazat, na položce jsou závislé jiné záznamy',
'cannot edit, there are other records depending on this one' => 'Nelze upravit, na položce jsou závislé jiné záznamy',
'cannot delete group - it has at least one children group' => 'Nelze smazat skupinu - má alespoň jednu potomkovskou skupinu.',
'cannot delete group - this group is protected against deletion' => 'Nelze smazat skupinu - tato skupina je chráněná proti mazání.',
'cannot enable voip driver, allow `%s` rights for mysql user' => 'Nemohu povolit VoIP ovladač, povolte právo `%s` pro MySQL uživatele',
'cannot find detail dumps' => 'Nemohu nalézt podrobné výpisy.',
'cannot load heading of invoice' => 'Nemohu načíst hlavičku faktury',
freenetis/branches/1.1/application/models/aro_group.php
*/
class Aro_group_Model extends ORM
{
// ARO groups (must correspinds to database) =>
// ARO groups (must corresponds to database) =>
const ALL = 21;
const REGULAR_MEMBERS = 22;
const REGISTERED_APPLICANTS = 23;
const AUDITING_COMITTEE = 24;
const EXECUTIVE_COUNSIL = 25;
const ENGINEERS = 26;
const ADMINS = 32;
const USERS = 33;
const ADMINS = 32;
const TELEPHONISTS = 44;
const CHAIRMAN_AND_AGENT = 28;
const FIRST_DEGREE_CERTIFIED_ENGINEERS = 29;
const VOIP_ADMINS = 34;
const SECOND_DEGREE_CERTIFIED_ENGINEERS = 35;
const THIRD_DEGREE_CERTIFIED_ENGINEERS = 36;
const FOURTH_DEGREE_CERTIFIED_ENGINEERS = 37;
const FIFTH_DEGREE_CERTIFIED_ENGINEERS = 38;
const SIXTH_DEGREE_CERTIFIED_ENGINEERS = 39;
const SEVENTH_DEGREE_CERTIFIED_ENGINEERS = 40;
const EIGHTH_DEGREE_CERTIFIED_ENGINEERS = 41;
const NINETH_DEGREE_CERTIFIED_ENGINEERS = 42;
const TENTH_DEGREE_CERTIFIED_ENGINEERS = 43;
// <= ARO groups
/**
* Is given ARO group deletable?
* If no ARO group given, current (this) ARO group is checked.
*
* @author Ondřej Fibich
* @param integer $aro_group_id [optional]
* @return boolean
*/
public function is_deletable($aro_group_id = NULL)
{
if ($aro_group_id === NULL && $this)
{
$aro_group_id = $this->id;
}
return (
$aro_group_id != self::ALL &&
$aro_group_id != self::REGULAR_MEMBERS &&
$aro_group_id != self::REGISTERED_APPLICANTS &&
$aro_group_id != self::ADMINS &&
$aro_group_id != self::TELEPHONISTS
);
}
/**
* Cleans ARO group - deletes all ARO objects
*
* @author Michal Kliment
......
if (!$group_id)
$group_id = $this->id;
$group_id = intval($group_id);
$sql_insert = "INSERT INTO groups_aro_map (group_id, aro_id) VALUES ";
$values = array();
foreach ($aros as $aro)
$values[] = "($group_id, $aro)";
$values[] = "($group_id, " . intval($aro) . ")";
if (count($values))
{
freenetis/branches/1.1/application/models/acl.php
if (!$acl_id)
$acl_id = $this->id;
$acl_id = intval($acl_id);
$sql_insert = "INSERT INTO aco_map (acl_id, value) VALUES ";
$values = array();
foreach ($acos as $aco)
$values[] = "($acl_id, '$aco')";
$values[] = "($acl_id, " . $this->db->escape($aco) . ")";
if (count($values))
{
......
if (!$acl_id)
$acl_id = $this->id;
$acl_id = intval($acl_id);
$sql_insert = "INSERT INTO aro_groups_map (acl_id, group_id) VALUES ";
$values = array();
foreach ($aro_groups as $aro_group)
$values[] = "($acl_id, '$aro_group')";
$values[] = "($acl_id, " . $this->db->escape($aro_group) . ")";
if (count($values))
{
......
if (!$acl_id)
$acl_id = $this->id;
$acl_id = intval($acl_id);
$sql_insert = "INSERT INTO axo_map (acl_id, section_value, value) VALUES ";
$values = array();
foreach ($axos as $axo)
$values[] = "($acl_id, '".$axo['section_value']."', '".$axo['value']."')";
$values[] = "($acl_id, " . $this->db->escape($axo['section_value'])
. ", " . $this->db->escape($axo['value']) . ")";
if (count($values))
{
freenetis/branches/1.1/application/models/groups_aro_map.php
*
* @author Ondřej Fibich
* @staticvar array $cache Cache of access
* @staticvar array $cache_aro_user Cache of ACL parent tree
* @staticvar array $cache_aro_hierarchy Cache of ACL parent tree
* @param integer $user_id User to check access
* @param string $aco_value ACO value - action (view_all, new_own, ...)
* @param string $axo_section_value AXO section value - Controller name
......
public function has_access(
$user_id, $aco_value, $axo_section_value, $axo_value)
{
// Cahce
// Cache
static $cache = array();
static $cache_aro_hierarchy = NULL;
static $cache_aro_user = array();
// This codes calculates all predecesors of ARO group for hieararchy of
// access rights.
if ($cache_aro_hierarchy === NULL)
{
////////////////////////////////////////////////////////////////////////////////
// // Debug for testing (benchmark)
// $start_time = microtime();
////////////////////////////////////////////////////////////////////////////////
// Gets all groups id with relation to parent
$aro_groups = ORM::factory('aro_group')->select_list('id', 'parent_id', 'id');
// Go throught groupd
foreach ($aro_groups as $i => $v)
{
// Final set of all parents (recursive) of group
$final_set = array($i);
// Stack for recursive walk throught groups
$stack = ($v == 0) ? array() : array($v);
// Go recursive throught parents
while (($top = array_pop($stack)) !== NULL)
{
// End of tree?
if ($aro_groups[$top] != 0)
{
// Add parents to stack
array_push($stack, $aro_groups[$top]);
// Add current to final set
$final_set[] = $top;
}
}
// Add to cache
$cache_aro_hierarchy[$i] = array_unique($final_set);
}
////////////////////////////////////////////////////////////////////////////////
// // Debug for testing
//
// $diff = microtime() - $start_time;
// echo 'It tooks: ' . $diff . 'ms <br>';
//
// foreach ($cache_acl as $i => $v)
// {
// echo '<b>' . ORM::factory('aro_group', $i)->name . '</b>: ';
// sort($v);
//
// foreach ($v as $id)
// {
// echo ORM::factory('aro_group', $id)->name . ', ';
// }
//
// echo "<br><br>";
// }
//
// die();
////////////////////////////////////////////////////////////////////////////////
}
// Cache key
$key = "$user_id#$aco_value#$axo_section_value#$axo_value";
// Is in cache?
if (!array_key_exists($key, $cache))
{
// Check and add to cache
$cache[$key] = $this->db->query("
SELECT COUNT(*) AS count
FROM groups_aro_map
LEFT JOIN aro_groups ON aro_groups.id = groups_aro_map.group_id
LEFT JOIN aro_groups_map ON aro_groups_map.group_id = aro_groups.id
LEFT JOIN acl ON acl.id = aro_groups_map.acl_id
LEFT JOIN aco_map ON aco_map.acl_id = acl.id
LEFT JOIN aco ON aco.value = aco_map.value
LEFT JOIN axo_map ON axo_map.acl_id = acl.id
WHERE groups_aro_map.aro_id = ? AND
aco.value = ? AND
axo_map.section_value = ? AND
axo_map.value = ?
", array
(
$user_id, $aco_value, $axo_section_value, $axo_value
))->current()->count > 0;
// Fill in user cache?
if (!array_key_exists($user_id, $cache_aro_user))
{
// Get all ARO groups of user
$user_in_groups = $this->where('aro_id', $user_id)
->select_list('group_id', 'aro_id');
// Set cache
$cache_aro_user[$user_id] = array();
// Add all parents for users group and set it to cache
foreach ($user_in_groups as $group_id => $aro_id)
{
$cache_aro_user[$user_id] = array_merge(
$cache_aro_user[$user_id],
$cache_aro_hierarchy[$group_id]
);
}
// Discart not unique values
$cache_aro_user[$user_id] = array_unique($cache_aro_user[$user_id]);
}
// Is user in any group?
if (count($cache_aro_user[$user_id]))
{
// Check and add to cache
$cache[$key] = $this->db->query("
SELECT COUNT(*) AS count
FROM aro_groups
LEFT JOIN aro_groups_map ON aro_groups_map.group_id = aro_groups.id
LEFT JOIN acl ON acl.id = aro_groups_map.acl_id
LEFT JOIN aco_map ON aco_map.acl_id = acl.id
LEFT JOIN aco ON aco.value = aco_map.value
LEFT JOIN axo_map ON axo_map.acl_id = acl.id
WHERE aro_groups.id IN(" . implode(',', $cache_aro_user[$user_id]) . ") AND
aco.value = ? AND
axo_map.section_value = ? AND
axo_map.value = ?
", array
(
$aco_value, $axo_section_value, $axo_value
))->current()->count > 0;
}
// No group, no access :-)
else
{
$cache[$key] = FALSE;
}
}
// Return access info
freenetis/branches/1.1/application/controllers/aro_groups.php
$count = $model_groups_aro_map->count_rows_by_group_id($group->id);
if ($group->id == 21)
if ($group->id == Aro_group_Model::ALL)
{
$rows[$i + 1] = '<tr><td style="width:400px">'
. $ret . __('' . $group->name)
......
Controller::error(RECORD);
// cannot delete group with some childrens
if (!$group->is_deletable())
{
status::warning('Cannot delete group - this group is protected against deletion');
url::redirect('aro_groups/show_all');
}
// cannot delete group with some childrens
if ($group->count_childrens())
{
status::warning('Cannot delete group - it has at least one children group');
url::redirect('access_rights/show_groups');
url::redirect('aro_groups/show_all');
}
$group->transaction_start();

Také k dispozici: Unified diff