Jump to content

Lock non-full admin users out of some pages


Adam Kiss
 Share

Recommended Posts

Hi,

I believe more people than me will be interested in this question.

situation

You, as either an agency or freelancer, want to give your client access to edit his website. After all, PW gives you very wide range of tools to create quite limited pages, having the exact fields you need to have, so your client doesn't make mistakes. However, you also use some pages or branches in your page tree to hold special types of data – banners, news, internal field pages, etc.

the need

You may need to lock some pages for clients: either make it un-editable (e.g. /news/ parent for news subpages) or flatout hidden (so clients are not confused with them, because they hold important page data, just un-editable by client)

the problem

How would you do this? While current system is quite nice, the user settings page isn't top of the class and also, it would be nice to know how pages' access settings override each other. If this has been already covered by documentation, please provide link (if google and other SE decide to pick up this topic – it might be easier to find for new users)

Adam

Link to comment
Share on other sites

This is one area where there are significant differences between PW 2.0 and 2.1, though both versions use a role-based access control system (RBAC). Here's how you do it in either version:

1. Create client role and assign permissions

The first thing you'll want to do is create a role for your client, called "client".These are the permissions you'd assign to your "client" role in 2.0:

  • ProcessPageView
  • ProcessPageEdit
  • ProcessPage... (any other Page permissions that you want them to have)
  • ProcessHome*
  • ProcessList*
  • ProcessLogin*
  • ProcessLogout*

The permissions listed above with an asterisk (*) are assumed in 2.1, so you don't have to specify them in 2.1.

These are the permissions you would assign to the "client" role in 2.1:

  • page-view
  • page-edit
  • page-* (any other "page-" permissions that you want them to have)

2. Create users and give them the client role

Now you have a role called "client" and it has most page editing permissions. Next you have to assign that role to some users. So you should create new users for your clients (or use existing users) and add the "client" role to them.

3. Assign the client role to the pages they can edit

You've got the "client" role and users added to that role. But those users still can't edit any pages. In order to give them edit access, you have to assign the "client" role to the pages the client can edit. On a large site this isn't practical on a page-by-page basis, so you will likely want to assign roles in a manner that affects multiple pages. This is the area where PW 2.0 and 2.1 differ the most.

3a. Assigning roles to pages in ProcessWire 2.0

In PW 2.0 you assign a role to a page, and any children inherit that role setting. That role inherits down through the tree to children, grandchildren, great-grandchildren, and so on. You can also remove that added role from any of those children (grandchildren, etc.) and that will likewise be inherited in the same way. This resembles how permissions inherit on a file system through a directory structure. In the case of your /news/ page, you would want to go ahead and edit that page and add the "client" role to it (on the page's settings tab). The client can now edit the /news/ page and any children. Note that you may not necessarily want them to be able to edit the actual /news/ page (as opposed to it's children)... unfortunately that's not an option in 2.0 unless you want to add roles to the news-items on a page-by-page basis.

3b. Assigning roles to pages in ProcessWire 2.1

In PW 2.1, you no longer assign roles to individual pages. Instead you assign them to templates. So you will want to assign the "client" role to your "news-item" template. If you also want them to be able to edit the actual "news" page, you can add the "client" role to your "news" template. But I'm guessing you only want them to be able to edit the news items, and not the actual news page. Assuming you added the "client" role to just your "news-item" template, the client can now edit any news item pages.

In either of the above cases, the client can't edit anything other than what you assigned to them. That client can edit "news-items" (and possibly the /news/ page), but they can't edit anything else in the site.

4. Hiding pages from the client role

If you want a page to be completely hidden from your client, they have to lack view access to it. In your case, I'm assuming we're talking about a branch to hold special types of data (banners, etc.) that isn't typically rendered as pages. Lets say these pages are located under /tools/, and you want that section to be invisible to anyone except the superuser.

In PW 2.0, you'd remove ALL roles from the "/tools/" page. In PW 2.1, you'd remove ALL roles from any of the templates used by pages in the "/tools/" tree of pages. If you still had some roles that you wanted these pages to be visible (like an "editor" role, or the like), then you would keep that role assigned, but remove all the others.

Now only the superuser can see those pages, and the client won't see them in the admin. You can still pull data from these pages via the API as much as you'd like.

4a. Letting roles inherit in 2.1

PW 2.1 also gives you the option of having roles inherit through pages (like they do in 2.0), which you might want to do if pages in your /tools/ section are using various different templates. In that case, you'd set those various templates to "not manage access" (under each template's "access" tab). And you'd remove all roles from whatever template is being used by your main /tools/ page (we'll assume it's called your "tools" template). Now all access to your /tools/ pages is managed in one spot.

4b. Tell PW 2.1 to automatically exclude pages from search results

If you are using PW 2.1, you might also want to check the box for the setting on the "tools" template that tells it to exclude pages from search results when the user doesn't have access to them. That way you won't have to worry about any of those pages showing up in any search engines you build for your site. (You couldn't do this in 2.0, instead you had to filter these yourself).

Automatically excluded pages and the API

Pages that a user doesn't have access to, and that are excluded from search results (as outlined above) are automatically excluded from $pages->find, $page->children and any API call that returns multiple pages. From the perspective of your API call, this is identical to the behavior of pages that have a "hidden" status. This is desirable for most of your site, but maybe not when you are trying to pull multiple banners from /tools/banners/ with a $pages->find. You can cancel that behavior for your API call by adding a "check_access=0" selector to your API call, i.e.

$banners = $pages->find("parent=/tools/banners/, limit=3, sort=random, check_access=0"); 

That "check_access=0" essentially tells it to ignore whatever access the current user has. You don't need to do this with API calls that return single pages (like $pages->get) because such filtering is more of an annoyance than a help on such specific calls. It also maintains consistency with the behavior of pages with a "hidden" status -- they are automatically excluded API functions that return multiple pages, but not those that return single pages.

Link to comment
Share on other sites

  • 10 months later...

Thanks for this excellent walk-through Ryan.

I am using a /tools/ pages (not visible to a client) to hide pages such as /search/ and /tagged/the-tags etc. This works fine, the only slight compromise is that any page I want to use for display below tools has /tools/ in it's url such as /tools/search/.

Am I missing something simple that would allow me to 'collapse-up', hide the /tools/ part of the URLs for such pages?

Link to comment
Share on other sites

Am I missing something simple that would allow me to 'collapse-up', hide the /tools/ part of the URLs for such pages?

You could do it with URL segments on your homepage template:

if($input->urlSegment1 == 'search') {
   echo $pages->get('/tools/search/')->render(); 
} else {
   // output your homepage
}

For me, I guess I've always seen something like "search" as a tool, and being a good fit in /tools/search/. But you can of course structure it however you'd like.

  • Like 1
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
 Share

  • Recently Browsing   0 members

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