/**
  * {@inheritDoc}
  */
 public function redirect($url, $status = null)
 {
     if (Router::normalize($this->Auth->config('loginAction')) == Router::normalize($url)) {
         return $this->Api->response(ApiReturnCode::NOT_AUTHENTICATED);
     }
     return parent::redirect($url, $status);
 }
 protected function getExistingUser(Request $request)
 {
     $login_url = isset($this->_config['login_url']) ? $this->_config['login_url'] : null;
     $server_unique_id_field = $this->_config['unique_id'];
     $user_unique_id_field = $this->_config['mapping'][$server_unique_id_field];
     /*
      * Check if the Shibboleth authentication must be done on the current URL
      */
     $do_login = false;
     if (empty($login_url)) {
         /*
          * By default, Shibboleth login is done on every urls
          */
         $do_login = true;
     } else {
         /*
          * A specific url is given for login. Check if it matches the current request
          */
         /*
          * When CsrfComponent is used, a '_csrfToken' key exist in $request->params and it prevents urls comparison
          * -> remove it
          * 
          * Since CakePHP 3.2.11 a '_matchedRoute' key may exist in $request->params, also preventing urls comparison
          * -> remove it
          */
         $request_params = $request->params;
         unset($request_params['_csrfToken']);
         unset($request_params['_matchedRoute']);
         $normalized_login_url = StringTool::remove_trailing(Router::normalize(Router::url($login_url)), '?');
         $normalized_current_url = StringTool::remove_trailing(Router::normalize(Router::url($request_params)), '?');
         if ($normalized_login_url == $normalized_current_url) {
             $do_login = true;
         }
     }
     if ($do_login) {
         $this->_config['fields']['username'] = $user_unique_id_field;
         $user = $this->_findUser($this->get_server_value($request, $server_unique_id_field));
         if (!empty($user)) {
             $user = $this->updateUserAttributes($request, $user);
             if (!empty($user)) {
                 return $user->toArray();
             }
         } else {
             if (isset($this->_config['create_new_user']) && $this->_config['create_new_user']) {
                 $user = $this->createNewUser($request);
                 if (!empty($user)) {
                     return $user->toArray();
                 }
             }
         }
     }
     return false;
 }
Exemplo n.º 3
0
 /**
  * test that the returned URL doesn't contain the base URL.
  *
  * @see https://cakephp.lighthouseapp.com/projects/42648/tickets/3922-authcomponentredirecturl-prepends-appbaseurl
  *
  * @return void This test method doesn't return anything.
  */
 public function testRedirectUrlWithBaseSet()
 {
     $App = Configure::read('App');
     Configure::write('App', ['dir' => APP_DIR, 'webroot' => 'webroot', 'base' => false, 'baseUrl' => '/cake/index.php']);
     $url = '/users/login';
     $this->Auth->request = $this->Controller->request = new Request($url);
     $this->Auth->request->addParams(Router::parse($url));
     $this->Auth->request->url = Router::normalize($url);
     Router::setRequestInfo($this->Auth->request);
     $this->Auth->config('loginAction', ['controller' => 'users', 'action' => 'login']);
     $this->Auth->config('loginRedirect', ['controller' => 'users', 'action' => 'home']);
     $result = $this->Auth->redirectUrl();
     $this->assertEquals('/users/home', $result);
     $this->assertFalse($this->Auth->session->check('Auth.redirect'));
     Configure::write('App', $App);
     Router::reload();
 }
Exemplo n.º 4
0
 /**
  * testUrlNormalization method
  *
  * @return void
  */
 public function testUrlNormalization()
 {
     Router::connect('/:controller/:action');
     $expected = '/users/logout';
     $result = Router::normalize('/users/logout/');
     $this->assertEquals($expected, $result);
     $result = Router::normalize('//users//logout//');
     $this->assertEquals($expected, $result);
     $result = Router::normalize('users/logout');
     $this->assertEquals($expected, $result);
     $result = Router::normalize(array('controller' => 'users', 'action' => 'logout'));
     $this->assertEquals($expected, $result);
     $result = Router::normalize('/');
     $this->assertEquals('/', $result);
     $result = Router::normalize('http://google.com/');
     $this->assertEquals('http://google.com/', $result);
     $result = Router::normalize('http://google.com//');
     $this->assertEquals('http://google.com//', $result);
     $result = Router::normalize('/users/login/scope://foo');
     $this->assertEquals('/users/login/scope:/foo', $result);
     $result = Router::normalize('/recipe/recipes/add');
     $this->assertEquals('/recipe/recipes/add', $result);
     $request = new Request();
     $request->base = '/us';
     Router::setRequestInfo($request);
     $result = Router::normalize('/us/users/logout/');
     $this->assertEquals('/users/logout', $result);
     Router::reload();
     $request = new Request();
     $request->base = '/cake_12';
     Router::setRequestInfo($request);
     $result = Router::normalize('/cake_12/users/logout/');
     $this->assertEquals('/users/logout', $result);
     Router::reload();
     $_back = Configure::read('App.fullBaseUrl');
     Configure::write('App.fullBaseUrl', '/');
     $request = new Request();
     $request->base = '/';
     Router::setRequestInfo($request);
     $result = Router::normalize('users/login');
     $this->assertEquals('/users/login', $result);
     Configure::write('App.fullBaseUrl', $_back);
     Router::reload();
     $request = new Request();
     $request->base = 'beer';
     Router::setRequestInfo($request);
     $result = Router::normalize('beer/admin/beers_tags/add');
     $this->assertEquals('/admin/beers_tags/add', $result);
     $result = Router::normalize('/admin/beers_tags/add');
     $this->assertEquals('/admin/beers_tags/add', $result);
 }
Exemplo n.º 5
0
 /**
  * Calls a controller's method from any location. Can be used to connect controllers together
  * or tie plugins into a main application. requestAction can be used to return rendered views
  * or fetch the return value from controller actions.
  *
  * Under the hood this method uses Router::reverse() to convert the $url parameter into a string
  * URL. You should use URL formats that are compatible with Router::reverse()
  *
  * ### Examples
  *
  * A basic example getting the return value of the controller action:
  *
  * ```
  * $variables = $this->requestAction('/articles/popular');
  * ```
  *
  * A basic example of request action to fetch a rendered page without the layout.
  *
  * ```
  * $viewHtml = $this->requestAction('/articles/popular', ['return']);
  * ```
  *
  * You can also pass the URL as an array:
  *
  * ```
  * $vars = $this->requestAction(['controller' => 'articles', 'action' => 'popular']);
  * ```
  *
  * ### Passing other request data
  *
  * You can pass POST, GET, COOKIE and other data into the request using the appropriate keys.
  * Cookies can be passed using the `cookies` key. Get parameters can be set with `query` and post
  * data can be sent using the `post` key.
  *
  * ```
  * $vars = $this->requestAction('/articles/popular', [
  *   'query' => ['page' => 1],
  *   'cookies' => ['remember_me' => 1],
  * ]);
  * ```
  *
  * ### Sending environment or header values
  *
  * By default actions dispatched with this method will use the global $_SERVER and $_ENV
  * values. If you want to override those values for a request action, you can specify the values:
  *
  * ```
  * $vars = $this->requestAction('/articles/popular', [
  *   'environment' => ['CONTENT_TYPE' => 'application/json']
  * ]);
  * ```
  *
  * ### Transmitting the session
  *
  * By default actions dispatched with this method will use the standard session object.
  * If you want a particular session instance to be used, you need to specify it.
  *
  * ```
  * $vars = $this->requestAction('/articles/popular', [
  *   'session' => new Session($someSessionConfig)
  * ]);
  * ```
  *
  * @param string|array $url String or array-based url.  Unlike other url arrays in CakePHP, this
  *    url will not automatically handle passed arguments in the $url parameter.
  * @param array $extra if array includes the key "return" it sets the autoRender to true.  Can
  *    also be used to submit GET/POST data, and passed arguments.
  * @return mixed Boolean true or false on success/failure, or contents
  *    of rendered action if 'return' is set in $extra.
  * @deprecated 3.3.0 You should refactor your code to use View Cells instead of this method.
  */
 public function requestAction($url, array $extra = [])
 {
     if (empty($url)) {
         return false;
     }
     if (($index = array_search('return', $extra)) !== false) {
         $extra['return'] = 0;
         $extra['autoRender'] = 1;
         unset($extra[$index]);
     }
     $extra += ['autoRender' => 0, 'return' => 1, 'bare' => 1, 'requested' => 1];
     $baseUrl = Configure::read('App.fullBaseUrl');
     if (is_string($url) && strpos($url, $baseUrl) === 0) {
         $url = Router::normalize(str_replace($baseUrl, '', $url));
     }
     if (is_string($url)) {
         $params = ['url' => $url];
     } elseif (is_array($url)) {
         $defaultParams = ['plugin' => null, 'controller' => null, 'action' => null];
         $params = ['params' => $url + $defaultParams, 'base' => false, 'url' => Router::reverse($url)];
         if (empty($params['params']['pass'])) {
             $params['params']['pass'] = [];
         }
     }
     $current = Router::getRequest();
     if ($current) {
         $params['base'] = $current->base;
         $params['webroot'] = $current->webroot;
     }
     $params['post'] = $params['query'] = [];
     if (isset($extra['post'])) {
         $params['post'] = $extra['post'];
     }
     if (isset($extra['query'])) {
         $params['query'] = $extra['query'];
     }
     if (isset($extra['cookies'])) {
         $params['cookies'] = $extra['cookies'];
     }
     if (isset($extra['environment'])) {
         $params['environment'] = $extra['environment'] + $_SERVER + $_ENV;
     }
     unset($extra['environment'], $extra['post'], $extra['query']);
     $params['session'] = isset($extra['session']) ? $extra['session'] : new Session();
     $request = new Request($params);
     $request->addParams($extra);
     $dispatcher = DispatcherFactory::create();
     // If an application is using PSR7 middleware,
     // we need to 'fix' their missing dispatcher filters.
     $needed = ['routing' => RoutingFilter::class, 'controller' => ControllerFactoryFilter::class];
     foreach ($dispatcher->filters() as $filter) {
         if ($filter instanceof RoutingFilter) {
             unset($needed['routing']);
         }
         if ($filter instanceof ControllerFactoryFilter) {
             unset($needed['controller']);
         }
     }
     foreach ($needed as $class) {
         $dispatcher->addFilter(new $class());
     }
     $result = $dispatcher->dispatch($request, new Response());
     Router::popRequest();
     return $result;
 }
Exemplo n.º 6
0
 /**
  * Get the URL a user should be redirected to upon login.
  *
  * Pass a URL in to set the destination a user should be redirected to upon
  * logging in.
  *
  * If no parameter is passed, gets the authentication redirect URL. The URL
  * returned is as per following rules:
  *
  *  - Returns the normalized URL from session Auth.redirect value if it is
  *    present and for the same domain the current app is running on.
  *  - If there is no session value and there is a config `loginRedirect`, the
  *    `loginRedirect` value is returned.
  *  - If there is no session and no `loginRedirect`, / is returned.
  *
  * @param string|array $url Optional URL to write as the login redirect URL.
  * @return string Redirect URL
  */
 public function redirectUrl($url = null)
 {
     if ($url !== null) {
         $redir = $url;
         $this->session->write('Auth.redirect', $redir);
     } elseif ($this->session->check('Auth.redirect')) {
         $redir = $this->session->read('Auth.redirect');
         $this->session->delete('Auth.redirect');
         if (Router::normalize($redir) === Router::normalize($this->_config['loginAction'])) {
             $redir = $this->_config['loginRedirect'];
         }
     } elseif ($this->_config['loginRedirect']) {
         $redir = $this->_config['loginRedirect'];
     } else {
         $redir = '/';
     }
     if (is_array($redir)) {
         return Router::url($redir + ['_base' => false]);
     }
     return $redir;
 }
 /**
  * Get the URL a user should be redirected to upon login.
  *
  * Pass a URL in to set the destination a user should be redirected to upon
  * logging in.
  *
  * If no parameter is passed, gets the authentication redirect URL. The URL
  * returned is as per following rules:
  *
  *  - Returns the normalized redirect URL from storage if it is
  *    present and for the same domain the current app is running on.
  *  - If there is no URL returned from storage and there is a config
  *    `loginRedirect`, the `loginRedirect` value is returned.
  *  - If there is no session and no `loginRedirect`, / is returned.
  *
  * @param string|array $url Optional URL to write as the login redirect URL.
  * @return string Redirect URL
  */
 public function redirectUrl($url = null)
 {
     if ($url !== null) {
         $redir = $url;
         $this->storage()->redirectUrl($redir);
     } elseif ($redir = $this->storage()->redirectUrl()) {
         $this->storage()->redirectUrl(false);
         if (Router::normalize($redir) === Router::normalize($this->_config['loginAction'])) {
             $redir = $this->_config['loginRedirect'];
         }
     } elseif ($this->_config['loginRedirect']) {
         $redir = $this->_config['loginRedirect'];
     } else {
         $redir = '/';
     }
     if (is_array($redir)) {
         return Router::url($redir + ['_base' => false]);
     }
     return $redir;
 }
Exemplo n.º 8
0
 /**
  * Gets content's details page URL.
  *
  * Content's details URL's follows the syntax below:
  *
  *     http://example.com/{content-type-slug}/{content-slug}{CONTENT_EXTENSION}
  *
  * Example:
  *
  *     http://example.com/blog-article/my-first-article.html
  *
  * @return string
  */
 protected function _getUrl()
 {
     $url = Router::getRequest()->base;
     if (option('url_locale_prefix')) {
         $url .= '/' . I18n::locale();
     }
     $url .= "/{$this->content_type_slug}/{$this->slug}";
     return Router::normalize($url) . CONTENT_EXTENSION;
 }
Exemplo n.º 9
0
 /**
  * Calls a controller's method from any location. Can be used to connect controllers together
  * or tie plugins into a main application. requestAction can be used to return rendered views
  * or fetch the return value from controller actions.
  *
  * Under the hood this method uses Router::reverse() to convert the $url parameter into a string
  * URL. You should use URL formats that are compatible with Router::reverse()
  *
  * ### Examples
  *
  * A basic example getting the return value of the controller action:
  *
  * ```
  * $variables = $this->requestAction('/articles/popular');
  * ```
  *
  * A basic example of request action to fetch a rendered page without the layout.
  *
  * ```
  * $viewHtml = $this->requestAction('/articles/popular', ['return']);
  * ```
  *
  * You can also pass the URL as an array:
  *
  * ```
  * $vars = $this->requestAction(['controller' => 'articles', 'action' => 'popular']);
  * ```
  *
  * ### Passing other request data
  *
  * You can pass POST, GET, COOKIE and other data into the request using the appropriate keys.
  * Cookies can be passed using the `cookies` key. Get parameters can be set with `query` and post
  * data can be sent using the `post` key.
  *
  * ```
  * $vars = $this->requestAction('/articles/popular', [
  *   'query' => ['page' => 1],
  *   'cookies' => ['remember_me' => 1],
  * ]);
  * ```
  *
  * ### Sending environment or header values
  *
  * By default actions dispatched with this method will use the global $_SERVER and $_ENV
  * values. If you want to override those values for a request action, you can specify the values:
  *
  * ```
  * $vars = $this->requestAction('/articles/popular', [
  *   'environment' => ['CONTENT_TYPE' => 'application/json']
  * ]);
  * ```
  *
  * ### Transmitting the session
  *
  * By default actions dispatched with this method will use the standard session object.
  * If you want a particular session instance to be used, you need to specify it.
  *
  * ```
  * $vars = $this->requestAction('/articles/popular', [
  *   'session' => new Session($someSessionConfig)
  * ]);
  * ```
  *
  * @param string|array $url String or array-based url.  Unlike other url arrays in CakePHP, this
  *    url will not automatically handle passed arguments in the $url parameter.
  * @param array $extra if array includes the key "return" it sets the autoRender to true.  Can
  *    also be used to submit GET/POST data, and passed arguments.
  * @return mixed Boolean true or false on success/failure, or contents
  *    of rendered action if 'return' is set in $extra.
  */
 public function requestAction($url, array $extra = [])
 {
     if (empty($url)) {
         return false;
     }
     if (($index = array_search('return', $extra)) !== false) {
         $extra['return'] = 0;
         $extra['autoRender'] = 1;
         unset($extra[$index]);
     }
     $extra += ['autoRender' => 0, 'return' => 1, 'bare' => 1, 'requested' => 1];
     $baseUrl = Configure::read('App.fullBaseUrl');
     if (is_string($url) && strpos($url, $baseUrl) === 0) {
         $url = Router::normalize(str_replace($baseUrl, '', $url));
     }
     if (is_string($url)) {
         $params = ['url' => $url];
     } elseif (is_array($url)) {
         $defaultParams = ['plugin' => null, 'controller' => null, 'action' => null];
         $params = ['params' => $url + $defaultParams, 'base' => false, 'url' => Router::reverse($url)];
         if (empty($params['params']['pass'])) {
             $params['params']['pass'] = [];
         }
     }
     $current = Router::getRequest();
     if ($current) {
         $params['base'] = $current->base;
         $params['webroot'] = $current->webroot;
     }
     $params['post'] = $params['query'] = [];
     if (isset($extra['post'])) {
         $params['post'] = $extra['post'];
     }
     if (isset($extra['query'])) {
         $params['query'] = $extra['query'];
     }
     if (isset($extra['cookies'])) {
         $params['cookies'] = $extra['cookies'];
     }
     if (isset($extra['environment'])) {
         $params['environment'] = $extra['environment'] + $_SERVER + $_ENV;
     }
     unset($extra['environment'], $extra['post'], $extra['query']);
     $params['session'] = isset($extra['session']) ? $extra['session'] : new Session();
     $request = new Request($params);
     $request->addParams($extra);
     $dispatcher = DispatcherFactory::create();
     $result = $dispatcher->dispatch($request, new Response());
     Router::popRequest();
     return $result;
 }
Exemplo n.º 10
0
 /**
  * Check if a given url is authorized
  *
  * @param Event $event event
  *
  * @return bool
  */
 public function isUrlAuthorized(Event $event)
 {
     $url = Hash::get((array) $event->data, 'url');
     if (empty($url)) {
         return false;
     }
     if (is_array($url)) {
         $requestUrl = Router::reverse($url);
         $requestParams = Router::parse($requestUrl);
     } else {
         try {
             //remove base from $url if exists
             $normalizedUrl = Router::normalize($url);
             $requestParams = Router::parse($normalizedUrl);
         } catch (MissingRouteException $ex) {
             //if it's a url pointing to our own app
             if (substr($normalizedUrl, 0, 1) === '/') {
                 throw $ex;
             }
             return true;
         }
         $requestUrl = $url;
     }
     // check if controller action is allowed
     if ($this->_isActionAllowed($requestParams)) {
         return true;
     }
     // check we are logged in
     $user = $this->_registry->getController()->Auth->user();
     if (empty($user)) {
         return false;
     }
     $request = new Request($requestUrl);
     $request->params = $requestParams;
     $isAuthorized = $this->_registry->getController()->Auth->isAuthorized(null, $request);
     return $isAuthorized;
 }
 public function isLinkActive($url)
 {
     //TODO: Maybe more intelligent active link detection
     $currentUrl = Router::url($this->request->params);
     if (!empty($this->request->base) || $this->request->base != '/') {
         $currentUrl = str_replace($this->request->base, '', $currentUrl);
     }
     if (!is_array($url)) {
         $url = Router::parse($url);
     }
     if ($this->request->params['controller'] == $url['controller']) {
         $url = Router::normalize($url);
         return (bool) preg_match("/^(" . preg_quote($url, "/") . ")/", trim($currentUrl));
     }
 }
Exemplo n.º 12
0
 /**
  * Calls a controller's method from any location. Can be used to connect controllers together
  * or tie plugins into a main application. requestAction can be used to return rendered views
  * or fetch the return value from controller actions.
  *
  * Under the hood this method uses Router::reverse() to convert the $url parameter into a string
  * URL. You should use URL formats that are compatible with Router::reverse()
  *
  * ### Examples
  *
  * A basic example getting the return value of the controller action:
  *
  * {{{
  * $variables = $this->requestAction('/articles/popular');
  * }}}
  *
  * A basic example of request action to fetch a rendered page without the layout.
  *
  * {{{
  * $viewHtml = $this->requestAction('/articles/popular', ['return']);
  * }}}
  *
  * You can also pass the URL as an array:
  *
  * {{{
  * $vars = $this->requestAction(['controller' => 'articles', 'action' => 'popular']);
  * }}}
  *
  * ### Passing other request data
  *
  * You can pass POST, GET, COOKIE and other data into the request using the apporpriate keys.
  * Cookies can be passed using the `cookies` key. Get parameters can be set with `query` and post
  * data can be sent using the `post` key.
  *
  * {{{
  * $vars = $this->requestAction('/articles/popular', [
  *   'query' => ['page' = > 1],
  *   'cookies' => ['remember_me' => 1],
  * ]);
  * }}}
  *
  * @param string|array $url String or array-based url.  Unlike other url arrays in CakePHP, this
  *    url will not automatically handle passed arguments in the $url parameter.
  * @param array $extra if array includes the key "return" it sets the autoRender to true.  Can
  *    also be used to submit GET/POST data, and passed arguments.
  * @return mixed Boolean true or false on success/failure, or contents
  *    of rendered action if 'return' is set in $extra.
  */
 public function requestAction($url, array $extra = array())
 {
     if (empty($url)) {
         return false;
     }
     if (($index = array_search('return', $extra)) !== false) {
         $extra['return'] = 0;
         $extra['autoRender'] = 1;
         unset($extra[$index]);
     }
     $extra = array_merge(['autoRender' => 0, 'return' => 1, 'bare' => 1, 'requested' => 1], $extra);
     $post = $query = [];
     if (isset($extra['post'])) {
         $post = $extra['post'];
     }
     if (isset($extra['query'])) {
         $query = $extra['query'];
     }
     unset($extra['post'], $extra['query']);
     if (is_string($url) && strpos($url, Configure::read('App.fullBaseUrl')) === 0) {
         $url = Router::normalize(str_replace(Configure::read('App.fullBaseUrl'), '', $url));
     }
     if (is_string($url)) {
         $params = ['url' => $url];
     } elseif (is_array($url)) {
         $params = array_merge($url, ['pass' => [], 'base' => false, 'url' => Router::reverse($url)]);
     }
     if (!empty($post)) {
         $params['post'] = $post;
     }
     if (!empty($query)) {
         $params['query'] = $query;
     }
     $request = new Request($params);
     $dispatcher = new Dispatcher();
     $result = $dispatcher->dispatch($request, new Response(), $extra);
     Router::popRequest();
     return $result;
 }
Exemplo n.º 13
0
 /**
  * Checks whether the user is allowed to access a specific URL
  *
  * @param array $user user to check with
  * @param array|string $url url to check
  * @return void
  */
 public function urlAllowed($user, $url)
 {
     if (empty($url)) {
         return false;
     }
     if (is_array($url)) {
         // prevent plugin confusion
         $url = Hash::merge(['plugin' => null], $url);
         $url = Router::url($url);
         // strip off the base path
         $url = Router::normalize($url);
     }
     $route = Router::parse($url);
     if (empty($route['controller']) || empty($route['action'])) {
         return false;
     }
     return $this->isAuthorized($user, $route['plugin'], $route['controller'], $route['action']);
 }