summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/base.php2
-rw-r--r--lib/private/AppFramework/Routing/RouteConfig.php55
-rw-r--r--lib/private/Route/Router.php12
-rw-r--r--ocs/v1.php25
-rw-r--r--tests/lib/AppFramework/Routing/RoutingTest.php131
5 files changed, 224 insertions, 1 deletions
diff --git a/lib/base.php b/lib/base.php
index 62ace1bc0ef..be9de93f73f 100644
--- a/lib/base.php
+++ b/lib/base.php
@@ -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;
diff --git a/lib/private/AppFramework/Routing/RouteConfig.php b/lib/private/AppFramework/Routing/RouteConfig.php
index 64179336020..eca0051691f 100644
--- a/lib/private/AppFramework/Routing/RouteConfig.php
+++ b/lib/private/AppFramework/Routing/RouteConfig.php
@@ -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']);
+ }
+ }
}
/**
diff --git a/lib/private/Route/Router.php b/lib/private/Route/Router.php
index 01262be390c..f7da827c3db 100644
--- a/lib/private/Route/Router.php
+++ b/lib/private/Route/Router.php
@@ -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'])) {
@@ -241,6 +246,13 @@ class Router implements IRouter {
$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);
} else if (substr($url, 0, 6) === '/core/' or substr($url, 0, 10) === '/settings/') {
\OC::$REQUESTEDAPP = $url;
if (!\OC::$server->getConfig()->getSystemValue('maintenance', false) && !Util::needUpgrade()) {
diff --git a/ocs/v1.php b/ocs/v1.php
index bbc2adf39b6..e3ecefccf29 100644
--- a/ocs/v1.php
+++ b/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();
}
diff --git a/tests/lib/AppFramework/Routing/RoutingTest.php b/tests/lib/AppFramework/Routing/RoutingTest.php
index 52a5eb33ba9..6c8b0f40133 100644
--- a/tests/lib/AppFramework/Routing/RoutingTest.php
+++ b/tests/lib/AppFramework/Routing/RoutingTest.php
@@ -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')));
@@ -146,6 +229,54 @@ class RoutingTest extends \Test\TestCase
}
/**
+ * @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
* @param string $controllerName