Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Sign In with Google Sign In with OpenID

User Levels

edited April 2013 in Framework

Can you create a user level that can only do basic edits to a page, view analytics, post blogs, etc.?


  • This is something we're planning for the next release, but not yet I'm afraid. Here's the github issue, although there's not much there yet:

  • Some questions/comments: Is using User::is('admin') same than User::require_admin() ? If I create a type 'editor' and use the is() method instead of require_admin() method in handlers where I want to grant access to editors, I will probably have to call both methods or change the is method so that it accepts an array or a comma separated list of types. But it seems like a dirty solution. In the future, do you intend to implement the Acl library for this? If so, I would go this way too and eventually make a contribution. If not, give me a tip about which way you plan to go. It's a feature I am not ready to wait for, so I will implement it either way. Better be usefull so someone else.

  • I'm going to need something like this in a saasy context as well, perhaps granting special permissions to additional account types.

  • User::require_admin checks for a user session and tries to authorize the user, User::is only checks the type (see line 305 in the same link).

    For Saasy, we can use the Acl class and the Account type property I believe.

    For Elefant admins, I think it will take extending the user app a bit to provide a way to manage the access rules, which could be stored in apps/user/conf and be easily loaded into the Acl class too. From there it's a matter of deciding where to add the permission checks, which could be app-wide (e.g., disabling the designer app entirely), or just a part of one (e.g., disabling the app/theme installer within the designer app).

    I think determining whether a type is an admin would then come from their role definition instead of relying on the single 'admin' user type. There's some basic access stuff in the user app config file already, but that would probably be replaced with the unified Acl system too I would think.

  • Minor correction, just looked at the Acl class again and the default config file is conf/acl.php, so makes sense to use that.

    To build a list of permissions for the permission editing, it would probably have to include each app itself, but each app could just list theirs in a conf/acl.php in their app, even something as simple as:

    designer/edit = "Create/update design themes"
    designer/install = "App/theme installer"

    That would make it pretty easy to build a simple edit form for managing roles.

  • How about changing User::require_admin to User::require_auth("admin") and then including a default conf/acl.php in each app that set the default permissions for an 'admin' user and a 'member' user. User::require_auth would take any valid role as a parameter, but everywhere we're now using User::require_auth would change to User::require_auth("admin").

    This would become the default elefantcms installation, and would also make it easy for someone to see how to setup permissions for a new user type. And then provide a simple edit form for managing roles, and modify the user/account profile forms to allow an 'admin' user to assign a role.

    And maybe do this for 2.0 instead of 2.2?

  • I like your solution @jonphipps However in order to use conf/acl.php the User::require_auth() should be called without arguments. The function will check current user's role against the conf file. If the configuration sets his role as having granted acces to the current handler, the function returns true. Using the function with argument would, simply check current users role against the string passed in the argument. I thing there should be at least one more role in the default install: the editor. It would be granted to use blocks, blog, files, pages and versions. I feel very uncomfortable leaving non technical people the access to the markup and the css files, even if I trust them :D

  • Since we don't want to hard-code role names anywhere, but rather resources, what User::require_auth('admin') would actually be saying is "check that the current user's role is allowed to access the 'admin' resource", so I don't think it makes sense as an empty method. It would use the current user's role info, which could be overridden in the same was as specifying an alternate user in the Acl class.

    User::require_admin() could become an alias for User::require_auth('admin'), but we may want to deprecate it too.

    And I do like the inclusion of a more limited "editor" role in the default install too.

    And I'm open to including this in 2.0 still as well :)

  • Just updated the issue on Github to move it to the 2.0 milestone.

  • Way to twist my rubber arm :P

  • Honestly one thing I don't like about WordPress is keeping up with two logins. One for me and one for the client. I have clients login as editors because most do not want to be exposed to all the "admin" related items. They just want to go in and edit some content and get out. I gave it further thought and I think Elefant is fine primarily as is. I just think perhaps I'll delete and remove apps as needed. Can you safely remove the users app and add back in when desired?

  • Definitely don't remove the user app, it's relied on pretty heavily throughout the CMS. You may still need a "master" login for your sites, but you could create a shared account type that's fairly non-restrictive and just keeps one or two things out of the way, that you share with them.

  • Before jumping into this one, I should ask if anyone else has started playing with user ACL? If not, I'll probably take a stab at it then.

  • No I won't do that. Could you possibly enhance bootstrap and further control the admin via that file. I'm not familiar with acl.

  • Okay, there's no GUI for editing roles yet, but the new access control seems to be working. Here's the commit:

    I've also pre-defined a bunch of ACL resources that I'll be adding checks for throughout. You can see how these are defined in an app like this:

    And the rules themselves are stored like this:

    And the path to that file can be set per-environment just like the files and navigation paths:

    I'll start on the role editing next.

  • I haven't started doing anything yet with ACL, but I think it's worth some more conversation.

    For instance (and I'm sure this is at least a bit out of scope), I just got a contract to allow translators to work on a collection of resources in a sassy-based system. A translator would have CRUD access to any of the collection resources, but only in their assigned language (there apparently has already been fighting between the fr-fr and fr-ca translators) and the assignment of a language to a user could be made only by the collection admin. Resource URLs would look like Fun, eh?

    Referencing your comment that "we don't want to hard code role names" I was under the impression that we did. That the access restrictions in the code would say "User must have role named "admin" to access this resource/handler". Looking at the acl API, it looks like the default role list map for an app and app/handler paths are defined in the acl.php ini for that app, so require_auth("admin") would override the defaults for that app/handler, which had already been established by the acl.php.

    I assume that roles would be implicitly hierarchically inclusive, and that an admin would inherit the access of an editor, who would inherit the access of a member, who would inherit the access of a guest. And I assume that we could do this by using the top to bottom ordering of roles in the acl.php file -- access would read from the bottom up and your access would stop at the highest level to which you were assigned.

    In the use case above, I should be able to assign a role to a user wrt a specific resource on-the-fly for the duration of a session.

  • Haha I know all about French translators and their disagreements. We do a lot of bilingual projects at my work and it's always a trick getting a translation that will satisfy everyone (and that's just for fr-ca). A translation from outside of Quebec will be laughed at in Quebec, and even translators from Quebec vs Montreal will argue over things...

    I'll try to clarify a few points about how the Acl class handles access control.

    • There's no inheritance between roles. Each role can be as limited or as open as you need, independent of any hierarchy. This allows for many different limited access roles (e.g., a translator accessing only that app). Inheritance wouldn't be too hard to add if we ever need to, but it ought to be explicit via something like an inherit_from = member type statement.
    • There's a default resource that says when a role doesn't specify access for a given resource, do we allow or deny by default. The master admin role is literally just default = On and doesn't need any other rules, whereas most will be default = Off and explicitly set what they can access. Another example, a "limited admin" role on the demo site could be default = On but explicitly turn off certain things like designer/install which would control access to the app/theme installer.
    • There's an admin resource as well as a role, and multiple roles will have access to the admin resource (the new editor role does, for example). In practice the change in what User::require_admin() means now doesn't visibly change much, but opens up the possibility for further restrictions that you can't do if you hard-code role names.

    I also added a new $this->require_acl() method to the controller that you can specify a list of resources to, so the designer app can say:

    $this->require_acl ('admin', 'designer');

    Which means "is this role able to access general admin stuff as well as the designer app?" so that we can easily limit admins with more fine-grained access in different places. You can also get the Acl object for the currently active user via User::acl().

    Take a look at the Acl class for example usage. The add_role(), allow() and deny() methods allow you to temporarily modify the rules for the current request, so you could escalate a user's permissions on the fly, as you mentioned you may need.

  • Just finished adding the GUI for managing roles as well :)

  • As so often seems to be the case, you exceed my expectations. Thanks!

  • "As so often seems to be the case, you exceed my expectations."


Sign In or Register to comment.