Jump to content

Redirect admin pages disables logout


ren
 Share

Recommended Posts

Hi all,

I'm creating a website for a magazine publisher. This will include a supplier section with press releases attached to company profiles. The idea is that companies can register and manage their profile and press releases (CRUD) via a dashboard.

The dashboard is a Process module. Ben Byford's RedirectAdminPages module is being used to lock out the rest of the backend, with a few modifications.

The following code should redirect every admin page to the dashboard page but still allowing logging out. However logging out just redirects to the dashboard page:

    // do not redirect if page matches:
    if($this->page->template != "admin" // any non-admin page 
	|| $this->page->is($this->redirectPage) // the dashboard page (prevent infinite loop)
	|| $this->page->parent->is('/admin/login/') // various attempts to allow logging out
	|| $this->wire("process") == 'ProcessLogin'
	|| strpos($this->page->url, $this->wire('config')->urls->admin . 'login/logout') !== false
	) {
      return;
    }

    // find roles set in module configuration and create array
    $roles = explode(',', $this->userRoles);

    // for each user in module config check to see if current user
    foreach ($roles as $key => $val) {

      // get a role from the roles array
      $roles[$key] = trim($roles[$key]);

      // if current user found with role then redirect
      if($this->user->hasRole($roles[$key])){

        // redirect session to page stored in config
        $this->session->redirect($this->redirectPage);

        // code should never get here but this is a simple fallback
        break;
      }
    }
  }
}

I'm surprised that this URL matching doesn't work:

|| strpos($this->page->url, $this->wire('config')->urls->admin . 'login/logout') !== false

Because this does work for allowing page edit:

|| strpos($this->page->url, $this->wire('config')->urls->admin . 'page/edit') !== false

Any ideas?

That issue aside, as a learning process I'm going to re-implement the dashboard as front-end pages. I guess that the advantage of using the ProcessWire back-end is most of the functionality is already there, you don't need to create forms and handle the processing, create / import css etc. So it'll be interesting to see how much of a difference this makes, and how much control each approach provides. I'd love to have some thoughts and feedback from those of you who've tried both methods?

PS this will be my third website created with ProcessWire and it's already been a lot of fun, and as a CMS it 'just feels right', so a big thanks to Ryan and everyone who has contributed.

Thanks :)

  • Like 1
Link to comment
Share on other sites

Hi and welcome @ren!

I recommend you install the Tracy Debugger module as you'll find this an essential tool when developing.

Then you can dump the $page object above your if() conditional and explore what its properties are (parent, url, etc). It should be obvious then why $page will or will not match those conditions you have set.

// do not redirect if page matches:
bd($this->page, 'page');
if($this->page->template != "admin" // any non-admin page 
    || $this->page->is($this->redirectPage) // the dashboard page (prevent infinite loop)
    || $this->page->parent->is('/admin/login/') // various attempts to allow logging out
    || $this->wire("process") == 'ProcessLogin'
    || strpos($this->page->url, $this->wire('config')->urls->admin . 'login/logout') !== false
) {
  return;
}

 

  • Like 3
Link to comment
Share on other sites

Hi @Robin S,

Thanks, Tracy Debugger is looovely. I did as you said, and put db calls to log both cases (redirect and no redirect):

// do not redirect if page matches:
if($this->page->template != "admin" // any non-admin page 
    || $this->page->is($this->redirectPage) // the dashboard page (prevent infinite loop)
    || $this->page->parent->is('/admin/login/') // various attempts to allow logging out
    || $this->wire("process") == 'ProcessLogin'
    || strpos($this->page->url, $this->wire('config')->urls->admin . 'login/logout') !== false
) {
	bd($this->page, 'no redirect page');
	return;
}

bd($this->page, 'redirect page');

When I tried to logout it logged both cases, with 'redirect page' first:

data protected => array (3) title => "Login" (5) process => "ProcessLogin" (12) urlSegment => "logout" (6)

... for some reason 'ProcessLogin' is sailing through the conditional.

Followed by 'no redirect page':

data protected => array (2) title => "Dashboard" (9) process => "ProcessDashboard" (16)
The first log gave me the idea to match the urlSegment, which works a charm!

So if it's of any use to anyone, the working code is:

    if($this->page->template != "admin" || $this->page->is($this->redirectPage) || $this->input->urlSegment1 == 'logout') {
      return;
    }

    // find roles set in module configuration and create array
    $roles = explode(',', $this->userRoles);

    // for each user in module config check to see if current user
    foreach ($roles as $key => $val) {

      // get a role from the roles array
      $roles[$key] = trim($roles[$key]);

      // if current user found with role then redirect
      if($this->user->hasRole($roles[$key])){

        // redirect session to page stored in config
        $this->session->redirect($this->redirectPage);

        // code should never get here but this is a simple fallback
        break;
      }
    }

Thanks Robin, you've been a great help, and I'm sure to be using Tracy Debugger again :)

  • Like 1
Link to comment
Share on other sites

14 minutes ago, ren said:

When I tried to logout it logged both cases, with 'redirect page' first:


data protected => array (3) title => "Login" (5) process => "ProcessLogin" (12) urlSegment => "logout" (6)

... for some reason 'ProcessLogin' is sailing through the conditional.

Not sure but perhaps because you are not checking the process property of $this->page, i.e. instead of this...

|| $this->wire("process") == 'ProcessLogin'

...try...

|| $this->page->process == 'ProcessLogin'

 

  • Like 1
Link to comment
Share on other sites

10 hours ago, Robin S said:

Not sure but perhaps because you are not checking the process property of $this->page, i.e. instead of this...


|| $this->wire("process") == 'ProcessLogin'

...try...


|| $this->page->process == 'ProcessLogin'

 

Doh. Yes, that works :-) Prefer this to matching urlSegment I think.

Thanks!

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...