Merge pull request #400 from nextcloud/ocs_appframework
OCS routes use AppFramework
This commit is contained in:
commit
13a25535d2
5 changed files with 224 additions and 1 deletions
|
@ -905,7 +905,7 @@ class OC {
|
|||
* @param OCP\IRequest $request
|
||||
* @return boolean
|
||||
*/
|
||||
private static function handleLogin(OCP\IRequest $request) {
|
||||
static function handleLogin(OCP\IRequest $request) {
|
||||
$userSession = self::$server->getUserSession();
|
||||
if (OC_User::handleApacheAuth()) {
|
||||
return true;
|
||||
|
|
|
@ -62,6 +62,61 @@ class RouteConfig {
|
|||
|
||||
// parse resources
|
||||
$this->processResources($this->routes);
|
||||
|
||||
/*
|
||||
* OCS routes go into a different collection
|
||||
*/
|
||||
$oldCollection = $this->router->getCurrentCollection();
|
||||
$this->router->useCollection($oldCollection.'.ocs');
|
||||
|
||||
// parse ocs simple routes
|
||||
$this->processOCS($this->routes);
|
||||
|
||||
$this->router->useCollection($oldCollection);
|
||||
}
|
||||
|
||||
private function processOCS(array $routes) {
|
||||
$ocsRoutes = isset($routes['ocs']) ? $routes['ocs'] : [];
|
||||
foreach ($ocsRoutes as $ocsRoute) {
|
||||
$name = $ocsRoute['name'];
|
||||
$postfix = '';
|
||||
|
||||
if (isset($ocsRoute['postfix'])) {
|
||||
$postfix = $ocsRoute['postfix'];
|
||||
}
|
||||
|
||||
$url = $ocsRoute['url'];
|
||||
$verb = isset($ocsRoute['verb']) ? strtoupper($ocsRoute['verb']) : 'GET';
|
||||
|
||||
$split = explode('#', $name, 2);
|
||||
if (count($split) != 2) {
|
||||
throw new \UnexpectedValueException('Invalid route name');
|
||||
}
|
||||
$controller = $split[0];
|
||||
$action = $split[1];
|
||||
|
||||
$controllerName = $this->buildControllerName($controller);
|
||||
$actionName = $this->buildActionName($action);
|
||||
|
||||
// register the route
|
||||
$handler = new RouteActionHandler($this->container, $controllerName, $actionName);
|
||||
|
||||
$router = $this->router->create('ocs.'.$this->appName.'.'.$controller.'.'.$action . $postfix, $url)
|
||||
->method($verb)
|
||||
->action($handler);
|
||||
|
||||
// optionally register requirements for route. This is used to
|
||||
// tell the route parser how url parameters should be matched
|
||||
if(array_key_exists('requirements', $ocsRoute)) {
|
||||
$router->requirements($ocsRoute['requirements']);
|
||||
}
|
||||
|
||||
// optionally register defaults for route. This is used to
|
||||
// tell the route parser how url parameters should be default valued
|
||||
if(array_key_exists('defaults', $ocsRoute)) {
|
||||
$router->defaults($ocsRoute['defaults']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -150,6 +150,11 @@ class Router implements IRouter {
|
|||
$collection = $this->getCollection($app);
|
||||
$collection->addPrefix('/apps/' . $app);
|
||||
$this->root->addCollection($collection);
|
||||
|
||||
// Also add the OCS collection
|
||||
$collection = $this->getCollection($app.'.ocs');
|
||||
$collection->addPrefix('/ocsapp/apps/' . $app);
|
||||
$this->root->addCollection($collection);
|
||||
}
|
||||
}
|
||||
if (!isset($this->loadedApps['core'])) {
|
||||
|
@ -238,6 +243,13 @@ class Router implements IRouter {
|
|||
// empty string / 'apps' / $app / rest of the route
|
||||
list(, , $app,) = explode('/', $url, 4);
|
||||
|
||||
$app = \OC_App::cleanAppId($app);
|
||||
\OC::$REQUESTEDAPP = $app;
|
||||
$this->loadRoutes($app);
|
||||
} else if (substr($url, 0, 13) === '/ocsapp/apps/') {
|
||||
// empty string / 'ocsapp' / 'apps' / $app / rest of the route
|
||||
list(, , , $app,) = explode('/', $url, 5);
|
||||
|
||||
$app = \OC_App::cleanAppId($app);
|
||||
\OC::$REQUESTEDAPP = $app;
|
||||
$this->loadRoutes($app);
|
||||
|
|
25
ocs/v1.php
25
ocs/v1.php
|
@ -42,6 +42,10 @@ if (\OCP\Util::needUpgrade()
|
|||
use Symfony\Component\Routing\Exception\ResourceNotFoundException;
|
||||
use Symfony\Component\Routing\Exception\MethodNotAllowedException;
|
||||
|
||||
/*
|
||||
* Try old routes first
|
||||
* We first try the old routes since the appframework triggers more login stuff.
|
||||
*/
|
||||
try {
|
||||
OC_App::loadApps(['session']);
|
||||
OC_App::loadApps(['authentication']);
|
||||
|
@ -52,6 +56,24 @@ try {
|
|||
\OC::$server->getL10NFactory()->setLanguageFromRequest();
|
||||
|
||||
OC::$server->getRouter()->match('/ocs'.\OC::$server->getRequest()->getRawPathInfo());
|
||||
return;
|
||||
} catch (ResourceNotFoundException $e) {
|
||||
// Fall through the not found
|
||||
} catch (MethodNotAllowedException $e) {
|
||||
OC_API::setContentType();
|
||||
OC_Response::setStatus(405);
|
||||
} catch (\OC\OCS\Exception $ex) {
|
||||
OC_API::respond($ex->getResult(), OC_API::requestedFormat());
|
||||
}
|
||||
|
||||
/*
|
||||
* Try the appframework routes
|
||||
*/
|
||||
try {
|
||||
if(!\OC::$server->getUserSession()->isLoggedIn()) {
|
||||
OC::handleLogin(\OC::$server->getRequest());
|
||||
}
|
||||
OC::$server->getRouter()->match('/ocsapp'.\OC::$server->getRequest()->getRawPathInfo());
|
||||
} catch (ResourceNotFoundException $e) {
|
||||
OC_API::setContentType();
|
||||
OC_OCS::notFound();
|
||||
|
@ -60,5 +82,8 @@ try {
|
|||
OC_Response::setStatus(405);
|
||||
} catch (\OC\OCS\Exception $ex) {
|
||||
OC_API::respond($ex->getResult(), OC_API::requestedFormat());
|
||||
} catch (\Exception $e) {
|
||||
OC_API::setContentType();
|
||||
OC_OCS::notFound();
|
||||
}
|
||||
|
||||
|
|
|
@ -18,6 +18,15 @@ class RoutingTest extends \Test\TestCase
|
|||
$this->assertSimpleRoute($routes, 'folders.open', 'GET', '/folders/{folderId}/open', 'FoldersController', 'open');
|
||||
}
|
||||
|
||||
public function testSimpleOCSRoute() {
|
||||
$routes = ['ocs' => [
|
||||
['name' => 'folders#open', 'url' => '/folders/{folderId}/open', 'verb' => 'GET']
|
||||
]
|
||||
];
|
||||
|
||||
$this->assertSimpleOCSRoute($routes, 'folders.open', 'GET', '/folders/{folderId}/open', 'FoldersController', 'open');
|
||||
}
|
||||
|
||||
public function testSimpleRouteWithMissingVerb()
|
||||
{
|
||||
$routes = array('routes' => array(
|
||||
|
@ -27,6 +36,15 @@ class RoutingTest extends \Test\TestCase
|
|||
$this->assertSimpleRoute($routes, 'folders.open', 'GET', '/folders/{folderId}/open', 'FoldersController', 'open');
|
||||
}
|
||||
|
||||
public function testSimpleOCSRouteWithMissingVerb() {
|
||||
$routes = ['ocs' => [
|
||||
['name' => 'folders#open', 'url' => '/folders/{folderId}/open']
|
||||
]
|
||||
];
|
||||
|
||||
$this->assertSimpleOCSRoute($routes, 'folders.open', 'GET', '/folders/{folderId}/open', 'FoldersController', 'open');
|
||||
}
|
||||
|
||||
public function testSimpleRouteWithLowercaseVerb()
|
||||
{
|
||||
$routes = array('routes' => array(
|
||||
|
@ -36,6 +54,15 @@ class RoutingTest extends \Test\TestCase
|
|||
$this->assertSimpleRoute($routes, 'folders.open', 'DELETE', '/folders/{folderId}/open', 'FoldersController', 'open');
|
||||
}
|
||||
|
||||
public function testSimpleOCSRouteWithLowercaseVerb() {
|
||||
$routes = ['ocs' => [
|
||||
['name' => 'folders#open', 'url' => '/folders/{folderId}/open', 'verb' => 'delete']
|
||||
]
|
||||
];
|
||||
|
||||
$this->assertSimpleOCSRoute($routes, 'folders.open', 'DELETE', '/folders/{folderId}/open', 'FoldersController', 'open');
|
||||
}
|
||||
|
||||
public function testSimpleRouteWithRequirements()
|
||||
{
|
||||
$routes = array('routes' => array(
|
||||
|
@ -45,6 +72,15 @@ class RoutingTest extends \Test\TestCase
|
|||
$this->assertSimpleRoute($routes, 'folders.open', 'DELETE', '/folders/{folderId}/open', 'FoldersController', 'open', array('something'));
|
||||
}
|
||||
|
||||
public function testSimpleOCSRouteWithRequirements() {
|
||||
$routes = ['ocs' => [
|
||||
['name' => 'folders#open', 'url' => '/folders/{folderId}/open', 'verb' => 'delete', 'requirements' => ['something']]
|
||||
]
|
||||
];
|
||||
|
||||
$this->assertSimpleOCSRoute($routes, 'folders.open', 'DELETE', '/folders/{folderId}/open', 'FoldersController', 'open', ['something']);
|
||||
}
|
||||
|
||||
public function testSimpleRouteWithDefaults()
|
||||
{
|
||||
$routes = array('routes' => array(
|
||||
|
@ -54,6 +90,16 @@ class RoutingTest extends \Test\TestCase
|
|||
$this->assertSimpleRoute($routes, 'folders.open', 'DELETE', '/folders/{folderId}/open', 'FoldersController', 'open', array(), array('param' => 'foobar'));
|
||||
}
|
||||
|
||||
|
||||
public function testSimpleOCSRouteWithDefaults() {
|
||||
$routes = ['ocs' => [
|
||||
['name' => 'folders#open', 'url' => '/folders/{folderId}/open', 'verb' => 'delete', 'defaults' => ['param' => 'foobar']]
|
||||
]
|
||||
];
|
||||
|
||||
$this->assertSimpleOCSRoute($routes, 'folders.open', 'DELETE', '/folders/{folderId}/open', 'FoldersController', 'open', [], ['param' => 'foobar']);
|
||||
}
|
||||
|
||||
public function testSimpleRouteWithPostfix()
|
||||
{
|
||||
$routes = array('routes' => array(
|
||||
|
@ -63,6 +109,14 @@ class RoutingTest extends \Test\TestCase
|
|||
$this->assertSimpleRoute($routes, 'folders.open', 'DELETE', '/folders/{folderId}/open', 'FoldersController', 'open', array(), array(), '_something');
|
||||
}
|
||||
|
||||
public function testSimpleOCSRouteWithPostfix() {
|
||||
$routes = ['ocs' => [
|
||||
['name' => 'folders#open', 'url' => '/folders/{folderId}/open', 'verb' => 'delete', 'postfix' => '_something']
|
||||
]
|
||||
];
|
||||
|
||||
$this->assertSimpleOCSRoute($routes, 'folders.open', 'DELETE', '/folders/{folderId}/open', 'FoldersController', 'open', [], [], '_something');
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \UnexpectedValueException
|
||||
|
@ -86,6 +140,27 @@ class RoutingTest extends \Test\TestCase
|
|||
$config->register();
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \UnexpectedValueException
|
||||
*/
|
||||
public function testSimpleOCSRouteWithBrokenName() {
|
||||
$routes = ['ocs' => [
|
||||
['name' => 'folders_open', 'url' => '/folders/{folderId}/open', 'verb' => 'delete']
|
||||
]];
|
||||
|
||||
// router mock
|
||||
$router = $this->getMockBuilder('\OC\Route\Router')
|
||||
->setMethods(['create'])
|
||||
->setConstructorArgs([$this->getMockBuilder('\OCP\ILogger')->getMock()])
|
||||
->getMock();
|
||||
|
||||
// load route configuration
|
||||
$container = new DIContainer('app1');
|
||||
$config = new RouteConfig($container, $router, $routes);
|
||||
|
||||
$config->register();
|
||||
}
|
||||
|
||||
public function testSimpleRouteWithUnderScoreNames()
|
||||
{
|
||||
$routes = array('routes' => array(
|
||||
|
@ -95,6 +170,14 @@ class RoutingTest extends \Test\TestCase
|
|||
$this->assertSimpleRoute($routes, 'admin_folders.open_current', 'DELETE', '/folders/{folderId}/open', 'AdminFoldersController', 'openCurrent');
|
||||
}
|
||||
|
||||
public function testSimpleOCSRouteWithUnderScoreNames() {
|
||||
$routes = ['ocs' => [
|
||||
['name' => 'admin_folders#open_current', 'url' => '/folders/{folderId}/open', 'verb' => 'delete']
|
||||
]];
|
||||
|
||||
$this->assertSimpleOCSRoute($routes, 'admin_folders.open_current', 'DELETE', '/folders/{folderId}/open', 'AdminFoldersController', 'openCurrent');
|
||||
}
|
||||
|
||||
public function testResource()
|
||||
{
|
||||
$routes = array('resources' => array('account' => array('url' => '/accounts')));
|
||||
|
@ -145,6 +228,54 @@ class RoutingTest extends \Test\TestCase
|
|||
$config->register();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $routes
|
||||
* @param string $name
|
||||
* @param string $verb
|
||||
* @param string $url
|
||||
* @param string $controllerName
|
||||
* @param string $actionName
|
||||
* @param array $requirements
|
||||
* @param array $defaults
|
||||
* @param string $postfix
|
||||
*/
|
||||
private function assertSimpleOCSRoute($routes,
|
||||
$name,
|
||||
$verb,
|
||||
$url,
|
||||
$controllerName,
|
||||
$actionName,
|
||||
array $requirements=array(),
|
||||
array $defaults=array(),
|
||||
$postfix='')
|
||||
{
|
||||
if ($postfix) {
|
||||
$name .= $postfix;
|
||||
}
|
||||
|
||||
// route mocks
|
||||
$container = new DIContainer('app1');
|
||||
$route = $this->mockRoute($container, $verb, $controllerName, $actionName, $requirements, $defaults);
|
||||
|
||||
// router mock
|
||||
$router = $this->getMockBuilder('\OC\Route\Router')
|
||||
->setMethods(['create'])
|
||||
->setConstructorArgs([$this->getMockBuilder('\OCP\ILogger')->getMock()])
|
||||
->getMock();
|
||||
|
||||
// we expect create to be called once:
|
||||
$router
|
||||
->expects($this->once())
|
||||
->method('create')
|
||||
->with($this->equalTo('ocs.app1.' . $name), $this->equalTo($url))
|
||||
->will($this->returnValue($route));
|
||||
|
||||
// load route configuration
|
||||
$config = new RouteConfig($container, $router, $routes);
|
||||
|
||||
$config->register();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $resourceName
|
||||
* @param string $url
|
||||
|
|
Loading…
Reference in a new issue