Jump to content

Restricting permissions on a specific page


jmart
 Share

Recommended Posts

found something intressting due to the new adminTemplate, hope someone can help me out here.

since every User is able to use the HeadButton (top right in breadcrumb), which seem to contain, on page/index , all templates you are allowed to create.
This will make my Startpoint irrelevant cause a User could "hack into other pages" through this little thing.

since my user is allowed to put in some content he can use the link "/page/add/?template_id=51" to see all pages (he shouldn't be allowed to)
so i thought "k fine.. gonna hook that"

when i was done i wanted to double check this hook with checking if i am allowed to still add pages
so by clicking a page in the admin menu -> new
i got this link "/page/add/?parent_id=1311"
nothing new for everyone who used PW so far.

but now comes the thing which wonders me.
my hook looked like this:
 

echo wire('user')->gsv_startingpoint->id;
if(wire('user')->gsv_startingpoint->id){
	$event->replace = true;
}
(i replace page/add when my startingpoint was set to a pageId)

wouldn't this mean that booth wouldn't give me any form ? (well should afaik)
/page/add/?parent_id=1311
/page/add/?template_id=51

but it doesn't
/page/add/?parent_id=1311 (normal functionality, also no echo is set at any point)
/page/add/?template_id=51 (no functionality as intended)


can someone explain me why it is like this ?
or help me with a workaround.
 
 
i had 2 ideas:
 
1. Edit the AdminTemplate Module (removing the HeadButton, but i actually like the functionality)
2. Hooking into PageAdd and removing its functionality when a starting point is set (when i crossed this weird bug)
Link to comment
Share on other sites

ahhhhhh...

i think i found the reason myself.

in ProcessPageAdd there is an execute and an executeTemplate function.

since i hooked into  executeTemplate it only works when ?template="something" is set

$this->addHookBefore('ProcessPageAdd::executeTemplate',$this,'executeTemplate');

so i choose the right one by accident and wondered about it in the end :D

Link to comment
Share on other sites

okay so this is what i got so far.
 

public function executeTemplate($event){

		//edit pageadd for startpoint
		//(otherwise user could use addnew to see other pages
		if(wire('user')->gsv_startingpoint->id > 0){
			$event->replace = true;
		}

		$templateID = (int) $this->input->get->template_id;
		if(!$templateID) throw new WireException("No template specified");
		$template = $this->templates->get($templateID);
		if(!$template) throw new WireException("Unknown template");
		$parentTemplates = $template->parentTemplates;
		$parentTemplate = $this->wire('templates')->get(reset($parentTemplates));
		if(!$parentTemplate) throw new WireException("Unable to locate parent template " . reset($parentTemplates));
		$parents = $this->wire('pages')->find("template=$parentTemplate, include=hidden, limit=500, sort=name, parent=".wire('user')->gsv_startingpoint->id);
		if(!count($parents)) throw new WireException("No usable parents match this template");
		if(count($parents) == 1) $this->wire('session')->redirect("./parent_id=" . $parents->first()->id);

		$templateLabel = $template;
		$parentTemplateLabel = $parentTemplate;
		$form = $this->wire('modules')->get('InputfieldForm');
		$form->description = $template;
		$form->method = 'get';
		$form->action = './';
		$form->attr('id', 'select_parent_form');
		$f = $this->wire('modules')->get('InputfieldSelect');
		$f->attr('name', 'parent_id');
		$f->attr('id', 'select_parent_id');
		$f->label = sprintf($this->_('Where do you want to add the new %s?'), strtolower($templateLabel));
		$f->description = sprintf($this->_('Please select a parent %s page below:'), strtolower($parentTemplateLabel));

		$options = array();
		foreach($parents as $parent) {

			if(!$parent->addable()) continue;
			$key = $parent->parent->title ? $parent->parent->title . " - " . $parent->parent->path : $parent->parent->path;

			if(!isset($options[$key])) $options[$key] = array();
			$options[$key][$parent->id] = $parent->get('title|name');
		}

		ksort($options);

		foreach($options as $optgroupLabel => $optgroup) {
			$f->addOption($optgroupLabel, $optgroup);
		}

		$form->add($f);
		$f = $this->wire('modules')->get('InputfieldSubmit');
		$f->attr('id', 'select_parent_submit');
		$form->add($f);
		return $form->render();

	}

my problem now is the return.. i cannot get the form into the content part of the page...

sadly i just needed to change only 1 line of code to get ryans code to work how i want it so i have some dublication of already existing code.
for those who want to know :

$parents = $this->wire('pages')->find("template=$parentTemplate, include=hidden, limit=500, sort=name, parent=".wire('user')->gsv_startingpoint->id); 

line of code i changed. ( i added the startingpoint id from the user object (gsv_startingpoin is a variable i needed to add to the user page object to get all this to work))
 

any ideas what i need to change to get the page add to work as intended ?

otherwise i will just remove the button, the work i put into this is getting out of hand...

Link to comment
Share on other sites

well.. seems like i found somewhat of a solution...
i would love if someone could tell me if this is done the right way or if someone is going to hunt me down for this solution :D

so what i did.

public function init() {

		$this->addHookBefore('ProcessPageList::execute', $this, 'startpoint');
******
		$this->addHookBefore('ProcessPageAdd::executeTemplate',$this,'cancel_executeTemplate');
		$this->addHookAfter('ProcessPageAdd::executeTemplate',$this,'executeTemplate');
******
	}

Startpoint is getting 2 new Hooks

1 Before

1 After

in the Before i check if the User has a page as Starting point.

public function cancel_executeTemplate(HookEvent $event){
		if(wire('user')->gsv_startingpoint->id > 0){
			$event->replace = true;
			$event->return = '';
		}
	}

i set replace to true so the original function should not be called

i remove the value from event return so otherwise it would be NULL

on after:

public function executeTemplate(HookEvent $event){

		if($event->return === ''){
			$templateID = (int) $this->input->get->template_id;
			if(!$templateID) throw new WireException("No template specified");
			$template = $this->templates->get($templateID);
			if(!$template) throw new WireException("Unknown template");
			$parentTemplates = $template->parentTemplates;
			$parentTemplate = $this->wire('templates')->get(reset($parentTemplates));
			if(!$parentTemplate) throw new WireException("Unable to locate parent template " . reset($parentTemplates));
			$parents = $this->wire('pages')->find("template=$parentTemplate, include=hidden, limit=500, sort=name, parent=".wire('user')->gsv_startingpoint->id);
			if(!count($parents)) throw new WireException("No usable parents match this template");
			if(count($parents) == 1) $this->wire('session')->redirect("./parent_id=" . $parents->first()->id);

			$templateLabel = $template;
			$parentTemplateLabel = $parentTemplate;
			$form = $this->wire('modules')->get('InputfieldForm');
			$form->description = $template;
			$form->method = 'get';
			$form->action = './';
			$form->attr('id', 'select_parent_form');
			$f = $this->wire('modules')->get('InputfieldSelect');
			$f->attr('name', 'parent_id');
			$f->attr('id', 'select_parent_id');
			$f->label = sprintf($this->_('Where do you want to add the new %s?'), strtolower($templateLabel));
			$f->description = sprintf($this->_('Please select a parent %s page below:'), strtolower($parentTemplateLabel));

			$options = array();
			foreach($parents as $parent) {

				if(!$parent->addable()) continue;
				$key = $parent->parent->title ? $parent->parent->title . " - " . $parent->parent->path : $parent->parent->path;

				if(!isset($options[$key])) $options[$key] = array();
				$options[$key][$parent->id] = $parent->get('title|name');
			}

			ksort($options);

			foreach($options as $optgroupLabel => $optgroup) {
				$f->addOption($optgroupLabel, $optgroup);
			}

			$form->add($f);
			$f = $this->wire('modules')->get('InputfieldSubmit');
			$f->attr('id', 'select_parent_submit');
			$form->add($f);
			$event->return = $form->render();
		}
	}

i doublecheck if the return value is '' (i don't like checking against null in php)

then using my own code for execute template (still i have almost the same code like ryan in his executeTemplate (ProcessPageAdd::executeTemplate))

as long as this code wont change i wont have a problem but as soon as, this could be problematic..

i tested this as superadmin and as user with sartingpoint and it seem to work properly.

attention:

of course you can use this code, but you need to change that one line !

public function cancel_executeTemplate(HookEvent $event){
		//use YOUR startpoint variable name here !!!!!
		if(wire('user')->gsv_startingpoint->id > 0){
			$event->replace = true;
			$event->return = '';
		}
	}
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

×
×
  • Create New...