March 13, 2014

This article is to showing my little idea about how to manage user permission in ExtJS component. In this post I not showing the full source code, just a little part of the code to get the idea how it works, however the complete source code still available on the download link at the end of this article.

The below example is a simple user management that user can manipulate other user data and users groups, user need to logged in to the system to do some action, and the feature are:

- Add, Update, Delete Users
- Add, Update, Delete Groups
- Administrator cannot be deleted or updated

Which mean it will take different action button in the application screen, depend on the users groups, what is not handled in this example is user restriction, if a group have granted to modify certain user, it can modify whole user although it is the administrator.

The image is the file structure that I have created on this example, there will be a form and two grid panel in this application, a usual login form with label and textfield, a grid contain user data with the toolbar menu and a grid contain group data.

In the database, we need to make a relation between user and groups and here the sql code that I created, for both groups and users table.

-- Table structure for table `groups`

CREATE TABLE IF NOT EXISTS `groups` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(50) NOT NULL,
  `user_add` int(1) NOT NULL,
  `user_edit` int(1) NOT NULL,
  `user_delete` int(1) NOT NULL,
  `group_add` int(1) NOT NULL,
  `group_edit` int(1) NOT NULL,
  `group_delete` int(1) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=13 ;

-- Table structure for table `users`

CREATE TABLE IF NOT EXISTS `users` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `group_id` int(11) NOT NULL,
  `username` varchar(50) NOT NULL,
  `password` varchar(100) NOT NULL,
  `real_name` varchar(150) NOT NULL,
  `email` varchar(100) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=6 ;


The groups table contains id, group name and all the action that user can do to the application, from the user_add field until group_delete column the value only contains 1 or 0, which mean 1 for user can do this action and zero otherwise, The idea to managing user interface is by disabling the button on the toolbar based on the user group permissions and this are generated from groups table, so we need to give a unique Id for each button.

As well in the controller there are two controller that we need to create, user controller in application/controllers/user.php and group controller in application/controllers/group.php. Inside the user controller create the function for login and fetching users session inside user controller.

public function ext_login()
{
    $cond = array(
        'username' => $_POST['textusername'],
        'password' => $_POST['textpassword']
    );
    $query = $this->db->get_where('users', $cond);
    if ($query->num_rows() != 0)
    {
        $row = $query->row();

        // get group detail
        $g_cond = array(
            'id' => $row->group_id
        );
        $g_query = $this->db->get_where('groups', $g_cond);
        $g_row = $g_query->row();

        // pass the the info to session
        $this->session->set_userdata('u_id', $row->id);
        $this->session->set_userdata('u_name', $_POST['textusername']);
        $this->session->set_userdata('g_id', $g_row->id);
        $this->session->set_userdata('g_u_add', $g_row->user_add);
        $this->session->set_userdata('g_u_edit', $g_row->user_edit);
        $this->session->set_userdata('g_u_delete', $g_row->user_delete);
        $this->session->set_userdata('g_g_add', $g_row->group_add);
        $this->session->set_userdata('g_g_edit', $g_row->group_edit);
        $this->session->set_userdata('g_g_delete', $g_row->group_delete);

        echo "{success:true}";
    }
    else
    {
        echo "{success:false, error:'User not found!'}";
    }
}

public function ext_get_session()
{
    $output = "{success:true, sessions: {";
    $output .= "u_id: '".$this->session->userdata('u_id')."',";
    $output .= "u_name: '".$this->session->userdata('u_name')."',";
    $output .= "g_id: '".$this->session->userdata('g_id')."',";
    $output .= "g_u_add: '".$this->session->userdata('g_u_add')."',";
    $output .= "g_u_edit: '".$this->session->userdata('g_u_edit')."',";
    $output .= "g_u_delete: '".$this->session->userdata('g_u_delete')."',";
    $output .= "g_g_add: '".$this->session->userdata('g_g_add')."',";
    $output .= "g_g_edit: '".$this->session->userdata('g_g_edit')."',";
    $output .= "g_g_delete: '".$this->session->userdata('g_g_delete')."'";
    $output .= "}}";
    echo $output;
}

The ext_get_sessions function above is to get session and pass it to the browser, and in the login function the session value will be defined when user logged in to the system, ext_get_sessions function will be used in the permissions.js, I'm sure you can add the logout function contain the code to unset all the sessions value and here the permissions function look like inside the permissions.js.

 function setPermissions() {
    Ext.Ajax.request({
        url: BASE_URL + 'user/ext_get_session',
        method: 'POST',
        success: function(o) {
            var obj = Ext.util.JSON.decode(o.responseText);
            // set enable/disable grid panel
            if (obj.sessions.u_id != '') {
                Ext.getCmp('fLogin').setDisabled(true);
                Ext.getCmp('gUsers').setDisabled(false);
                Ext.getCmp('gGroups').setDisabled(false);
                Ext.getCmp('userLabel').setText('Welcome "'+obj.sessions.u_name+'"');
            } else {
                Ext.getCmp('fLogin').setDisabled(false);
                Ext.getCmp('gUsers').setDisabled(true);
                Ext.getCmp('gGroups').setDisabled(true);
                Ext.getCmp('userLabel').setText('Please Login');
            }

            // set users toolbar button
            if (obj.sessions.g_u_add == '1') {
                Ext.getCmp('tbUserAdd').setDisabled(false);
            } else {
                Ext.getCmp('tbUserAdd').setDisabled(true);
            }
            if (obj.sessions.g_u_edit == '1') {
                Ext.getCmp('tbUserEdit').setDisabled(false);
            } else {
                Ext.getCmp('tbUserEdit').setDisabled(true);
            }
            if (obj.sessions.g_u_delete == '1') {
                Ext.getCmp('tbUserDelete').setDisabled(false);
            } else {
                Ext.getCmp('tbUserDelete').setDisabled(true);
            }

            // set groups toolbar button
            if (obj.sessions.g_g_add == '1') {
                Ext.getCmp('tbGroupAdd').setDisabled(false);
            } else {
                Ext.getCmp('tbGroupAdd').setDisabled(true);
            }
            if (obj.sessions.g_g_edit == '1') {
                Ext.getCmp('tbGroupEdit').setDisabled(false);
            } else {
                Ext.getCmp('tbGroupEdit').setDisabled(true);
            }
            if (obj.sessions.g_g_delete == '1') {
                Ext.getCmp('tbGroupDelete').setDisabled(false);
            } else {
                Ext.getCmp('tbGroupDelete').setDisabled(true);
            }
        }
    });
}

As you can see on the code above, I manipulate the ExtJS component based on "Id", so we need to to add Id properties for the required component,  here a part of login form script and the form id I called it 'fLogin' ( assets/js/login.js )

// part of login.js
var loginForm = new Ext.FormPanel({
    id: 'fLogin'
});

function fnLogin() {
    loginForm.getForm().submit({
        success: function() {
            setPermissions();
            strUsers.load();
        },
        failure: function(form, o) {
            if (typeof(o.response) != 'undefined') {
                var json = o.response.responseText;
                var r = Ext.util.JSON.decode(json);
                Ext.Msg.alert('Login failed', r.error);
            }
        }
    });
}

Now part of the user script in ExtJS ( assets/js/user.js )

// part of user.js
var tbUsers = new Ext.Toolbar({
    items: [{
        text: 'Add',
        id: 'tbUserAdd'
    }, '-', {
        text: 'Edit',
        id: 'tbUserEdit'
    }, '-', {
        text: 'Delete',
        id: 'tbUserDelete'
    }, '->', {
        text: '',
        xtype: 'label',
        style: 'color:#0066cc;font-weight:bold;',
        id: 'userLabel'
    }, '-', {
        text: 'Logout'
    }]
});

var gridUsers = new Ext.grid.GridPanel({
    id: 'gUsers'
});

In the group script (assets/js/group.js)

var tbGroups = new Ext.Toolbar({
    items: [{
        text: 'Add',
        id: 'tbGroupAdd'
    }, '-', {
        text: 'Edit',
        id: 'tbGroupEdit'
    }, '-', {
        text: 'Delete',
        id: 'tbGroupDelete'
    }]
});

var gridGroups = new Ext.grid.GridPanel({
    id: 'gGroups'
});

For the adding and editing users and group I'm using a pop up window that have form to be submitted inside it, and for delete action I'm just using simple alert confirmation box. Well I think it is too much if I show all the code in this post, just go to the download link if you want to see full source code of this example, and here some of the screen capture.


Click Here to download the source files.

0 comments:

Post a Comment