Welcome Guest, Not a member yet? Register   Sign In
Using Zend_Auth and Zend_ACL with CI
#21

[eluser]zackwragg[/eluser]
Here you go. Thanks for all the help, mate. It's much appreciated.

Code:
-- phpMyAdmin SQL Dump
-- version 2.11.5-rc1
-- http://www.phpmyadmin.net
--
-- Host: localhost
-- Generation Time: Dec 01, 2008 at 09:47 AM
-- Server version: 5.0.51
-- PHP Version: 5.2.5

SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO";

--
-- Database: `ds`
--

-- --------------------------------------------------------

--
-- Table structure for table `ds_acl_permission`
--

CREATE TABLE IF NOT EXISTS `ds_acl_permission` (
  `role` varchar(64) NOT NULL,
  `resource` varchar(64) NOT NULL,
  `allow` tinyint(1) NOT NULL,
  `privilege` varchar(64) NOT NULL,
  PRIMARY KEY  (`role`,`resource`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

--
-- Dumping data for table `ds_acl_permission`
--

INSERT INTO `ds_acl_permission` (`role`, `resource`, `allow`, `privilege`) VALUES
('admin', 'home', 1, 'index');

-- --------------------------------------------------------

--
-- Table structure for table `ds_acl_resource`
--

CREATE TABLE IF NOT EXISTS `ds_acl_resource` (
  `id` int(10) unsigned NOT NULL auto_increment,
  `name` varchar(64) NOT NULL,
  `description` text NOT NULL,
  `parent_id` varchar(64) default NULL,
  PRIMARY KEY  (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=2 ;

--
-- Dumping data for table `ds_acl_resource`
--

INSERT INTO `ds_acl_resource` (`id`, `name`, `description`, `parent_id`) VALUES
(1, 'home', 'home', NULL);

-- --------------------------------------------------------

--
-- Table structure for table `ds_acl_role`
--

CREATE TABLE IF NOT EXISTS `ds_acl_role` (
  `id` int(10) unsigned NOT NULL auto_increment,
  `name` varchar(64) NOT NULL,
  `description` text NOT NULL,
  `parent_id` varchar(64) default NULL,
  PRIMARY KEY  (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=5 ;

--
-- Dumping data for table `ds_acl_role`
--

INSERT INTO `ds_acl_role` (`id`, `name`, `description`, `parent_id`) VALUES
(1, 'guest', 'guest', NULL),
(2, 'member', 'member', 'guest'),
(3, 'admin', 'admin', 'member'),
(4, 'superadmin', 'superadmin', 'admin');
#22

[eluser]SirSickboy[/eluser]
Ok, solved it. You're using the ACL functions ($this->acl->isAllowed)in your hook which won't work as to use the ACL functions you have to extend from the ACL class.

What i'd suggest doing is creating an is_allowed method in your ACL library and calling that.

So add this to your ACL library

Code:
function is_allowed($role, $resource, $privilege)
{
     return $this->acl->isAllowed($role, $resource, $privilege)? TRUE: FALSE;
}

then change your hook to use the new method.

Code:
class Acl_Hook
{
    var $CI;

    function initialise_acl()
    {
        $this->CI =& get_instance();
        $this->CI->load->library('acl');
        $this->CI->load->library('session');

        $resource = $this->CI->uri->segment(1);
        $privilege = $this->CI->uri->segment(2);

        if( $this->CI->session->userdata('logged_in') )  // if user is logged in then get roles
        {
            $role = $this->CI->session->userdata('role');
        }
        else  // Role is guest
        {
            $role = 'guest';
        }

        if( ! $this->CI->acl->is_allowed($role, $resource, $privilege) )
        {
            // Not allowed access so redirect
        }
    }
}
#23

[eluser]zackwragg[/eluser]
OK, that has solved the exception problem but it still isn't getting me the correct result for the is_allowed() function.

I'm a little confused as well because my ACL class extends Zend_ACL so surely the isAllowed() function should work with the ACL object as it has been inherited from Zend_ACl, no?

OK, now when I run the following I get the result false, but I think it should be true:

Code:
$this->CI->acl->is_allowed('admin', 'home', 'index');
#24

[eluser]zackwragg[/eluser]
OMG, I am so stupid.

In my ACL class I am creating an $acl variable which is what I am loading my roles, resources and privileges into. So after having loaded the library with CI, to access the $acl var inside the ACL object I would need to use $this->acl->acl. However, given that my ACL class is itself an ACL object I don't need to create another $acl variable inside. Does that make sense?

What I have done now is take out the $this->acl = new Zend_ACL(); line from my ACL class and rather than having things like
Code:
$this->acl->addRole($role_object, $role->parent_id);

I can just have:

Code:
$this->addRole($role_object, $role->parent_id);

Now the calls from my hook can go to:

Code:
$this->CI->acl->isAllowed()

Having said that, the isAllowed line I posted before still comes up as false (but having put a few debug lines in I can see that I am now accessing an object which has all my roles, etc loaded into it so I am sure this is a simple problem of things not being quite set-up right).
#25

[eluser]zackwragg[/eluser]
Right, I have this one all sorted now.

Thanks to all who helped. SirSickBoy, you are absolute star. Couldn't have done it without you.
#26

[eluser]Lou K[/eluser]
Hi guys,

I just read through this thread, and found it very helpful--I'm considering Zend ACL for a project of my own, and was thinking about a similar hook-based solution to keep the controllers clean.

However, I have a question, especially for zackwragg: now that you're using your ACL wrapper library as an instance of Zend_ACL itself, how do you restore your ACL structure after having cached it? Whereas before you could have restored $this->acl from serialization, now $this itself is the ACL object, with all the roles, permissions, and resources built into it.

Just wondering if you've solved that particular problem.

Thanks!
-Lou
#27

[eluser]zackwragg[/eluser]
Hi Lou K,

I've actually not tackled the caching aspect properly yet.

I created another thread specifically asking questions about the caching of the object (http://ellislab.com/forums/viewthread/97950/) and someone there suggested that MySQL's caching could be enough for this.

I have not totally written off the idea of looking at caching to a file, but definitely need to read a bit more about it.

I guess, what you could do to ease the situation is to go back to when I had created the $acl object inside my ACL class, and write the is_allowed function to access the isAllowed function of the $acl object. Then you can serialize the Zend_ACL object, but reference your is_allowed function directly with your class (rather than $this->acl->acl->isAllowed()).

I'm currently setting up the admin side of the ACL management then I will probably come back to the issue of caching so I'd be interested to know which route you take.
#28

[eluser]zackwragg[/eluser]
Oh, in case this is of any help, I created a thread when I was looking at ways to access the controller and method name in my hook.

http://ellislab.com/forums/viewthread/98471/

I have changed it slightly now and have this:

Code:
$resource = $this->CI->router->fetch_directory() . $this->CI->router->fetch_class();
$privilege = $this->CI->router->fetch_method();

I put the directory bit in there so I could create distinctly different resources for my admin section of the site (e.g. I would have a resource called 'news' which would be the news on the front end of my site, and would have 'admin/news' which would refer to the news management section in the admin part of the site). I could have done it with privileges if I had wanted (e.g. resource called 'news' and privileges like 'view', 'edit', 'delete', etc) but I wanted to keep them separate to keep them a little clearer in my head, and also so I could use resource inheritance if I wanted (e.g. I could have a resource called 'admin' which is the parent of 'admin/news' and all other sections of the admin site.
#29

[eluser]vaff[/eluser]
Anyone know if its possible in 2010 to get Zend_auth + Zend_ACL up and running together with Codeigniter?
#30

[eluser]vaff[/eluser]
Taking the silent response as a "no"




Theme © iAndrew 2016 - Forum software by © MyBB