Browse Source

implement most of the basic stuff that was suggested in #8290

tags/v7.0.0alpha2
Bernhard Posselt 10 years ago
parent
commit
80648da431

+ 14
- 2
lib/private/appframework/dependencyinjection/dicontainer.php View File

@@ -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,11 @@ 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']
);
});


@@ -90,7 +95,11 @@ 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) {
@@ -118,6 +127,9 @@ class DIContainer extends SimpleContainer implements IAppContainer{
return new TimeFactory();
});

$this['ControllerMethodReflector'] = $this->share(function($c) {
return new ControllerMethodReflector();
});

}


+ 85
- 3
lib/private/appframework/http/dispatcher.php View File

@@ -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,71 @@ class Dispatcher {
}


/**
* Uses the reflected parameters, types and request parameters to execute
* the controller
* @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' ||
(
$this->request->method === 'POST' &&
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->formatResponse($response, $format);
}

return $response;
}

}

+ 8
- 8
lib/private/appframework/middleware/security/securitymiddleware.php View File

@@ -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;
@@ -55,10 +55,13 @@ class SecurityMiddleware extends Middleware {
/**
* @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 +75,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);
}

lib/private/appframework/utility/methodannotationreader.php → lib/private/appframework/utility/controllermethodreflector.php View File

@@ -28,23 +28,59 @@ 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 (?<type>\w+) \$(?<var>\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 strint $parameter the parameter whose type comments should be
* parsed
* @return string type in the type parameters (@param int $something) would
* return int
*/
public function getType($parameter) {
return $this->types[$parameter];
}


/**
* @return array the arguments of the method
*/
public function getParameters() {
return $this->parameters;
}



+ 65
- 0
lib/public/appframework/controller.php View File

@@ -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 $formatters;

/**
* constructor of the controller
@@ -66,11 +70,66 @@ abstract class Controller {
IRequest $request){
$this->appName = $appName;
$this->request = $request;

// default formatters
$this->formatters = 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 $closure
*/
protected function registerFormatter($format, \Closure $formatter) {
$this->formatters[$format] = $formatter;
}


/**
* 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 formatResponse($response, $format='json') {
if(array_key_exists($format, $this->formatters)) {

if ($this->serializer) {
$response = $this->serializer->serialize($response);
}

$formatter = $this->formatters[$format];
return $formatter($response);

} else {
throw new \DomainException('No formatter 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

tests/lib/appframework/utility/MethodAnnotationReaderTest.php → lib/public/appframework/http/iresponseserializer.php View File

@@ -1,5 +1,4 @@
<?php

/**
* ownCloud - App Framework
*
@@ -21,35 +20,8 @@
*
*/

namespace OCP\AppFramework\Http;

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'));
}


}
interface IResponseSerializer {
function serialize($response);
}

+ 7
- 3
lib/public/appframework/http/templateresponse.php View File

@@ -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;
}



+ 54
- 1
tests/lib/appframework/controller/ControllerTest.php View File

@@ -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->registerFormatter('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->formatResponse(null, 'test');
}


public function testFormat() {
$response = $this->controller->formatResponse(array('hi'), 'json');

$this->assertEquals(array('hi'), $response->getData());
}


public function testCustomFormatter() {
$response = $this->controller->custom('hi');
$response = $this->controller->formatResponse($response, 'json');

$this->assertEquals(array(2), $response->getData());
}


public function testCustomSerializer() {
$response = $this->controller->serializer('hi');
$response = $this->controller->formatResponse($response, 'json');

$this->assertEquals(array('HI'), $response->getData());
}


}

+ 154
- 10
tests/lib/appframework/http/DispatcherTest.php View File

@@ -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->registerFormatter('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' => '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,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]);
}

}

+ 16
- 30
tests/lib/appframework/http/TemplateResponseTest.php View File

@@ -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);

+ 22
- 11
tests/lib/appframework/middleware/security/SecurityMiddlewareTest.php View File

@@ -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);


+ 115
- 0
tests/lib/appframework/utility/ControllerMethodReflectorTest.php View File

@@ -0,0 +1,115 @@
<?php

/**
* ownCloud - App Framework
*
* @author Bernhard Posselt
* @copyright 2012 Bernhard Posselt nukeawhale@gmail.com
*
* 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 <http://www.gnu.org/licenses/>.
*
*/


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
*/
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());
}


}

Loading…
Cancel
Save