Changeset 348
Author: Adam Price
(2011/02/22 19:39) About 1 year ago
Updated the access module with the new code to handle the new access permissions system. Added a new log override in so that debug logs can be split up into smaller subsections.
Author: Adam Price
(2011/02/22 19:39) About 1 year ago
Updated the access module with the new code to handle the new access permissions system. Added a new log override in so that debug logs can be split up into smaller subsections.
$this->lang->load('access');$this->lang->load('access');log_message('debug', 'Access Controller Loaded');log_message('debug', 'Access Controller Loaded');{{$this->template->set_breadcrumb(lang('access_permissions'), 'access');// Get all language strings and output them to a page variable$this->template->set_title(lang('access_permissions'));$this->template->set_variable('ci_language', $this->lang->language); // TODO: This is temp please see ISSUE #11$this->template->set_breadcrumb(lang('access_access_permissions_title'), 'access');$this->template->set_title(lang('access_access_permissions_title'));$this->template->build('admin/index');$this->template->build('admin/index');public function load_groups(){$this->load->model('group_model');try{$groups = $this->group_model->get_all();$json_array = array();foreach($groups as $group){$json_array[$group->id] = array('name' => $group->name, 'locked' => $group->locked);}print json_encode($json_array);}catch(Exception $ex){$this->ajax_error(lang('access_group_load_failure'));}}/*** Output an ajax error** @param string $message Error message* @param bool $log Whether to log the error* @return void*/private function ajax_error($message, $log = TRUE){if($log){log_message('error', $message);}$this->output->set_status_header('400');print $message;exit;}$lang['access_permissions'] = 'Access Permissions';/* ----- Titles ----- */$lang['access_access_permissions_title'] = 'Access Permissions';$lang['access_select_group_title'] = 'Select Group';$lang['access_select_resource_title'] = 'Select Resource';$lang['access_select_actions_title'] = 'Select Actions';$lang['select_a_group'] = 'Select a Group';/* ----- Group ----- */$lang['choose_resource'] = 'Choose Resource';$lang['access_group_load_failure'] = 'Failed to load the groups';$lang['choose_actions'] = 'Choose Actions';$lang['access_invalid_group_id'] = 'The Group Id given is either undefined or is not numeric';$lang['access_add_group'] = 'Add';$lang['access_edit_group'] = 'Edit';$lang['access_delete_group'] = 'Delete';$lang['access_group_prompt'] = 'Please enter the Group name:';$lang['access_unable_to_save_group'] = 'Unable to save the group details';$lang['access_group_not_found'] = 'The group specified was not found';// Ajax error messages/* ----- Resource ----- */$lang['access_group_load_failure'] = 'Failed to load access groups';$lang['access_resource_load_failure'] = 'Failed to load the resources';$lang['access_invalid_resource_id'] = 'The Resource Id given is either undefined or is not numeric';$lang['access_confirm_resource_permission_revoke'] = 'You are about to remove permission for the %s group to access the %s resource. This will also remove all permissions to descendant resources. Are you sure you want to continue?';$lang['access_add_resource'] = 'Add';$lang['access_edit_resource'] = 'Edit';$lang['access_delete_resource'] = 'Delete';$lang['access_resource_prompt'] = 'Please enter the Resource name:';$lang['access_unable_to_save_resource'] = 'Unable to save the resource details';$lang['access_invalid_resource_save_parameters'] = 'When saving a resource an Id or Parent Id must be given';$lang['access_resource_not_found'] = 'The resource specified was not found';/* ----- Action ----- */$lang['access_action_load_failure'] = 'Failed to load the actions';$lang['access_all_actions'] = 'All Actions';$lang['access_view_action'] = 'View';$lang['access_add_action'] = 'Add';$lang['access_edit_action'] = 'Edit';$lang['access_delete_action'] = 'Delete';$lang['access_action_prompt'] = 'Please enter the Action name:';$lang['access_unable_to_save_action'] = 'Unable to save the action details';$lang['access_invalid_action_save_parameters'] = 'When saving an action an Id or Resource Id must be given';$lang['access_action_not_found'] = 'The action specified was not found';/* ----- Misc ----- */$lang['access_server_timeout'] = 'The server has timed out, please try again.';$lang['access_invalid_permission'] = "Invalid permission, only 'allow' and 'deny' are valid";$lang['access_unable_to_change_permission'] = 'Unable to save the new permission value for the selected resource/action';$lang['access_unknown_action'] = 'The action `%s` is invalid and is unknown';$lang['access_unknown_section'] = 'The section `%s` is invalid and is unknown';$lang['access_invalid_id'] = 'The id `%s` must be defined and be a number';$lang['access_invalid_value'] = 'The value `%s` must be defined and a string';$lang['access_unable_to_delete_item'] = 'Unable to delete the %s';$lang['access_unable_to_modify_locked_item'] = 'Unable to modify a locked item';$lang['access_confirm_delete'] = 'Are you sure you want to delete this %s?';//* ----- Validation ----- */$lang['access_failed_to_validate'] = 'An error occurred during validation of the data';$lang['access_validation_group_name_required'] = 'The Group name is required';$lang['access_validation_group_name_min_length'] = 'The Group name must be at least %s characters in length';$lang['access_validation_group_name_max_length'] = 'The Group name can not exceed %s characters in length';$lang['access_validation_group_name_unique'] = 'The Group name `%s` already exists. Please enter another name';$lang['access_validation_resource_name_required'] = 'The Resource name is required';$lang['access_validation_resource_name_min_length'] = 'The Resource name must be at least %s characters in length';$lang['access_validation_resource_name_max_length'] = 'The Resource name can not exceed %s characters in length';$lang['access_validation_resource_name_unique'] = 'The Resource name `%s` already exists. Please enter another name';$lang['access_validation_action_name_required'] = 'The Action name is required';$lang['access_validation_action_name_min_length'] = 'The Action name must be at least %s characters in length';$lang['access_validation_action_name_max_length'] = 'The Action name can not exceed %s characters in length';$lang['access_validation_action_name_unique'] = 'The Action name `%s` already exists. Please enter another name';* @param string $resource Resource name* @param string|int $resource_id Resource name or id* @param string $action Action name if given* @param string|int $action_id Action name or id if givenpublic function has_access($group_id, $resource, $action = NULL)public function has_access($group_id, $resource_id, $action_id = null){{log_message('debug', sprintf('Checking if the group %s has access to resource %s%s', $group_id, $resource_id, $action_msg));$this->db->where('permissions.group_id', $group_id);$this->db->where('permissions.group_id', $group_id);$this->db->where('resources.name', $resource);{$this->db->where('resources.id', $resource_id);{$this->db->where('resources.name', $resource_id);if($action != NULL)if ( ! is_null($action_id)){{$this->db->where('actions.name', $action);// Depending on if the action is the name or id adjust the queryif (is_numeric($action_id)){$this->db->where('actions.id', $action_id);}else{$this->db->where('actions.name', $action_id);}if($result === FALSE)if ($result === false){{throw new DatabaseException("Unable to check if the user has permission to the resouce");throw new DatabaseException("Unable to check if the user has permission to the resource");if ($result->num_rows() > 0){{log_message('debug','User does have access to \'' . $resource . ($action != NULL ? '.' . $action : '') . '\'');log_message('debug','Access Allowed');return TRUE;return true;{{log_message('debug','User does not have access to \'' . $resource . ($action != NULL ? '.' . $action : '') . '\'');log_message('debug','Access Denied');return FALSE;return false;{log_message('debug', sprintf('Granting access to resource:action = %s:%s for group %s', $resource_id, $action_id, $group_id));$CI->load->model('resource_model');{$this->db->select("$rt.id");$this->db->where('lft <=', $resource->lft);$this->db->where('rgt >=', $resource->rgt);$this->db->where('group_id', null);{throw new DatabaseException('Could not get all parent resources');{log_message('debug', sprintf('Granting access to %s parent resources', $resources->num_rows()));{$permissions[] = array('group_id' => $group_id, 'resource_id' => $value->id);{throw new DatabaseException('Cannot create resource permissions');log_message('debug', 'Resource access granted');{log_message('debug', 'Granting access to action ' . $action_id);if ($this->db->insert($this->tables['permission_actions'], array('permission_id' => $permission_id, 'action_id' => $action_id)) === false){throw new DatabaseException('Cannot create action permission');log_message('debug', 'Action access granted');{throw new DatabaseException('Unable to get the resource with Id' . $resource_id);log_message('debug', 'Access granted');{$result = $this->db->get_where($this->tables['permissions'], array('group_id' => $group_id, 'resource_id' => $resource_id));{throw new DatabaseException('Unable to get the permission with with (group_id, resource_id) (' . $group_id . ',' . $resource_id . ')');{throw new BackendProException('Expected 1 permission for group/resource, ' . $result->num_rows() . ' found');{log_message('debug', sprintf('Revoking access to resource:action = %s:%s for group %s', $resource_id, $action_id, $group_id));{if ($this->db->delete($this->tables['permission_actions'], array('permission_id' => $permission_id, 'action_id' => $action_id)) === false){throw new DatabaseException('Unable to delete the action permission');{if ($this->db->delete($this->tables['permissions'], array('id' => $permission_id)) === false){throw new DatabaseException('Unable to delete the resource permission');log_message('debug', 'Access revoked');* Get all actions by resource ID* Get an action by resource ID{return parent::get_all_by('resource_id', $resource_id);{{return parent::insert(array('name' => $name, 'resource_id' => $name));return parent::insert(array('name' => $name, 'resource_id' => $resource_id));{{return parent::update($id, array('name' => $name));return parent::update($id, array('name' => $name));{{{throw new BackendProException(lang('access_action_not_found'));{log_message('debug:backendpro', sprintf('Checking if the Action name `%s` is unique', $name));$result = parent::get_by(array('name' => $name));log_message('debug:backendpro', 'Action name is ' . ($result === false ? 'unique' : 'not unique'));{{return parent::update($id, array('name' => $name));return parent::update($id, array('name' => $name));{{{throw new BackendProException(lang('access_group_not_found'));{log_message('debug:backendpro', sprintf('Checking if the Group name `%s` is unique', $name));$result = parent::get_by(array('name' => $name));log_message('debug:backendpro', 'Group name is ' . ($result === false ? 'unique' : 'not unique'));{{parent::CI_Model();parent::__construct();log_message("debug", "Nested Sets Model Loaded");log_message("debug", "Nested Sets Model Loaded");{{if(!is_int($parent_id))if ( ! is_numeric($parent_id)){{show_error("Cannot insert resource, parent_id must be an int");show_error("Cannot insert resource, parent_id must be an int");{{if(!is_int($id))if( ! is_numeric($id)){{show_error("Cannot delete resource, id must be an int");show_error("Cannot delete resource, id must be an int");{{{throw new BackendProException(lang('access_resource_not_found'));{log_message('debug:backendpro', sprintf('Checking if the Resource name `%s` is unique', $name));$result = parent::get_by(array('name' => $name));log_message('debug:backendpro', 'Resource name is ' . ($result === false ? 'unique' : 'not unique'));$(document).ready(function(){$(document).ready(function(){$('#access_container').permission_manager();$('#access_container').permission_manager();.allow {.deny {.selected {<h3>1. <?php print lang('select_a_group');?></h3><h3>1. <?php print lang('access_select_group_title');?></h3><h3>2. <?php print lang('choose_resource');?></h3><h3>2. <?php print lang('access_select_resource_title');?></h3><ul class="treeview permissiontree"></ul><h3>3. <?php print lang('choose_actions');?></h3><h3>3. <?php print lang('access_select_actions_title');?></h3><ul id="group_menu" class="contextMenu groupContextMenu"><li class="add"><a href="#add"><?php print lang('access_add_group');?></a></li><li class="edit"><a href="#edit"><?php print lang('access_edit_group');?></a></li><li class="delete"><a href="#delete"><?php print lang('access_delete_group');?></a></li></ul><ul id="resource_menu" class="contextMenu resourceContextMenu"><li class="add"><a href="#add"><?php print lang('access_add_resource');?></a></li><li class="edit"><a href="#edit"><?php print lang('access_edit_resource');?></a></li><li class="delete"><a href="#delete"><?php print lang('access_delete_resource');?></a></li></ul><ul id="action_menu" class="contextMenu actionContextMenu"><li class="add"><a href="#add"><?php print lang('access_add_action');?></a></li><li class="edit"><a href="#edit"><?php print lang('access_edit_action');?></a></li><li class="delete"><a href="#delete"><?php print lang('access_delete_action');?></a></li></ul>$config['assets']['admin'][] = 'css/backendpro/row-actions.css';$config['assets']['admin'][] = 'js/codeigniter.js';$config['assets']['admin'][] = 'css/backendpro/row-actions.css'; // Used on Users page$config['assets']['admin'][] = 'js/backendpro/access_permissions.js';{{{{{{{{{{{{{{{{preg_match("#\\$(\w+)#", $fLine, $match);{{public function __construct($message, $code = 0, Exception $previous = null, $log = TRUE)public function __construct($message, $code = 0, Exception $previous = null, $log = true){{{{{{parent::__construct($message, $code, $previous, FALSE);parent::__construct($message, $code, $previous, false);//$lang['save'] = 'Save';//$lang['edit'] = 'Edit';//$lang['delete'] = 'Delete';* @param object $setting Setting to retrieve value from{{// Something was submitted, make this the selected item{{$output .= $this->convert_variable($value);$output .= ";\n";if($this->is_assoc($value)){$output .= "new Object();\n";foreach($value as $assoc_key => $assoc_value){// BUG: Make sure name doesn't have any spaces in it or illegal chars$output .= $name . "['" . $assoc_key . "'] = " . $this->convert_variable($assoc_value) . ";\n";}}else{$output .= $this->convert_variable($value) . ";\n";}$output .= "new Array(";$output .= "new Array(";{{$output .= $this->_handle_variable($item);$output .= $this->convert_variable($item);{{{{{log_message('debug','Updating the modified date');log_message('debug:backendpro','Updating the modified date');$data[$this->modified_date_column] = date('Y-m-d H:i:s');$data[$this->modified_date_column] = date('Y-m-d H:i:s');{{{{log_message('debug','Setting the created date');log_message('debug:backendpro','Setting the created date');$data[$this->created_date_column] = date('Y-m-d H:i:s');$data[$this->created_date_column] = date('Y-m-d H:i:s');{{{{var settings = {var settings = {'access_groups' : '#access_groups','access_resources' : '#access_resources','access_actions' : '#access_actions'var access_groups = $(settings.access_groups);var access_groups = $( '#access_groups');var access_resources = $(settings.access_resources);var access_resources = $('#access_resources');var access_actions = $(settings.access_actions);var access_actions = $('#access_actions');perform_ajax_post('load_groups', '', load_groups_onsuccess, 'json');show_loader();perform_ajax_post('access_fetch/load_groups', '', render_groups, 'json');function load_groups_onsuccess(json)/************************************************************************************************************* GROUP ACTIONS & EVENTS***********************************************************************************************************//*** Clear the group panel*/function clear_groups(){{alert('Loaded');clear_resources();// Remove all groups$('ul', access_groups).empty();// Set the selected group to nothingselected_group = null;* Perform an ajax post request to a specific method with* Render all groups to screen* certain data.* @param json JSON list of groups{for (var key in json) {{{var item = $('<li/>').attr('id', 'group_' + key).click(function(e){.contextMenu({ menu: 'group_menu', OnShowMenu: display_contextmenu}, function(action, el){{item.addClass('locked');$('ul', access_groups).append(item);{{selected_group.removeClass('selected');selected_group.addClass('selected');var id = extract_id(group.attr('id'));perform_ajax_post('access_fetch/load_resources',{{data = '&id=' + extract_id(element.attr('id'));prompt_and_validate_change('group', current_value, function (value){function(){reload_permission_manager('group');{generate_resource_structure($('resources', xml), $('ul', access_resources));{$('ul', access_resources).empty();{$('> resource', parentElement).each(function(){var permissionClass = ($(this).attr('has_access') == 'true') ? 'allow' : 'deny';var item = create_resource($(this).attr('id'), $(this).attr('name'), targetList, permissionClass, $(this).attr('locked') == 1);if($('> resource', $(this)).length > 0){var submenu = $('<ul/>');{var item = $('<li><span/></li>');item.find('span').attr('id', 'resource_' + id).click(function(e){.contextMenu({ menu: 'resource_menu', OnShowMenu: display_contextmenu }, function(action,el){{item.find("span").addClass('locked');{{selected_resource.removeClass('selected');selected_resource.addClass('selected');var resource_id = extract_id(resource.attr('id'));var group_id = extract_id(selected_group.attr('id'));perform_ajax_post('access_fetch/load_actions',{{data = '&id=' + extract_id(element.attr('id'));{data = '&parent_id=' + extract_id(element.attr('id'));prompt_and_validate_change('resource', current_value, function (value){function(){reload_permission_manager('resource');{$('ul', access_actions).empty();{var permission_class = (selected_resource.hasClass('allow') ? 'allow' : 'deny');{create_action('all', lang('access_all_actions'), permission_class, true);{create_action('view', lang('access_view_action'), permission_class, true);for (var key in json) {{{var item = $('<li/>').attr('id', 'action_' + id).click(function(e){.contextMenu({ menu: 'action_menu', OnShowMenu: display_contextmenu }, function(action, el){{item.addClass('locked');$('ul', access_actions).append(item);{var action_id = extract_id(action.attr('id'));var resource_id = extract_id(selected_resource.attr('id'));var group_id = extract_id(selected_group.attr('id'));if (action.hasClass('allow')){{var confirm_msg = sprintf(lang('access_confirm_resource_permission_revoke'), selected_group.text(), selected_resource.text());{perform_ajax_post('access_modify/change_permission',function(){action.addClass('deny');action.removeClass('allow');{perform_ajax_post('access_modify/change_permission',function(){action.addClass('deny');action.removeClass('allow');{{perform_ajax_post('access_modify/change_permission',function(){action.addClass('allow');action.removeClass('deny');{{{var main_action = $('li#action_view,li#action_all', access_actions);{.find('>span'); // Move down to the span item{{$('li', access_actions).each(function(){var childList = $('>ul', resource.parent());{$('> li > span', childList).each(function(){{{data = '&id=' + extract_id(element.attr('id'));{data = '&resource_id=' + extract_id(selected_resource.attr('id'));prompt_and_validate_change('action', current_value, function (value){function(){reload_permission_manager('action');{{{alert(sprintf(lang('access_unknown_section'), section));if (confirm(sprintf(lang('access_confirm_delete'), section))){'id=' + extract_id(element.attr('id')) + '§ion=' + section,function(){alert(sprintf(lang('access_unknown_action'), action));{{perform_ajax_post('access_fetch/load_groups', '', render_groups, 'json');alert(sprintf(lang('access_unknown_section'), section));{var value = prompt(lang('access_' + section + '_prompt'), current_value);{function(result){{{{{{return id.substring(id.indexOf("_") + 1);{var items = menu.find('li.edit, li.delete');if(item.hasClass('locked'))items.each(function(){$(this).addClass('disabled');});items.each(function(){$(this).removeClass('disabled');});{{$.ajax({$.ajax({error: function(xhr, textStatus, errorThrown){error: function(xhr, textStatus){alert('Server timeout, please try again');alert(lang('access_server_timeout'));alert('Error: ' + xhr.responseText);{{ // Create tree view html// Create tree view htmlgenerate_resource_structure($('resources', xml), $('ul', access_resources));generate_resource_structure($('resources', xml), $('ul', access_resources));