From fde9cabe9774b67e88ee8aa8fa39fe044fe2da2f Mon Sep 17 00:00:00 2001 From: Thomas Müller Date: Sat, 17 Aug 2013 11:16:48 +0200 Subject: initial import of appframework --- lib/appframework/middleware/middleware.php | 100 +++++++++++++ .../middleware/middlewaredispatcher.php | 159 +++++++++++++++++++++ .../middleware/security/securityexception.php | 41 ++++++ .../middleware/security/securitymiddleware.php | 141 ++++++++++++++++++ 4 files changed, 441 insertions(+) create mode 100644 lib/appframework/middleware/middleware.php create mode 100644 lib/appframework/middleware/middlewaredispatcher.php create mode 100644 lib/appframework/middleware/security/securityexception.php create mode 100644 lib/appframework/middleware/security/securitymiddleware.php (limited to 'lib/appframework/middleware') diff --git a/lib/appframework/middleware/middleware.php b/lib/appframework/middleware/middleware.php new file mode 100644 index 00000000000..4df88490468 --- /dev/null +++ b/lib/appframework/middleware/middleware.php @@ -0,0 +1,100 @@ +. + * + */ + + +namespace OC\AppFramework\Middleware; + +use OC\AppFramework\Http\Response; + + +/** + * Middleware is used to provide hooks before or after controller methods and + * deal with possible exceptions raised in the controller methods. + * They're modeled after Django's middleware system: + * https://docs.djangoproject.com/en/dev/topics/http/middleware/ + */ +abstract class Middleware { + + + /** + * This is being run in normal order before the controller is being + * called which allows several modifications and checks + * + * @param Controller $controller the controller that is being called + * @param string $methodName the name of the method that will be called on + * the controller + */ + public function beforeController($controller, $methodName){ + + } + + + /** + * This is being run when either the beforeController method or the + * controller method itself is throwing an exception. The middleware is + * asked in reverse order to handle the exception and to return a response. + * If the response is null, it is assumed that the exception could not be + * handled and the error will be thrown again + * + * @param Controller $controller the controller that is being called + * @param string $methodName the name of the method that will be called on + * the controller + * @param \Exception $exception the thrown exception + * @throws \Exception the passed in exception if it cant handle it + * @return Response a Response object in case that the exception was handled + */ + public function afterException($controller, $methodName, \Exception $exception){ + throw $exception; + } + + + /** + * This is being run after a successful controllermethod call and allows + * the manipulation of a Response object. The middleware is run in reverse order + * + * @param Controller $controller the controller that is being called + * @param string $methodName the name of the method that will be called on + * the controller + * @param Response $response the generated response from the controller + * @return Response a Response object + */ + public function afterController($controller, $methodName, Response $response){ + return $response; + } + + + /** + * This is being run after the response object has been rendered and + * allows the manipulation of the output. The middleware is run in reverse order + * + * @param Controller $controller the controller that is being called + * @param string $methodName the name of the method that will be called on + * the controller + * @param string $output the generated output from a response + * @return string the output that should be printed + */ + public function beforeOutput($controller, $methodName, $output){ + return $output; + } + +} diff --git a/lib/appframework/middleware/middlewaredispatcher.php b/lib/appframework/middleware/middlewaredispatcher.php new file mode 100644 index 00000000000..c2d16134dc5 --- /dev/null +++ b/lib/appframework/middleware/middlewaredispatcher.php @@ -0,0 +1,159 @@ +. + * + */ + + +namespace OC\AppFramework\Middleware; + +use OC\AppFramework\Controller\Controller; +use OC\AppFramework\Http\Response; + + +/** + * This class is used to store and run all the middleware in correct order + */ +class MiddlewareDispatcher { + + /** + * @var array array containing all the middlewares + */ + private $middlewares; + + /** + * @var int counter which tells us what middlware was executed once an + * exception occurs + */ + private $middlewareCounter; + + + /** + * Constructor + */ + public function __construct(){ + $this->middlewares = array(); + $this->middlewareCounter = 0; + } + + + /** + * Adds a new middleware + * @param Middleware $middleware the middleware which will be added + */ + public function registerMiddleware(Middleware $middleWare){ + array_push($this->middlewares, $middleWare); + } + + + /** + * returns an array with all middleware elements + * @return array the middlewares + */ + public function getMiddlewares(){ + return $this->middlewares; + } + + + /** + * This is being run in normal order before the controller is being + * called which allows several modifications and checks + * + * @param Controller $controller the controller that is being called + * @param string $methodName the name of the method that will be called on + * the controller + */ + public function beforeController(Controller $controller, $methodName){ + // we need to count so that we know which middlewares we have to ask in + // case theres an exception + for($i=0; $imiddlewares); $i++){ + $this->middlewareCounter++; + $middleware = $this->middlewares[$i]; + $middleware->beforeController($controller, $methodName); + } + } + + + /** + * This is being run when either the beforeController method or the + * controller method itself is throwing an exception. The middleware is asked + * in reverse order to handle the exception and to return a response. + * If the response is null, it is assumed that the exception could not be + * handled and the error will be thrown again + * + * @param Controller $controller the controller that is being called + * @param string $methodName the name of the method that will be called on + * the controller + * @param \Exception $exception the thrown exception + * @return Response a Response object if the middleware can handle the + * exception + * @throws \Exception the passed in exception if it cant handle it + */ + public function afterException(Controller $controller, $methodName, \Exception $exception){ + for($i=$this->middlewareCounter-1; $i>=0; $i--){ + $middleware = $this->middlewares[$i]; + try { + return $middleware->afterException($controller, $methodName, $exception); + } catch(\Exception $exception){ + continue; + } + } + throw $exception; + } + + + /** + * This is being run after a successful controllermethod call and allows + * the manipulation of a Response object. The middleware is run in reverse order + * + * @param Controller $controller the controller that is being called + * @param string $methodName the name of the method that will be called on + * the controller + * @param Response $response the generated response from the controller + * @return Response a Response object + */ + public function afterController(Controller $controller, $methodName, Response $response){ + for($i=count($this->middlewares)-1; $i>=0; $i--){ + $middleware = $this->middlewares[$i]; + $response = $middleware->afterController($controller, $methodName, $response); + } + return $response; + } + + + /** + * This is being run after the response object has been rendered and + * allows the manipulation of the output. The middleware is run in reverse order + * + * @param Controller $controller the controller that is being called + * @param string $methodName the name of the method that will be called on + * the controller + * @param string $output the generated output from a response + * @return string the output that should be printed + */ + public function beforeOutput(Controller $controller, $methodName, $output){ + for($i=count($this->middlewares)-1; $i>=0; $i--){ + $middleware = $this->middlewares[$i]; + $output = $middleware->beforeOutput($controller, $methodName, $output); + } + return $output; + } + +} diff --git a/lib/appframework/middleware/security/securityexception.php b/lib/appframework/middleware/security/securityexception.php new file mode 100644 index 00000000000..b32a2769ff5 --- /dev/null +++ b/lib/appframework/middleware/security/securityexception.php @@ -0,0 +1,41 @@ +. + * + */ + + +namespace OC\AppFramework\Middleware\Security; + + +/** + * Thrown when the security middleware encounters a security problem + */ +class SecurityException extends \Exception { + + /** + * @param string $msg the security error message + * @param bool $ajax true if it resulted because of an ajax request + */ + public function __construct($msg, $code = 0) { + parent::__construct($msg, $code); + } + +} diff --git a/lib/appframework/middleware/security/securitymiddleware.php b/lib/appframework/middleware/security/securitymiddleware.php new file mode 100644 index 00000000000..7a715f309a0 --- /dev/null +++ b/lib/appframework/middleware/security/securitymiddleware.php @@ -0,0 +1,141 @@ +. + * + */ + + +namespace OC\AppFramework\Middleware\Security; + +use OC\AppFramework\Controller\Controller; +use OC\AppFramework\Http\Http; +use OC\AppFramework\Http\Request; +use OC\AppFramework\Http\Response; +use OC\AppFramework\Http\JSONResponse; +use OC\AppFramework\Http\RedirectResponse; +use OC\AppFramework\Utility\MethodAnnotationReader; +use OC\AppFramework\Middleware\Middleware; +use OC\AppFramework\Core\API; + + +/** + * Used to do all the authentication and checking stuff for a controller method + * It reads out the annotations of a controller method and checks which if + * security things should be checked and also handles errors in case a security + * check fails + */ +class SecurityMiddleware extends Middleware { + + private $api; + + /** + * @var \OC\AppFramework\Http\Request + */ + private $request; + + /** + * @param API $api an instance of the api + */ + public function __construct(API $api, Request $request){ + $this->api = $api; + $this->request = $request; + } + + + /** + * This runs all the security checks before a method call. The + * security checks are determined by inspecting the controller method + * annotations + * @param string/Controller $controller the controllername or string + * @param string $methodName the name of the method + * @throws SecurityException when a security check fails + */ + 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->api->activateNavigationEntry(); + + // security checks + if(!$annotationReader->hasAnnotation('IsLoggedInExemption')) { + if(!$this->api->isLoggedIn()) { + throw new SecurityException('Current user is not logged in', Http::STATUS_UNAUTHORIZED); + } + } + + if(!$annotationReader->hasAnnotation('IsAdminExemption')) { + if(!$this->api->isAdminUser($this->api->getUserId())) { + throw new SecurityException('Logged in user must be an admin', Http::STATUS_FORBIDDEN); + } + } + + if(!$annotationReader->hasAnnotation('IsSubAdminExemption')) { + if(!$this->api->isSubAdminUser($this->api->getUserId())) { + throw new SecurityException('Logged in user must be a subadmin', Http::STATUS_FORBIDDEN); + } + } + + if(!$annotationReader->hasAnnotation('CSRFExemption')) { + if(!$this->api->passesCSRFCheck()) { + throw new SecurityException('CSRF check failed', Http::STATUS_PRECONDITION_FAILED); + } + } + + } + + + /** + * If an SecurityException is being caught, ajax requests return a JSON error + * response and non ajax requests redirect to the index + * @param Controller $controller the controller that is being called + * @param string $methodName the name of the method that will be called on + * the controller + * @param \Exception $exception the thrown exception + * @throws \Exception the passed in exception if it cant handle it + * @return Response a Response object or null in case that the exception could not be handled + */ + public function afterException($controller, $methodName, \Exception $exception){ + if($exception instanceof SecurityException){ + + if (stripos($this->request->getHeader('Accept'),'html')===false) { + + $response = new JSONResponse( + array('message' => $exception->getMessage()), + $exception->getCode() + ); + $this->api->log($exception->getMessage(), 'debug'); + } else { + + $url = $this->api->linkToAbsolute('index.php', ''); // TODO: replace with link to route + $response = new RedirectResponse($url); + $this->api->log($exception->getMessage(), 'debug'); + } + + return $response; + + } + + throw $exception; + } + +} -- cgit v1.2.3 From 395deacc6760564544a76338023d9b0bf39e0bfe Mon Sep 17 00:00:00 2001 From: Thomas Müller Date: Tue, 20 Aug 2013 21:21:21 +0200 Subject: reducing controller annotations to: @PublicPage - No user logon is expected @NoAdminRequired - the login user requires no admin rights @NoCSRFRequired - the incoming request will not check for CSRF token --- .../middleware/security/securitymiddleware.php | 19 +-- .../middleware/security/SecurityMiddlewareTest.php | 156 +++++---------------- 2 files changed, 41 insertions(+), 134 deletions(-) (limited to 'lib/appframework/middleware') diff --git a/lib/appframework/middleware/security/securitymiddleware.php b/lib/appframework/middleware/security/securitymiddleware.php index 7a715f309a0..52818b1b53e 100644 --- a/lib/appframework/middleware/security/securitymiddleware.php +++ b/lib/appframework/middleware/security/securitymiddleware.php @@ -77,25 +77,20 @@ class SecurityMiddleware extends Middleware { $this->api->activateNavigationEntry(); // security checks - if(!$annotationReader->hasAnnotation('IsLoggedInExemption')) { + $isPublicPage = $annotationReader->hasAnnotation('PublicPage'); + if(!$isPublicPage) { if(!$this->api->isLoggedIn()) { throw new SecurityException('Current user is not logged in', Http::STATUS_UNAUTHORIZED); } - } - - if(!$annotationReader->hasAnnotation('IsAdminExemption')) { - if(!$this->api->isAdminUser($this->api->getUserId())) { - throw new SecurityException('Logged in user must be an admin', Http::STATUS_FORBIDDEN); - } - } - if(!$annotationReader->hasAnnotation('IsSubAdminExemption')) { - if(!$this->api->isSubAdminUser($this->api->getUserId())) { - throw new SecurityException('Logged in user must be a subadmin', Http::STATUS_FORBIDDEN); + if(!$annotationReader->hasAnnotation('NoAdminRequired')) { + if(!$this->api->isAdminUser($this->api->getUserId())) { + throw new SecurityException('Logged in user must be an admin', Http::STATUS_FORBIDDEN); + } } } - if(!$annotationReader->hasAnnotation('CSRFExemption')) { + if(!$annotationReader->hasAnnotation('NoCSRFRequired')) { if(!$this->api->passesCSRFCheck()) { throw new SecurityException('CSRF check failed', Http::STATUS_PRECONDITION_FAILED); } diff --git a/tests/lib/appframework/middleware/security/SecurityMiddlewareTest.php b/tests/lib/appframework/middleware/security/SecurityMiddlewareTest.php index 0b2103564e4..90a19c9999d 100644 --- a/tests/lib/appframework/middleware/security/SecurityMiddlewareTest.php +++ b/tests/lib/appframework/middleware/security/SecurityMiddlewareTest.php @@ -80,67 +80,27 @@ class SecurityMiddlewareTest extends \PHPUnit_Framework_TestCase { /** - * @IsLoggedInExemption - * @CSRFExemption - * @IsAdminExemption - * @IsSubAdminExemption + * @PublicPage + * @NoCSRFRequired */ public function testSetNavigationEntry(){ $this->checkNavEntry('testSetNavigationEntry', true); } - private function ajaxExceptionCheck($method, $shouldBeAjax=false){ - $api = $this->getAPI(); - $api->expects($this->any()) - ->method('passesCSRFCheck') - ->will($this->returnValue(false)); - - $sec = new SecurityMiddleware($api, $this->request); - - try { - $sec->beforeController('\OC\AppFramework\Middleware\Security\SecurityMiddlewareTest', - $method); - } catch (SecurityException $ex){ - if($shouldBeAjax){ - $this->assertTrue($ex->isAjax()); - } else { - $this->assertFalse($ex->isAjax()); - } - - } - } - - - /** - * @Ajax - * @IsLoggedInExemption - * @CSRFExemption - * @IsAdminExemption - * @IsSubAdminExemption - */ - public function testAjaxException(){ - $this->ajaxExceptionCheck('testAjaxException'); - } - - - /** - * @IsLoggedInExemption - * @CSRFExemption - * @IsAdminExemption - * @IsSubAdminExemption - */ - public function testNoAjaxException(){ - $this->ajaxExceptionCheck('testNoAjaxException'); - } - - private function ajaxExceptionStatus($method, $test, $status) { $api = $this->getAPI(); $api->expects($this->any()) ->method($test) ->will($this->returnValue(false)); + // isAdminUser requires isLoggedIn call to return true + if ($test === 'isAdminUser') { + $api->expects($this->any()) + ->method('isLoggedIn') + ->will($this->returnValue(true)); + } + $sec = new SecurityMiddleware($api, $this->request); try { @@ -151,9 +111,6 @@ class SecurityMiddlewareTest extends \PHPUnit_Framework_TestCase { } } - /** - * @Ajax - */ public function testAjaxStatusLoggedInCheck() { $this->ajaxExceptionStatus( 'testAjaxStatusLoggedInCheck', @@ -163,8 +120,8 @@ class SecurityMiddlewareTest extends \PHPUnit_Framework_TestCase { } /** - * @Ajax - * @IsLoggedInExemption + * @NoCSRFRequired + * @NoAdminRequired */ public function testAjaxNotAdminCheck() { $this->ajaxExceptionStatus( @@ -175,23 +132,7 @@ class SecurityMiddlewareTest extends \PHPUnit_Framework_TestCase { } /** - * @Ajax - * @IsLoggedInExemption - * @IsAdminExemption - */ - public function testAjaxNotSubAdminCheck() { - $this->ajaxExceptionStatus( - 'testAjaxNotSubAdminCheck', - 'isSubAdminUser', - Http::STATUS_FORBIDDEN - ); - } - - /** - * @Ajax - * @IsLoggedInExemption - * @IsAdminExemption - * @IsSubAdminExemption + * @PublicPage */ public function testAjaxStatusCSRFCheck() { $this->ajaxExceptionStatus( @@ -202,11 +143,8 @@ class SecurityMiddlewareTest extends \PHPUnit_Framework_TestCase { } /** - * @Ajax - * @CSRFExemption - * @IsLoggedInExemption - * @IsAdminExemption - * @IsSubAdminExemption + * @PublicPage + * @NoCSRFRequired */ public function testAjaxStatusAllGood() { $this->ajaxExceptionStatus( @@ -231,11 +169,10 @@ class SecurityMiddlewareTest extends \PHPUnit_Framework_TestCase { ); } + /** - * @IsLoggedInExemption - * @CSRFExemption - * @IsAdminExemption - * @IsSubAdminExemption + * @PublicPage + * @NoCSRFRequired */ public function testNoChecks(){ $api = $this->getAPI(); @@ -245,9 +182,6 @@ class SecurityMiddlewareTest extends \PHPUnit_Framework_TestCase { $api->expects($this->never()) ->method('isAdminUser') ->will($this->returnValue(true)); - $api->expects($this->never()) - ->method('isSubAdminUser') - ->will($this->returnValue(true)); $api->expects($this->never()) ->method('isLoggedIn') ->will($this->returnValue(true)); @@ -264,10 +198,19 @@ class SecurityMiddlewareTest extends \PHPUnit_Framework_TestCase { ->method($expects) ->will($this->returnValue(!$shouldFail)); + // admin check requires login + if ($expects === 'isAdminUser') { + $api->expects($this->once()) + ->method('isLoggedIn') + ->will($this->returnValue(true)); + } + $sec = new SecurityMiddleware($api, $this->request); if($shouldFail){ $this->setExpectedException('\OC\AppFramework\Middleware\Security\SecurityException'); + } else { + $this->setExpectedException(null); } $sec->beforeController('\OC\AppFramework\Middleware\Security\SecurityMiddlewareTest', $method); @@ -275,9 +218,7 @@ class SecurityMiddlewareTest extends \PHPUnit_Framework_TestCase { /** - * @IsLoggedInExemption - * @IsAdminExemption - * @IsSubAdminExemption + * @PublicPage */ public function testCsrfCheck(){ $this->securityCheck('testCsrfCheck', 'passesCSRFCheck'); @@ -285,9 +226,7 @@ class SecurityMiddlewareTest extends \PHPUnit_Framework_TestCase { /** - * @IsLoggedInExemption - * @IsAdminExemption - * @IsSubAdminExemption + * @PublicPage */ public function testFailCsrfCheck(){ $this->securityCheck('testFailCsrfCheck', 'passesCSRFCheck', true); @@ -295,9 +234,8 @@ class SecurityMiddlewareTest extends \PHPUnit_Framework_TestCase { /** - * @CSRFExemption - * @IsAdminExemption - * @IsSubAdminExemption + * @NoCSRFRequired + * @NoAdminRequired */ public function testLoggedInCheck(){ $this->securityCheck('testLoggedInCheck', 'isLoggedIn'); @@ -305,9 +243,8 @@ class SecurityMiddlewareTest extends \PHPUnit_Framework_TestCase { /** - * @CSRFExemption - * @IsAdminExemption - * @IsSubAdminExemption + * @NoCSRFRequired + * @NoAdminRequired */ public function testFailLoggedInCheck(){ $this->securityCheck('testFailLoggedInCheck', 'isLoggedIn', true); @@ -315,9 +252,7 @@ class SecurityMiddlewareTest extends \PHPUnit_Framework_TestCase { /** - * @IsLoggedInExemption - * @CSRFExemption - * @IsSubAdminExemption + * @NoCSRFRequired */ public function testIsAdminCheck(){ $this->securityCheck('testIsAdminCheck', 'isAdminUser'); @@ -325,36 +260,13 @@ class SecurityMiddlewareTest extends \PHPUnit_Framework_TestCase { /** - * @IsLoggedInExemption - * @CSRFExemption - * @IsSubAdminExemption + * @NoCSRFRequired */ public function testFailIsAdminCheck(){ $this->securityCheck('testFailIsAdminCheck', 'isAdminUser', true); } - /** - * @IsLoggedInExemption - * @CSRFExemption - * @IsAdminExemption - */ - public function testIsSubAdminCheck(){ - $this->securityCheck('testIsSubAdminCheck', 'isSubAdminUser'); - } - - - /** - * @IsLoggedInExemption - * @CSRFExemption - * @IsAdminExemption - */ - public function testFailIsSubAdminCheck(){ - $this->securityCheck('testFailIsSubAdminCheck', 'isSubAdminUser', true); - } - - - public function testAfterExceptionNotCaughtThrowsItAgain(){ $ex = new \Exception(); $this->setExpectedException('\Exception'); -- cgit v1.2.3 From 911bd3c16f508eb8f3cb9b03a5a21e2aa72ebf79 Mon Sep 17 00:00:00 2001 From: Thomas Müller Date: Wed, 21 Aug 2013 01:00:26 +0200 Subject: moving response classes over to OCP --- lib/appframework/controller/controller.php | 4 +- lib/appframework/http/dispatcher.php | 3 + lib/appframework/http/downloadresponse.php | 2 +- lib/appframework/http/http.php | 62 +------- lib/appframework/http/jsonresponse.php | 74 --------- lib/appframework/http/redirectresponse.php | 2 + lib/appframework/http/response.php | 169 --------------------- lib/appframework/http/templateresponse.php | 126 --------------- lib/appframework/middleware/middleware.php | 2 +- .../middleware/middlewaredispatcher.php | 2 +- .../middleware/security/securitymiddleware.php | 4 +- lib/public/appframework/http/http.php | 89 +++++++++++ lib/public/appframework/http/jsonresponse.php | 74 +++++++++ lib/public/appframework/http/response.php | 169 +++++++++++++++++++++ lib/public/appframework/http/templateresponse.php | 126 +++++++++++++++ 15 files changed, 471 insertions(+), 437 deletions(-) delete mode 100644 lib/appframework/http/jsonresponse.php delete mode 100644 lib/appframework/http/response.php delete mode 100644 lib/appframework/http/templateresponse.php create mode 100644 lib/public/appframework/http/http.php create mode 100644 lib/public/appframework/http/jsonresponse.php create mode 100644 lib/public/appframework/http/response.php create mode 100644 lib/public/appframework/http/templateresponse.php (limited to 'lib/appframework/middleware') diff --git a/lib/appframework/controller/controller.php b/lib/appframework/controller/controller.php index f6f34618ec6..a7498ba0e1e 100644 --- a/lib/appframework/controller/controller.php +++ b/lib/appframework/controller/controller.php @@ -24,9 +24,9 @@ namespace OC\AppFramework\Controller; -use OC\AppFramework\Http\TemplateResponse; use OC\AppFramework\Http\Request; use OC\AppFramework\Core\API; +use OCP\AppFramework\Http\TemplateResponse; /** @@ -133,7 +133,7 @@ abstract class Controller { * @param string $renderAs user renders a full page, blank only your template * admin an entry in the admin settings * @param array $headers set additional headers in name/value pairs - * @return \OC\AppFramework\Http\TemplateResponse containing the page + * @return \OCP\AppFramework\Http\TemplateResponse containing the page */ public function render($templateName, array $params=array(), $renderAs='user', array $headers=array()){ diff --git a/lib/appframework/http/dispatcher.php b/lib/appframework/http/dispatcher.php index 183854650fb..ea57a6860cc 100644 --- a/lib/appframework/http/dispatcher.php +++ b/lib/appframework/http/dispatcher.php @@ -74,6 +74,9 @@ class Dispatcher { } catch(\Exception $exception){ $response = $this->middlewareDispatcher->afterException( $controller, $methodName, $exception); + if (is_null($response)) { + throw $exception; + } } $response = $this->middlewareDispatcher->afterController( diff --git a/lib/appframework/http/downloadresponse.php b/lib/appframework/http/downloadresponse.php index 096e4fc8331..67b9542dba6 100644 --- a/lib/appframework/http/downloadresponse.php +++ b/lib/appframework/http/downloadresponse.php @@ -28,7 +28,7 @@ namespace OC\AppFramework\Http; /** * Prompts the user to download the a file */ -abstract class DownloadResponse extends Response { +class DownloadResponse extends \OCP\AppFramework\Http\Response { private $filename; private $contentType; diff --git a/lib/appframework/http/http.php b/lib/appframework/http/http.php index 73f32d13b38..e00dc9cdc4a 100644 --- a/lib/appframework/http/http.php +++ b/lib/appframework/http/http.php @@ -25,67 +25,7 @@ namespace OC\AppFramework\Http; -class Http { - - const STATUS_CONTINUE = 100; - const STATUS_SWITCHING_PROTOCOLS = 101; - const STATUS_PROCESSING = 102; - const STATUS_OK = 200; - const STATUS_CREATED = 201; - const STATUS_ACCEPTED = 202; - const STATUS_NON_AUTHORATIVE_INFORMATION = 203; - const STATUS_NO_CONTENT = 204; - const STATUS_RESET_CONTENT = 205; - const STATUS_PARTIAL_CONTENT = 206; - const STATUS_MULTI_STATUS = 207; - const STATUS_ALREADY_REPORTED = 208; - const STATUS_IM_USED = 226; - const STATUS_MULTIPLE_CHOICES = 300; - const STATUS_MOVED_PERMANENTLY = 301; - const STATUS_FOUND = 302; - const STATUS_SEE_OTHER = 303; - const STATUS_NOT_MODIFIED = 304; - const STATUS_USE_PROXY = 305; - const STATUS_RESERVED = 306; - const STATUS_TEMPORARY_REDIRECT = 307; - const STATUS_BAD_REQUEST = 400; - const STATUS_UNAUTHORIZED = 401; - const STATUS_PAYMENT_REQUIRED = 402; - const STATUS_FORBIDDEN = 403; - const STATUS_NOT_FOUND = 404; - const STATUS_METHOD_NOT_ALLOWED = 405; - const STATUS_NOT_ACCEPTABLE = 406; - const STATUS_PROXY_AUTHENTICATION_REQUIRED = 407; - const STATUS_REQUEST_TIMEOUT = 408; - const STATUS_CONFLICT = 409; - const STATUS_GONE = 410; - const STATUS_LENGTH_REQUIRED = 411; - const STATUS_PRECONDITION_FAILED = 412; - const STATUS_REQUEST_ENTITY_TOO_LARGE = 413; - const STATUS_REQUEST_URI_TOO_LONG = 414; - const STATUS_UNSUPPORTED_MEDIA_TYPE = 415; - const STATUS_REQUEST_RANGE_NOT_SATISFIABLE = 416; - const STATUS_EXPECTATION_FAILED = 417; - const STATUS_IM_A_TEAPOT = 418; - const STATUS_UNPROCESSABLE_ENTITY = 422; - const STATUS_LOCKED = 423; - const STATUS_FAILED_DEPENDENCY = 424; - const STATUS_UPGRADE_REQUIRED = 426; - const STATUS_PRECONDITION_REQUIRED = 428; - const STATUS_TOO_MANY_REQUESTS = 429; - const STATUS_REQUEST_HEADER_FIELDS_TOO_LARGE = 431; - const STATUS_INTERNAL_SERVER_ERROR = 500; - const STATUS_NOT_IMPLEMENTED = 501; - const STATUS_BAD_GATEWAY = 502; - const STATUS_SERVICE_UNAVAILABLE = 503; - const STATUS_GATEWAY_TIMEOUT = 504; - const STATUS_HTTP_VERSION_NOT_SUPPORTED = 505; - const STATUS_VARIANT_ALSO_NEGOTIATES = 506; - const STATUS_INSUFFICIENT_STORAGE = 507; - const STATUS_LOOP_DETECTED = 508; - const STATUS_BANDWIDTH_LIMIT_EXCEEDED = 509; - const STATUS_NOT_EXTENDED = 510; - const STATUS_NETWORK_AUTHENTICATION_REQUIRED = 511; +class Http extends \OCP\AppFramework\Http\Http{ private $server; private $protocolVersion; diff --git a/lib/appframework/http/jsonresponse.php b/lib/appframework/http/jsonresponse.php deleted file mode 100644 index 750f8a2ad15..00000000000 --- a/lib/appframework/http/jsonresponse.php +++ /dev/null @@ -1,74 +0,0 @@ -. - * - */ - - -namespace OC\AppFramework\Http; - - -/** - * A renderer for JSON calls - */ -class JSONResponse extends Response { - - protected $data; - - - /** - * @param array|object $data the object or array that should be transformed - * @param int $statusCode the Http status code, defaults to 200 - */ - public function __construct($data=array(), $statusCode=Http::STATUS_OK) { - $this->data = $data; - $this->setStatus($statusCode); - $this->addHeader('X-Content-Type-Options', 'nosniff'); - $this->addHeader('Content-type', 'application/json; charset=utf-8'); - } - - - /** - * Returns the rendered json - * @return string the rendered json - */ - public function render(){ - return json_encode($this->data); - } - - /** - * Sets values in the data json array - * @param array|object $params an array or object which will be transformed - * to JSON - */ - public function setData($data){ - $this->data = $data; - } - - - /** - * Used to get the set parameters - * @return array the data - */ - public function getData(){ - return $this->data; - } - -} diff --git a/lib/appframework/http/redirectresponse.php b/lib/appframework/http/redirectresponse.php index 727e0fb642e..688447f1618 100644 --- a/lib/appframework/http/redirectresponse.php +++ b/lib/appframework/http/redirectresponse.php @@ -24,6 +24,8 @@ namespace OC\AppFramework\Http; +use OCP\AppFramework\Http\Response; + /** * Redirects to a different URL diff --git a/lib/appframework/http/response.php b/lib/appframework/http/response.php deleted file mode 100644 index 50778105f24..00000000000 --- a/lib/appframework/http/response.php +++ /dev/null @@ -1,169 +0,0 @@ -. - * - */ - - -namespace OC\AppFramework\Http; - - -/** - * Base class for responses. Also used to just send headers - */ -class Response { - - /** - * @var array default headers - */ - private $headers = array( - 'Cache-Control' => 'no-cache, must-revalidate' - ); - - - /** - * @var string - */ - private $status = Http::STATUS_OK; - - - /** - * @var \DateTime - */ - private $lastModified; - - - /** - * @var string - */ - private $ETag; - - - /** - * Caches the response - * @param int $cacheSeconds the amount of seconds that should be cached - * if 0 then caching will be disabled - */ - public function cacheFor($cacheSeconds) { - - if($cacheSeconds > 0) { - $this->addHeader('Cache-Control', 'max-age=' . $cacheSeconds . - ', must-revalidate'); - } else { - $this->addHeader('Cache-Control', 'no-cache, must-revalidate'); - } - - } - - - /** - * Adds a new header to the response that will be called before the render - * function - * @param string $name The name of the HTTP header - * @param string $value The value, null will delete it - */ - public function addHeader($name, $value) { - if(is_null($value)) { - unset($this->headers[$name]); - } else { - $this->headers[$name] = $value; - } - } - - - /** - * Returns the set headers - * @return array the headers - */ - public function getHeaders() { - $mergeWith = array(); - - if($this->lastModified) { - $mergeWith['Last-Modified'] = - $this->lastModified->format(\DateTime::RFC2822); - } - - if($this->ETag) { - $mergeWith['ETag'] = '"' . $this->ETag . '"'; - } - - return array_merge($mergeWith, $this->headers); - } - - - /** - * By default renders no output - * @return null - */ - public function render() { - return null; - } - - - /** - * Set response status - * @param int $status a HTTP status code, see also the STATUS constants - */ - public function setStatus($status) { - $this->status = $status; - } - - - /** - * Get response status - */ - public function getStatus() { - return $this->status; - } - - - /** - * @return string the etag - */ - public function getETag() { - return $this->ETag; - } - - - /** - * @return string RFC2822 formatted last modified date - */ - public function getLastModified() { - return $this->lastModified; - } - - - /** - * @param string $ETag - */ - public function setETag($ETag) { - $this->ETag = $ETag; - } - - - /** - * @param \DateTime $lastModified - */ - public function setLastModified($lastModified) { - $this->lastModified = $lastModified; - } - - -} diff --git a/lib/appframework/http/templateresponse.php b/lib/appframework/http/templateresponse.php deleted file mode 100644 index 0a32da4b1b4..00000000000 --- a/lib/appframework/http/templateresponse.php +++ /dev/null @@ -1,126 +0,0 @@ -. - * - */ - - -namespace OC\AppFramework\Http; - -use OC\AppFramework\Core\API; - - -/** - * Response for a normal template - */ -class TemplateResponse extends Response { - - protected $templateName; - protected $params; - protected $api; - protected $renderAs; - protected $appName; - - /** - * @param API $api an API instance - * @param string $templateName the name of the template - * @param string $appName optional if you want to include a template from - * a different app - */ - public function __construct(API $api, $templateName, $appName=null) { - $this->templateName = $templateName; - $this->appName = $appName; - $this->api = $api; - $this->params = array(); - $this->renderAs = 'user'; - } - - - /** - * Sets template parameters - * @param array $params an array with key => value structure which sets template - * variables - */ - public function setParams(array $params){ - $this->params = $params; - } - - - /** - * Used for accessing the set parameters - * @return array the params - */ - public function getParams(){ - return $this->params; - } - - - /** - * Used for accessing the name of the set template - * @return string the name of the used template - */ - public function getTemplateName(){ - return $this->templateName; - } - - - /** - * Sets the template page - * @param string $renderAs admin, user or blank. Admin also prints the admin - * settings header and footer, user renders the normal - * normal page including footer and header and blank - * just renders the plain template - */ - public function renderAs($renderAs){ - $this->renderAs = $renderAs; - } - - - /** - * Returns the set renderAs - * @return string the renderAs value - */ - public function getRenderAs(){ - return $this->renderAs; - } - - - /** - * Returns the rendered html - * @return string the rendered html - */ - public function render(){ - - if($this->appName !== null){ - $appName = $this->appName; - } else { - $appName = $this->api->getAppName(); - } - - $template = $this->api->getTemplate($this->templateName, $this->renderAs, $appName); - - foreach($this->params as $key => $value){ - $template->assign($key, $value); - } - - return $template->fetchPage(); - } - -} diff --git a/lib/appframework/middleware/middleware.php b/lib/appframework/middleware/middleware.php index 4df88490468..b12c03c3eb8 100644 --- a/lib/appframework/middleware/middleware.php +++ b/lib/appframework/middleware/middleware.php @@ -24,7 +24,7 @@ namespace OC\AppFramework\Middleware; -use OC\AppFramework\Http\Response; +use OCP\AppFramework\Http\Response; /** diff --git a/lib/appframework/middleware/middlewaredispatcher.php b/lib/appframework/middleware/middlewaredispatcher.php index c2d16134dc5..70ab108e6b8 100644 --- a/lib/appframework/middleware/middlewaredispatcher.php +++ b/lib/appframework/middleware/middlewaredispatcher.php @@ -25,7 +25,7 @@ namespace OC\AppFramework\Middleware; use OC\AppFramework\Controller\Controller; -use OC\AppFramework\Http\Response; +use OCP\AppFramework\Http\Response; /** diff --git a/lib/appframework/middleware/security/securitymiddleware.php b/lib/appframework/middleware/security/securitymiddleware.php index 52818b1b53e..4f1447e1afb 100644 --- a/lib/appframework/middleware/security/securitymiddleware.php +++ b/lib/appframework/middleware/security/securitymiddleware.php @@ -27,12 +27,12 @@ namespace OC\AppFramework\Middleware\Security; use OC\AppFramework\Controller\Controller; use OC\AppFramework\Http\Http; use OC\AppFramework\Http\Request; -use OC\AppFramework\Http\Response; -use OC\AppFramework\Http\JSONResponse; use OC\AppFramework\Http\RedirectResponse; use OC\AppFramework\Utility\MethodAnnotationReader; use OC\AppFramework\Middleware\Middleware; use OC\AppFramework\Core\API; +use OCP\AppFramework\Http\Response; +use OCP\AppFramework\Http\JSONResponse; /** diff --git a/lib/public/appframework/http/http.php b/lib/public/appframework/http/http.php new file mode 100644 index 00000000000..9eafe782726 --- /dev/null +++ b/lib/public/appframework/http/http.php @@ -0,0 +1,89 @@ +. + * + */ + + +namespace OCP\AppFramework\Http; + + +class Http { + + const STATUS_CONTINUE = 100; + const STATUS_SWITCHING_PROTOCOLS = 101; + const STATUS_PROCESSING = 102; + const STATUS_OK = 200; + const STATUS_CREATED = 201; + const STATUS_ACCEPTED = 202; + const STATUS_NON_AUTHORATIVE_INFORMATION = 203; + const STATUS_NO_CONTENT = 204; + const STATUS_RESET_CONTENT = 205; + const STATUS_PARTIAL_CONTENT = 206; + const STATUS_MULTI_STATUS = 207; + const STATUS_ALREADY_REPORTED = 208; + const STATUS_IM_USED = 226; + const STATUS_MULTIPLE_CHOICES = 300; + const STATUS_MOVED_PERMANENTLY = 301; + const STATUS_FOUND = 302; + const STATUS_SEE_OTHER = 303; + const STATUS_NOT_MODIFIED = 304; + const STATUS_USE_PROXY = 305; + const STATUS_RESERVED = 306; + const STATUS_TEMPORARY_REDIRECT = 307; + const STATUS_BAD_REQUEST = 400; + const STATUS_UNAUTHORIZED = 401; + const STATUS_PAYMENT_REQUIRED = 402; + const STATUS_FORBIDDEN = 403; + const STATUS_NOT_FOUND = 404; + const STATUS_METHOD_NOT_ALLOWED = 405; + const STATUS_NOT_ACCEPTABLE = 406; + const STATUS_PROXY_AUTHENTICATION_REQUIRED = 407; + const STATUS_REQUEST_TIMEOUT = 408; + const STATUS_CONFLICT = 409; + const STATUS_GONE = 410; + const STATUS_LENGTH_REQUIRED = 411; + const STATUS_PRECONDITION_FAILED = 412; + const STATUS_REQUEST_ENTITY_TOO_LARGE = 413; + const STATUS_REQUEST_URI_TOO_LONG = 414; + const STATUS_UNSUPPORTED_MEDIA_TYPE = 415; + const STATUS_REQUEST_RANGE_NOT_SATISFIABLE = 416; + const STATUS_EXPECTATION_FAILED = 417; + const STATUS_IM_A_TEAPOT = 418; + const STATUS_UNPROCESSABLE_ENTITY = 422; + const STATUS_LOCKED = 423; + const STATUS_FAILED_DEPENDENCY = 424; + const STATUS_UPGRADE_REQUIRED = 426; + const STATUS_PRECONDITION_REQUIRED = 428; + const STATUS_TOO_MANY_REQUESTS = 429; + const STATUS_REQUEST_HEADER_FIELDS_TOO_LARGE = 431; + const STATUS_INTERNAL_SERVER_ERROR = 500; + const STATUS_NOT_IMPLEMENTED = 501; + const STATUS_BAD_GATEWAY = 502; + const STATUS_SERVICE_UNAVAILABLE = 503; + const STATUS_GATEWAY_TIMEOUT = 504; + const STATUS_HTTP_VERSION_NOT_SUPPORTED = 505; + const STATUS_VARIANT_ALSO_NEGOTIATES = 506; + const STATUS_INSUFFICIENT_STORAGE = 507; + const STATUS_LOOP_DETECTED = 508; + const STATUS_BANDWIDTH_LIMIT_EXCEEDED = 509; + const STATUS_NOT_EXTENDED = 510; + const STATUS_NETWORK_AUTHENTICATION_REQUIRED = 511; +} diff --git a/lib/public/appframework/http/jsonresponse.php b/lib/public/appframework/http/jsonresponse.php new file mode 100644 index 00000000000..085fdbed2f9 --- /dev/null +++ b/lib/public/appframework/http/jsonresponse.php @@ -0,0 +1,74 @@ +. + * + */ + + +namespace OCP\AppFramework\Http; + + +/** + * A renderer for JSON calls + */ +class JSONResponse extends Response { + + protected $data; + + + /** + * @param array|object $data the object or array that should be transformed + * @param int $statusCode the Http status code, defaults to 200 + */ + public function __construct($data=array(), $statusCode=Http::STATUS_OK) { + $this->data = $data; + $this->setStatus($statusCode); + $this->addHeader('X-Content-Type-Options', 'nosniff'); + $this->addHeader('Content-type', 'application/json; charset=utf-8'); + } + + + /** + * Returns the rendered json + * @return string the rendered json + */ + public function render(){ + return json_encode($this->data); + } + + /** + * Sets values in the data json array + * @param array|object $params an array or object which will be transformed + * to JSON + */ + public function setData($data){ + $this->data = $data; + } + + + /** + * Used to get the set parameters + * @return array the data + */ + public function getData(){ + return $this->data; + } + +} diff --git a/lib/public/appframework/http/response.php b/lib/public/appframework/http/response.php new file mode 100644 index 00000000000..64477258948 --- /dev/null +++ b/lib/public/appframework/http/response.php @@ -0,0 +1,169 @@ +. + * + */ + + +namespace OCP\AppFramework\Http; + + +/** + * Base class for responses. Also used to just send headers + */ +class Response { + + /** + * @var array default headers + */ + private $headers = array( + 'Cache-Control' => 'no-cache, must-revalidate' + ); + + + /** + * @var string + */ + private $status = Http::STATUS_OK; + + + /** + * @var \DateTime + */ + private $lastModified; + + + /** + * @var string + */ + private $ETag; + + + /** + * Caches the response + * @param int $cacheSeconds the amount of seconds that should be cached + * if 0 then caching will be disabled + */ + public function cacheFor($cacheSeconds) { + + if($cacheSeconds > 0) { + $this->addHeader('Cache-Control', 'max-age=' . $cacheSeconds . + ', must-revalidate'); + } else { + $this->addHeader('Cache-Control', 'no-cache, must-revalidate'); + } + + } + + + /** + * Adds a new header to the response that will be called before the render + * function + * @param string $name The name of the HTTP header + * @param string $value The value, null will delete it + */ + public function addHeader($name, $value) { + if(is_null($value)) { + unset($this->headers[$name]); + } else { + $this->headers[$name] = $value; + } + } + + + /** + * Returns the set headers + * @return array the headers + */ + public function getHeaders() { + $mergeWith = array(); + + if($this->lastModified) { + $mergeWith['Last-Modified'] = + $this->lastModified->format(\DateTime::RFC2822); + } + + if($this->ETag) { + $mergeWith['ETag'] = '"' . $this->ETag . '"'; + } + + return array_merge($mergeWith, $this->headers); + } + + + /** + * By default renders no output + * @return null + */ + public function render() { + return null; + } + + + /** + * Set response status + * @param int $status a HTTP status code, see also the STATUS constants + */ + public function setStatus($status) { + $this->status = $status; + } + + + /** + * Get response status + */ + public function getStatus() { + return $this->status; + } + + + /** + * @return string the etag + */ + public function getETag() { + return $this->ETag; + } + + + /** + * @return string RFC2822 formatted last modified date + */ + public function getLastModified() { + return $this->lastModified; + } + + + /** + * @param string $ETag + */ + public function setETag($ETag) { + $this->ETag = $ETag; + } + + + /** + * @param \DateTime $lastModified + */ + public function setLastModified($lastModified) { + $this->lastModified = $lastModified; + } + + +} diff --git a/lib/public/appframework/http/templateresponse.php b/lib/public/appframework/http/templateresponse.php new file mode 100644 index 00000000000..97678c96cba --- /dev/null +++ b/lib/public/appframework/http/templateresponse.php @@ -0,0 +1,126 @@ +. + * + */ + + +namespace OCP\AppFramework\Http; + +use OC\AppFramework\Core\API; + + +/** + * Response for a normal template + */ +class TemplateResponse extends Response { + + protected $templateName; + protected $params; + protected $api; + protected $renderAs; + protected $appName; + + /** + * @param API $api an API instance + * @param string $templateName the name of the template + * @param string $appName optional if you want to include a template from + * a different app + */ + public function __construct(API $api, $templateName, $appName=null) { + $this->templateName = $templateName; + $this->appName = $appName; + $this->api = $api; + $this->params = array(); + $this->renderAs = 'user'; + } + + + /** + * Sets template parameters + * @param array $params an array with key => value structure which sets template + * variables + */ + public function setParams(array $params){ + $this->params = $params; + } + + + /** + * Used for accessing the set parameters + * @return array the params + */ + public function getParams(){ + return $this->params; + } + + + /** + * Used for accessing the name of the set template + * @return string the name of the used template + */ + public function getTemplateName(){ + return $this->templateName; + } + + + /** + * Sets the template page + * @param string $renderAs admin, user or blank. Admin also prints the admin + * settings header and footer, user renders the normal + * normal page including footer and header and blank + * just renders the plain template + */ + public function renderAs($renderAs){ + $this->renderAs = $renderAs; + } + + + /** + * Returns the set renderAs + * @return string the renderAs value + */ + public function getRenderAs(){ + return $this->renderAs; + } + + + /** + * Returns the rendered html + * @return string the rendered html + */ + public function render(){ + + if($this->appName !== null){ + $appName = $this->appName; + } else { + $appName = $this->api->getAppName(); + } + + $template = $this->api->getTemplate($this->templateName, $this->renderAs, $appName); + + foreach($this->params as $key => $value){ + $template->assign($key, $value); + } + + return $template->fetchPage(); + } + +} -- cgit v1.2.3