/** * testBeforeDispatch * * @return void */ public function testBeforeDispatch() { Configure::write('App.namespace', 'TestApp'); $filter = new ControllerFactoryFilter(); $request = new Request(); $response = new Response(); $request->addParams(['prefix' => 'admin', 'controller' => 'Posts', 'action' => 'index']); $event = new Event(__CLASS__, $this, compact('request', 'response')); $filter->beforeDispatch($event); $this->assertEquals('TestApp\\Controller\\Admin\\PostsController', get_class($event->data['controller'])); $request->addParams(['prefix' => 'admin/sub', 'controller' => 'Posts', 'action' => 'index']); $event = new Event(__CLASS__, $this, compact('request', 'response')); $filter->beforeDispatch($event); $this->assertEquals('TestApp\\Controller\\Admin\\Sub\\PostsController', get_class($event->data['controller'])); }
/** * Setup * * @return void */ public function setUp() { parent::setUp(); Router::connect('/:controller/:action'); $request = new Request(); $request->addParams(array('controller' => 'pages', 'action' => 'display')); $this->View = new View($request); $this->Toolbar = new ToolbarHelper($this->View); }
/** * test check() failing * * @return void */ public function testAuthorizeCheckFailure() { $request = new Request('posts/index'); $request->addParams(['controller' => 'posts', 'action' => 'index']); $user = ['Users' => ['username' => 'mark']]; $this->_mockAcl(); $this->Acl->expects($this->once())->method('check')->with($user, 'Posts', 'read')->will($this->returnValue(false)); $this->assertFalse($this->auth->authorize($user['Users'], $request)); }
/** * test setting parameters in beforeDispatch method * * @return void * @triggers __CLASS__ $this, compact(request) */ public function testBeforeDispatchSkipWhenControllerSet() { $filter = new RoutingFilter(); $request = new Request("/testcontroller/testaction/params1/params2/params3"); $request->addParams(['controller' => 'articles']); $event = new Event(__CLASS__, $this, compact('request')); $filter->beforeDispatch($event); $this->assertSame($request->params['controller'], 'articles'); $this->assertEmpty($request->params['action']); }
/** * Check if the user can access to the given URL. * * @param array $params The params to check. * * @return bool */ public function check(array $params = []) { if (!$this->request->session()->read('Auth.User')) { return false; } $params += ['_base' => false]; $url = Router::url($params); $params = Router::parse($url); $user = [$this->Authorize->config('userModel') => $this->request->session()->read('Auth.User')]; $request = new Request(); $request->addParams($params); $action = $this->Authorize->action($request); return $this->Acl->check($user, $action); }
/** * 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; }
/** * Test is('requested') and isRequested() * * @return void */ public function testIsRequested() { $request = new Request(); $request->addParams(['controller' => 'posts', 'action' => 'index', 'plugin' => null, 'requested' => 1]); $this->assertTrue($request->is('requested')); $this->assertTrue($request->isRequested()); $request = new Request(); $request->addParams(['controller' => 'posts', 'action' => 'index', 'plugin' => null]); $this->assertFalse($request->is('requested')); $this->assertFalse($request->isRequested()); }
/** * test scope failure. * * @expectedException \Cake\Network\Exception\UnauthorizedException * @expectedExceptionCode 401 * @return void */ public function testAuthenticateFailReChallenge() { $this->auth->config('scope.username', 'nate'); $request = new Request(['url' => 'posts/index', 'environment' => ['REQUEST_METHOD' => 'GET']]); $request->addParams(array('pass' => array())); $digest = <<<DIGEST Digest username="******", realm="localhost", nonce="123", uri="/dir/index.html", qop=auth, nc=1, cnonce="123", response="6629fae49393a05397450978507c4ef1", opaque="123abc" DIGEST; $request->env('PHP_AUTH_DIGEST', $digest); $this->auth->unauthenticated($request, $this->response); }
public function testActionWithPrefix() { $request = new Request('/admin/posts/index'); $request->addParams(['plugin' => null, 'prefix' => 'admin', 'controller' => 'posts', 'action' => 'index']); $result = $this->auth->action($request); $this->assertEquals('controllers/admin/Posts/index', $result); }
/** * Default to loginRedirect, if set, on authError. * * @return void * @triggers Controller.startup $Controller */ public function testDefaultToLoginRedirect() { $url = '/party/on'; $this->Auth->request = $request = new Request($url); $request->env('HTTP_REFERER', false); $request->addParams(Router::parse($url)); $request->addPaths(['base' => 'dirname', 'webroot' => '/dirname/']); Router::pushRequest($request); $this->Auth->config('authorize', ['Controller']); $this->Auth->setUser(['username' => 'mariano', 'password' => 'cake']); $this->Auth->config('loginRedirect', ['controller' => 'something', 'action' => 'else']); $response = new Response(); $Controller = $this->getMock('Cake\\Controller\\Controller', ['on', 'redirect'], [$request, $response]); $event = new Event('Controller.startup', $Controller); // Should not contain basedir when redirect is called. $expected = '/something/else'; $Controller->expects($this->once())->method('redirect')->with($this->equalTo($expected)); $this->Auth->startup($event); }
/** * Test that the compatibility method for incoming urls works. * * @return void */ public function testParseNamedParameters() { $request = new Request(); $request->addParams(array('controller' => 'posts', 'action' => 'index')); $result = Router::parseNamedParams($request); $this->assertSame([], $result->params['named']); $request = new Request(); $request->addParams(array('controller' => 'posts', 'action' => 'index', 'pass' => array('home', 'one:two', 'three:four', 'five[nested][0]:six', 'five[nested][1]:seven'))); Router::parseNamedParams($request); $expected = array('plugin' => null, 'controller' => 'posts', 'action' => 'index', '_ext' => null, 'pass' => array('home'), 'named' => array('one' => 'two', 'three' => 'four', 'five' => array('nested' => array('six', 'seven')))); $this->assertEquals($expected, $request->params); }
/** * test that a classes namespace is used in the viewPath. * * @return void */ public function testViewPathConventions() { $request = new Request('admin/posts'); $request->addParams(['prefix' => 'admin']); $response = $this->getMock('Cake\\Network\\Response'); $Controller = new \TestApp\Controller\Admin\PostsController($request, $response); $this->assertEquals('Admin' . DS . 'Posts', $Controller->viewPath); $request->addParams(['prefix' => 'admin/super']); $response = $this->getMock('Cake\\Network\\Response'); $Controller = new \TestApp\Controller\Admin\PostsController($request, $response); $this->assertEquals('Admin' . DS . 'Super' . DS . 'Posts', $Controller->viewPath); $request = new Request('pages/home'); $Controller = new \TestApp\Controller\PagesController($request, $response); $this->assertEquals('Pages', $Controller->viewPath); }
/** * Checks if the given user has permission to perform an action. * * @param array $params The params to check. * * @return string */ public function hasPermission(array $params = []) { $params += ['controller' => 'Permissions', '_base' => false, 'prefix' => 'chat']; $url = Router::url($params); $params = Router::parse($url); $request = new Request(); $request->addParams($params); $action = $this->Authorize->action($request); $user = [$this->Authorize->config('userModel') => $this->_session->read('Auth.User')]; return $this->Acl->check($user, $action); }
/** * test numbers() with routing parameters. * * @return void */ public function testNumbersRouting() { $this->Paginator->request->params['paging'] = array('Client' => array('page' => 2, 'current' => 2, 'count' => 30, 'prevPage' => false, 'nextPage' => 3, 'pageCount' => 3)); $request = new Request(); $request->addParams(array('controller' => 'clients', 'action' => 'index', 'plugin' => null)); $request->base = ''; $request->here = '/clients/index?page=2'; $request->webroot = '/'; Router::setRequestInfo($request); $result = $this->Paginator->numbers(); $expected = array(array('li' => array()), array('a' => array('href' => '/clients/index')), '1', '/a', '/li', array('li' => array('class' => 'active')), '<span', '2', '/span', '/li', array('li' => array()), array('a' => array('href' => '/clients/index?page=3')), '3', '/a', '/li'); $this->assertTags($result, $expected); }
/** * testAuthenticateWithBlowfish * * @return void */ public function testAuthenticateWithBlowfish() { $hash = Security::hash('password', 'blowfish'); $this->skipIf(strpos($hash, '$2a$') === false, 'Skipping blowfish tests as hashing is not working'); $request = new Request(['url' => 'posts/index', 'environment' => ['PHP_AUTH_USER' => 'mariano', 'PHP_AUTH_PW' => 'password']]); $request->addParams(array('pass' => array())); $User = TableRegistry::get('Users'); $User->updateAll(array('password' => $hash), array('username' => 'mariano')); $this->auth->config('passwordHasher', 'Blowfish'); $result = $this->auth->authenticate($request, $this->response); $expected = array('id' => 1, 'username' => 'mariano', 'created' => new Time('2007-03-17 01:16:23'), 'updated' => new Time('2007-03-17 01:18:31')); $this->assertEquals($expected, $result); }
/** * Test that requests are still blackholed when controller has incorrect * visibility keyword in the blackhole callback * * @expectedException \Cake\Network\Exception\BadRequestException * @return void * @triggers Controller.startup $Controller, $this->Controller */ public function testBlackholeWithBrokenCallback() { $request = new Request(['url' => 'posts/index', 'session' => $this->Security->session]); $request->addParams(['controller' => 'posts', 'action' => 'index']); $Controller = new \TestApp\Controller\SomePagesController($request); $event = new Event('Controller.startup', $Controller, $this->Controller); $Security = new SecurityComponent($Controller->components()); $Security->config('blackHoleCallback', '_fail'); $Security->startup($event); $Security->blackHole($Controller, 'csrf'); }
/** * test scope failure. * * @expectedException \Cake\Network\Exception\UnauthorizedException * @expectedExceptionCode 401 * @return void */ public function testAuthenticateFailReChallenge() { $this->auth->config('scope.username', 'nate'); $request = new Request(['url' => 'posts/index', 'environment' => ['PHP_AUTH_USER' => 'mariano', 'PHP_AUTH_PW' => 'password']]); $request->addParams(['pass' => []]); $this->auth->unauthenticated($request, $this->response); }
/** * 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; }
/** * test that a classes namespace is used in the viewPath. * * @return void */ public function testViewPathConventions() { $request = new Request('admin/posts'); $request->addParams(['prefix' => 'admin']); $response = $this->getMockBuilder('Cake\\Network\\Response')->getMock(); $Controller = new \TestApp\Controller\Admin\PostsController($request, $response); $Controller->eventManager()->on('Controller.beforeRender', function (Event $e) { return $e->subject()->response; }); $Controller->render(); $this->assertEquals('Admin' . DS . 'Posts', $Controller->viewBuilder()->templatePath()); $request->addParams(['prefix' => 'admin/super']); $response = $this->getMockBuilder('Cake\\Network\\Response')->getMock(); $Controller = new \TestApp\Controller\Admin\PostsController($request, $response); $Controller->eventManager()->on('Controller.beforeRender', function (Event $e) { return $e->subject()->response; }); $Controller->render(); $this->assertEquals('Admin' . DS . 'Super' . DS . 'Posts', $Controller->viewBuilder()->templatePath()); $request = new Request('pages/home'); $request->addParams(['prefix' => false]); $Controller = new \TestApp\Controller\PagesController($request, $response); $Controller->eventManager()->on('Controller.beforeRender', function (Event $e) { return $e->subject()->response; }); $Controller->render(); $this->assertEquals('Pages', $Controller->viewBuilder()->templatePath()); }
/** * test numbers() with routing parameters. * * @return void */ public function testNumbersRouting() { $this->Paginator->request->params['paging'] = ['Client' => ['page' => 2, 'current' => 2, 'count' => 30, 'prevPage' => false, 'nextPage' => 3, 'pageCount' => 3]]; $request = new Request(); $request->addParams(['controller' => 'clients', 'action' => 'index', 'plugin' => null]); $request->base = ''; $request->here = '/clients/index?page=2'; $request->webroot = '/'; Router::setRequestInfo($request); $result = $this->Paginator->numbers(); $expected = [['li' => []], ['a' => ['href' => '/clients/index']], '1', '/a', '/li', ['li' => ['class' => 'active']], '<a href=""', '2', '/a', '/li', ['li' => []], ['a' => ['href' => '/clients/index?page=3']], '3', '/a', '/li']; $this->assertHtml($expected, $result); }
/** * Takes parameter and path information back from the Dispatcher, sets these * parameters as the current request parameters that are merged with URL arrays * created later in the request. * * Nested requests will create a stack of requests. You can remove requests using * Router::popRequest(). This is done automatically when using Object::requestAction(). * * Will accept either a Cake\Network\Request object or an array of arrays. Support for * accepting arrays may be removed in the future. * * @param \Cake\Network\Request|array $request Parameters and path information or a Cake\Network\Request object. * @return void */ public static function setRequestInfo($request) { if ($request instanceof Request) { static::pushRequest($request); } else { $requestData = $request; $requestData += [[], []]; $requestData[0] += ['controller' => false, 'action' => false, 'plugin' => null]; $request = new Request(); $request->addParams($requestData[0])->addPaths($requestData[1]); static::pushRequest($request); } }
/** * test action() and plugins * * @return void */ public function testActionWithPlugin() { $request = new Request('/debug_kit/posts/index'); $request->addParams(array('plugin' => 'debug_kit', 'controller' => 'posts', 'action' => 'index')); $result = $this->auth->action($request); $this->assertEquals('controllers/DebugKit/Posts/index', $result); }