-
Notifications
You must be signed in to change notification settings - Fork 342
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
New redirect strategy #480
base: master
Are you sure you want to change the base?
Changes from 7 commits
418ac43
a720f37
5d54a4b
2becf29
98f0953
2115f58
d2f12b0
779a577
a4ca815
d3c228a
de165fb
e5b2977
d674ec2
6abfd1a
cf16a3f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,127 @@ | ||
<?php | ||
|
||
namespace ZfcUser\Controller; | ||
|
||
use Zend\Mvc\Application; | ||
use Zend\Mvc\Router\RouteInterface; | ||
use Zend\Mvc\Router\RouteMatch; | ||
use Zend\Mvc\Router\Exception; | ||
use Zend\Http\PhpEnvironment\Request; | ||
use Zend\Http\PhpEnvironment\Response; | ||
use ZfcUser\Options\ModuleOptions; | ||
|
||
/** | ||
* Class RedirectCallback | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not descriptive |
||
* @package ZfcUser\Controller | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No need for |
||
*/ | ||
class RedirectCallback | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Missing docblock |
||
{ | ||
/** @var RouteMatch */ | ||
protected $routeMatch; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. RouteMatch should not be part of the object's state There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you also make all properties |
||
|
||
/** @var RouteInterface */ | ||
protected $router; | ||
|
||
/** @var Response */ | ||
protected $response; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Request and response should not be localized as properties. |
||
|
||
/** @var Request */ | ||
protected $request; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same as above |
||
|
||
/** @var Application */ | ||
protected $application; | ||
|
||
/** @var ModuleOptions */ | ||
protected $options; | ||
|
||
/** | ||
* @param Application $application | ||
* @param RouteInterface $router | ||
* @param ModuleOptions $options | ||
*/ | ||
public function __construct(Application $application, RouteInterface $router, ModuleOptions $options) | ||
{ | ||
$this->routeMatch = $application->getMvcEvent()->getRouteMatch(); | ||
$this->router = $router; | ||
$this->application = $application; | ||
$this->options = $options; | ||
} | ||
|
||
/** | ||
* @return Response | ||
*/ | ||
public function __invoke() | ||
{ | ||
$redirect = $this->getRedirect($this->routeMatch->getMatchedRouteName(), $this->getRedirectRouteFromRequest()); | ||
|
||
$response = $this->application->getResponse(); | ||
$response->getHeaders()->addHeaderLine('Location', $redirect); | ||
$response->setStatusCode(302); | ||
return $response; | ||
} | ||
|
||
/** | ||
* Return the redirect from param. | ||
* First checks GET then POST | ||
* @return string | ||
*/ | ||
protected function getRedirectRouteFromRequest() | ||
{ | ||
$request = $this->application->getRequest(); | ||
$redirect = $request->getQuery('redirect'); | ||
if ($redirect && $this->routeExists($redirect)) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why would you allow passing in a redirect route name? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is mostly because of BC. It is possible with current versions, and i want to backport this into 1.x and 0.x branches. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, wondering if it's that important - this is additional useless complexity :( |
||
return $redirect; | ||
} | ||
|
||
$redirect = $request->getPost('redirect'); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why would you need to check There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Current versions checks both GET and POST for a redirect param. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same as above. I understand the BC concerns, but this is really overkill. Maybe get rid of it later (2.x)? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah this is only for 1.x and 0.x BC. |
||
if ($redirect && $this->routeExists($redirect)) { | ||
return $redirect; | ||
} | ||
|
||
return false; | ||
} | ||
|
||
/** | ||
* @param $route | ||
* @return bool | ||
*/ | ||
protected function routeExists($route) | ||
{ | ||
try { | ||
$this->router->assemble([], ['name' => $route]); | ||
} catch (Exception\RuntimeException $e) { | ||
return false; | ||
} | ||
return true; | ||
} | ||
|
||
/** | ||
* Returns the url to redirect to based on current route. | ||
* If $redirect is set and the option to use redirect is set to true, it will return the $redirect url. | ||
* | ||
* @param string $currentRoute | ||
* @param bool $redirect | ||
* @return mixed | ||
*/ | ||
protected function getRedirect($currentRoute, $redirect = false) | ||
{ | ||
$useRedirect = $this->options->getUseRedirectParameterIfPresent(); | ||
$routeExists = ($redirect && $this->routeExists($redirect)); | ||
if (!$useRedirect || !$routeExists) { | ||
$redirect = false; | ||
} | ||
|
||
switch ($currentRoute) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If you make this thing a controller plugin (which I would advice), you can also reuse the url and/or redirect controller plugins. This just duplicates logic of assembling and returning responses There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Agree, this should be a controller plugin. I am refactoring as we speak. |
||
case 'zfcuser/login': | ||
$route = ($redirect) ?: $this->options->getLoginRedirectRoute(); | ||
return $this->router->assemble([], ['name' => $route]); | ||
break; | ||
case 'zfcuser/logout': | ||
$route = ($redirect) ?: $this->options->getLogoutRedirectRoute(); | ||
return $this->router->assemble([], ['name' => $route]); | ||
break; | ||
default: | ||
return $this->router->assemble([], ['name' => 'zfcuser']); | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -55,6 +55,22 @@ class UserController extends AbstractActionController | |
*/ | ||
protected $options; | ||
|
||
/** | ||
* @var callable $redirectCallback | ||
*/ | ||
protected $redirectCallback; | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Remove this empty newline There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Was 2 before, 1 now as it should be. |
||
/** | ||
* @param callable $redirectCallback | ||
*/ | ||
public function __construct($redirectCallback) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Does ZfcUser require 5.3? Otherwise, |
||
{ | ||
if (!is_callable($redirectCallback)) { | ||
throw new \InvalidArgumentException('You must supply a callable redirectCallback'); | ||
} | ||
$this->redirectCallback = $redirectCallback; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Check against |
||
} | ||
|
||
/** | ||
* User page | ||
*/ | ||
|
@@ -116,13 +132,9 @@ public function logoutAction() | |
$this->zfcUserAuthentication()->getAuthAdapter()->logoutAdapters(); | ||
$this->zfcUserAuthentication()->getAuthService()->clearIdentity(); | ||
|
||
$redirect = $this->params()->fromPost('redirect', $this->params()->fromQuery('redirect', false)); | ||
|
||
if ($this->getOptions()->getUseRedirectParameterIfPresent() && $redirect) { | ||
return $this->redirect()->toRoute($redirect); | ||
} | ||
$redirect = $this->redirectCallback; | ||
|
||
return $this->redirect()->toRoute($this->getOptions()->getLogoutRedirectRoute()); | ||
return $redirect(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Newline before this line if possible |
||
} | ||
|
||
/** | ||
|
@@ -155,17 +167,16 @@ public function authenticateAction() | |
); | ||
} | ||
|
||
if ($this->getOptions()->getUseRedirectParameterIfPresent() && $redirect) { | ||
return $this->redirect()->toRoute($redirect); | ||
} | ||
|
||
$route = $this->getOptions()->getLoginRedirectRoute(); | ||
|
||
if (is_callable($route)) { | ||
$route = $route($this->zfcUserAuthentication()->getIdentity()); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why is a callback support needed here? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Now that we have this redirect callback, it's not needed, but it would be BC to remove. |
||
return $this->redirect()->toRoute($route); | ||
} | ||
|
||
return $this->redirect()->toRoute($route); | ||
$redirect = $this->redirectCallback; | ||
|
||
return $redirect(); | ||
} | ||
|
||
/** | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
<?php | ||
namespace ZfcUser\Factory\Controller; | ||
|
||
use Zend\Mvc\Application; | ||
use Zend\Mvc\Router\RouteInterface; | ||
use Zend\ServiceManager\FactoryInterface; | ||
use Zend\ServiceManager\ServiceLocatorInterface; | ||
use ZfcUser\Controller\RedirectCallback; | ||
use ZfcUser\Options\ModuleOptions; | ||
|
||
class RedirectCallbackFactory implements FactoryInterface | ||
{ | ||
/** | ||
* {@inheritDoc} | ||
*/ | ||
public function createService(ServiceLocatorInterface $serviceLocator) | ||
{ | ||
/* @var RouteInterface $router */ | ||
$router = $serviceLocator->get('Router'); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you add some IDE hints here? They help with static analysis |
||
|
||
/* @var Application $application */ | ||
$application = $serviceLocator->get('Application'); | ||
|
||
/* @var ModuleOptions $options */ | ||
$options = $serviceLocator->get('zfcuser_module_options'); | ||
|
||
return new RedirectCallback($application, $router, $options); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
<?php | ||
namespace ZfcUser\Factory\Controller; | ||
|
||
use Zend\Mvc\Controller\ControllerManager; | ||
use Zend\ServiceManager\FactoryInterface; | ||
use Zend\ServiceManager\ServiceLocatorInterface; | ||
use ZfcUser\Authentication\Adapter; | ||
use ZfcUser\Controller\RedirectCallback; | ||
use ZfcUser\Controller\UserController; | ||
|
||
class UserControllerFactory implements FactoryInterface | ||
{ | ||
/** | ||
* {@inheritDoc} | ||
*/ | ||
public function createService(ServiceLocatorInterface $controllerManager) | ||
{ | ||
/* @var ControllerManager $controllerManager*/ | ||
$serviceManager = $controllerManager->getServiceLocator(); | ||
|
||
/* @var RedirectCallback $redirectCallback */ | ||
$redirectCallback = $serviceManager->get('zfcuser_redirect_callback'); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same as above - hints |
||
|
||
/* @var UserController $controller */ | ||
$controller = new UserController($redirectCallback); | ||
|
||
return $controller; | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing headers
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As discussed, this may be done later