diff --git a/lib/private/appframework/app.php b/lib/private/appframework/app.php index 3b13194862..baf52d0205 100644 --- a/lib/private/appframework/app.php +++ b/lib/private/appframework/app.php @@ -4,7 +4,7 @@ * ownCloud - App Framework * * @author Bernhard Posselt - * @copyright 2012 Bernhard Posselt nukeawhale@gmail.com + * @copyright 2012 Bernhard Posselt * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE diff --git a/lib/private/appframework/core/api.php b/lib/private/appframework/core/api.php index e7269373bb..c114d0be9f 100644 --- a/lib/private/appframework/core/api.php +++ b/lib/private/appframework/core/api.php @@ -4,7 +4,7 @@ * ownCloud - App Framework * * @author Bernhard Posselt - * @copyright 2012 Bernhard Posselt nukeawhale@gmail.com + * @copyright 2012 Bernhard Posselt * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE diff --git a/lib/private/appframework/dependencyinjection/dicontainer.php b/lib/private/appframework/dependencyinjection/dicontainer.php index becd755bda..97a6569a0f 100644 --- a/lib/private/appframework/dependencyinjection/dicontainer.php +++ b/lib/private/appframework/dependencyinjection/dicontainer.php @@ -4,7 +4,7 @@ * ownCloud - App Framework * * @author Bernhard Posselt - * @copyright 2012 Bernhard Posselt nukeawhale@gmail.com + * @copyright 2012 Bernhard Posselt * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE @@ -33,6 +33,7 @@ use OC\AppFramework\Middleware\Security\SecurityMiddleware; use OC\AppFramework\Middleware\Security\CORSMiddleware; use OC\AppFramework\Utility\SimpleContainer; use OC\AppFramework\Utility\TimeFactory; +use OC\AppFramework\Utility\ControllerMethodReflector; use OCP\AppFramework\IApi; use OCP\AppFramework\IAppContainer; use OCP\AppFramework\Middleware; @@ -81,7 +82,12 @@ class DIContainer extends SimpleContainer implements IAppContainer{ }); $this['Dispatcher'] = $this->share(function($c) { - return new Dispatcher($c['Protocol'], $c['MiddlewareDispatcher']); + return new Dispatcher( + $c['Protocol'], + $c['MiddlewareDispatcher'], + $c['ControllerMethodReflector'], + $c['Request'] + ); }); @@ -90,11 +96,18 @@ class DIContainer extends SimpleContainer implements IAppContainer{ */ $app = $this; $this['SecurityMiddleware'] = $this->share(function($c) use ($app){ - return new SecurityMiddleware($app, $c['Request']); + return new SecurityMiddleware( + $app, + $c['Request'], + $c['ControllerMethodReflector'] + ); }); $this['CORSMiddleware'] = $this->share(function($c) { - return new CORSMiddleware($c['Request']); + return new CORSMiddleware( + $c['Request'], + $c['ControllerMethodReflector'] + ); }); $middleWares = &$this->middleWares; @@ -118,6 +131,9 @@ class DIContainer extends SimpleContainer implements IAppContainer{ return new TimeFactory(); }); + $this['ControllerMethodReflector'] = $this->share(function($c) { + return new ControllerMethodReflector(); + }); } diff --git a/lib/private/appframework/http.php b/lib/private/appframework/http.php index 65d926105f..d09e1d3ce2 100644 --- a/lib/private/appframework/http.php +++ b/lib/private/appframework/http.php @@ -4,7 +4,7 @@ * ownCloud - App Framework * * @author Bernhard Posselt, Thomas Tanghus, Bart Visscher - * @copyright 2012 Bernhard Posselt nukeawhale@gmail.com + * @copyright 2012 Bernhard Posselt * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE diff --git a/lib/private/appframework/http/dispatcher.php b/lib/private/appframework/http/dispatcher.php index a2afb53f0f..39ca3398c6 100644 --- a/lib/private/appframework/http/dispatcher.php +++ b/lib/private/appframework/http/dispatcher.php @@ -4,7 +4,7 @@ * ownCloud - App Framework * * @author Bernhard Posselt, Thomas Tanghus, Bart Visscher - * @copyright 2012 Bernhard Posselt nukeawhale@gmail.com + * @copyright 2012 Bernhard Posselt * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE @@ -26,7 +26,11 @@ namespace OC\AppFramework\Http; use \OC\AppFramework\Middleware\MiddlewareDispatcher; use \OC\AppFramework\Http; +use \OC\AppFramework\Utility\ControllerMethodReflector; + use OCP\AppFramework\Controller; +use OCP\AppFramework\Http\Response; +use OCP\IRequest; /** @@ -36,17 +40,25 @@ class Dispatcher { private $middlewareDispatcher; private $protocol; - + private $reflector; + private $request; /** * @param Http $protocol the http protocol with contains all status headers * @param MiddlewareDispatcher $middlewareDispatcher the dispatcher which * runs the middleware + * @param ControllerMethodReflector the reflector that is used to inject + * the arguments for the controller + * @param IRequest $request the incoming request */ public function __construct(Http $protocol, - MiddlewareDispatcher $middlewareDispatcher) { + MiddlewareDispatcher $middlewareDispatcher, + ControllerMethodReflector $reflector, + IRequest $request) { $this->protocol = $protocol; $this->middlewareDispatcher = $middlewareDispatcher; + $this->reflector = $reflector; + $this->request = $request; } @@ -63,10 +75,13 @@ class Dispatcher { $out = array(null, array(), null); try { + // prefill reflector with everything thats needed for the + // middlewares + $this->reflector->reflect($controller, $methodName); $this->middlewareDispatcher->beforeController($controller, $methodName); - $response = $controller->$methodName(); + $response = $this->executeController($controller, $methodName); // if an exception appears, the middleware checks if it can handle the // exception and creates a response. If no response is created, it is @@ -98,4 +113,70 @@ class Dispatcher { } + /** + * Uses the reflected parameters, types and request parameters to execute + * the controller + * @param Controller $controller the controller to be executed + * @param string $methodName the method on the controller that should be executed + * @return Response + */ + private function executeController($controller, $methodName) { + $arguments = array(); + + // valid types that will be casted + $types = array('int', 'integer', 'bool', 'boolean', 'float'); + + foreach($this->reflector->getParameters() as $param) { + + // try to get the parameter from the request object and cast + // it to the type annotated in the @param annotation + $value = $this->request->getParam($param); + $type = $this->reflector->getType($param); + + // if this is submitted using GET or a POST form, 'false' should be + // converted to false + if(($type === 'bool' || $type === 'boolean') && + $value === 'false' && + ( + $this->request->method === 'GET' || + strpos($this->request->getHeader('Content-Type'), + 'application/x-www-form-urlencoded') !== false + ) + ) { + $value = false; + + } elseif(in_array($type, $types)) { + settype($value, $type); + } + + $arguments[] = $value; + } + + $response = call_user_func_array(array($controller, $methodName), $arguments); + + // format response if not of type response + if(!($response instanceof Response)) { + + // get format from the url format or request format parameter + $format = $this->request->getParam('format'); + + // if none is given try the first Accept header + if($format === null) { + $header = $this->request->getHeader('Accept'); + $formats = explode(',', $header); + + if($header !== null && count($formats) > 0) { + $accept = strtolower(trim($formats[0])); + $format = str_replace('application/', '', $accept); + } else { + $format = 'json'; + } + } + + $response = $controller->buildResponse($response, $format); + } + + return $response; + } + } diff --git a/lib/private/appframework/http/request.php b/lib/private/appframework/http/request.php index 643fa685ad..8b68ca486f 100644 --- a/lib/private/appframework/http/request.php +++ b/lib/private/appframework/http/request.php @@ -3,7 +3,9 @@ * ownCloud - Request * * @author Thomas Tanghus + * @author Bernhard Posselt * @copyright 2013 Thomas Tanghus (thomas@tanghus.net) + * @copyright 2014 Bernhard Posselt * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE diff --git a/lib/private/appframework/middleware/middlewaredispatcher.php b/lib/private/appframework/middleware/middlewaredispatcher.php index 598743e523..dcb63a8e55 100644 --- a/lib/private/appframework/middleware/middlewaredispatcher.php +++ b/lib/private/appframework/middleware/middlewaredispatcher.php @@ -4,7 +4,7 @@ * ownCloud - App Framework * * @author Bernhard Posselt - * @copyright 2012 Bernhard Posselt nukeawhale@gmail.com + * @copyright 2012 Bernhard Posselt * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE diff --git a/lib/private/appframework/middleware/security/corsmiddleware.php b/lib/private/appframework/middleware/security/corsmiddleware.php index e32c5d4287..dca3996ea2 100644 --- a/lib/private/appframework/middleware/security/corsmiddleware.php +++ b/lib/private/appframework/middleware/security/corsmiddleware.php @@ -11,7 +11,7 @@ namespace OC\AppFramework\Middleware\Security; -use OC\AppFramework\Utility\MethodAnnotationReader; +use OC\AppFramework\Utility\ControllerMethodReflector; use OCP\IRequest; use OCP\AppFramework\Http\Response; use OCP\AppFramework\Middleware; @@ -25,12 +25,16 @@ use OCP\AppFramework\Middleware; class CORSMiddleware extends Middleware { private $request; + private $reflector; /** * @param IRequest $request + * @param ControllerMethodReflector $reflector */ - public function __construct(IRequest $request) { + public function __construct(IRequest $request, + ControllerMethodReflector $reflector) { $this->request = $request; + $this->reflector = $reflector; } @@ -46,10 +50,9 @@ class CORSMiddleware extends Middleware { */ public function afterController($controller, $methodName, Response $response){ // only react if its a CORS request and if the request sends origin and - $reflector = new MethodAnnotationReader($controller, $methodName); if(isset($this->request->server['HTTP_ORIGIN']) && - $reflector->hasAnnotation('CORS')) { + $this->reflector->hasAnnotation('CORS')) { // allow credentials headers must not be true or CSRF is possible // otherwise @@ -57,7 +60,7 @@ class CORSMiddleware extends Middleware { if(strtolower($header) === 'access-control-allow-credentials' && strtolower(trim($value)) === 'true') { $msg = 'Access-Control-Allow-Credentials must not be '. - 'set to true in order to prevent CSRF'; + 'set to true in order to prevent CSRF'; throw new SecurityException($msg); } } diff --git a/lib/private/appframework/middleware/security/securityexception.php b/lib/private/appframework/middleware/security/securityexception.php index e551675acd..df37d5e327 100644 --- a/lib/private/appframework/middleware/security/securityexception.php +++ b/lib/private/appframework/middleware/security/securityexception.php @@ -4,7 +4,7 @@ * ownCloud - App Framework * * @author Bernhard Posselt - * @copyright 2012 Bernhard Posselt nukeawhale@gmail.com + * @copyright 2012 Bernhard Posselt * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE diff --git a/lib/private/appframework/middleware/security/securitymiddleware.php b/lib/private/appframework/middleware/security/securitymiddleware.php index 0f160d224a..d7e398fe44 100644 --- a/lib/private/appframework/middleware/security/securitymiddleware.php +++ b/lib/private/appframework/middleware/security/securitymiddleware.php @@ -4,7 +4,7 @@ * ownCloud - App Framework * * @author Bernhard Posselt - * @copyright 2012 Bernhard Posselt nukeawhale@gmail.com + * @copyright 2012 Bernhard Posselt * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE @@ -25,7 +25,7 @@ namespace OC\AppFramework\Middleware\Security; use OC\AppFramework\Http; -use OC\AppFramework\Utility\MethodAnnotationReader; +use OC\AppFramework\Utility\ControllerMethodReflector; use OCP\AppFramework\Http\RedirectResponse; use OCP\AppFramework\Middleware; use OCP\AppFramework\Http\Response; @@ -52,13 +52,21 @@ class SecurityMiddleware extends Middleware { */ private $request; + /** + * @var OC\AppFramework\Utility\ControllerMethodReflector + */ + private $reflector; + /** * @param IAppContainer $app * @param IRequest $request + * @param ControllerMethodReflector $reflector */ - public function __construct(IAppContainer $app, IRequest $request){ + public function __construct(IAppContainer $app, IRequest $request, + ControllerMethodReflector $reflector){ $this->app = $app; $this->request = $request; + $this->reflector = $reflector; } @@ -72,28 +80,25 @@ class SecurityMiddleware extends Middleware { */ public function beforeController($controller, $methodName){ - // get annotations from comments - $annotationReader = new MethodAnnotationReader($controller, $methodName); - // this will set the current navigation entry of the app, use this only // for normal HTML requests and not for AJAX requests $this->app->getServer()->getNavigationManager()->setActiveEntry($this->app->getAppName()); // security checks - $isPublicPage = $annotationReader->hasAnnotation('PublicPage'); + $isPublicPage = $this->reflector->hasAnnotation('PublicPage'); if(!$isPublicPage) { if(!$this->app->isLoggedIn()) { throw new SecurityException('Current user is not logged in', Http::STATUS_UNAUTHORIZED); } - if(!$annotationReader->hasAnnotation('NoAdminRequired')) { + if(!$this->reflector->hasAnnotation('NoAdminRequired')) { if(!$this->app->isAdminUser()) { throw new SecurityException('Logged in user must be an admin', Http::STATUS_FORBIDDEN); } } } - if(!$annotationReader->hasAnnotation('NoCSRFRequired')) { + if(!$this->reflector->hasAnnotation('NoCSRFRequired')) { if(!$this->request->passesCSRFCheck()) { throw new SecurityException('CSRF check failed', Http::STATUS_PRECONDITION_FAILED); } diff --git a/lib/private/appframework/utility/methodannotationreader.php b/lib/private/appframework/utility/controllermethodreflector.php similarity index 55% rename from lib/private/appframework/utility/methodannotationreader.php rename to lib/private/appframework/utility/controllermethodreflector.php index 42060a0852..c9cdadcca4 100644 --- a/lib/private/appframework/utility/methodannotationreader.php +++ b/lib/private/appframework/utility/controllermethodreflector.php @@ -4,7 +4,7 @@ * ownCloud - App Framework * * @author Bernhard Posselt - * @copyright 2012 Bernhard Posselt nukeawhale@gmail.com + * @copyright 2014 Bernhard Posselt * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE @@ -28,23 +28,63 @@ namespace OC\AppFramework\Utility; /** * Reads and parses annotations from doc comments */ -class MethodAnnotationReader { +class ControllerMethodReflector { private $annotations; + private $types; + private $parameters; + + public function __construct() { + $this->types = array(); + $this->parameters = array(); + $this->annotations = array(); + } + /** * @param object $object an object or classname - * @param string $method the method which we want to inspect for annotations + * @param string $method the method which we want to inspect */ - public function __construct($object, $method){ - $this->annotations = array(); - + public function reflect($object, $method){ $reflection = new \ReflectionMethod($object, $method); $docs = $reflection->getDocComment(); // extract everything prefixed by @ and first letter uppercase preg_match_all('/@([A-Z]\w+)/', $docs, $matches); $this->annotations = $matches[1]; + + // extract type parameter information + preg_match_all('/@param (?\w+) \$(?\w+)/', $docs, $matches); + $this->types = array_combine($matches['var'], $matches['type']); + + // get method parameters + foreach ($reflection->getParameters() as $param) { + $this->parameters[] = $param->name; + } + } + + + /** + * Inspects the PHPDoc parameters for types + * @param string $parameter the parameter whose type comments should be + * parsed + * @return string|null type in the type parameters (@param int $something) + * would return int or null if not existing + */ + public function getType($parameter) { + if(array_key_exists($parameter, $this->types)) { + return $this->types[$parameter]; + } else { + return null; + } + } + + + /** + * @return array the arguments of the method + */ + public function getParameters() { + return $this->parameters; } diff --git a/lib/private/appframework/utility/timefactory.php b/lib/private/appframework/utility/timefactory.php index 2c3dd6cf5e..a9b07a356e 100644 --- a/lib/private/appframework/utility/timefactory.php +++ b/lib/private/appframework/utility/timefactory.php @@ -4,7 +4,7 @@ * ownCloud - App Framework * * @author Bernhard Posselt - * @copyright 2012 Bernhard Posselt nukeawhale@gmail.com + * @copyright 2012 Bernhard Posselt * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE diff --git a/lib/public/appframework/controller.php b/lib/public/appframework/controller.php index f42eba172c..50b5ed3a80 100644 --- a/lib/public/appframework/controller.php +++ b/lib/public/appframework/controller.php @@ -3,7 +3,7 @@ * ownCloud - App Framework * * @author Bernhard Posselt - * @copyright 2012 Bernhard Posselt nukeawhale@gmail.com + * @copyright 2012, 2014 Bernhard Posselt * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE @@ -28,6 +28,8 @@ namespace OCP\AppFramework; use OCP\AppFramework\Http\TemplateResponse; +use OCP\AppFramework\Http\JSONResponse; +use OCP\AppFramework\Http\IResponseSerializer; use OCP\IRequest; @@ -48,6 +50,8 @@ abstract class Controller { */ protected $request; + private $serializer; + private $responders; /** * constructor of the controller @@ -66,11 +70,66 @@ abstract class Controller { IRequest $request){ $this->appName = $appName; $this->request = $request; + + // default responders + $this->responders = array( + 'json' => function ($response) { + return new JSONResponse($response); + } + ); + } + + + /** + * Registers a serializer that is executed before a formatter is being + * called, useful for turning any data into PHP arrays that can be used + * by a JSONResponse for instance + * @param IResponseSerializer $serializer + */ + protected function registerSerializer(IResponseSerializer $serializer) { + $this->serializer = $serializer; + } + + + /** + * Registers a formatter for a type + * @param string $format + * @param \Closure $responder + */ + protected function registerResponder($format, \Closure $responder) { + $this->responders[$format] = $responder; + } + + + /** + * Serializes and formats a response + * @param mixed $response the value that was returned from a controller and + * is not a Response instance + * @param string $format the format for which a formatter has been registered + * @throws \DomainException if format does not match a registered formatter + * @return Response + */ + public function buildResponse($response, $format='json') { + if(array_key_exists($format, $this->responders)) { + + if ($this->serializer) { + $response = $this->serializer->serialize($response); + } + + $responder = $this->responders[$format]; + + return $responder($response); + + } else { + throw new \DomainException('No responder registered for format ' . + $format . '!'); + } } /** * Lets you access post and get parameters by the index + * @deprecated write your parameters as method arguments instead * @param string $key the key which you want to access in the URL Parameter * placeholder, $_POST or $_GET array. * The priority how they're returned is the following: @@ -88,6 +147,7 @@ abstract class Controller { /** * Returns all params that were received, be it from the request * (as GET or POST) or throuh the URL by the route + * @deprecated use $this->request instead * @return array the array with all parameters */ public function getParams() { @@ -97,6 +157,7 @@ abstract class Controller { /** * Returns the method of the request + * @deprecated use $this->request instead * @return string the method of the request (POST, GET, etc) */ public function method() { @@ -106,6 +167,7 @@ abstract class Controller { /** * Shortcut for accessing an uploaded file through the $_FILES array + * @deprecated use $this->request instead * @param string $key the key that will be taken from the $_FILES array * @return array the file in the $_FILES element */ @@ -116,6 +178,7 @@ abstract class Controller { /** * Shortcut for getting env variables + * @deprecated use $this->request instead * @param string $key the key that will be taken from the $_ENV array * @return array the value in the $_ENV element */ @@ -126,6 +189,7 @@ abstract class Controller { /** * Shortcut for getting cookie variables + * @deprecated use $this->request instead * @param string $key the key that will be taken from the $_COOKIE array * @return array the value in the $_COOKIE element */ @@ -136,6 +200,7 @@ abstract class Controller { /** * Shortcut for rendering a template + * @deprecated return a template response instead * @param string $templateName the name of the template * @param array $params the template parameters in key => value structure * @param string $renderAs user renders a full page, blank only your template diff --git a/lib/public/appframework/http.php b/lib/public/appframework/http.php index 60f314202c..c6e2ff8846 100644 --- a/lib/public/appframework/http.php +++ b/lib/public/appframework/http.php @@ -3,7 +3,7 @@ * ownCloud - App Framework * * @author Bernhard Posselt, Thomas Tanghus, Bart Visscher - * @copyright 2012 Bernhard Posselt nukeawhale@gmail.com + * @copyright 2012 Bernhard Posselt * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE diff --git a/lib/public/appframework/http/downloadresponse.php b/lib/public/appframework/http/downloadresponse.php index d3c2818e82..6b61490341 100644 --- a/lib/public/appframework/http/downloadresponse.php +++ b/lib/public/appframework/http/downloadresponse.php @@ -4,7 +4,7 @@ * ownCloud - App Framework * * @author Bernhard Posselt - * @copyright 2012 Bernhard Posselt nukeawhale@gmail.com + * @copyright 2012 Bernhard Posselt * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE diff --git a/lib/public/appframework/http/iresponseserializer.php b/lib/public/appframework/http/iresponseserializer.php new file mode 100644 index 0000000000..c16e106df3 --- /dev/null +++ b/lib/public/appframework/http/iresponseserializer.php @@ -0,0 +1,27 @@ + + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE + * License as published by the Free Software Foundation; either + * version 3 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU AFFERO GENERAL PUBLIC LICENSE for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with this library. If not, see . + * + */ + +namespace OCP\AppFramework\Http; + +interface IResponseSerializer { + function serialize($response); +} \ No newline at end of file diff --git a/lib/public/appframework/http/jsonresponse.php b/lib/public/appframework/http/jsonresponse.php index 6d029b7464..c6360e0a0f 100644 --- a/lib/public/appframework/http/jsonresponse.php +++ b/lib/public/appframework/http/jsonresponse.php @@ -3,7 +3,7 @@ * ownCloud - App Framework * * @author Bernhard Posselt - * @copyright 2012 Bernhard Posselt nukeawhale@gmail.com + * @copyright 2012 Bernhard Posselt * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE diff --git a/lib/public/appframework/http/redirectresponse.php b/lib/public/appframework/http/redirectresponse.php index 416e153363..a1b482c6b3 100644 --- a/lib/public/appframework/http/redirectresponse.php +++ b/lib/public/appframework/http/redirectresponse.php @@ -4,7 +4,7 @@ * ownCloud - App Framework * * @author Bernhard Posselt - * @copyright 2012 Bernhard Posselt nukeawhale@gmail.com + * @copyright 2012 Bernhard Posselt * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE diff --git a/lib/public/appframework/http/response.php b/lib/public/appframework/http/response.php index 559d14dd7e..20e936bb86 100644 --- a/lib/public/appframework/http/response.php +++ b/lib/public/appframework/http/response.php @@ -3,7 +3,7 @@ * ownCloud - App Framework * * @author Bernhard Posselt, Thomas Tanghus, Bart Visscher - * @copyright 2012 Bernhard Posselt nukeawhale@gmail.com + * @copyright 2012 Bernhard Posselt * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE diff --git a/lib/public/appframework/http/templateresponse.php b/lib/public/appframework/http/templateresponse.php index f5baf788ad..02589f4e2a 100644 --- a/lib/public/appframework/http/templateresponse.php +++ b/lib/public/appframework/http/templateresponse.php @@ -3,7 +3,7 @@ * ownCloud - App Framework * * @author Bernhard Posselt - * @copyright 2012 Bernhard Posselt nukeawhale@gmail.com + * @copyright 2012 Bernhard Posselt * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE @@ -61,12 +61,16 @@ class TemplateResponse extends Response { * constructor of TemplateResponse * @param string $appName the name of the app to load the template from * @param string $templateName the name of the template + * @param array $params an array of parameters which should be passed to the + * template + * @param string $renderAs how the page should be rendered, defaults to user */ - public function __construct($appName, $templateName) { + public function __construct($appName, $templateName, array $params=array(), + $renderAs='user') { $this->templateName = $templateName; $this->appName = $appName; - $this->params = array(); - $this->renderAs = 'user'; + $this->params = $params; + $this->renderAs = $renderAs; } diff --git a/lib/public/appframework/iapi.php b/lib/public/appframework/iapi.php index c4aeea2d4e..9af251be85 100644 --- a/lib/public/appframework/iapi.php +++ b/lib/public/appframework/iapi.php @@ -3,7 +3,7 @@ * ownCloud - App Framework * * @author Bernhard Posselt - * @copyright 2012 Bernhard Posselt nukeawhale@gmail.com + * @copyright 2012 Bernhard Posselt * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE diff --git a/lib/public/appframework/middleware.php b/lib/public/appframework/middleware.php index 24f3193993..2e1111e9d5 100644 --- a/lib/public/appframework/middleware.php +++ b/lib/public/appframework/middleware.php @@ -3,7 +3,7 @@ * ownCloud - App Framework * * @author Bernhard Posselt - * @copyright 2012 Bernhard Posselt nukeawhale@gmail.com + * @copyright 2012 Bernhard Posselt * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE diff --git a/tests/lib/app.php b/tests/lib/app.php index 49f40f089b..683820cabb 100644 --- a/tests/lib/app.php +++ b/tests/lib/app.php @@ -1,6 +1,6 @@ + * Copyright (c) 2012 Bernhard Posselt * This file is licensed under the Affero General Public License version 3 or * later. * See the COPYING-README file. diff --git a/tests/lib/appframework/AppTest.php b/tests/lib/appframework/AppTest.php index 3628e4ceab..92fa483834 100644 --- a/tests/lib/appframework/AppTest.php +++ b/tests/lib/appframework/AppTest.php @@ -4,7 +4,7 @@ * ownCloud - App Framework * * @author Bernhard Posselt - * @copyright 2012 Bernhard Posselt nukeawhale@gmail.com + * @copyright 2012 Bernhard Posselt * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE diff --git a/tests/lib/appframework/controller/ControllerTest.php b/tests/lib/appframework/controller/ControllerTest.php index b6c83125da..3c1716a91d 100644 --- a/tests/lib/appframework/controller/ControllerTest.php +++ b/tests/lib/appframework/controller/ControllerTest.php @@ -4,7 +4,7 @@ * ownCloud - App Framework * * @author Bernhard Posselt - * @copyright 2012 Bernhard Posselt nukeawhale@gmail.com + * @copyright 2012 Bernhard Posselt * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE @@ -26,9 +26,31 @@ namespace OCP\AppFramework; use OC\AppFramework\Http\Request; use OCP\AppFramework\Http\TemplateResponse; +use OCP\AppFramework\Http\JSONResponse; +use OCP\AppFramework\Http\IResponseSerializer; -class ChildController extends Controller {}; +class ToUpperCaseSerializer implements IResponseSerializer { + public function serialize($response) { + return array(strtoupper($response)); + } +} + +class ChildController extends Controller { + public function custom($in) { + $this->registerResponder('json', function ($response) { + return new JSONResponse(array(strlen($response))); + }); + + return $in; + } + + public function serializer($in) { + $this->registerSerializer(new ToUpperCaseSerializer()); + + return $in; + } +}; class ControllerTest extends \PHPUnit_Framework_TestCase { @@ -129,4 +151,35 @@ class ControllerTest extends \PHPUnit_Framework_TestCase { } + /** + * @expectedException \DomainException + */ + public function testFormatResonseInvalidFormat() { + $this->controller->buildResponse(null, 'test'); + } + + + public function testFormat() { + $response = $this->controller->buildResponse(array('hi'), 'json'); + + $this->assertEquals(array('hi'), $response->getData()); + } + + + public function testCustomFormatter() { + $response = $this->controller->custom('hi'); + $response = $this->controller->buildResponse($response, 'json'); + + $this->assertEquals(array(2), $response->getData()); + } + + + public function testCustomSerializer() { + $response = $this->controller->serializer('hi'); + $response = $this->controller->buildResponse($response, 'json'); + + $this->assertEquals(array('HI'), $response->getData()); + } + + } diff --git a/tests/lib/appframework/dependencyinjection/DIContainerTest.php b/tests/lib/appframework/dependencyinjection/DIContainerTest.php index d1bc900fb2..acc5c2e66d 100644 --- a/tests/lib/appframework/dependencyinjection/DIContainerTest.php +++ b/tests/lib/appframework/dependencyinjection/DIContainerTest.php @@ -5,8 +5,8 @@ * * @author Bernhard Posselt * @author Morris Jobke - * @copyright 2012 Bernhard Posselt nukeawhale@gmail.com - * @copyright 2013 Morris Jobke morris.jobke@gmail.com + * @copyright 2012 Bernhard Posselt + * @copyright 2013 Morris Jobke * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE diff --git a/tests/lib/appframework/http/DispatcherTest.php b/tests/lib/appframework/http/DispatcherTest.php index 9841dcaa1f..2aef2911e2 100644 --- a/tests/lib/appframework/http/DispatcherTest.php +++ b/tests/lib/appframework/http/DispatcherTest.php @@ -4,7 +4,7 @@ * ownCloud - App Framework * * @author Bernhard Posselt - * @copyright 2012 Bernhard Posselt nukeawhale@gmail.com + * @copyright 2012 Bernhard Posselt * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE @@ -25,8 +25,28 @@ namespace OC\AppFramework\Http; use OC\AppFramework\Middleware\MiddlewareDispatcher; +use OC\AppFramework\Utility\ControllerMethodReflector; use OCP\AppFramework\Http; -//require_once(__DIR__ . "/../classloader.php"); +use OCP\AppFramework\Http\JSONResponse; +use OCP\AppFramework\Controller; + + +class TestController extends Controller { + public function __construct($appName, $request) { + parent::__construct($appName, $request); + } + + /** + * @param int $int + * @param bool $bool + */ + public function exec($int, $bool) { + $this->registerResponder('text', function($in) { + return new JSONResponse(array('text' => $in)); + }); + return array($int, $bool); + } +} class DispatcherTest extends \PHPUnit_Framework_TestCase { @@ -39,6 +59,7 @@ class DispatcherTest extends \PHPUnit_Framework_TestCase { private $lastModified; private $etag; private $http; + private $reflector; protected function setUp() { $this->controllerMethod = 'test'; @@ -64,8 +85,17 @@ class DispatcherTest extends \PHPUnit_Framework_TestCase { '\OCP\AppFramework\Controller', array($this->controllerMethod), array($app, $request)); + $this->request = $this->getMockBuilder( + '\OC\AppFramework\Http\Request') + ->disableOriginalConstructor() + ->getMock(); + + $this->reflector = new ControllerMethodReflector(); + $this->dispatcher = new Dispatcher( - $this->http, $this->middlewareDispatcher); + $this->http, $this->middlewareDispatcher, $this->reflector, + $this->request + ); $this->response = $this->getMockBuilder( '\OCP\AppFramework\Http\Response') @@ -81,7 +111,7 @@ class DispatcherTest extends \PHPUnit_Framework_TestCase { * @param string $out * @param string $httpHeaders */ - private function setMiddlewareExpections($out=null, + private function setMiddlewareExpectations($out=null, $httpHeaders=null, $responseHeaders=array(), $ex=false, $catchEx=true) { @@ -159,14 +189,12 @@ class DispatcherTest extends \PHPUnit_Framework_TestCase { ->with($this->equalTo($this->controller), $this->equalTo($this->controllerMethod), $this->equalTo($out)) - ->will($this->returnValue($out)); - - + ->will($this->returnValue($out)); } public function testDispatcherReturnsArrayWith2Entries() { - $this->setMiddlewareExpections(); + $this->setMiddlewareExpectations(); $response = $this->dispatcher->dispatch($this->controller, $this->controllerMethod); @@ -180,7 +208,7 @@ class DispatcherTest extends \PHPUnit_Framework_TestCase { $out = 'yo'; $httpHeaders = 'Http'; $responseHeaders = array('hell' => 'yeah'); - $this->setMiddlewareExpections($out, $httpHeaders, $responseHeaders); + $this->setMiddlewareExpectations($out, $httpHeaders, $responseHeaders); $response = $this->dispatcher->dispatch($this->controller, $this->controllerMethod); @@ -195,7 +223,7 @@ class DispatcherTest extends \PHPUnit_Framework_TestCase { $out = 'yo'; $httpHeaders = 'Http'; $responseHeaders = array('hell' => 'yeah'); - $this->setMiddlewareExpections($out, $httpHeaders, $responseHeaders, true); + $this->setMiddlewareExpectations($out, $httpHeaders, $responseHeaders, true); $response = $this->dispatcher->dispatch($this->controller, $this->controllerMethod); @@ -210,7 +238,7 @@ class DispatcherTest extends \PHPUnit_Framework_TestCase { $out = 'yo'; $httpHeaders = 'Http'; $responseHeaders = array('hell' => 'yeah'); - $this->setMiddlewareExpections($out, $httpHeaders, $responseHeaders, true, false); + $this->setMiddlewareExpectations($out, $httpHeaders, $responseHeaders, true, false); $this->setExpectedException('\Exception'); $response = $this->dispatcher->dispatch($this->controller, @@ -218,4 +246,120 @@ class DispatcherTest extends \PHPUnit_Framework_TestCase { } + + private function dispatcherPassthrough() { + $this->middlewareDispatcher->expects($this->once()) + ->method('beforeController'); + $this->middlewareDispatcher->expects($this->once()) + ->method('afterController') + ->will($this->returnCallback(function($a, $b, $in) { + return $in; + })); + $this->middlewareDispatcher->expects($this->once()) + ->method('beforeOutput') + ->will($this->returnCallback(function($a, $b, $in) { + return $in; + })); + } + + public function testControllerParametersInjected() { + $this->request = new Request(array( + 'post' => array( + 'int' => '3', + 'bool' => 'false' + ), + 'method' => 'POST' + )); + $this->dispatcher = new Dispatcher( + $this->http, $this->middlewareDispatcher, $this->reflector, + $this->request + ); + $controller = new TestController('app', $this->request); + + // reflector is supposed to be called once + $this->dispatcherPassthrough(); + $response = $this->dispatcher->dispatch($controller, 'exec'); + + $this->assertEquals('[3,true]', $response[2]); + } + + + public function testResponseTransformedByUrlFormat() { + $this->request = new Request(array( + 'post' => array( + 'int' => '3', + 'bool' => 'false' + ), + 'urlParams' => array( + 'format' => 'text' + ), + 'method' => 'GET' + )); + $this->dispatcher = new Dispatcher( + $this->http, $this->middlewareDispatcher, $this->reflector, + $this->request + ); + $controller = new TestController('app', $this->request); + + // reflector is supposed to be called once + $this->dispatcherPassthrough(); + $response = $this->dispatcher->dispatch($controller, 'exec'); + + $this->assertEquals('{"text":[3,false]}', $response[2]); + } + + + public function testResponseTransformedByAcceptHeader() { + $this->request = new Request(array( + 'post' => array( + 'int' => '3', + 'bool' => 'false' + ), + 'server' => array( + 'HTTP_ACCEPT' => 'application/text, test', + 'HTTP_CONTENT_TYPE' => 'application/x-www-form-urlencoded' + ), + 'method' => 'PUT' + )); + $this->dispatcher = new Dispatcher( + $this->http, $this->middlewareDispatcher, $this->reflector, + $this->request + ); + $controller = new TestController('app', $this->request); + + // reflector is supposed to be called once + $this->dispatcherPassthrough(); + $response = $this->dispatcher->dispatch($controller, 'exec'); + + $this->assertEquals('{"text":[3,false]}', $response[2]); + } + + + public function testResponsePrimarilyTransformedByParameterFormat() { + $this->request = new Request(array( + 'post' => array( + 'int' => '3', + 'bool' => 'false' + ), + 'get' => array( + 'format' => 'text' + ), + 'server' => array( + 'HTTP_ACCEPT' => 'application/json, test' + ), + 'method' => 'POST' + )); + $this->dispatcher = new Dispatcher( + $this->http, $this->middlewareDispatcher, $this->reflector, + $this->request + ); + $controller = new TestController('app', $this->request); + + // reflector is supposed to be called once + $this->dispatcherPassthrough(); + $response = $this->dispatcher->dispatch($controller, 'exec'); + + $this->assertEquals('{"text":[3,true]}', $response[2]); + } + } diff --git a/tests/lib/appframework/http/DownloadResponseTest.php b/tests/lib/appframework/http/DownloadResponseTest.php index b305c63ad4..5be16ce3c4 100644 --- a/tests/lib/appframework/http/DownloadResponseTest.php +++ b/tests/lib/appframework/http/DownloadResponseTest.php @@ -4,7 +4,7 @@ * ownCloud - App Framework * * @author Bernhard Posselt - * @copyright 2012 Bernhard Posselt nukeawhale@gmail.com + * @copyright 2012 Bernhard Posselt * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE diff --git a/tests/lib/appframework/http/HttpTest.php b/tests/lib/appframework/http/HttpTest.php index 0bdcee24c9..c62fa43863 100644 --- a/tests/lib/appframework/http/HttpTest.php +++ b/tests/lib/appframework/http/HttpTest.php @@ -4,7 +4,7 @@ * ownCloud - App Framework * * @author Bernhard Posselt - * @copyright 2012 Bernhard Posselt nukeawhale@gmail.com + * @copyright 2012 Bernhard Posselt * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE diff --git a/tests/lib/appframework/http/JSONResponseTest.php b/tests/lib/appframework/http/JSONResponseTest.php index fbaae1b922..c0c58ebf76 100644 --- a/tests/lib/appframework/http/JSONResponseTest.php +++ b/tests/lib/appframework/http/JSONResponseTest.php @@ -5,8 +5,8 @@ * * @author Bernhard Posselt * @author Morris Jobke - * @copyright 2012 Bernhard Posselt nukeawhale@gmail.com - * @copyright 2013 Morris Jobke morris.jobke@gmail.com + * @copyright 2012 Bernhard Posselt + * @copyright 2013 Morris Jobke * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE diff --git a/tests/lib/appframework/http/RedirectResponseTest.php b/tests/lib/appframework/http/RedirectResponseTest.php index f62b420f4e..dfd0d7ee7d 100644 --- a/tests/lib/appframework/http/RedirectResponseTest.php +++ b/tests/lib/appframework/http/RedirectResponseTest.php @@ -4,7 +4,7 @@ * ownCloud - App Framework * * @author Bernhard Posselt - * @copyright 2012 Bernhard Posselt nukeawhale@gmail.com + * @copyright 2012 Bernhard Posselt * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE diff --git a/tests/lib/appframework/http/ResponseTest.php b/tests/lib/appframework/http/ResponseTest.php index 4b8d3ae50e..e83fe9e2d8 100644 --- a/tests/lib/appframework/http/ResponseTest.php +++ b/tests/lib/appframework/http/ResponseTest.php @@ -4,7 +4,7 @@ * ownCloud - App Framework * * @author Bernhard Posselt - * @copyright 2012 Bernhard Posselt nukeawhale@gmail.com + * @copyright 2012 Bernhard Posselt * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE diff --git a/tests/lib/appframework/http/TemplateResponseTest.php b/tests/lib/appframework/http/TemplateResponseTest.php index 0b158edff6..afdcf322b8 100644 --- a/tests/lib/appframework/http/TemplateResponseTest.php +++ b/tests/lib/appframework/http/TemplateResponseTest.php @@ -4,7 +4,7 @@ * ownCloud - App Framework * * @author Bernhard Posselt - * @copyright 2012 Bernhard Posselt nukeawhale@gmail.com + * @copyright 2012 Bernhard Posselt * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE @@ -51,6 +51,22 @@ class TemplateResponseTest extends \PHPUnit_Framework_TestCase { } + public function testSetParamsConstructor(){ + $params = array('hi' => 'yo'); + $this->tpl = new TemplateResponse($this->api, 'home', $params); + + $this->assertEquals(array('hi' => 'yo'), $this->tpl->getParams()); + } + + + public function testSetRenderAsConstructor(){ + $renderAs = 'myrender'; + $this->tpl = new TemplateResponse($this->api, 'home', array(), $renderAs); + + $this->assertEquals($renderAs, $this->tpl->getRenderAs()); + } + + public function testSetParams(){ $params = array('hi' => 'yo'); $this->tpl->setParams($params); @@ -63,36 +79,6 @@ class TemplateResponseTest extends \PHPUnit_Framework_TestCase { $this->assertEquals('home', $this->tpl->getTemplateName()); } - -// public function testRender(){ -// $ocTpl = $this->getMock('Template', array('fetchPage')); -// $ocTpl->expects($this->once()) -// ->method('fetchPage'); -// -// $tpl = new TemplateResponse('core', 'error'); -// -// $tpl->render(); -// } -// -// -// public function testRenderAssignsParams(){ -// $params = array('john' => 'doe'); -// -// $tpl = new TemplateResponse('app', 'home'); -// $tpl->setParams($params); -// -// $tpl->render(); -// } -// -// -// public function testRenderDifferentApp(){ -// -// $tpl = new TemplateResponse('app', 'home', 'app2'); -// -// $tpl->render(); -// } - - public function testGetRenderAs(){ $render = 'myrender'; $this->tpl->renderAs($render); diff --git a/tests/lib/appframework/middleware/MiddlewareDispatcherTest.php b/tests/lib/appframework/middleware/MiddlewareDispatcherTest.php index 935f97d2a6..b1a58e2128 100644 --- a/tests/lib/appframework/middleware/MiddlewareDispatcherTest.php +++ b/tests/lib/appframework/middleware/MiddlewareDispatcherTest.php @@ -4,7 +4,7 @@ * ownCloud - App Framework * * @author Bernhard Posselt - * @copyright 2012 Bernhard Posselt nukeawhale@gmail.com + * @copyright 2012 Bernhard Posselt * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE diff --git a/tests/lib/appframework/middleware/MiddlewareTest.php b/tests/lib/appframework/middleware/MiddlewareTest.php index 7a93c0d4dd..814efdd811 100644 --- a/tests/lib/appframework/middleware/MiddlewareTest.php +++ b/tests/lib/appframework/middleware/MiddlewareTest.php @@ -4,7 +4,7 @@ * ownCloud - App Framework * * @author Bernhard Posselt - * @copyright 2012 Bernhard Posselt nukeawhale@gmail.com + * @copyright 2012 Bernhard Posselt * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE diff --git a/tests/lib/appframework/middleware/security/CORSMiddlewareTest.php b/tests/lib/appframework/middleware/security/CORSMiddlewareTest.php index 8224e9b4aa..79cd3b278a 100644 --- a/tests/lib/appframework/middleware/security/CORSMiddlewareTest.php +++ b/tests/lib/appframework/middleware/security/CORSMiddlewareTest.php @@ -13,11 +13,19 @@ namespace OC\AppFramework\Middleware\Security; use OC\AppFramework\Http\Request; +use OC\AppFramework\Utility\ControllerMethodReflector; + use OCP\AppFramework\Http\Response; class CORSMiddlewareTest extends \PHPUnit_Framework_TestCase { + private $reflector; + + protected function setUp() { + $this->reflector = new ControllerMethodReflector(); + } + /** * @CORS */ @@ -25,11 +33,11 @@ class CORSMiddlewareTest extends \PHPUnit_Framework_TestCase { $request = new Request( array('server' => array('HTTP_ORIGIN' => 'test')) ); + $this->reflector->reflect($this, __FUNCTION__); + $middleware = new CORSMiddleware($request, $this->reflector); - $middleware = new CORSMiddleware($request); $response = $middleware->afterController($this, __FUNCTION__, new Response()); $headers = $response->getHeaders(); - $this->assertEquals('test', $headers['Access-Control-Allow-Origin']); } @@ -38,7 +46,7 @@ class CORSMiddlewareTest extends \PHPUnit_Framework_TestCase { $request = new Request( array('server' => array('HTTP_ORIGIN' => 'test')) ); - $middleware = new CORSMiddleware($request); + $middleware = new CORSMiddleware($request, $this->reflector); $response = $middleware->afterController($this, __FUNCTION__, new Response()); $headers = $response->getHeaders(); @@ -51,8 +59,9 @@ class CORSMiddlewareTest extends \PHPUnit_Framework_TestCase { */ public function testNoOriginHeaderNoCORSHEADER() { $request = new Request(); + $this->reflector->reflect($this, __FUNCTION__); + $middleware = new CORSMiddleware($request, $this->reflector); - $middleware = new CORSMiddleware($request); $response = $middleware->afterController($this, __FUNCTION__, new Response()); $headers = $response->getHeaders(); $this->assertFalse(array_key_exists('Access-Control-Allow-Origin', $headers)); @@ -67,7 +76,8 @@ class CORSMiddlewareTest extends \PHPUnit_Framework_TestCase { $request = new Request( array('server' => array('HTTP_ORIGIN' => 'test')) ); - $middleware = new CORSMiddleware($request); + $this->reflector->reflect($this, __FUNCTION__); + $middleware = new CORSMiddleware($request, $this->reflector); $response = new Response(); $response->addHeader('AcCess-control-Allow-Credentials ', 'TRUE'); diff --git a/tests/lib/appframework/middleware/security/SecurityMiddlewareTest.php b/tests/lib/appframework/middleware/security/SecurityMiddlewareTest.php index 19e8a68c38..6a1bbf72c1 100644 --- a/tests/lib/appframework/middleware/security/SecurityMiddlewareTest.php +++ b/tests/lib/appframework/middleware/security/SecurityMiddlewareTest.php @@ -4,7 +4,7 @@ * ownCloud - App Framework * * @author Bernhard Posselt - * @copyright 2012 Bernhard Posselt nukeawhale@gmail.com + * @copyright 2012 Bernhard Posselt * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE @@ -26,6 +26,7 @@ namespace OC\AppFramework\Middleware\Security; use OC\AppFramework\Http; use OC\AppFramework\Http\Request; +use OC\AppFramework\Utility\ControllerMethodReflector; use OCP\AppFramework\Http\RedirectResponse; use OCP\AppFramework\Http\JSONResponse; @@ -37,14 +38,16 @@ class SecurityMiddlewareTest extends \PHPUnit_Framework_TestCase { private $secException; private $secAjaxException; private $request; + private $reader; public function setUp() { $api = $this->getMock('OC\AppFramework\DependencyInjection\DIContainer', array(), array('test')); $this->controller = $this->getMock('OCP\AppFramework\Controller', array(), array($api, new Request())); + $this->reader = new ControllerMethodReflector(); $this->request = new Request(); - $this->middleware = new SecurityMiddleware($api, $this->request); + $this->middleware = new SecurityMiddleware($api, $this->request, $this->reader); $this->secException = new SecurityException('hey', false); $this->secAjaxException = new SecurityException('hey', true); } @@ -68,7 +71,8 @@ class SecurityMiddlewareTest extends \PHPUnit_Framework_TestCase { $api->expects($this->any())->method('getServer') ->will($this->returnValue($serverMock)); - $sec = new SecurityMiddleware($api, $this->request); + $sec = new SecurityMiddleware($api, $this->request, $this->reader); + $this->reader->reflect('\OC\AppFramework\Middleware\Security\SecurityMiddlewareTest', $method); $sec->beforeController('\OC\AppFramework\Middleware\Security\SecurityMiddlewareTest', $method); } @@ -99,11 +103,12 @@ class SecurityMiddlewareTest extends \PHPUnit_Framework_TestCase { ->will($this->returnValue(true)); } - $sec = new SecurityMiddleware($api, $this->request); + $sec = new SecurityMiddleware($api, $this->request, $this->reader); try { - $sec->beforeController('\OC\AppFramework\Middleware\Security\SecurityMiddlewareTest', - $method); + $controller = '\OC\AppFramework\Middleware\Security\SecurityMiddlewareTest'; + $this->reader->reflect($controller, $method); + $sec->beforeController($controller, $method); } catch (SecurityException $ex){ $this->assertEquals($status, $ex->getCode()); } @@ -184,7 +189,9 @@ class SecurityMiddlewareTest extends \PHPUnit_Framework_TestCase { ->method('isLoggedIn') ->will($this->returnValue(true)); - $sec = new SecurityMiddleware($api, $this->request); + $sec = new SecurityMiddleware($api, $this->request, $this->reader); + $this->reader->reflect('\OC\AppFramework\Middleware\Security\SecurityMiddlewareTest', + 'testNoChecks'); $sec->beforeController('\OC\AppFramework\Middleware\Security\SecurityMiddlewareTest', 'testNoChecks'); } @@ -207,7 +214,7 @@ class SecurityMiddlewareTest extends \PHPUnit_Framework_TestCase { ->will($this->returnValue(true)); } - $sec = new SecurityMiddleware($api, $this->request); + $sec = new SecurityMiddleware($api, $this->request, $this->reader); if($shouldFail){ $this->setExpectedException('\OC\AppFramework\Middleware\Security\SecurityException'); @@ -215,6 +222,7 @@ class SecurityMiddlewareTest extends \PHPUnit_Framework_TestCase { $this->setExpectedException(null); } + $this->reader->reflect('\OC\AppFramework\Middleware\Security\SecurityMiddlewareTest', $method); $sec->beforeController('\OC\AppFramework\Middleware\Security\SecurityMiddlewareTest', $method); } @@ -230,7 +238,8 @@ class SecurityMiddlewareTest extends \PHPUnit_Framework_TestCase { ->method('passesCSRFCheck') ->will($this->returnValue(false)); - $sec = new SecurityMiddleware($api, $request); + $sec = new SecurityMiddleware($api, $request, $this->reader); + $this->reader->reflect('\OC\AppFramework\Middleware\Security\SecurityMiddlewareTest', 'testCsrfCheck'); $sec->beforeController('\OC\AppFramework\Middleware\Security\SecurityMiddlewareTest', 'testCsrfCheck'); } @@ -246,7 +255,8 @@ class SecurityMiddlewareTest extends \PHPUnit_Framework_TestCase { ->method('passesCSRFCheck') ->will($this->returnValue(false)); - $sec = new SecurityMiddleware($api, $request); + $sec = new SecurityMiddleware($api, $request, $this->reader); + $this->reader->reflect('\OC\AppFramework\Middleware\Security\SecurityMiddlewareTest', 'testNoCsrfCheck'); $sec->beforeController('\OC\AppFramework\Middleware\Security\SecurityMiddlewareTest', 'testNoCsrfCheck'); } @@ -261,7 +271,8 @@ class SecurityMiddlewareTest extends \PHPUnit_Framework_TestCase { ->method('passesCSRFCheck') ->will($this->returnValue(true)); - $sec = new SecurityMiddleware($api, $request); + $sec = new SecurityMiddleware($api, $request, $this->reader); + $this->reader->reflect('\OC\AppFramework\Middleware\Security\SecurityMiddlewareTest', 'testFailCsrfCheck'); $sec->beforeController('\OC\AppFramework\Middleware\Security\SecurityMiddlewareTest', 'testFailCsrfCheck'); } @@ -318,7 +329,7 @@ class SecurityMiddlewareTest extends \PHPUnit_Framework_TestCase { $this->request = new Request( array('server' => array('HTTP_ACCEPT' => 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8'))); - $this->middleware = new SecurityMiddleware($api, $this->request); + $this->middleware = new SecurityMiddleware($api, $this->request, $this->reader); $response = $this->middleware->afterException($this->controller, 'test', $this->secException); diff --git a/tests/lib/appframework/utility/ControllerMethodReflectorTest.php b/tests/lib/appframework/utility/ControllerMethodReflectorTest.php new file mode 100644 index 0000000000..cccc768888 --- /dev/null +++ b/tests/lib/appframework/utility/ControllerMethodReflectorTest.php @@ -0,0 +1,115 @@ + + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE + * License as published by the Free Software Foundation; either + * version 3 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU AFFERO GENERAL PUBLIC LICENSE for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with this library. If not, see . + * + */ + + +namespace OC\AppFramework\Utility; + + +class ControllerMethodReflectorTest extends \PHPUnit_Framework_TestCase { + + + /** + * @Annotation + */ + public function testReadAnnotation(){ + $reader = new ControllerMethodReflector(); + $reader->reflect( + '\OC\AppFramework\Utility\ControllerMethodReflectorTest', + 'testReadAnnotation' + ); + + $this->assertTrue($reader->hasAnnotation('Annotation')); + } + + + /** + * @Annotation + * @param test + */ + public function testReadAnnotationNoLowercase(){ + $reader = new ControllerMethodReflector(); + $reader->reflect( + '\OC\AppFramework\Utility\ControllerMethodReflectorTest', + 'testReadAnnotationNoLowercase' + ); + + $this->assertTrue($reader->hasAnnotation('Annotation')); + $this->assertFalse($reader->hasAnnotation('param')); + } + + + /** + * @Annotation + * @param int $test + */ + public function testReadTypeIntAnnotations(){ + $reader = new ControllerMethodReflector(); + $reader->reflect( + '\OC\AppFramework\Utility\ControllerMethodReflectorTest', + 'testReadTypeIntAnnotations' + ); + + $this->assertEquals('int', $reader->getType('test')); + } + + + /** + * @Annotation + * @param double $test something special + */ + public function testReadTypeDoubleAnnotations(){ + $reader = new ControllerMethodReflector(); + $reader->reflect( + '\OC\AppFramework\Utility\ControllerMethodReflectorTest', + 'testReadTypeDoubleAnnotations' + ); + + $this->assertEquals('double', $reader->getType('test')); + } + + + public function arguments($arg, $arg2) {} + public function testReflectParameters() { + $reader = new ControllerMethodReflector(); + $reader->reflect( + '\OC\AppFramework\Utility\ControllerMethodReflectorTest', + 'arguments' + ); + + $this->assertEquals(array('arg', 'arg2'), $reader->getParameters()); + } + + + public function arguments2($arg) {} + public function testReflectParameters2() { + $reader = new ControllerMethodReflector(); + $reader->reflect( + '\OC\AppFramework\Utility\ControllerMethodReflectorTest', + 'arguments2' + ); + + $this->assertEquals(array('arg',), $reader->getParameters()); + } + + +} diff --git a/tests/lib/appframework/utility/MethodAnnotationReaderTest.php b/tests/lib/appframework/utility/MethodAnnotationReaderTest.php deleted file mode 100644 index c68812aa5c..0000000000 --- a/tests/lib/appframework/utility/MethodAnnotationReaderTest.php +++ /dev/null @@ -1,55 +0,0 @@ -. - * - */ - - -namespace OC\AppFramework\Utility; - - -class MethodAnnotationReaderTest extends \PHPUnit_Framework_TestCase { - - - /** - * @Annotation - */ - public function testReadAnnotation(){ - $reader = new MethodAnnotationReader('\OC\AppFramework\Utility\MethodAnnotationReaderTest', - 'testReadAnnotation'); - - $this->assertTrue($reader->hasAnnotation('Annotation')); - } - - - /** - * @Annotation - * @param test - */ - public function testReadAnnotationNoLowercase(){ - $reader = new MethodAnnotationReader('\OC\AppFramework\Utility\MethodAnnotationReaderTest', - 'testReadAnnotationNoLowercase'); - - $this->assertTrue($reader->hasAnnotation('Annotation')); - $this->assertFalse($reader->hasAnnotation('param')); - } - - -} diff --git a/tests/lib/group.php b/tests/lib/group.php index 26232187c3..724e723b18 100644 --- a/tests/lib/group.php +++ b/tests/lib/group.php @@ -4,8 +4,8 @@ * * @author Robin Appelman * @author Bernhard Posselt - * @copyright 2012 Robin Appelman icewind@owncloud.com - * @copyright 2012 Bernhard Posselt nukeawhale@gmail.com + * @copyright 2012 Robin Appelman + * @copyright 2012 Bernhard Posselt * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE diff --git a/tests/lib/template.php b/tests/lib/template.php index eedf688721..819d592aac 100644 --- a/tests/lib/template.php +++ b/tests/lib/template.php @@ -3,7 +3,7 @@ * ownCloud * * @author Bernhard Posselt -* @copyright 2012 Bernhard Posselt nukeawhale@gmail.com +* @copyright 2012 Bernhard Posselt * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE