Jump to content

Page-specific permissions?


doolak

Recommended Posts

Hello there,

i think it wouldn't be bad if it could be possible to give a specific usergroup (and maybe a specific user too) the possibility to edit that page by changing this in the page settings.

In the moment just someone who know how to add a new template would be able to do this - he would have to add a template where that one group or that one user has access to edit it. That would be too much for most of the typical administrator.

Maybe with the option to choose, if this inherits to children or not.

What do you think about that? Would that interfer somehow with the actual permission system or would that be possible?

Kind regards,

Christian

Link to comment
Share on other sites

This is how it works in PW 2.0. At some point Ryan was planning to do both. Here are thoughts behind that change: http://processwire.com/talk/index.php/topic,229.0.html

I have somehow fixed feelings (and lots of emails with Ryan ;)) about this myself. We build sites mainly for big associations, and those can be very complex and hierarchical organisations. They have many times sections for geographical areas and in each of those they have vertical groups (like members, admins, board, volunteers etc). It is not rare to have over 50 user groups (one of our site has 700...), and hundreds of user access definitions. With current way (2.1) it leads to hundreds "just for ua" templates.

In the other hand, it is clear that we need user access on template level. It would be pain to manage who can add news, who can add events etc. As we know pw pages are powerful, and much more than usual content pages - you build software on top of the pages. So after using the latest 2.1. and it's access management I really love it.

But still, I do miss the easiness of adding page-specific permissions. It would keep the number of templates at minimum. Also, I recently thought that if there would be one admin page, that shows all the individual pages that have custom ua defined, then it wouldn't be such a mess. For sites that are complicated on "who can view what" then I feel that page-specific ua is clear winner. When you have public site and the main question is "who can edit what", then template based ua is clear winner.

For us it a definite need to allow our clients to edit permissions (at least who can view and what). And template editing is something that I will not allow for our clients - so if page-specific ua is not coming, then my plan is to build module to add custom "ua" templates and also admin page where our client can manage access (and only that).

Link to comment
Share on other sites

Yes, i can imagine that its very difficult to find a solution which fits everybodys needs and to all situations...

Maybe a combination could be nice: a template-based permission system with the additional possibility to add page-based permissions for groups and/or users by including or excluding their access to that page or pagetree.

So you wouldn't have to use 20 similar templates for 20 different pages when there are 20 different users which should have access to just one of those pages.

Link to comment
Share on other sites

Yes, i can imagine that its very difficult to find a solution which fits everybodys needs and to all situations...

It is. Also - many of our sites where client have "gone wild" with permissions are insanely complex - when they don't need to be. So some middle ground there could be nice (thinking about not allowing clients to manage access on every page, just on predefined pages).

Link to comment
Share on other sites

thinking about not allowing clients to manage access on every page, just on predefined pages

That sounds like a good idea - if the superadministrator could decide if a page allows managing access or not. So one could define that for a pagetree with hundreds of pages (like "Cities" in the Skyscraper example) the client can manage access to the root-page of that tree, but not to all children - and avoid that there are hundreds of different permissions for all those cities.

But, if it would be necessary - f.e. if there are lots of hotels listed and each hotel should be administred by a different person (hotel manager), one could define that on each of those pages one could manage access...

Link to comment
Share on other sites

what if one could specify "editable pages" and "working dirs" on a user and or role basis?

I've yet to come across a user management system that's simple to understand, logic, enough flexible and still working bugfree/solid... :) , so i'm excited about what is there already even I understand, ... buuut maybe also there could be a little more... ;)

I work with a CMS that does allow to define access controlls on a per user, role, page and template basis. Whilst it gives great power it can get very complicated and out of control quickly... something's always not working...

I think there should be at least a way to additionally give single pages users acces or give users access to single pages/dirs, without the need to create duplicates of templates just for single users.

Link to comment
Share on other sites

I definitely don't want people to have to create any large amount of templates just for user access, so would want to find a solution for that. Though I'm still not sure that I understand the scenarios where a template needs to exist just for user access? Hundreds of templates just for UA (or even far less) would be a deal killer for sure, so we will definitely want to find an alternative there. Seriously, hundreds or even dozens of templates for ua?… I'm doing something wrong. Help me understand these access control scenarios–The more I can understand these types of access control scenarios I think the better.

My thought is that we will offer page-level access control, but that the template-level access control provides us a better and more straightforward foundation for the core. That leaves us room to handle more complicated scenarios with needs targeted, specific solutions. I've always wanted to keep the core as simple as possible, primarily for the end-users, but also for long term maintenance and reliability of the software.

Page level access control could be provided as something built-in, or as a special fieldtype that one can add to any template that then allows them to override the template-level access definitions. In such a case, template-level definitions would serve as starting points [defaults] rather than ending points. As much as I don't care for access being defined in the same place where it is granted or revoked, I'm certainly not opposed to providing this option where it makes things simpler. There are no sacred cows and the goal is always to make things simpler.

  • Like 1
Link to comment
Share on other sites

Seriously, hundreds or even dozens of templates for ua?… I'm doing something wrong. Help me understand these access control scenarios–The more I can understand these types of access control scenarios I think the better.

You are not doing it wrong, I think what pw 2.1 has now is in many factors best ua management I have seen. It is simple and powerful, just like pw.

I have done a poor job trying to describe our ua scenarios, but that is probably because I don't know the association jargon in English very well. But I have another example, a soccer club:

There are 20 teams (male, female, different junior teams etc). Each team have their private section (20 ua "locks" here). Under each team there are two more restricted areas, one for "management" (+20 ua locks here) and other for "players only" (+20 ua locks here).

Take the example above, change 20 teams to 200 associations, take those "two more restricted areas" to "five more restricted areas" and you have 200 * 6 = 1200 ua locks. One might think that isn't a job for cms (and maybe this is a bit extreme case), but I disagree. Managing 300 website instead of one is even more a mess. This kind a site requires client admins that can manage users & user access on each of those associations (they have full time employees just to manage their members).

Link to comment
Share on other sites

I have done a poor job trying to describe our ua scenarios, but that is probably because I don't know the association jargon in English very well. But I have another example, a soccer club:

No actually I think you are doing a good job of describing it, especially with the examples you just posted. You have complex access control needs and I think it would be difficult to describe in any language. :)

Take the example above, change 20 teams to 200 associations, take those "two more restricted areas" to "five more restricted areas" and you have 200 * 6 = 1200 ua locks. One might think that isn't a job for cms (and maybe this is a bit extreme case), but I disagree. Managing 300 website instead of one is even more a mess. This kind a site requires client admins that can manage users & user access on each of those associations (they have full time employees just to manage their members).

Wow. This is all in one site? Stepping outside UA for a moment, I do wonder about possible efficiency, security and diversification benefits in having each association run off a separate database (smaller databases, less data, smaller indexes, faster execution, less chance of a problem in one affecting others). I'm only taking about separate databases, but sharing the code. This is more of an inquiry–how do you diversify these large scale needs?

Stepping back into UA, I think that I understand now. It sounds like this is likely a complex UA setup regardless of where its implemented. If you were doing page-level UA, wouldn't you still need just as many (or potentially more?) access control points?

I can see why you have so many templates in this scenario. But the main reason for that seems to be that there are 200 sites bundled into 1? If these were independent sites, they would have 2 access control points for teams, or 6 access control points for associations? That would seem much more manageable and more consistent with the intentions behind the current system.

While it may be possible to implement, PW was admittedly not designed for managing the access control of 200 sites in one database (sounds like we need template pagination!). :) But I do think we can open the hood and add some custom modifications to make it sing in your situation. I would suggest that because your needs are pretty unique, we should collaborate on custom building an access control system specific to the needs of your company. I think we can make this a lot simpler just by focusing on this specific case with custom access control modules. I also wonder about abstracting the access control out of the site(s) completely, moving it to a shared web service (perhaps powered by PW) so that you could run the sites independently on separate databases, but allow the access control managers to control it in one place, just like the developers would edit the templates in one place. That way you could still get the efficiency and diversification benefits of separate databases. These are just ideas from an outsider that knows very little about the reality and scope of the needs there.

Link to comment
Share on other sites

Ryan, thank you for your answer.

Wow. This is all in one site? Stepping outside UA for a moment, I do wonder about possible efficiency, security and diversification benefits in having each association run off a separate database (smaller databases, less data, smaller indexes, faster execution, less chance of a problem in one affecting others). I'm only taking about separate databases, but sharing the code. This is more of an inquiry–how do you diversify these large scale needs?

Good questions. In example above (it was a simplified - but BIG - imaginary scenario. Usually they are smaller but much more complex) each association (or sub-association) site is not real website. It might be just one news section. Or small file sharing area. Or private discussion. Also same data (ie. news, events, files etc) are reused on different sections (main editor adds news, checks which associations can see what etc). Also same user can belong to more than one association - so he/she needs to go to different parts of the site.

When scenario has been "big, but clear" we have build those as separate sites that our client manages (can add/edit/remove new sites), just like you proposed. But they are usually smaller, but more complex scenarios, with many many more user roles and deep levels of content. If you read my above paragraph again, you see that if those all are in separate sites, you need a secure way to share data between sites, you also need single identity provider with single sign-on solution between sites (ok, our clients has member registry where user data is kept) etc. So many times it is actually more simpler to have one bigger and more complex site than to build many smaller one.

But whenever we can take logical part away from the "big site" - we do that. We also courage our client to avoid complex ua scenarios and just be open and share data whenever it is possible. But organisational culture is something that we cannot force overnight - our solutions need to bend to our clients needs.

It sounds like this is likely a complex UA setup regardless of where its implemented. If you were doing page-level UA, wouldn't you still need just as many (or potentially more?) access control points?

Yes we would. Difference is that our client does that by themselves, not us. Also currently you need to a) create template and configure access b) edit page and change template. So in a way that is currently also managed in page level, because you need to change the template.

I agree that our needs are pretty complex and custom. Also - we are not sure how complex stuff we want/need to build anymore. I do not want to build (or buy to be build) anything for this before it starts to slow down our sales. So I am pretty confident that current level is mostly enough for us (cannot predict too much tough, we'll see :)).

Currently I see that the way pw manages access is very clean, efficient and great way for site builders - and it allows all the possible "who can edit what" scenarios that there is easily. But if you are building extranets or intranets your needs are very different. It is more like "who can see what" and "I need to share some data with these roles now". Page-spesicific permissions are clear winner there. Something that client can quickly do by themselves (add new page => select which roles can access it => save).

As doolak wrote in first post:

In the moment just someone who know how to add a new template would be able to do this - he would have to add a template where that one group or that one user has access to edit it. That would be too much for most of the typical administrator.

I don't want to allow my clients anywhere near template settings. And when this is only place where access can be managed, then it is very limited what client can do here (manage users and their roles). Most of the time that is exactly how we also want it, but I think we are not only ones who will have situations where more ad hoc solution would do much better.

Link to comment
Share on other sites

I would suggest that because your needs are pretty unique, we should collaborate on custom building an access control system specific to the needs of your company. I think we can make this a lot simpler just by focusing on this specific case with custom access control modules. I also wonder about abstracting the access control out of the site(s) completely, moving it to a shared web service (perhaps powered by PW) so that you could run the sites independently on separate databases, but allow the access control managers to control it in one place, just like the developers would edit the templates in one place. That way you could still get the efficiency and diversification benefits of separate databases. These are just ideas from an outsider that knows very little about the reality and scope of the needs there.

That is not bad idea. Need for it depends a lot about sales - our customers are trade unions, political parties, charity organisations, student organisations, sports clubs etc... so some of those can have 200 000 members and others just 500. As I said it won't probably get that big in our future projects (or at least that is what we hope :)), but if it gets, then that kind of solution is something that we will definitely consider.

I think pretty usual request is this: "Can I add new page and select who can view it?". In page based ua I could say: "Yes, you can do it by yourselves".

Now the answer for that would be: "you just call us, and we set up new role for you" (under the hood we create new template and role).

Sometimes that is better, sometimes worse. For some it is requirement and very much needed feature, for others it is something that they don't need or don't wanna use and ask from us anyway.

Link to comment
Share on other sites

Attached is a module that gives you page level access control for view access in PW 2.1. It's fairly basic, but gets the job done and it's something to at least start from. I've tested it to make sure everything works, but not exhaustively, so let me know if you run into any issues with it.

To install

1. Copy the attached file (CustomPageRoles.module) to /site/modules/  

2. Click 'Check for new modules' in Setup > Modules.

3. Click the install button for 'Custom Page Roles'.  

It will automatically add a field called 'page_roles' to your fields list. Add this field to any templates that you want to have page-level access control. Now when you edit a page using a template that has this field, you'll have checkboxes for roles that you can choose to define access from.

When at least one role is checked, the page has access control authority for 'view' permission, rather than the template. When no roles are checked, then it will check the parent page to see if it has a page_roles field and delegate control to it. That parent's page_roles field is used in the same manner. As a result, you can inherit up (or down) the tree as long as the parents have page_roles fields. Authority will be given to whatever parent ultimately defines access (by having at least one role checked).

If a page has a page_roles field with nothing selected, and it's parent doesn't have a page_roles field, then access inheritance stops and access control is deferred to the template. As an extra security measure, I've also set it up so that a page's template has to allow 'view' access in order for a page using it to inherit access from a parent page. Though I'm not sure if I should keep it this way... But here's the thinking: page level access control is a little bit dangerous in that one change can affect a lot of children (grandchildren, etc.), so that extra security is just so that the superuser exercise additional control where they deem necessary.

This is similar to access control in PW 2.0 except that it's a little simpler (and perhaps less powerful) in that all the roles are inherited as a group rather than individually. Though this also means less ambiguity, which is a good thing. But ultimately this module is just a starting point and you all may want to suggest improvements or take it further.

Caveats

The main caveat here is that this does not affect results returned from $pages->find(), $page->children(), etc. Those are purely controlled at the template level. Here's two scenarios where that could affect you:

1. If access is allowed by your template, but not by your page, your page may still appear in search results and API functions like $page->find() and $page->children(). That doesn't mean the user can view the page, only that it may appear in searches. If you don't want that to happen, you'd have to take the same approach that you did in PW 2.0. When outputting a list of pages, skip over any where $page->viewable() returns false.

2. I think this will be an uncommon situation, but if you have guest access disabled in a template, but enabled on the page, the page is not going to show up in API functions that return PageArray. To make it show up, you'd have to add: "check_access=0" to your selector, like this: $page->children("check_access=0").

---

Edit: re-uploaded CustomPagesRoles.module file to remove two lines of unnecessary code and incorrect summary. No significant functional changes though, so you don't need to re-download if you don't want to.

CustomPageRoles.module

  • Like 1
Link to comment
Share on other sites

Damn you Ryan. You write code faster than I write English?

Seriously, can't thank you enough. Additional module for page based permissions feels like best solution possible. Will test this soon and will give feedback on this.

Link to comment
Share on other sites

Thanks guys, don't give me too much credit or you'll be disappointed in this thing because it was put together quickly and there really isn't much to it. :) But I figure it at least gives us a good starting point.

Link to comment
Share on other sites

  • 3 months later...

Hi,

Just trying this module for this first time, and wanted to check on my expectations re what it is meant to do.

I've got a page that I don't want to be seen in the admin by users in a custom role I've created.  I've added the page_roles field to the template, and chosen only the superuser role in the Roles that can view this page section of the page.

However, when logged in as a user with the custom role I still see the page in the admin.

Am I missing something or shouldn't that page not be seen in the admin by this user?

Thanks to all of you for your great work on what is now my favorite CMS :)

- Evan

Link to comment
Share on other sites

This module bolts on top of the built-in access system rather than replacing it. It gets involved in runtime access control, but not low-level access control. As a result:

1. If access is allowed by your template, but not by your page, your page may still appear in search results and API functions like $page->find() and $page->children(). That doesn't mean the user can view the page, only that it may appear in searches. If you don't want that to happen, you'd have to take the same approach that you did in PW 2.0. When outputting a list of pages, skip over any where $page->viewable() returns false.

For the same reason, the pages can appear in your PageList, like you mentioned. Perhaps we can make a future version of this module hook into PageList and other things to add a viewable() check before showing in the PageList. But for the moment, I think this particular module is more of a good starting point for further coding/customization rather than something to use as your primary access control solution. I actually think the built-in access system with templates is the best way to go most of the time, but this module is a good fit for more rare specific instances.

Link to comment
Share on other sites

  • 2 months later...

Ryan, what you think about current status of this module? Do you think it will be core module at some point (disabled by default of course)?

I have site where is 5 main sections. All those 5 section have same template called "section". I use that information in many places of my code. Now client needs to have roles which can only edit pages in certain sections. If I would have known that before, I would probably added own template for each of those 5 main sections. But afterwards this is much more work, since I rely on that "section" template on many of my selectors etc... So I think that page-based access management might be best way to go here. All pages are public, this is only about editing access.

Link to comment
Share on other sites

Just realized that this module handles only view access. Looking at the code it seems like it could be relatively easy to extend for edit also, but how about other aspects (like creating new pages etc)?

Link to comment
Share on other sites

I think that ideally you would maintain a separate template for each of those sections, but I understand what you are saying that it may be more hassle to do that. I am interested in updating the CustomPageRoles module to go much further than it currently does, but that's down the road a bit. But I think it would be possible to create a module and hook after Page::editable (like CustomPageRoles is doing with Page::viewable). Your section template should enable access for all the roles that have edit access to any given section. But then your custom editable() function will remove that access when they aren't in the right section. You'll create a new role that has the same name as the section page, and then assign that role to the users that you want to be able to edit that section. Then you'd create an autoload module with logic like this:

public function init() {
   $this->addHookAfter('Page::editable', $this, 'editable'); 
}

public function editable(HookEvent $event) {

   $page = $event->object;

   // if this isn't a section template, or user is superuser, no need to check further
   if($page->template != 'section' || wire('user')->isSuperuser()) return;  

   // if they had no access at the template, then no need for us to check further
   if(!$event->return) return; 

   // we assume not-editable, until proven otherwise
   $editable = false; 

   // get a role that has the same name as the section page
   $role = wire('roles')->get($page->name); 

   // if the role exists, the user has the role, and the role has edit permission, then it's editable
   if($role && wire('user')->hasRole($role) && $role->hasPermission('page-edit') {
       $editable = true;
   }

   $event->return = $editable; 
}
Link to comment
Share on other sites

  • 1 month later...

On the topic of creating templates

I think that ideally you would maintain a separate template for each of those sections, but I understand what you are saying that it may be more hassle to do that.

I have found, so far, that I generally use one/few PHP template(s) but refer to it with different PW Admin templates (using Advanced > Alternate Template Filename), of course using different PW templates allows me to do lots of stuff in PW. But often I actually want the same editor presented to a client, regardless of which PW template a page is using.

As noted my solution is I duplicate the template and all is good. This however presents me with a small maintenance challenge, the lack of a DRY definition. E.g. After duplicating I now have two templates that I want to be the same but that can differ if one is changed and not the other, e.g. one has fields added or removed.

At the risk of adding complexity, for these cases I would love to be able to 'Template Alias', that is, create a new Template in PW Admin that is locked (useable for an editor to add content but not editable by the Admin to change the Template) and the Template Alias always mimics the settings of the source template, taking on changes that are made to it, such as field removal or addition.

This is likely an edge case request and so not worth doing, but it occurred to me more than once so I thought I'd note it both in it seems to have merit and also in case even if it's not directly useful maybe suggesting it will help in some way I've not thought of.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...