Granting and Checking Permissions with LiveUser

I was reminded by maxi_million in the comments on one of my previous LiveUser tutorial entries that I never completed the promised third entry in that series. After the initial procrastination wore off and I initially turned my mind to writing this piece, my main project using LiveUser ended up being converted (for various reasons) into a drupal site, so my further use of the library has been quite minimal. But I do have a little code sitting around, so will try and draw together a few notes on how I was using Liveuser.

While many powerful authorization systems are purely role-based, something that can be achieved in LiveUser with the groups functionality covered in the previous entry on this subject, LiveUser also supports much more fine grained permissions. Each permission is its own entity, and permissions are grouped into areas. I created my areas directly in the database so won’t be covering that here. Once you have your area’s id in the variable $area_id and an instance of LiveUser_Admin in $admin you can call:

$right = $admin->perm->addRight(
  array('area_id' => $area_id,
    'right_define_name' => 'a name for your right'));

to create the right and capture its ID in $right.

You can then ‘grant’ that right to a user with:

$admin->perm->grantUserRight(
  array('right_id' => $right,
    'perm_user_id' => $perm_user_id));

Or grant it to a group with:

$admin->perm->grantGroupRight(
  array('right_id' => $right,
    'group_id' => $group_id));

Where I ran into problems was when I attempted to check those permissions. From the API documentation, it wasn’t clear how to check for a right given only its name, but after a little exploration I put together the following method (used within my wrapper class) that handles it. $this->user is an instance of LiveUser and $this->admin is an instance of LiveUser_Admin:

function checkRight($area_id, $right_desc) {
  if (empty($this->admin)) {
    $this->getAdminInstance();
  }
  $filter = array(
    "fields" => array("right_id"),
    "filters" => array(
      "area_id" => $area_id,
      "right_define_name" => $right_desc));
  $rights = array_keys($this->admin->getRights($filter));
  $right_id = $rights[0];
  return $this->user->_perm->checkRight($right_id);
}

You’ll note that the final line makes use of the _perm property. In PEAR coding conventions a preceding underscore means a method or property is private and should not be accessed from outside the class, but this was the neatest approach I was able to find in the time. If anyone can tell me how to do this within the approved public API I’ll happily update this entry.

Update: Be sure to check out the comments, where Lukas has been adding some very useful information.

Tags: , , , , ,

7 comments

  1. Thanks James…as always a great article on a great library. Personally I feel LiveUser deserves to be an application in its own rights. Things are beginning to take shape as far my usage of LU is concerned. But a question still lingers:

    say if i grant a group some rights, as i understand it, every group member also inherits that right…but can i also give an individual member within that group some extra rights not available to other mmbers within the group?

    thanks again

  2. Yes. Simply set up two rights, and grant one to a group, and the other to just particular users. Any right can be granted to groups or users regardless of other rights they may also have.

  3. $rights = array_keys($this->admin->getRights($filter));

    this looks odd .. it would only make sense if you also set ‘rekey’ => true in the params array.

    however a mor elegant solution is to instead just set ‘select’ => ‘one’. that way you just get a single scalar integer containing the right_id.

  4. regarding maxi’s question .. the reverse also works .. you can even specifically disallow a user from ever getting a right from a role by simply granting the right to the user with a negative right_level. in that case liveuser subtracts that value from the right_level at which the right was granted to the group. if it comes out 0 or lower the user will not get the right.

    so for example

    Role A groups the following rights:
    right 1 at level 3
    right 2 at level 2
    right 3 at level 3
    right 4 at level 1

    User I is assigned Role A, but also the following rights:
    right 1 at level -2
    right 2 at level -3
    right 3 at level 1
    right 4 at level 2
    right 5 at level 1

    the final rights for the user will be as follows
    right 1 at level 1 (3-2)
    right 3 at level 3 (the Role A has a higher right level
    right 4 at level 2 (the User I has the higher level)
    right 5 at level 1

    the user does not however gain the right 2 since 2-3 is equal or lower than 0

  5. i should not say substract .. more like add that negative value ..
    however thinking about the feature .. maybe it would be nicer to have something like the following:

    1) a value of 0 indicates that you do not want the user to gain this right at all

    2) a negativ value indicates you want to make sure that the level is set to only a specific maximum level of “3 + (the negative level)” through some group membership.

    now i am unsure what makes more sense either:
    2a) giving the right at a negativ level actually implies that you grant the right at “3 + (the negative level)”
    or:
    2b) gibing the right at a negative level does not imply that the user gains. he still needs to be member in a group that has the right

  6. thanks Lukas

    never thought of these possibilities…but thats exactly what i need

  7. Good function to find rights of logged in users belonging to a particular group

    /**
    * Enter description here…
    *
    * @param int $group_id
    * @param string $right_desc
    * @return bool
    */
    function checkRights($group_id,$right_desc)
    {
    global $admin;
    $filter = array(‘filters’ => array(‘group_id’ => $group_id,’right_define_name’ => $right_desc),’by_group’ => array(1),’selectable_tables’ => array(‘rights’, ‘grouprights’, ‘areas’, ‘applications’,’groups’) );

    $right = $admin->getRights($filter);
    if(count($right) > 0)
    return true;
    else
    return false;
    }