Welcome Guest, Not a member yet? Register   Sign In
Auth control by uri request
#1

[eluser]FlashUK[/eluser]
I just had an idea about some code that could be used for a Auth library.

Controlling access to a controller/section by using the uri_string

This data could be stored into the database (group_id & request_uri). There is then no need to hardcode a group id into the page, just simply match it against the database.

Table layout I thought of for MySQL:
Code:
group_id | request_uri

It would also allow you to add access to other controls easily as you create them, or give a group more privileges via a admin panel.

If you wanted, you could use "/" as the request_uri for the group_id if you want to allow access to ALL controllers throughout the site (obviously for someone like "Super Admins" only).

What do you guys think? Any flaws?
#2

[eluser]webthink[/eluser]
Can you give an example of what a url might look like?
#3

[eluser]FlashUK[/eluser]
The controller then action e.g.:

/home/index
#4

[eluser]webthink[/eluser]
I see so you just look up the current controller action in your permissions table. That could definitely work it just depends on if you as the developer would find managing permissions in a table vs. directly in the controller easier. The advantage of the permissions table is that you could build an interface for administrator user to assign permissions rather than having it controlled strictly by the developer.
#5

[eluser]FlashUK[/eluser]
Yup, it makes it really easy to change permissions in the database, plus its really fast since it only does 1 query.

I finished making the code, here it is:

Code:
function check()
    {
        $_pass = false;

        $_group = $this->obj->session->userdata('group_id');

        if ( $this->obj->session AND $this->obj->config->item('CL_Auth') AND !empty($_group) )
        {
            $_controller = '/'.$this->obj->uri->rsegment(1);
            $_action = $_controller.'/'.$this->obj->uri->rsegment(2);

            $query = $this->obj->group_uri->findURI(array($_controller, $_action), $_group);

            if ( $query->num_rows() )
            {
                $data = $query->row();

                $_pass = true;
                $this->_fullAccess = $data->is_admin;
            }
            else
            {
                $query = $this->obj->group_uri->globalAccess($_group);

                if ( $query->num_rows() )
                {
                    $data = $query->row();

                    $_pass = true;
                    $this->_fullAccess = $data->is_admin;
                }
            }
        }

        if ( $_pass == false )
        {
            $this->denyAccess($_group);
        }
    }

    function isAdmin()
    {
        return $this->_fullAccess;
    }

So all you do is call "$this->auth->check()" at the top of the controller if you want to protect it all, or sit it within an action.

Heres the model as well:
Code:
function findURI($_uri=array(), $_group_id)
    {
        $this->db->where_in('request_uri', $_uri);
        $this->db->where('group_id', $_group_id);

        return $this->db->get($this->_table);
    }
    
    function globalAccess($_group_id)
    {
        $this->db->where(array('group_id' => $_group_id, 'request_uri' => '/'));
        return $this->db->get($this->_table);
    }

Some example data too:

Code:
group_id | request_uri | is_admin

1   |   /            |   1
2   |   /home        |   1
3   |   /home/test   |   0
#6

[eluser]webthink[/eluser]
Neat stuff. You wouldn't need to sit it within an action at all actually because the constructor would get called regardless of the action and then the check function would handle the permissions based on permissions for each action depending on the uri. So really all you'd need is $this->auth->check() in the constructor and assuming you remembered to add the appropriate permissions in the table all your actions would be covered.
Of course any custom routes might be worth thinking about.
#7

[eluser]FlashUK[/eluser]
[quote author="webthink" date="1205438005"]
Of course any custom routes might be worth thinking about.[/quote]

You don't need to worry about custom routes. The function uses "rsegment" which re-routes the path and confirms the true path.

[quote author="webthink" date="1205438005"]... You wouldn't need to sit it within an action at all actually because the constructor would get called regardless of the action ...[/quote]

You only need to include it in the action if you don't include the check() in the constructor. You would do this only in a controller when you want to protect one action (which is highly unlikely). Otherwise, you would have to add granted access for guests/normal users in the database which can be cumbersome.
#8

[eluser]webthink[/eluser]
Hmm yeah could be cumbersome but perhaps if you could add wildcards or something like this to the table
/controller/*any*
where the presence of *any* can be overridden by specific (real) actions controller/update
#9

[eluser]FlashUK[/eluser]
There is a check for this already, it checks for "/controller" together with the action as well. If the action doesn't exist as a record but "/controller" does, then it automatically overrides the call.

Code:
$this->obj->group_uri->findURI(array($_controller, $_action), $_group);

...

    function findURI($_uri=array(), $_group_id)
    {
        $this->db->where_in('request_uri', $_uri);
        $this->db->where('group_id', $_group_id);

        return $this->db->get($this->_table);
    }
#10

[eluser]FlashUK[/eluser]
Just an update to this thread.

I have created a completely new auth system using this method. I shall be releasing it in BETA form when I am happy with it for public testing. It's quite an extensive system and has everything you would expect from a login library.




Theme © iAndrew 2016 - Forum software by © MyBB