0

I am currently in the process of developing a fairly large and complex user management system using sfDoctrineGuard

I have created 4 groups, editors, moderators, admins and superadmins.

What I'm looking to do, is restrict certain users in the admin to be able to create/view/edit other users in the sfGuardUser admin module.

So for example a superadmins user can create editors, moderators, admins and other superadmins, but a moderator can only create editors.

Is this possible in sfDoctrineGuard, if so, could someone give me an insight on how I'd achieve this?

Thanks

sipher_z
  • 1,221
  • 7
  • 25
  • 48

1 Answers1

0

First of all you can set credentials in generator.yml to show/hide links to actions and object actions based on credentials. For example:

config:
  list:
    object_actions:
      _delete:
        confirm: Вы уверены, что хотите удалить пользователя?
        credentials: superuser
    actions:
      _new:
        credentails: moderator

Next, configure your forms with custom table methods for doctrine choice widgets of groups:

class sfGuardUserForm extends PluginsfGuardUserForm
{
  public function configure()
  {
    //groups_list
    $this->getWidget('groups_list')->setOption('expanded', true);
    $this->getWidget('groups_list')->setOption('table_method', 'getListForAdmin');
    $this->getValidator('groups_list')->setOption('query', Doctrine::getTable('sfGuardGroup')->getListForAdmin());
  }
}

class sfGuardGroupTable extends PluginsfGuardGroupTable
{
  /**
   * Builds list query based on credentials
   *
   */
  public function getListForAdmin()
  {
    $user = sfContext::getInstance()->getUser();

    $q = $this->createQuery('g');

    if (!$user->isSuperAdmin() && $user->hasCredential('moderator'))
    {
      $q->addWhere('g.name IN (?)', array('editor'));
    }
    else if ($user->hasCredential('editor'))
    {
      $q->addWhere('g.name IN (?)', array('editor'));
    }        
    return $q;
  }
}

A couple of enhancements: get rid of singletone call by passing user instance from action (in preExecute) and load group names form app.yml with sfConfig::get instead of hardcoding in it in code.

Dziamid
  • 11,225
  • 12
  • 69
  • 104
  • If I am logged in as a moderator, will I still see all users, or just the moderatoes and editor users in the list? – sipher_z Apr 20 '11 at 11:05
  • You can make a custom list of users based on credentials with the same approach. Create a sfGuardUserTable::getForList method, and specify it in generator.yml > list > table_method. – Dziamid Apr 20 '11 at 11:58
  • Ok, but that will be called no matter what user I'm logged in as. I have 4 user groups, with let's say 2 users in each group. A super user can see all users. But a moderator should only be able to see moderators and editors and an editor should only be able to see other editors. – sipher_z Apr 20 '11 at 12:09
  • No this will be called depending on what user is loggin in, rest assured. Look at the line: "$user = sfContext::getInstance()->getUser(); ". Here you get instance of the logged in user. Although this is not a best practice. – Dziamid Apr 20 '11 at 13:11
  • @Dziamid I have tried your code above, but I cannot get it working. I've logged in with a basic account, i.e. has permissions of an editor, but I can still see all users and all groups. It doesn't seem to call the `getListForAdmin` method. Any ideas/help? – sipher_z May 03 '11 at 08:42
  • I looked at implementing it, but I have been on vaccation. – sipher_z May 03 '11 at 10:29
  • Thank you! I needed it! An editor can `view/edit/create/delete` other editors ONLY. I also need editors to only be able to filter other editors and no other users. A `moderator` can `create/edit/delete/view/list/search` other `moderators` AND 'editors'. They should only be able to filter/search for `moderators/editors`. Current editor permissons are `Create.Editor`, `View.Editor`, `List.Editor`, `Delete.Editor`, `Search.Editor`. Thank you – sipher_z May 03 '11 at 10:52
  • Well, just add your logic to getForAdminList function. I suggest you also configure it in app.yml for convenience. Good luck. Filters are configured the same way as forms. – Dziamid May 03 '11 at 11:19
  • I do have the `getforAdminList` defined in my model, but it doesn't seem to get called. I had `public function getListForAdmin(){exit;}`, which doesn't exit the call. Also, what do mean about configuring it in the `app.yml` – sipher_z May 03 '11 at 12:12
  • @Dziamid would there be any reason why this method doesn not get called, even when I have followed the code that you provided? Thanks – sipher_z May 04 '11 at 15:39
  • It should be called: $this->getWidget('groups_list')->setOption('table_method', 'getListForAdmin'); I've tested it on my mashine (2 weeks ago). You really should install xdebug and track what went wrong. – Dziamid May 05 '11 at 14:02
  • Hi. I have put this code in: `lib/model/doctrine/sfDoctrineGuardPlugin/sfGuardUserGroupTable.class.php` and in `lib/model/doctrine/sfGuardUserGroupTable.class.php` both give me: `Unknown method sfGuardGroupTable::getListForAdmin`. This is really annoying me now, as I cannot get it woring! :( – sipher_z May 09 '11 at 15:41
  • but it does throw an error if i put the code in `sfGuardUserAdminForm` – sipher_z May 09 '11 at 15:50
  • I don't know what is troubling you. I've done it again and uploaded a test project on github here: https://github.com/dziamid/sipher. Hope this will help. – Dziamid May 10 '11 at 11:26