Changeset 348

User picture

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.

Affected files

Added trunk/application/backendpro_modules/access/config/access.php

Show contents

Updated trunk/application/backendpro_modules/access/controllers/access.php Download diff

347348
26
26
27
        $this->lang->load('access');
27
        $this->lang->load('access');
28
28
29
        // TODO: We need to perform access checks
30
29
        log_message('debug', 'Access Controller Loaded');
31
        log_message('debug', 'Access Controller Loaded');
30
    }
32
    }
31
33
32
    public function index()
34
    public function index()
33
    {
35
    {
34
        $this->template->set_breadcrumb(lang('access_permissions'), 'access');
36
        // Get all language strings and output them to a page variable
35
        $this->template->set_title(lang('access_permissions'));
37
        $this->template->set_variable('ci_language', $this->lang->language); // TODO: This is temp please see ISSUE #11
38
39
        $this->template->set_breadcrumb(lang('access_access_permissions_title'), 'access');
40
        $this->template->set_title(lang('access_access_permissions_title'));
36
        $this->template->build('admin/index');
41
        $this->template->build('admin/index');
37
    }
42
    }
38
39
    public function load_groups()
40
    {
41
        $this->load->model('group_model');
42
43
        try
44
        {
45
            $groups = $this->group_model->get_all();
46
47
            $json_array = array();
48
            foreach($groups as $group)
49
            {
50
                $json_array[$group->id] = array('name' => $group->name, 'locked' => $group->locked);
51
            }
52
53
            print json_encode($json_array);
54
        }
55
        catch(Exception $ex)
56
        {
57
            $this->ajax_error(lang('access_group_load_failure'));
58
        }
59
    }
60
61
    /**
62
     * Output an ajax error
63
     *
64
     * @param string $message Error message
65
     * @param bool $log Whether to log the error
66
     * @return void
67
     */
68
    private function ajax_error($message, $log = TRUE)
69
    {
70
        if($log)
71
        {
72
            log_message('error', $message);
73
        }
74
75
        $this->output->set_status_header('400');
76
        print $message;
77
        exit;
78
    }
79
}
43
}
80
 
44
 
81
/* End of access.php */
45
/* End of access.php */

Added trunk/application/backendpro_modules/access/controllers/access_ajax.php

Show contents

Added trunk/application/backendpro_modules/access/controllers/access_fetch.php

Show contents

Added trunk/application/backendpro_modules/access/controllers/access_modify.php

Show contents

Updated trunk/application/backendpro_modules/access/language/english/access_lang.php Download diff

347348
13
 * @filesource
13
 * @filesource
14
 */
14
 */
15
15
16
$lang['access_permissions'] = 'Access Permissions';
16
/* ----- Titles ----- */
17
$lang['access_access_permissions_title'] = 'Access Permissions';
18
$lang['access_select_group_title'] = 'Select Group';
19
$lang['access_select_resource_title'] = 'Select Resource';
20
$lang['access_select_actions_title'] = 'Select Actions';
17
21
18
$lang['select_a_group'] = 'Select a Group';
22
/* ----- Group ----- */
19
$lang['choose_resource'] = 'Choose Resource';
23
$lang['access_group_load_failure'] = 'Failed to load the groups';
20
$lang['choose_actions'] = 'Choose Actions';
24
$lang['access_invalid_group_id'] = 'The Group Id given is either undefined or is not numeric';
25
$lang['access_add_group'] = 'Add';
26
$lang['access_edit_group'] = 'Edit';
27
$lang['access_delete_group'] = 'Delete';
28
$lang['access_group_prompt'] = 'Please enter the Group name:';
29
$lang['access_unable_to_save_group'] = 'Unable to save the group details';
30
$lang['access_group_not_found'] = 'The group specified was not found';
21
31
22
// Ajax error messages
32
/* ----- Resource ----- */
23
$lang['access_group_load_failure'] = 'Failed to load access groups';
33
$lang['access_resource_load_failure'] = 'Failed to load the resources';
34
$lang['access_invalid_resource_id'] = 'The Resource Id given is either undefined or is not numeric';
35
$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?';
36
$lang['access_add_resource'] = 'Add';
37
$lang['access_edit_resource'] = 'Edit';
38
$lang['access_delete_resource'] = 'Delete';
39
$lang['access_resource_prompt'] = 'Please enter the Resource name:';
40
$lang['access_unable_to_save_resource'] = 'Unable to save the resource details';
41
$lang['access_invalid_resource_save_parameters'] = 'When saving a resource an Id or Parent Id must be given';
42
$lang['access_resource_not_found'] = 'The resource specified was not found';
43
44
/* ----- Action ----- */
45
$lang['access_action_load_failure'] = 'Failed to load the actions';
46
$lang['access_all_actions'] = 'All Actions';
47
$lang['access_view_action'] = 'View';
48
$lang['access_add_action'] = 'Add';
49
$lang['access_edit_action'] = 'Edit';
50
$lang['access_delete_action'] = 'Delete';
51
$lang['access_action_prompt'] = 'Please enter the Action name:';
52
$lang['access_unable_to_save_action'] = 'Unable to save the action details';
53
$lang['access_invalid_action_save_parameters'] = 'When saving an action an Id or Resource Id must be given';
54
$lang['access_action_not_found'] = 'The action specified was not found';
55
56
/* ----- Misc ----- */
57
$lang['access_server_timeout'] = 'The server has timed out, please try again.';
58
$lang['access_invalid_permission'] = "Invalid permission, only 'allow' and 'deny' are valid";
59
$lang['access_unable_to_change_permission'] = 'Unable to save the new permission value for the selected resource/action';
60
$lang['access_unknown_action'] = 'The action `%s` is invalid and is unknown';
61
$lang['access_unknown_section'] = 'The section `%s` is invalid and is unknown';
62
$lang['access_invalid_id'] = 'The id `%s` must be defined and be a number';
63
$lang['access_invalid_value'] = 'The value `%s` must be defined and a string';
64
$lang['access_unable_to_delete_item'] = 'Unable to delete the %s';
65
$lang['access_unable_to_modify_locked_item'] = 'Unable to modify a locked item';
66
$lang['access_confirm_delete'] = 'Are you sure you want to delete this %s?';
67
68
//* ----- Validation ----- */
69
$lang['access_failed_to_validate'] = 'An error occurred during validation of the data';
70
$lang['access_validation_group_name_required'] = 'The Group name is required';
71
$lang['access_validation_group_name_min_length'] = 'The Group name must be at least %s characters in length';
72
$lang['access_validation_group_name_max_length'] = 'The Group name can not exceed %s characters in length';
73
$lang['access_validation_group_name_unique'] = 'The Group name `%s` already exists. Please enter another name';
74
75
$lang['access_validation_resource_name_required'] = 'The Resource name is required';
76
$lang['access_validation_resource_name_min_length'] = 'The Resource name must be at least %s characters in length';
77
$lang['access_validation_resource_name_max_length'] = 'The Resource name can not exceed %s characters in length';
78
$lang['access_validation_resource_name_unique'] = 'The Resource name `%s` already exists. Please enter another name';
79
80
$lang['access_validation_action_name_required'] = 'The Action name is required';
81
$lang['access_validation_action_name_min_length'] = 'The Action name must be at least %s characters in length';
82
$lang['access_validation_action_name_max_length'] = 'The Action name can not exceed %s characters in length';
83
$lang['access_validation_action_name_unique'] = 'The Action name `%s` already exists. Please enter another name';
24
 
84
 
25
/* End of access_lang.php */
85
/* End of access_lang.php */
26
/* Location: ./application/backendpro_modules/access/language/english/access_lang.php */
86
/* Location: ./application/backendpro_modules/access/language/english/access_lang.php */

Updated trunk/application/backendpro_modules/access/models/Access_model.php Download diff

347348
43
     * an action
43
     * an action
44
     *
44
     *
45
     * @param int $group_id Group ID
45
     * @param int $group_id Group ID
46
     * @param string $resource Resource name
46
     * @param string|int $resource_id Resource name or id
47
     * @param string $action Action name if given
47
     * @param string|int $action_id Action name or id if given
48
     * @return bool
48
     * @return bool
49
     */
49
     */
50
    public function has_access($group_id, $resource, $action = NULL)
50
    public function has_access($group_id, $resource_id, $action_id = null)
51
    {
51
    {
52
        // Get the tables
52
        // Get the tables
53
        $permissions = $this->tables['permissions'];
53
        $permissions = $this->tables['permissions'];
...
...
55
        $resources = $this->tables['resources'];
55
        $resources = $this->tables['resources'];
56
        $actions = $this->tables['actions'];
56
        $actions = $this->tables['actions'];
57
57
58
        $action_msg = (is_null($action_id) ? '' : ' and action ' . $action_id);
59
        log_message('debug', sprintf('Checking if the group %s has access to resource %s%s', $group_id, $resource_id, $action_msg));
60
58
        $this->db->from($permissions . ' AS permissions');
61
        $this->db->from($permissions . ' AS permissions');
59
        $this->db->join($resources . ' AS resources', 'resources.id = permissions.resource_id');        
62
        $this->db->join($resources . ' AS resources', 'resources.id = permissions.resource_id');        
60
63
61
        $this->db->where('permissions.group_id', $group_id);
64
        $this->db->where('permissions.group_id', $group_id);
62
        $this->db->where('resources.name', $resource);
63
65
66
        // Depending on if the resource is the name or id adjust the query
67
        if (is_numeric($resource_id))
68
        {
69
            $this->db->where('resources.id', $resource_id);
70
        }
71
        else
72
        {
73
            $this->db->where('resources.name', $resource_id);
74
        }
75
64
        // If we are checking permission on an action add an extra clause
76
        // If we are checking permission on an action add an extra clause
65
        if($action != NULL)
77
        if ( ! is_null($action_id))
66
        {
78
        {
67
            $this->db->join($permission_actions . ' AS permission_actions', 'permission_actions.permission_id = permissions.id', 'LEFT');
79
            $this->db->join($permission_actions . ' AS permission_actions', 'permission_actions.permission_id = permissions.id', 'LEFT');
68
            $this->db->join($actions . ' AS actions', 'actions.id = permission_actions.action_id', 'LEFT');
80
            $this->db->join($actions . ' AS actions', 'actions.id = permission_actions.action_id', 'LEFT');
69
            $this->db->where('actions.name', $action);
81
82
            // Depending on if the action is the name or id adjust the query
83
            if (is_numeric($action_id))
84
            {
85
                $this->db->where('actions.id', $action_id);
86
            }
87
            else
88
            {
89
                $this->db->where('actions.name', $action_id);
90
            }           
70
        }        
91
        }        
71
92
72
        $result = $this->db->get();
93
        $result = $this->db->get();
73
94
        
74
        if($result === FALSE)
95
        if ($result === false)
75
        {
96
        {
76
            throw new DatabaseException("Unable to check if the user has permission to the resouce");
97
            throw new DatabaseException("Unable to check if the user has permission to the resource");
77
        }
98
        }
78
99
79
        if($result->num_rows() > 0)
100
        if ($result->num_rows() > 0)
80
        {
101
        {
81
            // Permission has been found
102
            // Permission has been found
82
            log_message('debug','User does have access to \'' . $resource . ($action != NULL ? '.' . $action : '') . '\'');
103
            log_message('debug','Access Allowed');
83
            return TRUE;
104
            return true;
84
        }
105
        }
85
        else
106
        else
86
        {
107
        {
87
            // Permission not found
108
            // Permission not found
88
            log_message('debug','User does not have access to \'' . $resource . ($action != NULL ? '.' . $action : '') . '\'');   
109
            log_message('debug','Access Denied');
89
            return FALSE;
110
            return false;
90
        }
111
        }
91
    }
112
    }
113
114
    /**
115
     * Grant the group access to a given resource & optional action
116
     *
117
     * @throws DatabaseException
118
     * @param int $group_id Group Id
119
     * @param int $resource_id Resource Id
120
     * @param int|false $action_id Action Id
121
     * @return void
122
     */
123
    public function grant_access($group_id, $resource_id, $action_id = false)
124
    {
125
        log_message('debug', sprintf('Granting access to resource:action = %s:%s for group %s', $resource_id, $action_id, $group_id));
126
        $CI = &get_instance();
127
        $CI->load->model('resource_model');
128
129
        $this->db->trans_start();
130
131
        // Fetch the resource
132
        if (($resource = $CI->resource_model->get($resource_id)) !== false)
133
        {
134
            $rt = $this->tables['resources'];
135
            $pt = $this->tables['permissions'];
136
137
            // Get all parent resources which the user does not have
138
            // access to at the moment
139
            $this->db->select("$rt.id");
140
            $this->db->from($rt);
141
            $this->db->join($pt, "$rt.id = $pt.resource_id AND `$pt`.`group_id` = $group_id", 'left');
142
            $this->db->where('lft <=', $resource->lft);
143
            $this->db->where('rgt >=', $resource->rgt);
144
            $this->db->where('group_id', null);
145
146
            if (($resources = $this->db->get()) === false)
147
            {
148
                throw new DatabaseException('Could not get all parent resources');
149
            }
150
151
            if ($resources->num_rows() > 0)
152
            {
153
                log_message('debug', sprintf('Granting access to %s parent resources', $resources->num_rows()));
154
                // Now update the permission table by granting the group
155
                // access to all the resources
156
                $permissions = array();
157
158
                foreach ($resources->result() as $value)
159
                {
160
                    $permissions[] = array('group_id' => $group_id, 'resource_id' => $value->id);
161
                }
162
163
                if ($this->db->insert_batch($pt, $permissions) === false)
164
                {
165
                    throw new DatabaseException('Cannot create resource permissions');
166
                }
167
                log_message('debug', 'Resource access granted');
168
            }
169
170
            // If an action_id has been given then create a permission for it
171
            if ($action_id !== false)
172
            {
173
                log_message('debug', 'Granting access to action ' . $action_id);
174
                // Get the permission id which matches the group & resource
175
                $permission_id = $this->get_permission_id($group_id, $resource_id);
176
177
                // Insert into the permission_actions table
178
                if ($this->db->insert($this->tables['permission_actions'], array('permission_id' => $permission_id, 'action_id' => $action_id))
=== false)
179
                {
180
                    throw new DatabaseException('Cannot create action permission');
181
                }
182
                log_message('debug', 'Action access granted');
183
            }
184
        }
185
        else
186
        {
187
            throw new DatabaseException('Unable to get the resource with Id' . $resource_id);
188
        }
189
190
        $this->db->trans_complete();
191
        log_message('debug', 'Access granted');
192
    }
193
194
    /**
195
     * Get the permission id for a given group & resource
196
     *
197
     * @throws DatabaseException
198
     * @param int $group_id Group Id
199
     * @param int $resource_id Resource Id
200
     * @return int
201
     */
202
    private function get_permission_id($group_id, $resource_id)
203
    {
204
        $result = $this->db->get_where($this->tables['permissions'], array('group_id' => $group_id, 'resource_id' => $resource_id));
205
206
        if ($result === false)
207
        {
208
            throw new DatabaseException('Unable to get the permission with with (group_id, resource_id) (' . $group_id . ',' . $resource_id . ')');
209
        }
210
211
        if ($result->num_rows() != 1)
212
        {
213
            throw new BackendProException('Expected 1 permission for group/resource, ' . $result->num_rows() . ' found');
214
        }
215
216
        return $result->row()->id;
217
    }
218
219
    /**
220
     * Revoke any permissions a group has to a specific resource and action
221
     *
222
     * @param int $group_id Group Id
223
     * @param int $resource_id Resource Id
224
     * @param int $action_id Action Id
225
     * @return void
226
     */
227
    public function revoke_access($group_id, $resource_id, $action_id = null)
228
    {
229
        log_message('debug', sprintf('Revoking access to resource:action = %s:%s for group %s', $resource_id, $action_id, $group_id));
230
        
231
        // Get the matching permission id
232
        $permission_id = $this->get_permission_id($group_id, $resource_id);
233
        
234
        if ( ! is_null($action_id) && $action_id !== false)
235
        {
236
            // We must only revoke access to the action not the resource
237
            if ($this->db->delete($this->tables['permission_actions'], array('permission_id' => $permission_id, 'action_id' => $action_id)) ===
false)
238
            {
239
                throw new DatabaseException('Unable to delete the action permission');
240
            }
241
        }
242
        else
243
        {
244
            // Delete the resource permission
245
            if ($this->db->delete($this->tables['permissions'], array('id' => $permission_id)) === false)
246
            {
247
                throw new DatabaseException('Unable to delete the resource permission');
248
            }
249
        }
250
        log_message('debug', 'Access revoked');
251
    }
92
}
252
}
93
253
94
/* End of Access_model.php */
254
/* End of Access_model.php */

Updated trunk/application/backendpro_modules/access/models/Action_model.php Download diff

347348
34
    }
34
    }
35
35
36
    /**
36
    /**
37
     * Get all actions by resource ID
37
     * Get an action by resource ID
38
     *
38
     *
39
     * @param int $resource_id Resource ID
39
     * @param int $resource_id Resource ID
40
     * @return object
40
     * @return object
...
...
45
    }
45
    }
46
46
47
    /**
47
    /**
48
     * Get all actions with a given resource Id
49
     *
50
     * @param int $resource_id Resource Id
51
     * @return objects
52
     */
53
    public function get_all_by_resource($resource_id)
54
    {
55
        return parent::get_all_by('resource_id', $resource_id);
56
    }
57
58
    /**
48
     * Insert action
59
     * Insert action
49
     *
60
     *
50
     * @param string $name Action name
61
     * @param string $name Action name
...
...
53
     */
64
     */
54
    public function insert($name, $resource_id)
65
    public function insert($name, $resource_id)
55
    {
66
    {
56
        return parent::insert(array('name' => $name, 'resource_id' => $name));
67
        return parent::insert(array('name' => $name, 'resource_id' => $resource_id));
57
    }
68
    }
58
69
59
    /**
70
    /**
...
...
67
    {
78
    {
68
        return parent::update($id, array('name' => $name));
79
        return parent::update($id, array('name' => $name));
69
    }
80
    }
81
82
    /**
83
     * Check to see if an action is locked or not
84
     *
85
     * @throws BackendProException
86
     * @param int $id Action Id
87
     * @return bool
88
     */
89
    public function is_locked($id)
90
    {
91
        $action = $this->get($id);
92
93
        if ( ! is_null($action))
94
        {
95
            return $action->locked == 1;
96
        }
97
        else
98
        {
99
            throw new BackendProException(lang('access_action_not_found'));
100
        }
101
    }
102
103
    /**
104
     * Check if a action name is unique
105
     *
106
     * @param string $name The name to check
107
     * @return bool
108
     */
109
    public function is_unique($name)
110
    {
111
        log_message('debug:backendpro', sprintf('Checking if the Action name `%s` is unique', $name));
112
        $result = parent::get_by(array('name' => $name));
113
114
        log_message('debug:backendpro', 'Action name is ' . ($result === false ? 'unique' : 'not unique'));
115
        return $result === false;
116
    }
70
}
117
}
71
118
72
 /* End of Action_model.php */
119
 /* End of Action_model.php */

Updated trunk/application/backendpro_modules/access/models/Group_model.php Download diff

347348
55
    {
55
    {
56
        return parent::update($id, array('name' => $name));
56
        return parent::update($id, array('name' => $name));
57
    }
57
    }
58
59
    /**
60
     * Check to see if a group is locked or not
61
     *
62
     * @throws BackendProException
63
     * @param int $id Group Id
64
     * @return bool
65
     */
66
    public function is_locked($id)
67
    {
68
        $group = $this->get($id);
69
70
        if ( $group !== false)
71
        {
72
            return $group->locked == 1;
73
        }
74
        else
75
        {
76
            throw new BackendProException(lang('access_group_not_found'));
77
        }
78
    }
79
80
    /**
81
     * Check if a group name is unique
82
     *
83
     * @param string $name The name to check
84
     * @return bool
85
     */
86
    public function is_unique($name)
87
    {
88
        log_message('debug:backendpro', sprintf('Checking if the Group name `%s` is unique', $name));
89
        $result = parent::get_by(array('name' => $name));
90
91
        log_message('debug:backendpro', 'Group name is ' . ($result === false ? 'unique' : 'not unique'));
92
        return $result === false;
93
    }
58
}
94
}
59
95
60
 /* End of Group_model.php */
96
 /* End of Group_model.php */

Updated trunk/application/backendpro_modules/access/models/Nested_sets_model.php Download diff

347348
35
	function Nested_sets_model()
35
	function Nested_sets_model()
36
	{
36
	{
37
        // Call the parent constructor
37
        // Call the parent constructor
38
		parent::CI_Model();
38
		parent::__construct();
39
39
40
		log_message("debug", "Nested Sets Model Loaded");
40
		log_message("debug", "Nested Sets Model Loaded");
41
    }
41
    }

Updated trunk/application/backendpro_modules/access/models/Resource_model.php Download diff

347348
42
     */
42
     */
43
    public function insert($name, $parent_id)
43
    public function insert($name, $parent_id)
44
    {
44
    {
45
        if(!is_int($parent_id))
45
        if ( ! is_numeric($parent_id))
46
        {
46
        {
47
            show_error("Cannot insert resource, parent_id must be an int");
47
            show_error("Cannot insert resource, parent_id must be an int");
48
        }
48
        }
...
...
80
     */
80
     */
81
    public function delete($id)
81
    public function delete($id)
82
    {
82
    {
83
        if(!is_int($id))
83
        if( ! is_numeric($id))
84
        {
84
        {
85
            show_error("Cannot delete resource, id must be an int");
85
            show_error("Cannot delete resource, id must be an int");
86
        }
86
        }
...
...
95
95
96
        $this->nested_sets_model->deleteNode($node);
96
        $this->nested_sets_model->deleteNode($node);
97
    }
97
    }
98
99
    /**
100
     * Check to see if a resource is locked or not
101
     *
102
     * @throws BackendProException
103
     * @param int $id Resource Id
104
     * @return bool
105
     */
106
    public function is_locked($id)
107
    {
108
        $resource = $this->get($id);
109
110
        if ( ! is_null($resource))
111
        {
112
            return $resource->locked == 1;
113
        }
114
        else
115
        {
116
            throw new BackendProException(lang('access_resource_not_found'));
117
        }
118
    }
119
120
    /**
121
     * Check if a resource name is unique
122
     *
123
     * @param string $name The name to check
124
     * @return bool
125
     */
126
    public function is_unique($name)
127
    {
128
        log_message('debug:backendpro', sprintf('Checking if the Resource name `%s` is unique', $name));
129
        $result = parent::get_by(array('name' => $name));
130
131
        log_message('debug:backendpro', 'Resource name is ' . ($result === false ? 'unique' : 'not unique'));
132
        return $result === false;
133
    }
98
}
134
}
99
135
100
 /* End of Resource_model.php */
136
 /* End of Resource_model.php */

Updated trunk/application/backendpro_modules/access/views/admin/index.php Download diff

347348
2
2
3
<script type="text/javascript">
3
<script type="text/javascript">
4
    $(document).ready(function(){
4
    $(document).ready(function(){
5
        // Setup the permission Manager and bind it to the controls on the page
5
        $('#access_container').permission_manager();
6
        $('#access_container').permission_manager();
6
    });
7
    });
7
</script>
8
</script>
8
9
10
<style type="text/css">
11
    .allow {
12
        color: green;
13
    }
14
15
    .deny {
16
        color: red;
17
    }
18
19
    .selected {
20
        font-weight: bold;
21
    }
22
</style>
23
9
<table cellpadding="0" cellspacing="0" id="access_container">
24
<table cellpadding="0" cellspacing="0" id="access_container">
10
    <tr>
25
    <tr>
11
        <td width="25%">
26
        <td width="25%">
12
            <div id="access_groups">
27
            <div id="access_groups">
13
                <h3>1. <?php print lang('select_a_group');?></h3>
28
                <h3>1. <?php print lang('access_select_group_title');?></h3>
14
                <ul></ul>
29
                <ul></ul>
15
            </div>
30
            </div>
16
        </td>
31
        </td>
17
32
18
        <td>
33
        <td>
19
            <div id="access_resources">
34
            <div id="access_resources">
20
                <h3>2. <?php print lang('choose_resource');?></h3>
35
                <h3>2. <?php print lang('access_select_resource_title');?></h3>
21
                <ul class="treeview permissiontree"></ul>
36
                <ul></ul>
22
            </div>
37
            </div>
23
        </td>
38
        </td>
24
39
25
        <td width="25%">
40
        <td width="25%">
26
            <div id="access_actions">
41
            <div id="access_actions">
27
                <h3>3. <?php print lang('choose_actions');?></h3>
42
                <h3>3. <?php print lang('access_select_actions_title');?></h3>
28
                <ul></ul>
43
                <ul></ul>
29
            </div>
44
            </div>
30
        </td>
45
        </td>
31
    </tr>
46
    </tr>
32
</table>
47
</table>
48
49
<ul id="group_menu" class="contextMenu groupContextMenu">
50
    <li class="add"><a href="#add"><?php print lang('access_add_group');?></a></li>
51
    <li class="edit"><a href="#edit"><?php print lang('access_edit_group');?></a></li>
52
    <li class="delete"><a href="#delete"><?php print lang('access_delete_group');?></a></li>
53
</ul>
54
55
<ul id="resource_menu" class="contextMenu resourceContextMenu">
56
    <li class="add"><a href="#add"><?php print lang('access_add_resource');?></a></li>
57
    <li class="edit"><a href="#edit"><?php print lang('access_edit_resource');?></a></li>
58
    <li class="delete"><a href="#delete"><?php print lang('access_delete_resource');?></a></li>
59
</ul>
60
61
<ul id="action_menu" class="contextMenu actionContextMenu">
62
    <li class="add"><a href="#add"><?php print lang('access_add_action');?></a></li>
63
    <li class="edit"><a href="#edit"><?php print lang('access_edit_action');?></a></li>
64
    <li class="delete"><a href="#delete"><?php print lang('access_delete_action');?></a></li>
65
</ul>

Updated trunk/application/backendpro_modules/core/config/backendpro_assets.php Download diff

347348
24
$config['assets']['public'][] = 'css/backendpro/jquery-ui.css';
24
$config['assets']['public'][] = 'css/backendpro/jquery-ui.css';
25
25
26
$config['assets']['admin'] = $config['assets']['public'];
26
$config['assets']['admin'] = $config['assets']['public'];
27
$config['assets']['admin'][] = 'css/backendpro/row-actions.css';
28
27
29
$config['assets']['admin'][] = 'js/codeigniter.js';
28
$config['assets']['admin'][] = 'css/backendpro/row-actions.css';            // Used on Users page
30
$config['assets']['admin'][] = 'js/backendpro/access_permissions.js';
31
29
30
$config['assets']['admin'][] = 'js/codeigniter.js';                         // User throughout the admin area
32
31
32
$config['assets']['admin'][] = 'js/sprintf-0.7-beta1.js';                   // Used on the access page
33
$config['assets']['admin'][] = 'css/backendpro/jquery.contextMenu.css';     // Used on the access page
34
$config['assets']['admin'][] = 'js/jquery.contextMenu.js';                  // Used on the access page
35
$config['assets']['admin'][] = 'js/backendpro/access_permissions.js';       // Used on the access page
36
33
/* End of backendpro_assets.php */
37
/* End of backendpro_assets.php */
34
/* Location: ./application/backendpro_modules/core/config/backendpro_assets.php */
38
/* Location: ./application/backendpro_modules/core/config/backendpro_assets.php */

Updated trunk/application/backendpro_modules/core/controllers/Site_controller.php Download diff

347348
13
 * @filesource
13
 * @filesource
14
 */
14
 */
15
15
16
class Guard
17
{
18
    /**
19
     * Check that the value provided is not null
20
     *
21
     * @static
22
     * @throws Exception
23
     * @param object $value Value to check
24
     * @return void
25
     */
26
    public static function null($value)
27
    {
28
        if ( is_null($value))
29
        {
30
            throw new Exception(Guard::var_name($value) . ' must not be null');
31
        }
32
    }
33
34
    /**
35
     * Check that the value given is numeric
36
     *
37
     * @static
38
     * @throws Exception
39
     * @param object $value Value to check
40
     * @return void
41
     */
42
    public static function numeric($value)
43
    {
44
        if ( ! is_numeric($value))
45
        {
46
            throw new Exception(Guard::var_name($value) . ' must be numeric');
47
        }
48
    }
49
50
    /**
51
     * Check that the value given is a string
52
     *
53
     * @static
54
     * @throws Exception
55
     * @param object $value Value to check
56
     * @return void
57
     */
58
    public static function string($value)
59
    {
60
        if ( ! is_string($value))
61
        {
62
            throw new Exception(Guard::var_name($value) . ' must be a string');
63
        }
64
    }
65
66
    /**
67
     * Check that the value given is a float
68
     *
69
     * @static
70
     * @throws Exception
71
     * @param object $value Value to check
72
     * @return void
73
     */
74
    public static function float($value)
75
    {
76
        if ( ! is_float($value))
77
        {
78
            throw new Exception(Guard::var_name($value) . ' must be a float');
79
        }
80
    }
81
82
    /**
83
     * Check that the value given is an object
84
     *
85
     * @static
86
     * @throws Exception
87
     * @param object $value Value to check
88
     * @return void
89
     */
90
    public static function object($value)
91
    {
92
        if ( ! is_object($value))
93
        {
94
            throw new Exception(Guard::var_name($value) . ' must be an object');
95
        }
96
    }
97
98
    /**
99
     * Check that the value given is a bool
100
     *
101
     * @static
102
     * @throws Exception
103
     * @param object $value Value to check
104
     * @return void
105
     */
106
    public static function bool($value)
107
    {
108
        if ( ! is_bool($value))
109
        {
110
            throw new Exception(Guard::var_name($value) . ' must be a bool');
111
        }
112
    }
113
114
    /**
115
     * Check that the value given is an int
116
     *
117
     * @static
118
     * @throws Exception
119
     * @param object $value Value to check
120
     * @return void
121
     */
122
    public static function int($value)
123
    {
124
        if ( ! is_int($value))
125
        {
126
            throw new Exception(Guard::var_name($value) . ' must be an int');
127
        }
128
    }
129
130
    /**
131
     * Get the name of the variable passed in
132
     * 
133
     * @static
134
     * @param object $v Variable to get fetch name of
135
     * @return string
136
     */
137
    private static function var_name($v)
138
    {
139
        $trace = debug_backtrace();
140
        $vLine = file($trace[1]['file']);
141
        $fLine = $vLine[$trace[1]['line'] - 1];
142
        preg_match("#\\$(\w+)#", $fLine, $match);
143
144
        return (isset($match[0]) ? $match[0] : 'Value');
145
    }
146
}
147
16
/**
148
/**
17
 * BackendPro Site Controller. Sets up the BackendPro system and loads
149
 * BackendPro Site Controller. Sets up the BackendPro system and loads
18
 * any required files.
150
 * any required files.

Updated trunk/application/backendpro_modules/core/exceptions/BackendProException.php Download diff

347348
21
 */
21
 */
22
class BackendProException extends Exception
22
class BackendProException extends Exception
23
{
23
{
24
    public function __construct($message, $code = 0, Exception $previous = null, $log = TRUE)
24
    public function __construct($message, $code = 0, Exception $previous = null, $log = true)
25
    {
25
    {
26
        parent::__construct($message, $code, $previous);
26
        parent::__construct($message, $code, $previous);
27
27

Updated trunk/application/backendpro_modules/core/exceptions/DatabaseException.php Download diff

347348
23
{
23
{
24
    public function __construct($message, $code = 0, Exception $previous = null)
24
    public function __construct($message, $code = 0, Exception $previous = null)
25
    {
25
    {
26
        parent::__construct($message, $code, $previous, FALSE);
26
        parent::__construct($message, $code, $previous, false);
27
27
28
        // Get the error message thrown by the database and log
28
        // Get the error message thrown by the database and log
29
        $CI = &get_instance();
29
        $CI = &get_instance();

Updated trunk/application/backendpro_modules/core/language/english/backendpro_lang.php Download diff

347348
18
$lang['logged_in_as'] = 'Logged in as';
18
$lang['logged_in_as'] = 'Logged in as';
19
$lang['logout'] = 'Logout';
19
$lang['logout'] = 'Logout';
20
20
21
$lang['save'] = 'Save';
21
//$lang['save'] = 'Save';
22
$lang['edit'] = 'Edit';
22
//$lang['edit'] = 'Edit';
23
$lang['delete'] = 'Delete';
23
//$lang['delete'] = 'Delete';
24
24
25
/* End of backendpro_lang.php */
25
/* End of backendpro_lang.php */
26
/* Location: ./application/backendpro_modules/core/language/english/backendpro_lang.php */
26
/* Location: ./application/backendpro_modules/core/language/english/backendpro_lang.php */

Updated trunk/application/backendpro_modules/settings/libraries/Setting_controls.php Download diff

347348
104
    /**
104
    /**
105
     * Get a multi-select value and convert into a flat string
105
     * Get a multi-select value and convert into a flat string
106
     *
106
     *
107
     * @param object $setting Setting to retrive value from
107
     * @param object $setting Setting to retrieve value from
108
     * @return string
108
     * @return string
109
     */
109
     */
110
    private function get_multiselect_value($setting)
110
    private function get_multiselect_value($setting)
...
...
174
174
175
            if($CI->input->post($setting->slug) !== FALSE)
175
            if($CI->input->post($setting->slug) !== FALSE)
176
            {
176
            {
177
                // Something was submited, make this the selected item
177
                // Something was submitted, make this the selected item
178
                $selected = $CI->input->post($setting->slug);
178
                $selected = $CI->input->post($setting->slug);
179
            }
179
            }
180
            else
180
            else

Updated trunk/application/backendpro_modules/template/libraries/Template.php Download diff

347348
266
            $output = "<script type=\"text/javascript\">\n<!--\n";
266
            $output = "<script type=\"text/javascript\">\n<!--\n";
267
            foreach($this->variables as $name => $value)
267
            foreach($this->variables as $name => $value)
268
            {
268
            {
269
                // BUG: Make sure the name dosn't have spaces or illegal chars
269
                $output .= "var " . $name . " = ";
270
                $output .= "var " . $name . " = ";
270
                $output .= $this->convert_variable($value);
271
271
                $output .= ";\n";
272
                if($this->is_assoc($value))
273
                {
274
                    $output .= "new Object();\n";
275
276
                    foreach($value as $assoc_key => $assoc_value)
277
                    {
278
                        // BUG: Make sure name doesn't have any spaces in it or illegal chars
279
                        $output .= $name . "['" . $assoc_key . "'] = " . $this->convert_variable($assoc_value) . ";\n";
280
                    }
281
                }
282
                else
283
                {
284
                    $output .= $this->convert_variable($value) . ";\n";
285
                }
272
            }
286
            }
273
            $output .= "// -->\n</script>\n";
287
            $output .= "// -->\n</script>\n";
274
288
...
...
307
                $output .= "new Array(";
321
                $output .= "new Array(";
308
                foreach($value as $item)
322
                foreach($value as $item)
309
                {
323
                {
310
                    $output .= $this->_handle_variable($item);
324
                    $output .= $this->convert_variable($item);
311
                    $output .= ",";
325
                    $output .= ",";
312
                }
326
                }
313
                $output = substr($output,0,-1);
327
                $output = substr($output,0,-1);
...
...
323
        return $output;
337
        return $output;
324
    }
338
    }
325
339
340
    function is_assoc($array)
341
    {
342
        return (is_array($array) && (0 !== count(array_diff_key($array, array_keys(array_keys($array)))) || count($array)==0));
343
    }
344
326
    /**
345
    /**
327
     * Set a breadcrumb link
346
     * Set a breadcrumb link
328
     *
347
     *

Updated trunk/application/core/MY_Model.php Download diff

347348
170
    {
170
    {
171
        if($this->set_modified_date)
171
        if($this->set_modified_date)
172
        {
172
        {
173
            log_message('debug','Updating the modified date');
173
            log_message('debug:backendpro','Updating the modified date');
174
            $data[$this->modified_date_column] = date('Y-m-d H:i:s');
174
            $data[$this->modified_date_column] = date('Y-m-d H:i:s');
175
        }
175
        }
176
        
176
        
...
...
196
    {
196
    {
197
        if($this->set_created_date)
197
        if($this->set_created_date)
198
        {
198
        {
199
            log_message('debug','Setting the created date');
199
            log_message('debug:backendpro','Setting the created date');
200
            $data[$this->created_date_column] = date('Y-m-d H:i:s');
200
            $data[$this->created_date_column] = date('Y-m-d H:i:s');
201
        }
201
        }
202
202

Added trunk/application/libraries/MY_Log.php

Show contents

Added trunk/assets/css/reset.css

Show contents

Updated trunk/assets/js/backendpro/access_permissions.js Download diff

347348
17
    {
17
    {
18
        return this.each(function()
18
        return this.each(function()
19
        {
19
        {
20
            var container = $(this);
21
20
            var settings = {
22
            var settings = {
21
                'access_groups' : '#access_groups',
22
                'access_resources' : '#access_resources',
23
                'access_actions' : '#access_actions'
24
            };
23
            };
25
24
26
            // If options exist, lets merge them
25
            // If options exist, lets merge them
...
...
31
            }
30
            }
32
31
33
            // Declare some variables which will help us
32
            // Declare some variables which will help us
34
            var access_groups = $(settings.access_groups);
33
            var access_groups = $( '#access_groups');
35
            var access_resources = $(settings.access_resources);
34
            var access_resources = $('#access_resources');
36
            var access_actions = $(settings.access_actions);
35
            var access_actions = $('#access_actions');
37
36
38
            // This is the currently selected group the user has clicked on
37
            // This is the currently selected group the user has clicked on
39
            var selected_group = null;
38
            var selected_group = null;
40
39
41
            // This is the currently selected resource the user has clicked on
40
            // This is the currently selected resource the user has clicked on
42
            var selected_resource = null;
41
            var selected_resource = null;
43
42
            
44
            // Load the initial groups
43
            // Load the initial groups
45
            perform_ajax_post('load_groups', '', load_groups_onsuccess, 'json');
44
            show_loader();
45
            perform_ajax_post('access_fetch/load_groups', '', render_groups, 'json');
46
46
47
            function load_groups_onsuccess(json)
47
            /***********************************************************************************************************
48
             *
49
             *  GROUP ACTIONS & EVENTS
50
             *
51
             **********************************************************************************************************/
52
53
            /**
54
             * Clear the group panel
55
             */
56
            function clear_groups()
48
            {
57
            {
49
                alert('Loaded');
58
                clear_resources();
59
60
                // Remove all groups
61
                $('ul', access_groups).empty();
62
63
                // Set the selected group to nothing
64
                selected_group = null;
50
            }
65
            }
51
66
52
            /**
67
            /**
53
             * Perform an ajax post request to a specific method with
68
             * Render all groups to screen
54
             * certain data.
69
             *
70
             * @param json JSON list of groups
55
             */
71
             */
72
            function render_groups(json)
73
            {
74
                clear_groups();
75
76
                // The groups are returned in the format
77
                for (var key in json) {
78
                    if (json.hasOwnProperty(key))
79
                    {
80
                        create_group(json[key]['id'], json[key]['name'], json[key]['locked'] == 1);
81
                    }
82
                }
83
84
                // Hide the loading screen
85
                hide_loader();
86
            }
87
            
88
            /**
89
             * Create a group
90
             *
91
             * @param key Group Key
92
             * @param name Group name
93
             * @param locked Whether the group is locked
94
             */
95
            function create_group(key, name, locked)
96
            {
97
                // Create a new group item with context menu
98
                var item = $('<li/>')
99
                    .attr('id', 'group_' + key)
100
                    .text(name)
101
                    .click(function(e){
102
                        switch_to_group($(e.target));
103
                    })
104
                    .contextMenu({ menu: 'group_menu', OnShowMenu: display_contextmenu}, function(action, el){
105
                        handle_contextmenu_action(action, el, 'group');
106
                });
107
108
                if(locked)
109
                {
110
                    // If its locked apply locked style
111
                    item.addClass('locked');
112
                }
113
114
                // Add to group list
115
                $('ul', access_groups).append(item);
116
117
                return item;
118
            }
119
120
            /**
121
             * Switch the manager so its focused on a new group
122
             *
123
             * @param group
124
             */
125
            function switch_to_group(group)
126
            {
127
                show_loader();
128
129
                if(selected_group != null)
130
                {
131
                    // Remove the selected style from the previously selected group
132
                    selected_group.removeClass('selected');
133
                }
134
                
135
                // Save the selected group to the GLOBAL var
136
                selected_group = group;
137
138
                // Highlight it as selected
139
                selected_group.addClass('selected');
140
141
                // Clear the current resources
142
                clear_resources();
143
144
                var id = extract_id(group.attr('id'));
145
146
                // Fetch the new resources using Ajax
147
                perform_ajax_post('access_fetch/load_resources',
148
                        'group=' + id,
149
                        render_resources,
150
                        'xml');
151
            }
152
153
            /**
154
             * Prompt the user for the change they want to make, validate it
155
             * and if valid save back and update the UI
156
             * 
157
             * @param action The action being carried out, either add/edit
158
             * @param element The element which was clicked
159
             */
160
            function save_group(action, element)
161
            {
162
                var data = '';
163
                var current_value = null;
164
                
165
                if(action == 'edit')
166
                {
167
                    current_value = element.text();
168
                    data = '&id=' + extract_id(element.attr('id'));
169
                }
170
171
                prompt_and_validate_change('group', current_value, function (value){
172
                    // The new value is valid save changes to the DB
173
                    perform_ajax_post(
174
                        'access_modify/save_group',
175
                        'value=' + value + data,
176
                        function(){
177
                            reload_permission_manager('group');
178
                        },
179
                        null);
180
                });
181
            }
182
            
183
            /***********************************************************************************************************
184
             *
185
             *  RESOURCE ACTIONS & EVENTS
186
             *
187
             **********************************************************************************************************/
188
189
            /**
190
             * Render all resources to screen based on the Xml
191
             * returned by ajax
192
             * 
193
             * @param xml
194
             */
195
            function render_resources(xml)
196
            {
197
                // Create tree view html
198
                generate_resource_structure($('resources', xml), $('ul', access_resources));
199
200
                // Turn the nested lists into a tree view
201
                //reset_resource_tree(); // TODO: Implemented the nested tree view for resources
202
203
                hide_loader();
204
            }
205
206
            /**
207
             * Clear the resource panel
208
             */
209
            function clear_resources()
210
            {
211
                clear_actions();
212
213
                // Remove all resources
214
                $('ul', access_resources).empty();
215
216
                // Set the selected resource to nothing
217
                selected_resource = null;
218
            }
219
220
            /**
221
             * Generate Resource UL Structure
222
             *
223
             * Create all resource LI's. Bind events for on click
224
             * so the actions are loaded, also add a context menu
225
             * to each resource.
226
             */
227
            function generate_resource_structure(parentElement, targetList)
228
            {
229
                // Get all child resource elements
230
                $('> resource', parentElement).each(function()
231
                {
232
                    // Determine what permission the resource is in
233
                    var permissionClass = ($(this).attr('has_access') == 'true') ? 'allow' : 'deny';
234
235
                    // Determine if the resource is locked
236
                    var item = create_resource($(this).attr('id'), $(this).attr('name'), targetList, permissionClass, $(this).attr('locked') == 1);
237
238
                    // Does this resource have children
239
                    if($('> resource', $(this)).length > 0)
240
                    {
241
                        // Create a target for the sub items
242
                        var submenu = $('<ul/>');
243
244
                        // Generate child resource structure
245
                        generate_resource_structure($(this), submenu);
246
247
                        submenu.appendTo(item);
248
                    }
249
                });
250
            }
251
252
            /**
253
             * Create a resource element
254
             *
255
             * @param id Resource Id
256
             * @param name Resource name
257
             * @param parent Parent resource element
258
             * @param permission_class Permission class to apply to the element, either allow or deny
259
             * @param locked Whether the resource is locked
260
             */
261
            function create_resource(id, name, parent, permission_class, locked)
262
            {
263
                // Create a new resource item with context menu
264
                var item = $('<li><span/></li>');
265
266
                item.find('span')
267
                    .attr('id', 'resource_' + id)
268
                    .text(name)
269
                    .addClass(permission_class)
270
                    .click(function(e){
271
                        switch_to_resource($(e.target));
272
                    })
273
                    .contextMenu({ menu: 'resource_menu', OnShowMenu: display_contextmenu }, function(action,el){
274
                        handle_contextmenu_action(action, el, 'resource');
275
                });
276
277
                if(locked)
278
                {
279
                    // If its locked apply locked style
280
                    item.find("span").addClass('locked');
281
                }
282
283
                // Add resource to parent list
284
                item.appendTo(parent);
285
286
                return item;
287
            }
288
289
            /**
290
             * Switch the manager so its focused on a new resource
291
             * 
292
             * @param resource
293
             */
294
            function switch_to_resource(resource)
295
            {
296
                show_loader();
297
                
298
                if(selected_resource != null)
299
                {
300
                    // Remove the selected style from the current resource
301
                    selected_resource.removeClass('selected');
302
                }
303
304
                // Save the selected resource to the GLOBAL var
305
                selected_resource = resource;
306
307
                // Highlight it as selected
308
                selected_resource.addClass('selected');
309
310
                // Clear the current actions
311
                clear_actions();
312
313
                var resource_id = extract_id(resource.attr('id'));
314
                var group_id = extract_id(selected_group.attr('id'));
315
316
                // Fetch the actions using Ajax
317
                perform_ajax_post('access_fetch/load_actions',
318
                        'resource_id=' + resource_id + '&group_id=' + group_id,
319
                        render_actions,
320
                        'json');
321
            }
322
323
            /**
324
             * Prompt the user for the change they want to make, validate it
325
             * and if valid save back and update the UI
326
             *
327
             * @param action The action being carried out, either add/edit
328
             * @param element The element which was clicked
329
             */
330
            function save_resource(action, element)
331
            {
332
                var data = '';
333
                var current_value = null;
334
335
                if(action == 'edit')
336
                {
337
                    current_value = element.text();
338
                    data = '&id=' + extract_id(element.attr('id'));
339
                }
340
                else
341
                {
342
                    data = '&parent_id=' + extract_id(element.attr('id'));
343
                }
344
345
                prompt_and_validate_change('resource', current_value, function (value){
346
                    // The new value is valid save changes to the DB
347
                    perform_ajax_post(
348
                        'access_modify/save_resource',
349
                        'value=' + value + data,
350
                        function(){
351
                            reload_permission_manager('resource');
352
                        },
353
                        null);
354
                });
355
            }
356
357
            /***********************************************************************************************************
358
             *
359
             *  ACTION ACTIONS & EVENTS
360
             *
361
             **********************************************************************************************************/
362
363
            /**
364
             * Clear the actions panel
365
             */
366
            function clear_actions()
367
            {
368
                // Remove all actions
369
                $('ul', access_actions).empty();
370
            }
371
372
            /**
373
             * Render all actions contained in the JSON result
374
             * 
375
             * @param json
376
             */
377
            function render_actions(json)
378
            {
379
                var permission_class = (selected_resource.hasClass('allow') ? 'allow' : 'deny');
380
381
                if(json.length == 0)
382
                {
383
                    // Display an All Actions permission
384
                    create_action('all', lang('access_all_actions'), permission_class, true);
385
                }
386
                else
387
                {
388
                    // Display a view permission action & all custom actions
389
                    create_action('view', lang('access_view_action'), permission_class, true);
390
391
                    for (var key in json) {
392
                        if (json.hasOwnProperty(key))
393
                        {
394
                            permission_class = (json[key]['has_access']) ? 'allow' : 'deny';
395
396
                            create_action(json[key]['id'], json[key]['name'], permission_class, json[key]['locked'] == '1');
397
                        }
398
                    }
399
                }
400
401
                hide_loader();
402
            }
403
404
            /**
405
             * Create an action element inside the actions list
406
             *
407
             * @param id Action ID
408
             * @param name Action display name
409
             * @param permission_class The permission class to apply to the action, either allow or deny
410
             * @param locked Whether the action should be locked to modification
411
             */
412
            function create_action(id, name, permission_class, locked)
413
            {
414
                // Create an action item with context menu
415
                var item = $('<li/>')
416
                    .attr('id', 'action_' + id)
417
                    .text(name)
418
                    .addClass(permission_class)
419
                    .click(function(e){
420
                        change_action_permission($(e.target));
421
                    })
422
                    .contextMenu({ menu: 'action_menu', OnShowMenu: display_contextmenu }, function(action, el){
423
                        handle_contextmenu_action(action, el, 'action');
424
                });
425
426
                if(locked)
427
                {
428
                    // If its locked apply locked style
429
                    item.addClass('locked');
430
                }
431
432
                // Add action to action list
433
                $('ul', access_actions).append(item);
434
435
                return item;
436
            }
437
438
            /**
439
             * Change the current access level for the selected action
440
             * If they are allowed access then deny them access
441
             * If they are denied then grant them access
442
             *
443
             * If the action requires to be propagated up to parent
444
             * resources then do so
445
             *
446
             * @param action
447
             */
448
            function change_action_permission(action)
449
            {
450
                var action_id = extract_id(action.attr('id'));
451
                var resource_id = extract_id(selected_resource.attr('id'));
452
                var group_id = extract_id(selected_group.attr('id'));
453
454
                if (action.hasClass('allow'))
455
                {
456
                    // Switch to Deny
457
                    if (action_id == 'all' || action_id == 'view')
458
                    {
459
                        // Since we are removing all permissions for this resource prompt the user
460
                        var confirm_msg = sprintf(lang('access_confirm_resource_permission_revoke'), selected_group.text(), selected_resource.text());
461
                        if(confirm(confirm_msg))
462
				        {
463
                            perform_ajax_post('access_modify/change_permission',
464
                                'resource_id=' + resource_id + '&group_id=' + group_id + '&permission=deny',
465
                                function(){
466
                                    // Propagate the permission change down
467
                                    propagate_permission_change(selected_resource, 'deny');
468
469
                                    action.addClass('deny');
470
                                    action.removeClass('allow');
471
                                },
472
                                null);
473
                        }
474
                    }
475
                    else
476
                    {
477
                        // We are only revoking an action permission don't prompt
478
                        perform_ajax_post('access_modify/change_permission',
479
                            'resource_id=' + resource_id + '&group_id=' + group_id + '&action_id=' + action_id + '&permission=deny',
480
                            function(){
481
                                action.addClass('deny');
482
                                action.removeClass('allow');
483
                            },
484
                            null);
485
                    }
486
                }
487
                else
488
                {
489
                    // Switch to Allow
490
                    var action_url = '&action_id=' + action_id;
491
                    if (action_id == 'all' || action_id == 'view')
492
                    {
493
                        // No action ID, we are just granting access to the resource
494
                        action_url = '';
495
                    }
496
497
                    perform_ajax_post('access_modify/change_permission',
498
                        'resource_id=' + resource_id + '&group_id=' + group_id + '&permission=allow' + action_url,
499
                        function(){
500
                            // Propagate the permission change up
501
                            propagate_permission_change(selected_resource, 'allow');
502
503
                            action.addClass('allow');
504
                            action.removeClass('deny');
505
                        },
506
                        null);
507
                }
508
            }
509
510
            /**
511
             * Propagate a permission change either up to the parent resources
512
             * or down depending on what the new permission should be.
513
             * Allow propagates up
514
             * Deny propagates down
515
             *
516
             * @param resource The resource to start at
517
             * @param new_permission The permission to apply
518
             */
519
            function propagate_permission_change(resource, new_permission)
520
            {
521
                var current_permission = new_permission == 'allow' ? 'deny' : 'allow';
522
                if(new_permission == 'allow')
523
                {
524
                    // We need to move up the tree
525
                    if ( ! resource.hasClass(new_permission))
526
                    {
527
                        // Apply the class to the resource
528
                        resource.removeClass(current_permission);
529
                        resource.addClass(new_permission);
530
531
                        // Check that the sub action called view/all is also changed
532
                        var main_action = $('li#action_view,li#action_all', access_actions);
533
                        if( ! main_action.hasClass(new_permission))
534
                        {
535
                            main_action.removeClass(current_permission);
536
                            main_action.addClass(new_permission);
537
                        }
538
539
                        // Can we move up any more
540
                        var new_parent = resource
541
                            .parent() // Get the parent LI
542
                            .parent() // Get the parent UL
543
                            .parent() // Get LI above the span item we want
544
                            .find('>span'); // Move down to the span item
545
546
                        if(new_parent.length == 1)
547
                        {
548
                            propagate_permission_change(new_parent, new_permission);
549
                        }
550
                    }
551
                }
552
                else
553
                {
554
                    // We need to move down the tree
555
                    resource.removeClass(current_permission);
556
                    resource.addClass(new_permission);
557
558
                    // Apply the new permission to all actions
559
                    $('li', access_actions).each(function(){
560
                        $(this).removeClass(current_permission);
561
                        $(this).addClass(new_permission);
562
                    });
563
564
                    // If any child resources exist, move to them
565
                    var childList = $('>ul', resource.parent());
566
567
                    if(childList.length == 1)
568
                    {
569
                        $('> li > span', childList).each(function(){
570
                            propagate_permission_change($(this), new_permission);
571
                        });
572
                    }
573
                }
574
            }
575
576
            /**
577
             * Prompt the user for the change they want to make, validate it
578
             * and if valid save back and update the UI
579
             *
580
             * @param action The action being carried out, either add/edit
581
             * @param element The element which was clicked
582
             */
583
            function save_action(action, element)
584
            {
585
                var data = '';
586
                var current_value = null;
587
588
                if (action == 'edit')
589
                {
590
                    current_value = element.text();
591
                    data = '&id=' + extract_id(element.attr('id'));
592
                }
593
                else
594
                {
595
                    data = '&resource_id=' + extract_id(selected_resource.attr('id'));
596
                }
597
598
                prompt_and_validate_change('action', current_value, function (value){
599
                    // The new value is valid save changes to the DB
600
                    perform_ajax_post(
601
                        'access_modify/save_action',
602
                        'value=' + value + data,
603
                        function(){
604
                            reload_permission_manager('action');
605
                        },
606
                        null);
607
                });
608
            }
609
610
            /***********************************************************************************************************
611
             *
612
             *  HELPER METHODS
613
             * 
614
             **********************************************************************************************************/
615
616
            function handle_contextmenu_action(action, element, section)
617
            {
618
                switch(action)
619
                {
620
                    case 'add':
621
                    case 'edit':
622
                        switch(section)
623
                        {
624
                            case 'group':
625
                                save_group(action, element);
626
                            break;
627
628
                            case 'resource':
629
                                save_resource(action, element);
630
                            break;
631
632
                            case 'action':
633
                                save_action(action, element);
634
                            break;
635
636
                            default:
637
                                alert(sprintf(lang('access_unknown_section'), section));
638
                        }
639
                    break;
640
641
                    case 'delete':
642
                            if (confirm(sprintf(lang('access_confirm_delete'), section)))
643
                            {
644
                                perform_ajax_post(
645
                                    'access_modify/delete_item',
646
                                    'id=' + extract_id(element.attr('id')) + '&section=' + section,
647
                                    function(){
648
                                        reload_permission_manager(section);
649
                                    },
650
                                    null);
651
                            }
652
                    break;
653
654
                    default:
655
                        // Not sure what the action is, warn the user
656
                        alert(sprintf(lang('access_unknown_action'), action));
657
                }
658
            }
659
660
            function reload_permission_manager(section)
661
            {
662
                switch(section)
663
                {
664
                    case 'group':
665
                        // Reload all the groups
666
                        show_loader();
667
                        perform_ajax_post('access_fetch/load_groups', '', render_groups, 'json');
668
                    break;
669
670
                    case 'resource':
671
                        // Reload the resource view
672
                        switch_to_group(selected_group);
673
                    break;
674
675
                    case 'action':
676
                        // Reload the action view
677
                        switch_to_resource(selected_resource);
678
                    break;
679
                    
680
                    default:
681
                        alert(sprintf(lang('access_unknown_section'), section));
682
                }
683
            }
684
685
            /**
686
             * Prompt the user for a new value and then validate it
687
             *
688
             * @param section The section the prompt is for group/action/resource
689
             * @param current_value The current value if an edit is being performed
690
             * @param success_callback The function to call after a valid input has been entered
691
             */
692
            function prompt_and_validate_change(section, current_value, success_callback)
693
            {
694
                var value = prompt(lang('access_' + section + '_prompt'), current_value);
695
696
                // If the user entered a value
697
                if (value != null && value != current_value)
698
                {
699
                    perform_ajax_post(
700
                            'access_modify/validate_' + section,
701
                            'value=' + value,
702
                            function(result){
703
                                if(result == 'valid')
704
                                {
705
                                    success_callback(value);
706
                                }
707
                                else
708
                                {
709
                                    alert(result);
710
                                    prompt_and_validate_change(section, current_value, success_callback);
711
                                }
712
                            },
713
                            null);
714
                }
715
            }
716
            
717
            function hide_loader()
718
            {
719
                // TODO: Implement a Overlay loader
720
            }
721
722
            function show_loader()
723
            {
724
                // TODO: Implement an Overlay loader
725
            }
726
727
            /**
728
             * Extract the unique ID part from an Id string.
729
             * So if given reason_12 this will return 12
730
             *
731
             * @param id ID String
732
             */
733
            function extract_id(id)
734
            {
735
                return id.substring(id.indexOf("_") + 1);
736
            }
737
738
            function display_contextmenu(item, menu)
739
            {
740
                // Get the edit and delete menu items
741
                var items = menu.find('li.edit, li.delete');
742
743
                // If Item is locked disable edit and delete
744
                if(item.hasClass('locked'))
745
                    items.each(function(){$(this).addClass('disabled');});
746
                else
747
                    items.each(function(){$(this).removeClass('disabled');});
748
            }
749
750
            /**
751
             * Perform an ajax request to a target method and call the success
752
             * callback method on return
753
             * 
754
             * @param method
755
             * @param data
756
             * @param callback
757
             * @param dataType
758
             */
56
            function perform_ajax_post(method, data, callback, dataType)
759
            function perform_ajax_post(method, data, callback, dataType)
57
            {
760
            {
58
                $.ajax({
761
                $.ajax({
...
...
61
                    dataType: dataType,
764
                    dataType: dataType,
62
                    data: data,
765
                    data: data,
63
                    success: callback,
766
                    success: callback,
64
                    error: function(xhr, textStatus, errorThrown){
767
                    error: function(xhr, textStatus){
65
                        if(textStatus == 'timeout')
768
                        if(textStatus == 'timeout')
66
                            alert('Server timeout, please try again');
769
                            alert(lang('access_server_timeout'));
67
                        else
770
                        else
68
                            alert(xhr.responseText);
771
                            alert('Error: ' + xhr.responseText);
69
                    }
772
                    }
70
                });
773
                });
71
            }
774
            }

Updated trunk/assets/js/backendpro/accessTool.js Download diff

347348
252
	 * 
252
	 * 
253
	 * Add all resources to the list and turn them into a treeview.
253
	 * Add all resources to the list and turn them into a treeview.
254
 	 */
254
 	 */
255
255
	function resource_fetch_onSucces(xml)
256
	function resource_fetch_onSucces(xml)
256
	{
257
	{	// Create tree view html
257
		// Create tree view html
258
		generate_resource_structure($('resources', xml), $('ul', access_resources));
258
		generate_resource_structure($('resources', xml), $('ul', access_resources));
259
		
259
		
260
		// Turn the nested lists into a tree view
260
		// Turn the nested lists into a tree view