ridgedale

[Solved] PW3 - Backend Access Roles & Permissions

Recommended Posts

Reference: PW 3.0.62 and uikit3 based site using the Regular-Master profile.

I have a multi-site running where I now need to start adding users. All my searches have drawn a blank regarding how to setup users with restricted permissions.

In the first instance I would like to be able to give a potential site admin access to the backend with sufficient permissions so that s/he may be able to navigate round the backend to familiarise herself/himself with the interface without actually submitting edits, making deletions, changing templates, etc. Is it actually possible to do this? If so, could anyone give me an idea how I go about implementing this?

What I tried initially was to give View and Page Edit permissions to the guest admin user but when I logged in as that user all that user is able to do is effectively view the website. When I ran a search for any modules that might help the returned hits all appeared to relate to old incompatible modules.

An alternative solution I thought of would be to setup a duplicate of the live website that I could allow guest users to go in with full privileges, but I'm not really sure how it wold be best to go about that. I can see that I am rapidly needing to move from a simple multi-site setup to a demo / dev / staging / production setup for this group of sites.

Any guidance would be appreciated.

Share this post


Link to post
Share on other sites

Hi @ridgedale

ProcessWire can do anything! Like, I'm serious. When people call it more of a framework, they are right. There are no limitations here.

So you want to be able to have someone have the ability to look around the interface without submitting anything? Easily done using hooks.

wire()->addHookBefore("Pages::saveReady", function($event) {
	if(wire("user")->hasRole('YOUR-ROLE')) {
		$this->error("Sorry, you do not have permission to edit.");
		return false;
	}
}

I haven't tested this, but I think it will work how you want. Replace 'YOUR-ROLE' with a created role.

You can add this by creating a 'ready.php' in your /site/ folder.

  • Like 1

Share this post


Link to post
Share on other sites

Hi Tom,

Thanks again for your reply.

52 minutes ago, Tom. said:

... So you want to be able to have someone have the ability to look around the interface without submitting anything?

That's correct. In addition to other restrictions that I think ought to be applied such as: with deleting, moving or sorting anything, adding, removing and configuring modules and adding, removing and editing templates. So taking on board your suggestion I am wondering whether or not it might be possible to implement this with the following logic:

If the wire user does NOT

->hasRole('YOUR-ROLE')

then if trying to install, configure, edit or delete anything

exit;
} else {
		$this->error("Sorry. You do not have permission to perform this action.");
		return false;
}

Are there any actions a superuser might have access to that you wouldn't want a guest potential superuser messing about with that I haven't covered?

Share this post


Link to post
Share on other sites

@ridgedale I think the "} else {" wouldn't work in this instance as it's just a hook. However, you can hook all the actions you want to prevent. 

wire()->addHookBefore("Pages::saveReady", function($event) {
	if(wire("user")->hasRole('demo-user')) {
		$this->error("Sorry. You do not have permission to edit pages.");
		return false;
	}
}

wire()->addHookBefore("Pages::moved", function($event) {
	if(wire("user")->hasRole('demo-user')) {
		$this->error("Sorry. You do not have permission to move pages.");
		return false;
	}
}

wire()->addHookBefore("Pages::sorted", function($event) {
	if(wire("user")->hasRole('demo-user')) {
		$this->error("Sorry. You do not have permission to sort pages.");
		return false;
	}
}

wire()->addHookBefore("Pages::trashed", function($event) {
	if(wire("user")->hasRole('demo-user')) {
		$this->error("Sorry. You do not have permission to delete pages.");
		return false;
	}
}

If I recall Pages::saveReady get's called in all of these as they all require saving new information to the page. For example Trashed is just a status on the page. So you may only need Pages::saveReady but it's worth checking because I don't know for sure. 

  • Like 1

Share this post


Link to post
Share on other sites

@Tom. Thanks again for your feedback.

I'll give that a try, test it and let you know how I get on.

Does the wire()->addHookBefore("Pages::... also apply to modules and templates, as well as pages? 

Share this post


Link to post
Share on other sites

I haven't tested it, but in ProcessWire - everything is a page. So I think so.

Share this post


Link to post
Share on other sites

@Tom. Thanks for the update.

I've created the ready.php file and added the following code with and without enclosing it with <?php namespace ProcessWire; ?> to no avail. The user with the demo-admin role still has the permissions to make changes.

<?php namespace ProcessWire; 

wire()->addHookBefore("Pages::moved", function($event) {
	if(wire("user")->hasRole('demo-admin')) {
		$this->error("Sorry. You do not have permission to move pages.");
		return false;
	}
}

wire()->addHookBefore("Pages::sorted", function($event) {
	if(wire("user")->hasRole('demo-admin')) {
		$this->error("Sorry. You do not have permission to sort pages.");
		return false;
	}
}

wire()->addHookBefore("Pages::cloneReady", function($event) {
	if(wire("user")->hasRole('demo-admin')) {
		$this->error("Sorry. You do not have permission to clone pages.");
		return false;
	}
}

wire()->addHookBefore("Pages::deleteReady", function($event) {
	if(wire("user")->hasRole('demo-admin')) {
		$this->error("Sorry. You do not have permission to delete pages.");
		return false;
	}
}

wire()->addHookBefore("Pages::publishReady", function($event) {
	if(wire("user")->hasRole('demo-admin')) {
		$this->error("Sorry. You do not have permission to publish pages.");
		return false;
	}
}

wire()->addHookBefore("Pages::saveFieldReady", function($event) {
	if(wire("user")->hasRole('demo-admin')) {
		$this->error("Sorry. You do not have permission to save field changes.");
		return false;
	}
}

wire()->addHookBefore("Pages::saveReady", function($event) {
	if(wire("user")->hasRole('demo-admin')) {
		$this->error("Sorry. You do not have permission to edit pages.");
		return false;
	}
}

wire()->addHookBefore("Pages::statusChangeReady", function($event) {
	if(wire("user")->hasRole('demo-admin')) {
		$this->error("Sorry. You do not have permission to unpublish pages.");
		return false;
	}
}

wire()->addHookBefore("Pages::unpublishReady", function($event) {
	if(wire("user")->hasRole('demo-admin')) {
		$this->error("Sorry. You do not have permission to unpublish pages.");
		return false;
	}
}
?>

I also note that my comment regarding modules and templates is irrelevant as non-superusers have no access to them by default.

I'm not sure where I'm going wrong. Any thoughts appreciated.

Share this post


Link to post
Share on other sites

Hey, sorry. So I've looked into this for you and I was completely wrong. 

To explain - hooks are functions that run before or after another function such as Page::save(). So return false; will only return false on the extended function and not the save() function itself so the save will still happen. Actually the solution is much, much simpler.

In your ready.php all you need is

<?php
    if(wire('user')->hasRole('demo-user')) {
      wire('config')->demo = true;
    }
?>

That's it 🙂

  • Like 4

Share this post


Link to post
Share on other sites

There is no need to apologise, Tom, for freely offering your time to help. Your assistance is greatly appreciated.

Just to clarify, is the role "demo-user" a built-in role? If so, how do I assign it to a user, as that role does not currently exist?

Also, does demo in:

wire('config')->demo = true;

to a built-in demo capability for any website? Or is demo something that needs to be setup?

Share this post


Link to post
Share on other sites

Hi Ridgedale,

The 'demo-user' is a role you will have to setup and assign to the user in which you want to have a demo experience. The $config->demo or wire('config')->demo when inside a function is built in ProcessWire functionality which powers the demo which Ryan provides - https://processwire.com/demo/

After you put the code provided into ready.php - all you have to do is create the role and assign it to the users you want a demo experience.

 

Share this post


Link to post
Share on other sites

Thanks again for your reply, @Tom.

Unfortunately the https://processwire.com/demo/ isn't really very help as I would prefer that demo-admin users are able to view the backend interface they will very likely be using with all the current pages. I wonder: Is possible to set up a demo site based on an existing site and, if so, how to go about it?

Share this post


Link to post
Share on other sites

Hi @Tom. ,

I did a search for wire('config')->demo and found the following topic:

and have downloaded the v.3 Skyscrapers profile from the link provided by @Robin S .

That should provide the information I need.

Many thanks again for your assistance and patience.

Share this post


Link to post
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.